|
40 | 40 | import io
|
41 | 41 |
|
42 | 42 | import numpy as np
|
43 |
| -import matplotlib # temporary )assuming we refactor where marked below) |
44 | 43 | import matplotlib.cbook as cbook
|
45 | 44 | import matplotlib.colors as colors
|
46 | 45 | import matplotlib.transforms as transforms
|
@@ -133,6 +132,33 @@ def get_registered_canvas_class(format):
|
133 | 132 | return backend_class
|
134 | 133 |
|
135 | 134 |
|
| 135 | +class MainLoopBase(object): |
| 136 | + """This gets used as a key maintaining the event loop. |
| 137 | + Backends should only need to override begin and end. |
| 138 | + It should not matter if this gets used as a singleton or not due to |
| 139 | + clever magic. |
| 140 | + """ |
| 141 | + _instance_count = {} |
| 142 | + def __init__(self): |
| 143 | + MainLoopBase._instance_count.setdefault(self.__class__, 0) |
| 144 | + MainLoopBase._instance_count[self.__class__] += 1 |
| 145 | + |
| 146 | + def begin(self): |
| 147 | + pass |
| 148 | + |
| 149 | + def end(self): |
| 150 | + pass |
| 151 | + |
| 152 | + def __call__(self): |
| 153 | + self.begin() |
| 154 | + |
| 155 | + def __del__(self): |
| 156 | + MainLoopBase._instance_count[self.__class__] -= 1 |
| 157 | + if (MainLoopBase._instance_count[self.__class__] <= 0 and |
| 158 | + not is_interactive()): |
| 159 | + self.end() |
| 160 | + |
| 161 | + |
136 | 162 | class ShowBase(object):
|
137 | 163 | """
|
138 | 164 | Simple base class to generate a show() callable in backends.
|
@@ -2460,7 +2486,10 @@ def key_press_handler(event, canvas, toolbar=None):
|
2460 | 2486 |
|
2461 | 2487 | # quit the figure (defaut key 'ctrl+w')
|
2462 | 2488 | if event.key in quit_keys:
|
2463 |
| - Gcf.destroy_fig(canvas.figure) |
| 2489 | + if isinstance(canvas.manager.mainloop, MainLoopBase): # If new no Gcf. |
| 2490 | + canvas.manager._destroy('window_destroy_event') |
| 2491 | + else: |
| 2492 | + Gcf.destroy_fig(canvas.figure) |
2464 | 2493 |
|
2465 | 2494 | if toolbar is not None:
|
2466 | 2495 | # home or reset mnemonic (default key 'h', 'home' and 'r')
|
@@ -2540,15 +2569,9 @@ def __init__(self, name, window):
|
2540 | 2569 | self.name = name
|
2541 | 2570 | self.window = window
|
2542 | 2571 |
|
2543 |
| -class WindowBase(object): |
| 2572 | +class WindowBase(cbook.EventListener): |
2544 | 2573 | 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) |
| 2574 | + cbook.EventListener.__init__(self) |
2552 | 2575 |
|
2553 | 2576 | def show(self):
|
2554 | 2577 | """
|
@@ -2589,112 +2612,12 @@ def add_element_to_window(self, element, expand, fill, padding, from_start=False
|
2589 | 2612 | """
|
2590 | 2613 | pass
|
2591 | 2614 |
|
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 | 2615 | def destroy_event(self, *args):
|
2599 | 2616 | s = 'window_destroy_event'
|
2600 | 2617 | event = WindowEvent(s, self)
|
2601 | 2618 | self._callbacks.process(s, event)
|
2602 | 2619 |
|
2603 | 2620 |
|
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 |
2697 |
| - |
2698 | 2621 | class FigureManagerBase(object):
|
2699 | 2622 | """
|
2700 | 2623 | Helper class for pyplot mode, wraps everything up into a neat bundle
|
|
0 commit comments