Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
9813e43
Refactor pass 1. Refactoring Gcf out of specific backend (backend_gt…
OceanWolf Feb 21, 2015
91cbffc
Refactor Pass 2. Refactored Gcf out of all backend code.
OceanWolf Feb 22, 2015
aa3ff59
Quick fix to figure for safe unpickling.
OceanWolf Feb 25, 2015
f046e01
GTK3Agg
OceanWolf Feb 26, 2015
39ff708
Refactored making `FigureManager` a *figure* manager, plus added miss…
OceanWolf Feb 27, 2015
45c5fc2
keyword
OceanWolf Feb 27, 2015
ebf0c57
Make add_element more general, and make sure the code complies with it.
OceanWolf Feb 27, 2015
9d25441
Better destroy order.
OceanWolf Feb 27, 2015
6ae52f2
GTK simplifications
OceanWolf Feb 28, 2015
1a47d3b
Added doc and cleaned backend_managers, don't want our new file dirty.
OceanWolf Mar 3, 2015
bc17372
Improve layout!
OceanWolf Apr 6, 2015
3fb46f2
Move knowledge of the backend to the manager.
OceanWolf Apr 7, 2015
2758f3f
Incorporate MEP22 into MEP27
OceanWolf Apr 12, 2015
f354d3c
Improved new toolbar and updated tool_manager example accoridingly.
OceanWolf Apr 12, 2015
51c0598
fullscreen
OceanWolf Apr 13, 2015
6b35d85
MEP update
OceanWolf Apr 14, 2015
724b622
Finish MEP22 conversion
OceanWolf Apr 14, 2015
0b42bbe
rename window method
OceanWolf Apr 17, 2015
ef65740
Add backend anme to widgets
OceanWolf Apr 17, 2015
fb5202a
Handle FigureManager destroy internaly without pyplot.
OceanWolf Jun 4, 2015
26ce3e6
Make functionality more consistant for embedded applications
OceanWolf Jun 7, 2015
1cfebc4
Backend getter method for FigureManager
OceanWolf Jun 13, 2015
bc32fb1
Improve example after new method
OceanWolf Jun 13, 2015
81b9e69
Clean up the code a bit
OceanWolf Jun 13, 2015
85f0668
Remove old code from backend_managers
OceanWolf Jun 15, 2015
6535148
Cleanup
OceanWolf Jun 22, 2015
73e1122
Explicity get set manager as None if appropiate.
OceanWolf Jun 22, 2015
592c49b
figure attribute and canvas property
fariza Jun 22, 2015
b5d7f57
Fix FigureCanvasBase
OceanWolf Jun 23, 2015
b842bdc
super
OceanWolf Jun 25, 2015
92de15e
figure setter
fariza Jun 25, 2015
b619923
Improve MEP22 Tool Searching Structure
OceanWolf Jun 25, 2015
a07e482
adding example file
fariza Jun 25, 2015
2dd8895
super dooper
OceanWolf Jun 26, 2015
ce9c8e7
Revert old example and fix new one.
OceanWolf Jun 26, 2015
5542c5a
Improve MEP22 tool-searching method.
OceanWolf Jun 27, 2015
a975717
MEP22 Save Figure Tool
OceanWolf Jun 27, 2015
ecf1f23
pep8
OceanWolf Jun 27, 2015
4531085
Make ToolConfigureSubplots a generic tool
OceanWolf Jun 28, 2015
87fbd59
Improve flow handling and make it a lot more generic
OceanWolf Jun 28, 2015
f7eb33d
Missing resize method
OceanWolf Jun 28, 2015
0a2aa5c
Convert to new structure for finding tools
OceanWolf Jun 28, 2015
777b162
doc
OceanWolf Jun 29, 2015
468bdd7
Add ExpandableBase
OceanWolf Jun 29, 2015
209af6b
Template Backend plus fix FigManager for non-GUI backends and add gen…
OceanWolf Jun 29, 2015
06686c7
rcParam and Travis
OceanWolf Jul 19, 2015
2d93df8
test always MEP27
OceanWolf Jul 20, 2015
6b15982
Fix FigureManager to allow pyplot to work for non GUI backends
OceanWolf Jul 27, 2015
61f61f6
Fix Gcf.show_all()
OceanWolf Jul 27, 2015
71f4813
doc
OceanWolf Jul 27, 2015
d3064b6
pep8
OceanWolf Jul 27, 2015
2ca898c
remove show_popup
OceanWolf Jul 27, 2015
a567af6
AttributeError
OceanWolf Sep 22, 2015
09fc887
Fixes for MEP27
OceanWolf Aug 3, 2016
f60333d
STY: replace \ with () for line continuation
tacaswell Jun 19, 2017
072c47a
ENH: make MainLoopBase a context manager
tacaswell Jun 19, 2017
214b684
MNT: further simplify MainLoopBase
tacaswell Jun 25, 2017
35838c9
WIP:
tacaswell Jun 27, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Refactor pass 1. Refactoring Gcf out of specific backend (backend_gtk…
…3.py)
  • Loading branch information
OceanWolf authored and tacaswell committed Jun 19, 2017
commit 9813e4356e5ec8857be2f7e54cac2a24ab06be64
160 changes: 160 additions & 0 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import warnings

import numpy as np
import matplotlib # temporary )assuming we refactor where marked below)
import matplotlib.cbook as cbook
import matplotlib.colors as colors
import matplotlib.transforms as transforms
Expand Down Expand Up @@ -2609,6 +2610,165 @@ def _get_uniform_gridstate(ticks):
class NonGuiException(Exception):
pass

class WindowEvent(object):
def __init__(self, name, window):
self.name = name
self.window = window

class WindowBase(object):
def __init__(self, title):
self._callbacks = cbook.CallbackRegistry()

def mpl_connect(self, s, func):
return self._callbacks.connect(s, func)

def mpl_disconnect(self, cid):
return self._callbacks.disconnect(cid)

def show(self):
"""
For GUI backends, show the figure window and redraw.
For non-GUI backends, raise an exception to be caught
by :meth:`~matplotlib.figure.Figure.show`, for an
optional warning.
"""
raise NonGuiException()

def destroy(self):
pass

def set_fullscreen(self, fullscreen):
pass

def resize(self, w, h):
""""For gui backends, resize the window (in pixels)."""
pass

def get_window_title(self):
"""
Get the title text of the window containing the figure.
Return None for non-GUI backends (e.g., a PS backend).
"""
return 'image'

def set_window_title(self, title):
"""
Set the title text of the window containing the figure. Note that
this has no effect for non-GUI backends (e.g., a PS backend).
"""
pass

def add_element_to_window(self, element, expand, fill, padding, from_start=False):
""" Adds a gui widget to the window.
This has no effect for non-GUI backends
"""
pass

def terminate_backend(self):
"""Method to terminate the usage of the backend
"""
# TODO refactor me out on second pass
pass

def destroy_event(self, *args):
s = 'window_destroy_event'
event = WindowEvent(s, self)
self._callbacks.process(s, event)


class FigureManager(object):
def __init__(self, canvas, num, classes):
self._classes = classes
self.canvas = canvas
canvas.manager = self
self.num = num

self.key_press_handler_id = self.canvas.mpl_connect('key_press_event',
self.key_press)

self.window = classes['Window']('Figure %d' % num)
self.window.mpl_connect('window_destroy_event', self._destroy)

w = int(self.canvas.figure.bbox.width)
h = int(self.canvas.figure.bbox.height)

self.window.add_element_to_window(self.canvas, True, True, 0, True)

self.toolbar = self._get_toolbar(canvas)
if self.toolbar is not None:
h += self.window.add_element_to_window(self.toolbar, False, False, 0)

self.window.set_default_size(w,h)

# Refactor this? If so, delete import matplotlib from above.
if matplotlib.is_interactive():
self.window.show()

def notify_axes_change(fig):
'this will be called whenever the current axes is changed'
if self.toolbar is not None: self.toolbar.update()
self.canvas.figure.add_axobserver(notify_axes_change)

self.canvas.grab_focus()

def key_press(self, event):
"""
Implement the default mpl key bindings defined at
:ref:`key-event-handling`
"""
key_press_handler(event, self.canvas, self.canvas.toolbar)

def _destroy(self, event):
Gcf.destroy(self.num) # TODO refactor me out of here on second pass!

def destroy(self, *args):
self.window.destroy()
self.canvas.destroy()
if self.toolbar:
self.toolbar.destroy()

# TODO refactor out on second pass
if Gcf.get_num_fig_managers()==0 and not matplotlib.is_interactive():
self.window.terminate_backend()

def show(self):
self.window.show()

def full_screen_toggle(self):
self._full_screen_flag = not self._full_screen_flag
self.window.set_fullscreen(self._full_screen_flag)

def resize(self, w, h):
self.window.resize(w,h)

def get_window_title(self):
"""
Get the title text of the window containing the figure.
Return None for non-GUI backends (e.g., a PS backend).
"""
return self.window.get_window_title()

def set_window_title(self, title):
"""
Set the title text of the window containing the figure. Note that
this has no effect for non-GUI backends (e.g., a PS backend).
"""
self.window.set_window_title(title)

def show_popup(self, msg):
"""
Display message in a popup -- GUI only
"""
pass

def _get_toolbar(self, canvas):
# must be inited after the window, drawingArea and figure
# attrs are set
if rcParams['toolbar'] == 'toolbar2':
toolbar = self._classes['Toolbar2'](canvas, self.window)
else:
toolbar = None
return toolbar

class FigureManagerBase(object):
"""
Expand Down
82 changes: 81 additions & 1 deletion lib/matplotlib/backends/backend_gtk3.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from matplotlib._pylab_helpers import Gcf
from matplotlib.backend_bases import (
FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
NavigationToolbar2, RendererBase, TimerBase, cursors)
NavigationToolbar2, RendererBase, TimerBase, cursors, WindowBase)
from matplotlib.backend_bases import (
ShowBase, ToolContainerBase, StatusbarBase)
from matplotlib.backend_managers import ToolManager
Expand Down Expand Up @@ -361,6 +361,85 @@ def stop_event_loop(self):
FigureCanvasBase.stop_event_loop_default(self)
stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__

class WindowGTK3(WindowBase):
def __init__(self, title):
WindowBase.__init__(self, title)
self.window = Gtk.Window()
self.set_window_title(title)

try:
self.window.set_icon_from_file(window_icon)
except (SystemExit, KeyboardInterrupt):
# re-raise exit type Exceptions
raise
except:
# some versions of gtk throw a glib.GError but not
# all, so I am not sure how to catch it. I am unhappy
# doing a blanket catch here, but am not sure what a
# better way is - JDH
verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])

self.vbox = Gtk.Box()
self.vbox.set_property('orientation', Gtk.Orientation.VERTICAL)
self.window.add(self.vbox)
self.vbox.show()

self.window.connect('destroy', self.destroy_event) # TODO create in base
self.window.connect('delete_event', self.destroy_event)

def add_element_to_window(self, element, expand, fill, padding, from_start=False):
element.show()
if from_start:
self.vbox.pack_start(element, expand, fill, padding)
else:
self.vbox.pack_end(element, False, False, 0)
size_request = element.size_request()
return size_request.height

def set_default_size(self, width, height):
self.window.set_default_size(width, height)

def show(self):
# show the figure window
self.window.show()

def destroy(self):
self.vbox.destroy()
self.window.destroy()

# TODO refactor out on second pass.
def terminate_backend(self):
if Gtk.main_level() >= 1:
Gtk.main_quit()

def set_fullscreen(self, fullscreen):
if fullscreen:
self.window.fullscreen()
else:
self.window.unfullscreen()

def _get_toolbar(self, canvas):
# must be inited after the window, drawingArea and figure
# attrs are set
if rcParams['toolbar'] == 'toolbar2':
toolbar = NavigationToolbar2GTK3 (canvas, self.window)
else:
toolbar = None
return toolbar

def get_window_title(self):
return self.window.get_title()

def set_window_title(self, title):
self.window.set_title(title)

def resize(self, width, height):
'set the canvas size in pixels'
#_, _, cw, ch = self.canvas.allocation
#_, _, ww, wh = self.window.allocation
#self.window.resize (width-cw+ww, height-ch+wh)
self.window.resize(width, height)


class FigureManagerGTK3(FigureManagerBase):
"""
Expand Down Expand Up @@ -953,3 +1032,4 @@ def error_msg_gtk(msg, parent=None):
Toolbar = ToolbarGTK3
FigureCanvas = FigureCanvasGTK3
FigureManager = FigureManagerGTK3
Window = WindowGTK3
8 changes: 4 additions & 4 deletions lib/matplotlib/backends/backend_gtk3cairo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from . import backend_cairo
from .backend_cairo import cairo, HAS_CAIRO_CFFI
from matplotlib.figure import Figure
from matplotlib.backend_bases import FigureManager

class RendererGTK3Cairo(backend_cairo.RendererCairo):
def set_context(self, ctx):
Expand Down Expand Up @@ -51,7 +52,6 @@ def on_draw_event(self, widget, ctx):
class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3):
pass


def new_figure_manager(num, *args, **kwargs):
"""
Create a new figure manager instance
Expand All @@ -66,10 +66,10 @@ def new_figure_manager_given_figure(num, figure):
Create a new figure manager instance for the given figure.
"""
canvas = FigureCanvasGTK3Cairo(figure)
manager = FigureManagerGTK3Cairo(canvas, num)
manager = FigureManager(canvas, num, classes)
return manager


classes = {'Window': backend_gtk3.WindowGTK3,
'Toolbar2': backend_gtk3.NavigationToolbar2GTK3}
FigureCanvas = FigureCanvasGTK3Cairo
FigureManager = FigureManagerGTK3Cairo
show = backend_gtk3.show