Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 00a2252

Browse files
committed
Refactor pass 1. Refactoring Gcf out of specific backend (backend_gtk3.py)
1 parent 30f9def commit 00a2252

File tree

3 files changed

+245
-5
lines changed

3 files changed

+245
-5
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import io
4141

4242
import numpy as np
43+
import matplotlib # temporary )assuming we refactor where marked below)
4344
import matplotlib.cbook as cbook
4445
import matplotlib.colors as colors
4546
import matplotlib.transforms as transforms
@@ -2534,6 +2535,165 @@ def key_press_handler(event, canvas, toolbar=None):
25342535
class NonGuiException(Exception):
25352536
pass
25362537

2538+
class WindowEvent(object):
2539+
def __init__(self, name, window):
2540+
self.name = name
2541+
self.window = window
2542+
2543+
class WindowBase(object):
2544+
def __init__(self, title):
2545+
self._callbacks = cbook.CallbackRegistry()
2546+
2547+
def mpl_connect(self, s, func):
2548+
return self._callbacks.connect(s, func)
2549+
2550+
def mpl_disconnect(self, cid):
2551+
return self._callbacks.disconnect(cid)
2552+
2553+
def show(self):
2554+
"""
2555+
For GUI backends, show the figure window and redraw.
2556+
For non-GUI backends, raise an exception to be caught
2557+
by :meth:`~matplotlib.figure.Figure.show`, for an
2558+
optional warning.
2559+
"""
2560+
raise NonGuiException()
2561+
2562+
def destroy(self):
2563+
pass
2564+
2565+
def set_fullscreen(self, fullscreen):
2566+
pass
2567+
2568+
def resize(self, w, h):
2569+
""""For gui backends, resize the window (in pixels)."""
2570+
pass
2571+
2572+
def get_window_title(self):
2573+
"""
2574+
Get the title text of the window containing the figure.
2575+
Return None for non-GUI backends (e.g., a PS backend).
2576+
"""
2577+
return 'image'
2578+
2579+
def set_window_title(self, title):
2580+
"""
2581+
Set the title text of the window containing the figure. Note that
2582+
this has no effect for non-GUI backends (e.g., a PS backend).
2583+
"""
2584+
pass
2585+
2586+
def add_element_to_window(self, element, expand, fill, padding, from_start=False):
2587+
""" Adds a gui widget to the window.
2588+
This has no effect for non-GUI backends
2589+
"""
2590+
pass
2591+
2592+
def terminate_backend(self):
2593+
"""Method to terminate the usage of the backend
2594+
"""
2595+
# TODO refactor me out on second pass
2596+
pass
2597+
2598+
def destroy_event(self, *args):
2599+
s = 'window_destroy_event'
2600+
event = WindowEvent(s, self)
2601+
self._callbacks.process(s, event)
2602+
2603+
2604+
class FigureManager(object):
2605+
def __init__(self, canvas, num, classes):
2606+
self._classes = classes
2607+
self.canvas = canvas
2608+
canvas.manager = self
2609+
self.num = num
2610+
2611+
self.key_press_handler_id = self.canvas.mpl_connect('key_press_event',
2612+
self.key_press)
2613+
2614+
self.window = classes['Window']('Figure %d' % num)
2615+
self.window.mpl_connect('window_destroy_event', self._destroy)
2616+
2617+
w = int(self.canvas.figure.bbox.width)
2618+
h = int(self.canvas.figure.bbox.height)
2619+
2620+
self.window.add_element_to_window(self.canvas, True, True, 0, True)
2621+
2622+
self.toolbar = self._get_toolbar(canvas)
2623+
if self.toolbar is not None:
2624+
h += self.window.add_element_to_window(self.toolbar, False, False, 0)
2625+
2626+
self.window.set_default_size(w,h)
2627+
2628+
# Refactor this? If so, delete import matplotlib from above.
2629+
if matplotlib.is_interactive():
2630+
self.window.show()
2631+
2632+
def notify_axes_change(fig):
2633+
'this will be called whenever the current axes is changed'
2634+
if self.toolbar is not None: self.toolbar.update()
2635+
self.canvas.figure.add_axobserver(notify_axes_change)
2636+
2637+
self.canvas.grab_focus()
2638+
2639+
def key_press(self, event):
2640+
"""
2641+
Implement the default mpl key bindings defined at
2642+
:ref:`key-event-handling`
2643+
"""
2644+
key_press_handler(event, self.canvas, self.canvas.toolbar)
2645+
2646+
def _destroy(self, event):
2647+
Gcf.destroy(self.num) # TODO refactor me out of here on second pass!
2648+
2649+
def destroy(self, *args):
2650+
self.window.destroy()
2651+
self.canvas.destroy()
2652+
if self.toolbar:
2653+
self.toolbar.destroy()
2654+
2655+
# TODO refactor out on second pass
2656+
if Gcf.get_num_fig_managers()==0 and not matplotlib.is_interactive():
2657+
self.window.terminate_backend()
2658+
2659+
def show(self):
2660+
self.window.show()
2661+
2662+
def full_screen_toggle(self):
2663+
self._full_screen_flag = not self._full_screen_flag
2664+
self.window.set_fullscreen(self._full_screen_flag)
2665+
2666+
def resize(self, w, h):
2667+
self.window.resize(w,h)
2668+
2669+
def get_window_title(self):
2670+
"""
2671+
Get the title text of the window containing the figure.
2672+
Return None for non-GUI backends (e.g., a PS backend).
2673+
"""
2674+
return self.window.get_window_title()
2675+
2676+
def set_window_title(self, title):
2677+
"""
2678+
Set the title text of the window containing the figure. Note that
2679+
this has no effect for non-GUI backends (e.g., a PS backend).
2680+
"""
2681+
self.window.set_window_title(title)
2682+
2683+
def show_popup(self, msg):
2684+
"""
2685+
Display message in a popup -- GUI only
2686+
"""
2687+
pass
2688+
2689+
def _get_toolbar(self, canvas):
2690+
# must be inited after the window, drawingArea and figure
2691+
# attrs are set
2692+
if rcParams['toolbar'] == 'toolbar2':
2693+
toolbar = self._classes['Toolbar2'](canvas, self.window)
2694+
else:
2695+
toolbar = None
2696+
return toolbar
25372697

