8000 Refactor pass 1. Refactoring Gcf out of specific backend (backend_gt… · matplotlib/matplotlib@cd30d5b · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cd30d5b

Browse files
committed
Refactor pass 1. Refactoring Gcf out of specific backend (backend_gtk3.py)
1 parent 9edca5f commit cd30d5b

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
@@ -2536,6 +2537,165 @@ def key_press_handler(event, canvas, toolbar=None):
25362537
class NonGuiException(Exception):
25372538
pass
25382539

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

25402700
class FigureManagerBase(object):
25412701
"""

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)
0