def _renderer_init(self): """Override by GTK backends to select a different renderer Renderer should provide the methods: _set_pixmap () _set_width_height () that are used by _render_to_pixmap() """ self._renderer = RendererGDK (self, self.figure.dpi)
class FigureCanvasGTK(gtk.DrawingArea, FigureCanvasBase): keyvald = {65507 : 'control', 65505 : 'shift', 65513 : 'alt', 65508 : 'control', 65506 : 'shift', 65514 : 'alt', } def __init__(self, figure): FigureCanvasBase.__init__(self, figure) gtk.DrawingArea.__init__(self) self._idleID = 0 # used in gtkAgg self._draw_pixmap = True self._pixmap_width = -1 self._pixmap_height = -1 self._lastCursor = None self.set_flags(gtk.CAN_FOCUS) self.grab_focus() self.set_size_request (int (figure.bbox.width()), int (figure.bbox.height())) self.set_double_buffered(False) self.connect('key_press_event', self.key_press_event) self.connect('key_release_event', self.key_release_event) self.connect('expose_event', self.expose_event) self.connect('configure_event', self.configure_event) self.connect('motion_notify_event', self.motion_notify_event) self.connect('button_press_event', self.button_press_event) self.connect('button_release_event', self.button_release_event) self.set_events( #gdk.FOCUS_CHANGE_MASK | gdk.KEY_PRESS_MASK | gdk.KEY_RELEASE_MASK | gdk.EXPOSURE_MASK | gdk.LEAVE_NOTIFY_MASK | gdk.BUTTON_PRESS_MASK | gdk.BUTTON_RELEASE_MASK | gdk.POINTER_MOTION_MASK ) self._renderer_init() def button_press_event(self, widget, event): x = event.x # flipy so y=0 is bottom of canvas y = self.figure.bbox.height() - event.y FigureCanvasBase.button_press_event(self, x, y, event.button) def button_release_event(self, widget, event): x = event.x # flipy so y=0 is bottom of canvas y = self.figure.bbox.height() - event.y FigureCanvasBase.button_release_event(self, x, y, event.button) def motion_notify_event(self, widget, event): x = event.x # flipy so y=0 is bottom of canvas y = self.figure.bbox.height() - event.y FigureCanvasBase.motion_notify_event(self, x, y) def _get_key(self, event): if self.keyvald.has_key(event.keyval): key = self.keyvald[event.keyval] elif event.keyval <256: key = chr(event.keyval) else: key = None ctrl = event.state & gtk.gdk.CONTROL_MASK shift = event.state & gtk.gdk.SHIFT_MASK return key def key_press_event(self, widget, event): key = self._get_key(event) FigureCanvasBase.key_press_event(self, key) def key_release_event(self, widget, event): key = self._get_key(event) FigureCanvasBase.key_release_event(self, key) def configure_event(self, widget, event): if widget.window == None: return w,h = widget.window.get_size() if w==1 or h==1: return # empty fig # resize the figure (in inches) dpi = self.figure.dpi.get() self.figure.set_figsize_inches (w/dpi, h/dpi) self._draw_pixmap = True return True def draw(self): self._draw_pixmap = True self.expose_event(self, None) def _renderer_init(self): """Override by GTK backends to select a different renderer Renderer should provide the methods: _set_pixmap () _set_width_height () that are used by _render_to_pixmap() """ self._renderer = RendererGDK (self, self.figure.dpi) def _render_to_pixmap(self, width, height): """Render the figure to a gdk.Pixmap, is used for - rendering the pixmap to display (pylab.draw) - rendering the pixmap to save to a file (pylab.savefig) Should not be overridden """ if DEBUG: print 'FigureCanvasGTK.%s' % fn_name() create_pixmap = False if width > self._pixmap_width: # increase the pixmap in 10%+ (rather than 1 pixel) steps self._pixmap_width = max (int (self._pixmap_width * 1.1), width) create_pixmap = True if height > self._pixmap_height: self._pixmap_height = max (int (self._pixmap_height * 1.1), height) create_pixmap = True if create_pixmap: if DEBUG: print 'FigureCanvasGTK.%s new pixmap' % fn_name() self._pixmap = gtk.gdk.Pixmap (self.window, self._pixmap_width, self._pixmap_height) self._renderer._set_pixmap (self._pixmap) self._renderer._set_width_height (width, height) self.figure.draw (self._renderer) def expose_event(self, widget, event): """Expose_event for all GTK backends Should not be overridden. """ if DEBUG: print 'FigureCanvasGTK.%s' % fn_name() if self._draw_pixmap and GTK_WIDGET_DRAWABLE(self): width, height = self.allocation.width, self.allocation.height self._render_to_pixmap(width, height) self.window.set_back_pixmap (self._pixmap, False) self.window.clear() # draw pixmap as the gdk.Window's bg self._draw_pixmap = False return True def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', orientation='portrait'): # TODO - use gdk print figure? root, ext = os.path.splitext(filename) ext = ext[1:] if ext == '': ext = IMAGE_FORMAT_DEFAULT filename = filename + '.' + ext # save figure settings origDPI = self.figure.dpi.get() origfacecolor = self.figure.get_facecolor() origedgecolor = self.figure.get_edgecolor() origWIn, origHIn = self.figure.get_size_inches() if self.flags() & gtk.REALIZED == 0: # for self.window(for pixmap) and has a side effect of altering figure width,height (via configure-event?) gtk.DrawingArea.realize(self) self.figure.dpi.set(dpi) self.figure.set_facecolor(facecolor) self.figure.set_edgecolor(edgecolor) ext = ext.lower() if ext in ('jpg', 'png'): # native printing width, height = self.figure.get_width_height() width, height = int(width), int(height) self._render_to_pixmap(width, height) # jpg colors don't match the display very well, png colors match better pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, width, height) pixbuf.get_from_drawable(self._pixmap, self._pixmap.get_colormap(), 0, 0, 0, 0, width, height) # pixbuf.save() recognises 'jpeg' not 'jpg' if ext == 'jpg': ext = 'jpeg' try: pixbuf.save(filename, ext) except gobject.GError, exc: error_msg('Save figure failure:\n%s' % (exc,), parent=self) elif ext in ('eps', 'ps', 'svg',): if ext == 'svg': from backend_svg import FigureCanvasSVG as FigureCanvas else: from backend_ps import FigureCanvasPS as FigureCanvas try: fc = self.switch_backends(FigureCanvas) fc.print_figure(filename, dpi, facecolor, edgecolor, orientation) except IOError, exc: error_msg("Save figure failure:\n%s: %s" % (exc.filename, exc.strerror), parent=self)
class FigureCanvasGTK(gtk.DrawingArea, FigureCanvasBase): keyvald = {65507 : 'control', 65505 : 'shift', 65513 : 'alt', 65508 : 'control', 65506 : 'shift', 65514 : 'alt', } def __init__(self, figure): FigureCanvasBase.__init__(self, figure) gtk.DrawingArea.__init__(self) self._idleID = 0 # used in gtkAgg self._draw_pixmap = True self._pixmap_width = -1 self._pixmap_height = -1 self._lastCursor = None self._button = None # the button pressed self._key = None # the key pressed self.set_flags(gtk.CAN_FOCUS) self.grab_focus() self.set_size_request (int (figure.bbox.width()), int (figure.bbox.height())) self.set_double_buffered(False) self.connect('key_press_event', self.key_press_event) self.connect('key_release_event', self.key_release_event) self.connect('expose_event', self.expose_event) self.connect('configure_event', self.configure_event) self.connect('motion_notify_event', self.motion_notify_event) self.connect('button_press_event', self.button_press_event) self.connect('button_release_event', self.button_release_event) self.set_events( #gdk.FOCUS_CHANGE_MASK | gdk.KEY_PRESS_MASK | gdk.KEY_RELEASE_MASK | gdk.EXPOSURE_MASK | gdk.LEAVE_NOTIFY_MASK | gdk.BUTTON_PRESS_MASK | gdk.BUTTON_RELEASE_MASK | gdk.POINTER_MOTION_MASK ) self._renderer_init() def button_press_event(self, widget, event): self._button = event.button def button_release_event(self, widget, event): self._button = None def motion_notify_event(self, widget, event): #print 'backend_gtk', event.x, event.y pass def key_press_event(self, widget, event): if self.keyvald.has_key(event.keyval): key = self.keyvald[event.keyval] elif event.keyval <256: key = chr(event.keyval) else: key = None ctrl = event.state & gtk.gdk.CONTROL_MASK shift = event.state & gtk.gdk.SHIFT_MASK self._key = key def key_release_event(self, widget, event): self._key = None def mpl_connect(self, s, func): if s not in self.events: raise MPLError('Can only connect events of type "%s"\nDo not know how to handle "%s"' %(', '.join(self.events), s)) #error_msg('Can only connect events of type "%s"\nDo not know how to handle "%s"' %(', '.join(self.events), s), # parent=self) def wrapper(widget, event): thisEvent = MplEvent(s, self) thisEvent.x = event.x # flipy so y=0 is bottom of canvas thisEvent.y = self.figure.bbox.height() - event.y thisEvent.button = self._button thisEvent.key = self._key thisEvent.inaxes = None for a in self.figure.get_axes(): if a.in_axes(thisEvent.x, thisEvent.y): thisEvent.inaxes = a xdata, ydata = a.transData.inverse_xy_tup((thisEvent.x, thisEvent.y)) thisEvent.xdata = xdata thisEvent.ydata = ydata break func(thisEvent) return False # return True blocks other connects cid = self.connect(s, wrapper) return cid def mpl_disconnect(self, cid): self.disconnect(cid) return None def configure_event(self, widget, event): if widget.window == None: return w,h = widget.window.get_size() if w==1 or h==1: return # empty fig # resize the figure (in inches) dpi = self.figure.dpi.get() self.figure.set_figsize_inches (w/dpi, h/dpi) self._draw_pixmap = True return True def draw(self): self._draw_pixmap = True self.expose_event(self, None) def _renderer_init(self): """Override by GTK backends to select a different renderer Renderer should provide the methods: _set_pixmap () _set_width_height () that are used by _render_to_pixmap() """ self._renderer = RendererGDK (self, self.figure.dpi) def _render_to_pixmap(self, width, height): """Render the figure to a gdk.Pixmap, is used for - rendering the pixmap to display (pylab.draw) - rendering the pixmap to save to a file (pylab.savefig) Should not be overridden """ if DEBUG: print 'FigureCanvasGTK.%s' % fn_name() create_pixmap = False if width > self._pixmap_width: # increase the pixmap in 10%+ (rather than 1 pixel) steps self._pixmap_width = max (int (self._pixmap_width * 1.1), width) create_pixmap = True if height > self._pixmap_height: self._pixmap_height = max (int (self._pixmap_height * 1.1), height) create_pixmap = True if create_pixmap: if DEBUG: print 'FigureCanvasGTK.%s new pixmap' % fn_name() self._pixmap = gtk.gdk.Pixmap (self.window, self._pixmap_width, self._pixmap_height) self._renderer._set_pixmap (self._pixmap) self._renderer._set_width_height (width, height) self.figure.draw (self._renderer) def expose_event(self, widget, event): """Expose_event for all GTK backends Should not be overridden. """ if DEBUG: print 'FigureCanvasGTK.%s' % fn_name() if self._draw_pixmap and GTK_WIDGET_DRAWABLE(self): width, height = self.allocation.width, self.allocation.height self._render_to_pixmap(width, height) self.window.set_back_pixmap (self._pixmap, False) self.window.clear() # draw pixmap as the gdk.Window's bg self._draw_pixmap = False return True def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', orientation='portrait'): root, ext = os.path.splitext(filename) ext = ext[1:] if ext == '': ext = IMAGE_FORMAT_DEFAULT filename = filename + '.' + ext # save figure settings origDPI = self.figure.dpi.get() origfacecolor = self.figure.get_facecolor() origedgecolor = self.figure.get_edgecolor() origWIn, origHIn = self.figure.get_size_inches() if self.flags() & gtk.REALIZED == 0: # for self.window(for pixmap) and has a side effect of altering figure width,height (via configure-event?) gtk.DrawingArea.realize(self) self.figure.dpi.set(dpi) self.figure.set_facecolor(facecolor) self.figure.set_edgecolor(edgecolor) ext = ext.lower() if ext in ('jpg', 'png'): # native printing width, height = self.figure.get_width_height() width, height = int(width), int(height) self._render_to_pixmap(width, height) # jpg colors don't match the display very well, png colors match better pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, width, height) pixbuf.get_from_drawable(self._pixmap, self._pixmap.get_colormap(), 0, 0, 0, 0, width, height) # pixbuf.save() recognises 'jpeg' not 'jpg' if ext == 'jpg': ext = 'jpeg' try: pixbuf.save(filename, ext) except gobject.GError, exc: error_msg('Save figure failure:\n%s' % (exc,), parent=self) elif ext in ('eps', 'ps', 'svg',): if ext == 'svg': from backend_svg import FigureCanvasSVG as FigureCanvas else: from backend_ps import FigureCanvasPS as FigureCanvas try: fc = self.switch_backends(FigureCanvas) fc.print_figure(filename, dpi, facecolor, edgecolor, orientation) except IOError, exc: error_msg("Save figure failure:\n%s: %s" % (exc.filename, exc.strerror), parent=self)
class FigureCanvasGTK(gtk.DrawingArea, FigureCanvasBase): keyvald = { 65507: 'control', 65505: 'shift', 65513: 'alt', 65508: 'control', 65506: 'shift', 65514: 'alt', 65361: 'left', 65362: 'up', 65363: 'right', 65364: 'down', } def __init__(self, figure): FigureCanvasBase.__init__(self, figure) gtk.DrawingArea.__init__(self) self._idleID = 0 self._draw_pixmap = True self._pixmap_width = -1 self._pixmap_height = -1 self._lastCursor = None self.set_flags(gtk.CAN_FOCUS) self.grab_focus() self.set_double_buffered(False) self.connect('key_press_event', self.key_press_event) self.connect('key_release_event', self.key_release_event) self.connect('expose_event', self.expose_event) self.connect('configure_event', self.configure_event) self.connect('motion_notify_event', self.motion_notify_event) self.connect('button_press_event', self.button_press_event) self.connect('button_release_event', self.button_release_event) self.set_events( #gdk.FOCUS_CHANGE_MASK | gdk.KEY_PRESS_MASK | gdk.KEY_RELEASE_MASK | gdk.EXPOSURE_MASK | gdk.LEAVE_NOTIFY_MASK | gdk.BUTTON_PRESS_MASK | gdk.BUTTON_RELEASE_MASK | gdk.POINTER_MOTION_MASK) self._renderer_init() def button_press_event(self, widget, event): x = event.x # flipy so y=0 is bottom of canvas y = self.figure.bbox.height() - event.y FigureCanvasBase.button_press_event(self, x, y, event.button) def button_release_event(self, widget, event): x = event.x # flipy so y=0 is bottom of canvas y = self.figure.bbox.height() - event.y FigureCanvasBase.button_release_event(self, x, y, event.button) def motion_notify_event(self, widget, event): x = event.x # flipy so y=0 is bottom of canvas y = self.figure.bbox.height() - event.y FigureCanvasBase.motion_notify_event(self, x, y) def _get_key(self, event): if self.keyvald.has_key(event.keyval): key = self.keyvald[event.keyval] elif event.keyval < 256: key = chr(event.keyval) else: key = None ctrl = event.state & gtk.gdk.CONTROL_MASK shift = event.state & gtk.gdk.SHIFT_MASK return key def key_press_event(self, widget, event): key = self._get_key(event) #print "hit", key FigureCanvasBase.key_press_event(self, key) def key_release_event(self, widget, event): key = self._get_key(event) #print "release", key FigureCanvasBase.key_release_event(self, key) def configure_event(self, widget, event): if widget.window == None: return w, h = widget.window.get_size() if w == 1 or h == 1: return # empty fig # resize the figure (in inches) dpi = self.figure.dpi.get() self.figure.set_figsize_inches(w / dpi, h / dpi) self._draw_pixmap = True return True def draw(self): self._draw_pixmap = True self.expose_event(self, None) def draw_idle(self): def idle_draw(*args): self.draw() self._idleID = 0 return False if self._idleID == 0: self._idleID = gobject.idle_add(idle_draw) def _renderer_init(self): """Override by GTK backends to select a different renderer Renderer should provide the methods: _set_pixmap () _set_width_height () that are used by _render_figure() """ self._renderer = RendererGDK(self, self.figure.dpi) def _render_figure(self, width, height): """Render the figure to a gdk.Pixmap, used by expose_event(). Is used for - rendering the pixmap to display (pylab.draw) - rendering the pixmap to save to a file (pylab.savefig) Should not be overridden by GTK backends """ if DEBUG: print 'FigureCanvasGTK.%s' % fn_name() create_pixmap = False if width > self._pixmap_width: # increase the pixmap in 10%+ (rather than 1 pixel) steps self._pixmap_width = max(int(self._pixmap_width * 1.1), width) create_pixmap = True if height > self._pixmap_height: self._pixmap_height = max(int(self._pixmap_height * 1.1), height) create_pixmap = True if create_pixmap: if DEBUG: print 'FigureCanvasGTK.%s new pixmap' % fn_name() self._pixmap = gtk.gdk.Pixmap(self.window, self._pixmap_width, self._pixmap_height) self._renderer._set_pixmap(self._pixmap) self._renderer._set_width_height(width, height) self.figure.draw(self._renderer) def expose_event(self, widget, event): """Expose_event for all GTK backends Should not be overridden. """ if DEBUG: print 'FigureCanvasGTK.%s' % fn_name() if not GTK_WIDGET_DRAWABLE(self): return False if self._draw_pixmap: width, height = self.allocation.width, self.allocation.height self._render_figure(width, height) self.window.set_back_pixmap(self._pixmap, False) self.window.clear() # draw pixmap as the gdk.Window's bg self._draw_pixmap = False else: # workaround pygtk 2.6 problem - bg not being redrawn self.window.clear_area(event.area.x, event.area.y, event.area.width, event.area.height) return False # allow signal to propagate further def print_figure(self, filename, dpi=150, facecolor='w', edgecolor='w', orientation='portrait'): # TODO - use gdk print figure? root, ext = os.path.splitext(filename) ext = ext[1:] if ext == '': ext = IMAGE_FORMAT_DEFAULT filename = filename + '.' + ext # save figure settings origDPI = self.figure.dpi.get() origfacecolor = self.figure.get_facecolor() origedgecolor = self.figure.get_edgecolor() origWIn, origHIn = self.figure.get_size_inches() if self.flags() & gtk.REALIZED == 0: # for self.window(for pixmap) and has a side effect of altering # figure width,height (via configure-event?) gtk.DrawingArea.realize(self) self.figure.dpi.set(dpi) self.figure.set_facecolor(facecolor) self.figure.set_edgecolor(edgecolor) ext = ext.lower() if ext in ('jpg', 'png'): # native printing width, height = self.figure.get_width_height() width, height = int(width), int(height) self._render_figure(width, height) # jpg colors don't match the display very well, png colors match # better pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, width, height) pixbuf.get_from_drawable(self._pixmap, self._pixmap.get_colormap(), 0, 0, 0, 0, width, height) # pixbuf.save() recognises 'jpeg' not 'jpg' if ext == 'jpg': ext = 'jpeg' try: pixbuf.save(filename, ext) except gobject.GError, exc: error_msg_gtk('Save figure failure:\n%s' % (exc, ), parent=self) elif ext in ( 'eps', 'ps', 'svg', ): if ext == 'svg': from backend_svg import FigureCanvasSVG as FigureCanvas else: from backend_ps import FigureCanvasPS as FigureCanvas try: fc = self.switch_backends(FigureCanvas) fc.print_figure(filename, dpi, facecolor, edgecolor, orientation) except IOError, exc: error_msg_gtk("Save figure failure:\n%s: %s" % (exc.filename, exc.strerror), parent=self)