25382698
class FigureManagerBase(object):
25392699
"""

lib/matplotlib/backends/backend_gtk3.py

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def fn_name(): return sys._getframe(1).f_code.co_name
2929
import matplotlib
3030
from matplotlib._pylab_helpers import Gcf
3131
from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \
32-
FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase
32+
FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase, WindowBase
3333
from matplotlib.backend_bases import ShowBase
3434

3535
from matplotlib.cbook import is_string_like, is_writable_file_like
@@ -374,6 +374,85 @@ def stop_event_loop(self):
374374
FigureCanvasBase.stop_event_loop_default(self)
375375
stop_event_loop.__doc__=FigureCanvasBase.stop_event_loop_default.__doc__
376376

377+
class WindowGTK3(WindowBase):
378+
def __init__(self, title):
379+
WindowBase.__init__(self, title)
380+
self.window = Gtk.Window()
381+
self.set_window_title(title)
382+
383+
try:
384+
self.window.set_icon_from_file(window_icon)
385+
except (SystemExit, KeyboardInterrupt):
386+
# re-raise exit type Exceptions
387+
raise
388+
except:
389+
# some versions of gtk throw a glib.GError but not
390+
# all, so I am not sure how to catch it. I am unhappy
391+
# doing a blanket catch here, but am not sure what a
392+
# better way is - JDH
393+
verbose.report('Could not load matplotlib icon: %s' % sys.exc_info()[1])
394+
395+
self.vbox = Gtk.Box()
396+
self.vbox.set_property('orientation', Gtk.Orientation.VERTICAL)
397+
self.window.add(self.vbox)
398+
self.vbox.show()
399+
400+
self.window.connect('destroy', self.destroy_event) # TODO create in base
401+
self.window.connect('delete_event', self.destroy_event)
402+
403+
def add_element_to_window(self, element, expand, fill, padding, from_start=False):
404+
element.show()
405+
if from_start:
406+
self.vbox.pack_start(element, expand, fill, padding)
407+
else:
408+
self.vbox.pack_end(element, False, False, 0)
409+
size_request = element.size_request()
410+
return size_request.height
411+
412+
def set_default_size(self, width, height):
413+
self.window.set_default_size(width, height)
414+
415+
def show(self):
416+
# show the figure window
417+
self.window.show()
418+
419+
def destroy(self):
420+
self.vbox.destroy()
421+
self.window.destroy()
422+
423+
# TODO refactor out on second pass.
424+
def terminate_backend(self):
425+
if Gtk.main_level() >= 1:
426+
Gtk.main_quit()
427+
428+
def set_fullscreen(self, fullscreen):
429+
if fullscreen:
430+
self.window.fullscreen()
431+
else:
432+
self.window.unfullscreen()
433+
434+
def _get_toolbar(self, canvas):
435+
# must be inited after the window, drawingArea and figure
436+
# attrs are set
437+
if rcParams['toolbar'] == 'toolbar2':
438+
toolbar = NavigationToolbar2GTK3 (canvas, self.window)
439+
else:
440+
toolbar = None
441+
return toolbar
442+
443+
def get_window_title(self):
444+
return self.window.get_title()
445+
446+
def set_window_title(self, title):
447+
self.window.set_title(title)
448+
449+
def resize(self, width, height):
450+
'set the canvas size in pixels'
451+
#_, _, cw, ch = self.canvas.allocation
452+
#_, _, ww, wh = self.window.allocation
453+
#self.window.resize (width-cw+ww, height-ch+wh)
454+
self.window.resize(width, height)
455+
377456

378457
class FigureManagerGTK3(FigureManagerBase):
379458
"""
@@ -887,3 +966,4 @@ def error_msg_gtk(msg, parent=None):
887966

888967
FigureCanvas = FigureCanvasGTK3
889968
FigureManager = FigureManagerGTK3
969+
Window = WindowGTK3

lib/matplotlib/backends/backend_gtk3cairo.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from . import backend_cairo
88
from .backend_cairo import cairo, HAS_CAIRO_CFFI
99
from matplotlib.figure import Figure
10+
from matplotlib.backend_bases import FigureManager
1011

1112
class RendererGTK3Cairo(backend_cairo.RendererCairo):
1213
def set_context(self, ctx):
@@ -51,7 +52,6 @@ def on_draw_event(self, widget, ctx):
5152
class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3):
5253
pass
5354

54-
5555
def new_figure_manager(num, *args, **kwargs):
5656
"""
5757
Create a new figure manager instance
@@ -66,10 +66,10 @@ def new_figure_manager_given_figure(num, figure):
6666
Create a new figure manager instance for the given figure.
6767
"""
6868
canvas = FigureCanvasGTK3Cairo(figure)
69-
manager = FigureManagerGTK3Cairo(canvas, num)
69+
manager = FigureManager(canvas, num, classes)
7070
return manager
7171

72-
72+
classes = {'Window': backend_gtk3.WindowGTK3,
73+
'Toolbar2': backend_gtk3.NavigationToolbar2GTK3}
7374
FigureCanvas = FigureCanvasGTK3Cairo
74-
FigureManager = FigureManagerGTK3Cairo
7575
show = backend_gtk3.show

0 commit comments

Comments
 (0)