|
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