def create_ui(self): # create element self.ui_live = LiveControler(self, width=self.width, visible=False) self.ui_canvas = SlideContainer(self, pos=self.pos, size=self.size) self.ui_bookmark = BookmarkBar(self, pos=(80, self.height - 80), size=(self.width - 80, 80)) self.ui_toolbar = AddItemMenu(self, pos=(0, 0), size=(self.width, 80)) self.ui_workmode = WorkModeControler(self) self.ui_workmode.x = self.width - self.ui_workmode.width filename = os.path.join(os.path.dirname(__file__), 'data', 'save.png') self.ui_saveview = PresemtButton(filename=filename, cls='btnsave', pos=(0, self.height - 80), size=(80, 80)) # connect self.ui_saveview.connect('on_release', self.save_view) # add to root self.add_widget(self.ui_canvas) self.add_widget(self.ui_bookmark) self.add_widget(self.ui_toolbar) self.add_widget(self.ui_saveview) self.add_widget(self.ui_workmode) self.add_widget(self.ui_live)
class Presemt(MTWidget): slide_class = [] def __init__(self, **kwargs): super(Presemt, self).__init__(**kwargs) self.dirty = True self.filename = None self._mode = 'layout' self._filebrowser = None self._filebrowser_cb = None self.current_bookmark = None self.interpolation = 0.0 self.create_ui() @staticmethod def register_slide_class(type_factory): Presemt.slide_class.append(type_factory) def _filebrowser_select(self, files, *largs): if self._filebrowser_cb is None: return if not len(files): return filename = files[0] if os.path.isdir(filename): return self._filebrowser_cb(filename) def _filebrowser_touch(self, touch): if not self._filebrowser.collide_point(*touch.pos): self.close_filebrowser() def is_filebrowser_open(self): if self._filebrowser is None: return False return self._filebrowser in self.children def close_filebrowser(self): if self._filebrowser is None: return self.remove_widget(self._filebrowser) self._filebrowser_cb = None def open_filebrowser(self, callback, filters=[]): if self._filebrowser is None: self._filebrowser = MTFileBrowserView(pos=(0, 80), size=(350, getWindow().height - 160)) self._filebrowser.path = '.' self._filebrowser.connect('on_selection_change', self._filebrowser_select) self._filebrowser.connect('on_touch_down', self._filebrowser_touch) self.remove_widget(self._filebrowser) self.add_widget(self._filebrowser) self._filebrowser.filters = filters self._filebrowser_cb = callback self._filebrowser.update() return self._filebrowser def draw(self): set_color(*self.style.get('bg-color')) drawRectangle(pos=self.pos, size=self.size) def _get_mode(self): return self._mode def _set_mode(self, mode): self._mode = mode self.ui_workmode.update_state() if mode in ('layout', 'edit'): self.ui_canvas.show_grid = True self.ui_workmode.show() self.ui_bookmark.show() self.ui_toolbar.show() self.ui_saveview.show() self.ui_live.hide() else: self.ui_canvas.show_grid = False self.ui_workmode.hide() self.ui_bookmark.hide() self.ui_toolbar.hide() self.ui_saveview.hide() self.ui_live.show() mode = property(_get_mode, _set_mode) def create_ui(self): # create element self.ui_live = LiveControler(self, width=self.width, visible=False) self.ui_canvas = SlideContainer(self, pos=self.pos, size=self.size) self.ui_bookmark = BookmarkBar(self, pos=(80, self.height - 80), size=(self.width - 80, 80)) self.ui_toolbar = AddItemMenu(self, pos=(0, 0), size=(self.width, 80)) self.ui_workmode = WorkModeControler(self) self.ui_workmode.x = self.width - self.ui_workmode.width filename = os.path.join(os.path.dirname(__file__), 'data', 'save.png') self.ui_saveview = PresemtButton(filename=filename, cls='btnsave', pos=(0, self.height - 80), size=(80, 80)) # connect self.ui_saveview.connect('on_release', self.save_view) # add to root self.add_widget(self.ui_canvas) self.add_widget(self.ui_bookmark) self.add_widget(self.ui_toolbar) self.add_widget(self.ui_saveview) self.add_widget(self.ui_workmode) self.add_widget(self.ui_live) # set dirty def set_dirty(self, *largs): self.dirty = True def set_layout_mode(self, *largs): self.mode = 'layout' def goto_previous(self, *largs): self.ui_bookmark.previous() def goto_next(self, *largs): self.ui_bookmark.next() def save_view(self, *largs): self.ui_bookmark.create_bookmark() return True def capture_current_view(self): #current view = translation, scale and rotation around(0,0) #we store quaternion, becasue it is much better for interpolating angles (always rotates shortest way) scale = self.ui_canvas.scale pos = self.ui_canvas.to_parent(0, 0) quat = quaternion_from_matrix(self.ui_canvas.transform) return (scale, pos, quat) def goto_view(self, bookmark): self.source_view = self.capture_current_view() self.destination_view = bookmark.view_transform self.current_bookmark = bookmark self.interpolation = 1.0 def on_update(self): super(Presemt, self).on_update() if self.interpolation <= 0.0: return self.interpolation -= getFrameDt() if self.interpolation < 0: self.interpolation = 0 #i goes from 0.0 to 1.0 i = AnimationAlpha.ease_in_out_quint(abs(1.0-self.interpolation)) #create interpolated scale, translation and rotation matrix from saved state s = self.source_view[0] + i * (self.destination_view[0] - self.source_view[0]) scale = scale_matrix(s) spos, dpos = Vector(*self.source_view[1]), Vector(*self.destination_view[1]) t = spos + i*(dpos - spos ) translate = translation_matrix((t.x, t.y, 0)) q = quaternion_slerp(self.source_view[2], self.destination_view[2], i) rotate = quaternion_matrix(q) #combine the three matrices to get the transform for teh current interpolation value mat = concatenate_matrices(translate,rotate,scale) self.ui_canvas.transform = mat # finished ? if self.interpolation == 0 and self.current_bookmark: self.ui_bookmark.update_screenshot(self.current_bookmark) self.current_bookmark = None def export_to_pdf(self): def _screenshot(): # method imported from keybinding screenshot import pygame from OpenGL.GL import glReadBuffer, glReadPixels, GL_RGB, \ GL_UNSIGNED_BYTE, GL_BACK, GL_FRONT win = getWindow() glReadBuffer(GL_FRONT) data = glReadPixels(0, 0, win.width, win.height, GL_RGB, GL_UNSIGNED_BYTE) surface = pygame.image.fromstring(str(buffer(data)), win.size, 'RGB', True) filename = 'presemt.screenshot.tmp.jpg' pygame.image.save(surface, filename) return filename # create PDF ! from reportlab.pdfgen import canvas # do capture in live mode self.mode = 'live' self.remove_widget(self.ui_live) # create a pdf with the same name as our filename filename = '%s.pdf' % ('.'.join(self.filename.split('.')[:-1])) pdf = canvas.Canvas(filename, pagesize=getWindow().size) # prepare pymt to run in slave mode runTouchApp(self, slave=True) evloop = getEventLoop() # ensure the window have the good size getWindow().dispatch_event('on_resize', *getWindow().size) # wait loader to finished print 'Wait loader to finish to load all childrens' for x in self.ui_canvas.children: if not x.is_loaded: time.sleep(.1) evloop.idle() # capture all bookmark last_screenshot = None for bookmark in self.ui_bookmark.bookmarks_keys: # XXX called 2 times to be sure that translation is done self.goto_view(bookmark) self.interpolation = 0.0000001 # call idle twice evloop.idle() evloop.idle() # put image on pdf last_screenshot = _screenshot() pdf.drawInlineImage(last_screenshot, 0, 0) pdf.showPage() os.unlink(last_screenshot) # save pdf pdf.save() print print 'PDF saved to', filename print def save(self, *largs): data = {} data['view'] = self.ui_canvas.state data['bookmark'] = self.ui_bookmark.state data['items'] = [x.state for x in self.ui_canvas.children] data = json.dumps(data) filename = self.filename if filename is None: print data else: with open(filename, 'w') as fd: fd.write(data) self.dirty = False def load(self, filename): self.filename = filename data = None try: with open(filename, 'r') as fd: data = fd.read() except: return data = json.loads(data) if data is None: return # load view view = data.get('view', None) if view: self.ui_canvas.state = view # load bookmark bookmark = data.get('bookmark', None) if bookmark: self.ui_bookmark.state = bookmark # load items for x in data.get('items', []): name = x.get('name', None) if name is None: continue # search the item in the factory slide = None for slide_class in Presemt.slide_class: if slide_class.name == name: slide = slide_class(self, restoremode=True) if slide is None: print 'Unable to found Slide with name = ', name continue slide.state = x self.ui_canvas.add_widget(slide) self.dirty = False