From 2605f99d0f47aadec95b3ba5f5dc75d60853413d Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Thu, 12 Feb 2015 22:01:04 +0100 Subject: [PATCH 1/8] Refactored Toolbar out of NavigationBase --- lib/matplotlib/backend_bases.py | 63 +++++++++++++------------ lib/matplotlib/backend_tools.py | 41 ++++++++-------- lib/matplotlib/backends/backend_gtk3.py | 3 +- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 9f6f9f364433..f1c755772800 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -3387,17 +3387,15 @@ def add_tools(self, tools): ---------- tools : List List in the form - [[group1, [(Tool1, name1), (Tool2, name2) ...]][group2...]] - where group1 is the name of the group where the - Tool1, Tool2... are going to be added, and name1, name2... are the - names of the tools + [(Tool1, name1), (Tool2, name2) ...] + where Tool1, name1 represent the tool, and the respective name + of the tool which gets used as an id. """ - for group, grouptools in tools: - for position, tool in enumerate(grouptools): - self.add_tool(tool[1], tool[0], group, position) + for tool, name in tools: + self.add_tool(name, tool) - def add_tool(self, name, tool, group=None, position=None): + def add_tool(self, name, tool): """Add tool to `NavigationBase` Add a tool to the tools controlled by Navigation @@ -3412,10 +3410,6 @@ def add_tool(self, name, tool, group=None, position=None): Name of the tool, treated as the ID, has to be unique tool : string or `matplotlib.backend_tools.ToolBase` derived class Reference to find the class of the Tool to be added - group: String - Group to position the tool in - position : int or None (default) - Position within its group in the toolbar, if None, it goes at the end """ tool_cls = self._get_cls_to_instantiate(tool) @@ -3441,14 +3435,11 @@ def add_tool(self, name, tool, group=None, position=None): else: self._toggled.setdefault(tool_cls.radio_group, None) - self._tool_added_event(self._tools[name], group, position) + self._tool_added_event(self._tools[name]) - def _tool_added_event(self, tool, group, position): + def _tool_added_event(self, tool): s = 'tool_added_event' - event = ToolEvent(s, - self, - tool, - data={'group': group, 'position': position}) + event = ToolEvent(s, self, tool) self._callbacks.process(s, event) def _handle_toggle(self, tool, sender, canvasevent, data): @@ -3588,7 +3579,6 @@ def __init__(self, navigation): self.navigation = navigation self.navigation.nav_connect('tool_message_event', self._message_cbk) - self.navigation.nav_connect('tool_added_event', self._add_tool_cbk) self.navigation.nav_connect('tool_removed_event', self._remove_tool_cbk) @@ -3606,18 +3596,31 @@ def _tool_triggered_cbk(self, event): self.toggle_toolitem(event.tool.name) - def _add_tool_cbk(self, event): - """Captures 'tool_added_event' and adds the tool to the toolbar""" - image = self._get_image_filename(event.tool.image) - toggle = getattr(event.tool, 'toggled', None) is not None - self.add_toolitem(event.tool.name, - event.data['group'], - event.data['position'], - image, - event.tool.description, - toggle) + def add_tools(self, tools): + """ Add multiple tools to `Navigation` + + Parameters + ---------- + tools : List + List in the form + [[group1, [name1, name2 ...]][group2...]] + where group1 is the name of the group where the + Tool1, Tool2... are going to be added, and name1, name2... are the + names of the tools + """ + + for group, grouptools in tools: + for position, tool in enumerate(grouptools): + self.add_tool(self.navigation.get_tool(tool), group, position) + + def add_tool(self, tool, group, position): + """Adds a tool to the toolbar""" + image = self._get_image_filename(tool.image) + toggle = getattr(tool, 'toggled', None) is not None + self.add_toolitem(tool.name, group, position, image, + tool.description, toggle) if toggle: - self.navigation.nav_connect('tool_trigger_%s' % event.tool.name, + self.navigation.nav_connect('tool_trigger_%s' % tool.name, self._tool_triggered_cbk) def _remove_tool_cbk(self, event): diff --git a/lib/matplotlib/backend_tools.py b/lib/matplotlib/backend_tools.py index 97fbc0b680b3..0252657ce75f 100644 --- a/lib/matplotlib/backend_tools.py +++ b/lib/matplotlib/backend_tools.py @@ -903,26 +903,23 @@ def _mouse_move(self, event): self.navigation.canvas.draw_idle() -tools = [['navigation', [(ToolHome, 'home'), - (ToolBack, 'back'), - (ToolForward, 'forward')]], - - ['zoompan', [(ToolZoom, 'zoom'), - (ToolPan, 'pan')]], - - ['layout', [('ToolConfigureSubplots', 'subplots'), ]], - - ['io', [('ToolSaveFigure', 'save'), ]], - - [None, [(ToolGrid, 'grid'), - (ToolFullScreen, 'fullscreen'), - (ToolQuit, 'quit'), - (ToolEnableAllNavigation, 'allnav'), - (ToolEnableNavigation, 'nav'), - (ToolXScale, 'xscale'), - (ToolYScale, 'yscale'), - (ToolCursorPosition, 'position'), - (ToolViewsPositions, 'viewpos'), - ('ToolSetCursor', 'cursor'), - ('ToolRubberband', 'rubberband')]]] +tools = [(ToolHome, 'home'), (ToolBack, 'back'), (ToolForward, 'forward'), + (ToolZoom, 'zoom'), (ToolPan, 'pan'), + ('ToolConfigureSubplots', 'subplots'), + ('ToolSaveFigure', 'save'), + (ToolGrid, 'grid'), + (ToolFullScreen, 'fullscreen'), + (ToolQuit, 'quit'), + (ToolEnableAllNavigation, 'allnav'), + (ToolEnableNavigation, 'nav'), + (ToolXScale, 'xscale'), + (ToolYScale, 'yscale'), + (ToolCursorPosition, 'position'), + (ToolViewsPositions, 'viewpos'), + ('ToolSetCursor', 'cursor'), + ('ToolRubberband', 'rubberband')] +toolbar_tools = [['navigation', ['home', 'back', 'forward']], + ['zoompan', ['zoom', 'pan']], + ['layout', ['subplots']], + ['io', ['save']]] """Default tools""" diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index 5aa6474e4ee8..f5be4c2d4462 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -32,7 +32,7 @@ def fn_name(): return sys._getframe(1).f_code.co_name FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase from matplotlib.backend_bases import ShowBase, ToolbarBase, NavigationBase from matplotlib.backend_tools import SaveFigureBase, ConfigureSubplotsBase, \ - tools, SetCursorBase, RubberbandBase + tools, toolbar_tools, SetCursorBase, RubberbandBase from matplotlib.cbook import is_string_like, is_writable_file_like from matplotlib.colors import colorConverter @@ -418,6 +418,7 @@ def __init__(self, canvas, num): self.toolbar = self._get_toolbar() if matplotlib.rcParams['toolbar'] == 'navigation': self.navigation.add_tools(tools) + self.toolbar.add_tools(toolbar_tools) # calculate size for window w = int (self.canvas.figure.bbox.width) From 7683b0bc4711d19718c1d2e5b119a39937e5a442 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Mon, 16 Feb 2015 18:59:15 +0100 Subject: [PATCH 2/8] Some short cuts for adding tools --- lib/matplotlib/backend_bases.py | 22 ++++++++++++++++++++-- lib/matplotlib/backend_tools.py | 3 +++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index f1c755772800..dc5b7a0ca475 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -3422,7 +3422,13 @@ def add_tool(self, name, tool): 'not added') return - self._tools[name] = tool_cls(self, name) + if isinstance(tool_cls, type): + self._tools[name] = tool_cls(self, name) + else: + tool_cls.set_navigation(self) + tool.name = name + self._tools[name] = tool_cls + if tool_cls.keymap is not None: self.set_tool_keymap(name, tool_cls.keymap) @@ -3437,6 +3443,8 @@ def add_tool(self, name, tool): self._tool_added_event(self._tools[name]) + return self._tools[name] + def _tool_added_event(self, tool): s = 'tool_added_event' event = ToolEvent(s, self, tool) @@ -3611,10 +3619,20 @@ def add_tools(self, tools): for group, grouptools in tools: for position, tool in enumerate(grouptools): - self.add_tool(self.navigation.get_tool(tool), group, position) + self.add_tool(tool, group, position) def add_tool(self, tool, group, position): """Adds a tool to the toolbar""" + t = self.navigation.get_tool(tool) + if t is None: + if isinstance(tool, (list, tuple)): + t = self.navigation.add_tool(tool[0], tool[1]) + elif isinstance(tool, ToolBase): + t = self.navigation.add_tool(tool.name, tool) + else: + warning.warn('Cannot add tool %s'%tool) + return + tool = t image = self._get_image_filename(tool.image) toggle = getattr(tool, 'toggled', None) is not None self.add_toolitem(tool.name, group, position, image, diff --git a/lib/matplotlib/backend_tools.py b/lib/matplotlib/backend_tools.py index 0252657ce75f..8900aa6e9439 100644 --- a/lib/matplotlib/backend_tools.py +++ b/lib/matplotlib/backend_tools.py @@ -65,6 +65,9 @@ class ToolBase(object): def __init__(self, navigation, name): self._name = name self.figure = None + self.set_navigation(navigation) + + def set_navigation(self, navigation): self.navigation = navigation self.set_figure(navigation.canvas.figure) From 5dd6099d5227e777073e82334d7b2bae29cfb395 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Wed, 18 Feb 2015 16:17:04 +0100 Subject: [PATCH 3/8] Lots of fixes --- examples/user_interfaces/navigation.py | 2 +- lib/matplotlib/backend_bases.py | 56 ++++++++++++++----------- lib/matplotlib/backend_tools.py | 3 -- lib/matplotlib/backends/backend_gtk3.py | 22 ++++------ 4 files changed, 42 insertions(+), 41 deletions(-) diff --git a/examples/user_interfaces/navigation.py b/examples/user_interfaces/navigation.py index 8142082d98fd..4c4d320c176f 100644 --- a/examples/user_interfaces/navigation.py +++ b/examples/user_interfaces/navigation.py @@ -56,7 +56,7 @@ def trigger(self, *args, **kwargs): fig.canvas.manager.navigation.add_tool('List', ListTools) if matplotlib.rcParams['backend'] == 'GTK3Cairo': fig.canvas.manager.navigation.add_tool('copy', CopyToolGTK3) - +fig.canvas.manager.toolbar.add_tool('zoom', 'foo') # Uncomment to remove the forward button # fig.canvas.manager.navigation.remove_tool('forward') diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index dc5b7a0ca475..9901d518678a 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -3395,7 +3395,7 @@ def add_tools(self, tools): for tool, name in tools: self.add_tool(name, tool) - def add_tool(self, name, tool): + def add_tool(self, name, tool, *args, **kwargs): """Add tool to `NavigationBase` Add a tool to the tools controlled by Navigation @@ -3410,6 +3410,10 @@ def add_tool(self, name, tool): Name of the tool, treated as the ID, has to be unique tool : string or `matplotlib.backend_tools.ToolBase` derived class Reference to find the class of the Tool to be added + + Notes + ----- + args and kwargs get passed directly to the tools constructor. """ tool_cls = self._get_cls_to_instantiate(tool) @@ -3422,12 +3426,7 @@ def add_tool(self, name, tool): 'not added') return - if isinstance(tool_cls, type): - self._tools[name] = tool_cls(self, name) - else: - tool_cls.set_navigation(self) - tool.name = name - self._tools[name] = tool_cls + self._tools[name] = tool_cls(self, name, *args, **kwargs) if tool_cls.keymap is not None: self.set_tool_keymap(name, tool_cls.keymap) @@ -3442,7 +3441,6 @@ def add_tool(self, name, tool): self._toggled.setdefault(tool_cls.radio_group, None) self._tool_added_event(self._tools[name]) - return self._tools[name] def _tool_added_event(self, tool): @@ -3565,7 +3563,7 @@ def get_tool(self, name): name : String, ToolBase Name of the tool, or the tool itself """ - if isinstance(name, tools.ToolBase): + if isinstance(name, tools.ToolBase) and tool.name in self._tools: return name if name not in self._tools: warnings.warn("%s is not a tool controlled by Navigation" % name) @@ -3594,15 +3592,12 @@ def _message_cbk(self, event): """Captures the 'tool_message_event' to set the message on the toolbar""" self.set_message(event.message) - def _tool_triggered_cbk(self, event): + def _tool_toggled_cbk(self, event): """Captures the 'tool-trigger-toolname This only gets used for toggled tools """ - if event.sender is self: - return - - self.toggle_toolitem(event.tool.name) + self.toggle_toolitem(event.tool.name, event.tool.toggled) def add_tools(self, tools): """ Add multiple tools to `Navigation` @@ -3621,17 +3616,30 @@ def add_tools(self, tools): for position, tool in enumerate(grouptools): self.add_tool(tool, group, position) - def add_tool(self, tool, group, position): - """Adds a tool to the toolbar""" + def add_tool(self, tool, group, position=-1, name=None, **kwargs): + """Adds a tool to the toolbar + + Parameters + ---------- + tool : string, tool + The name or the type of tool to add. + group : string + The name of the group to add this tool to. + position : int + the relative position within the group to place this tool. + name : string (optional) + If given, and the above fails, we use this to create a new tool of + type given by tool, and use this as the name of the tool. + """ t = self.navigation.get_tool(tool) if t is None: - if isinstance(tool, (list, tuple)): - t = self.navigation.add_tool(tool[0], tool[1]) - elif isinstance(tool, ToolBase): - t = self.navigation.add_tool(tool.name, tool) - else: - warning.warn('Cannot add tool %s'%tool) - return + if isinstance(tool, type): + tool = tool.__class__ + if name is not None: + t = self.navigation.add_tool(name, tool, **kwargs) + if t is None: + warning.warn('Cannot add tool %s'%tool) + return tool = t image = self._get_image_filename(tool.image) toggle = getattr(tool, 'toggled', None) is not None @@ -3639,7 +3647,7 @@ def add_tool(self, tool, group, position): tool.description, toggle) if toggle: self.navigation.nav_connect('tool_trigger_%s' % tool.name, - self._tool_triggered_cbk) + self._tool_toggled_cbk) def _remove_tool_cbk(self, event): """Captures the 'tool_removed_event' signal and removes the tool""" diff --git a/lib/matplotlib/backend_tools.py b/lib/matplotlib/backend_tools.py index 8900aa6e9439..0252657ce75f 100644 --- a/lib/matplotlib/backend_tools.py +++ b/lib/matplotlib/backend_tools.py @@ -65,9 +65,6 @@ class ToolBase(object): def __init__(self, navigation, name): self._name = name self.figure = None - self.set_navigation(navigation) - - def set_navigation(self, navigation): self.navigation = navigation self.set_figure(navigation.canvas.figure) diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index f5be4c2d4462..531ab664a54b 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -764,7 +764,6 @@ def __init__(self, navigation): self.pack_start(self._toolbar, False, False, 0) self._toolbar.show_all() self._toolitems = {} - self._signals = {} self._setup_message_area() def _setup_message_area(self): @@ -785,9 +784,6 @@ def _setup_message_area(self): def add_toolitem(self, name, group, position, image_file, description, toggle): - if group is None: - return - if toggle: tbutton = Gtk.ToggleToolButton() else: @@ -806,8 +802,8 @@ def add_toolitem(self, name, group, position, image_file, description, signal = tbutton.connect('clicked', self._call_tool, name) tbutton.set_tooltip_text(description) tbutton.show_all() - self._toolitems[name] = tbutton - self._signals[name] = signal + self._toolitems.setdefault(name, []) + self._toolitems[name].append((tbutton, signal)) def _call_tool(self, btn, name): self.trigger_tool(name) @@ -815,20 +811,20 @@ def _call_tool(self, btn, name): def set_message(self, s): self.message.set_label(s) - def toggle_toolitem(self, name): + def toggle_toolitem(self, name, toggled): if name not in self._toolitems: return - - status = self._toolitems[name].get_active() - self._toolitems[name].handler_block(self._signals[name]) - self._toolitems[name].set_active(not status) - self._toolitems[name].handler_unblock(self._signals[name]) + for toolitem, signal in self._toolitems[name]: + toolitem.handler_block(signal) + toolitem.set_active(toggled) + toolitem.handler_unblock(signal) def remove_toolitem(self, name): if name not in self._toolitems: self.set_message('%s Not in toolbar' % name) return - self._toolbar.remove(self._toolitems[name]) + for toolitem, signal in self._toolitems[name]: + self._toolbar.remove(toolitem) del self._toolitems[name] def add_separator(self, pos=-1): From e5d47c157e92aa29e88fd83913a3ef3f9b34d95b Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Wed, 18 Feb 2015 17:01:09 +0100 Subject: [PATCH 4/8] Rename ToolbarBase -> ToolContainerBase --- lib/matplotlib/backend_bases.py | 4 ++-- lib/matplotlib/backends/backend_gtk3.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 9901d518678a..93608ca38fc3 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -30,7 +30,7 @@ user interaction (key press, toolbar clicks, ..) and the actions in response to the user inputs. -:class:`ToolbarBase` +:class:`ToolContainerBase` The base class for the Toolbar class of each interactive backend. """ @@ -3571,7 +3571,7 @@ def get_tool(self, name): return self._tools[name] -class ToolbarBase(object): +class ToolContainerBase(object): """Base class for `Toolbar` implementation Attributes diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index 531ab664a54b..9d7f41b81c5f 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -30,7 +30,7 @@ def fn_name(): return sys._getframe(1).f_code.co_name from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import RendererBase, GraphicsContextBase, \ FigureManagerBase, FigureCanvasBase, NavigationToolbar2, cursors, TimerBase -from matplotlib.backend_bases import ShowBase, ToolbarBase, NavigationBase +from matplotlib.backend_bases import ShowBase, ToolContainerBase, NavigationBase from matplotlib.backend_tools import SaveFigureBase, ConfigureSubplotsBase, \ tools, toolbar_tools, SetCursorBase, RubberbandBase @@ -753,9 +753,9 @@ def draw_rubberband(self, x0, y0, x1, y1): ToolRubberband = RubberbandGTK3 -class ToolbarGTK3(ToolbarBase, Gtk.Box): +class ToolbarGTK3(ToolContainerBase, Gtk.Box): def __init__(self, navigation): - ToolbarBase.__init__(self, navigation) + ToolContainerBase.__init__(self, navigation) Gtk.Box.__init__(self) self.set_property("orientation", Gtk.Orientation.VERTICAL) From 5276dd9080f04bdaed80a2675ee40ff0cece450c Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Thu, 19 Feb 2015 12:37:35 +0100 Subject: [PATCH 5/8] Fixes --- lib/matplotlib/backend_bases.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 93608ca38fc3..5d20d4d00ca6 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -3555,7 +3555,7 @@ def tools(self): return self._tools - def get_tool(self, name): + def get_tool(self, name, warn=True): """Return the tool object, also accepts the actual tool for convenience Parameters @@ -3563,10 +3563,11 @@ def get_tool(self, name): name : String, ToolBase Name of the tool, or the tool itself """ - if isinstance(name, tools.ToolBase) and tool.name in self._tools: + if isinstance(name, tools.ToolBase) and name.name in self._tools: return name if name not in self._tools: - warnings.warn("%s is not a tool controlled by Navigation" % name) + if warn: + warnings.warn("Navigation does not control tool %s" % name) return None return self._tools[name] @@ -3631,20 +3632,22 @@ def add_tool(self, tool, group, position=-1, name=None, **kwargs): If given, and the above fails, we use this to create a new tool of type given by tool, and use this as the name of the tool. """ - t = self.navigation.get_tool(tool) + t = self.navigation.get_tool(tool, False) if t is None: - if isinstance(tool, type): + if not (isinstance(tool, str) or isinstance(tool, type)): + # if not string nor class, then object, we need a class. tool = tool.__class__ if name is not None: t = self.navigation.add_tool(name, tool, **kwargs) if t is None: - warning.warn('Cannot add tool %s'%tool) + warnings.warn('Tool %s unknown by our navigation.' % tool + + ' To add a tool to navigation, give a name.') return tool = t image = self._get_image_filename(tool.image) toggle = getattr(tool, 'toggled', None) is not None - self.add_toolitem(tool.name, group, position, image, - tool.description, toggle) + self.add_toolitem(tool.name, group, position, + image, tool.description, toggle) if toggle: self.navigation.nav_connect('tool_trigger_%s' % tool.name, self._tool_toggled_cbk) From 94bc085dbec6dc165dbd3bb46f6892bf0c730bce Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Thu, 19 Feb 2015 16:41:59 +0100 Subject: [PATCH 6/8] Warning --- lib/matplotlib/backend_bases.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 5d20d4d00ca6..0f493edd366c 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -3573,13 +3573,13 @@ def get_tool(self, name, warn=True): class ToolContainerBase(object): - """Base class for `Toolbar` implementation + """Base class for all tool containers, e.g. toolbars. Attributes ---------- manager : `FigureManager` object that integrates this `Toolbar` - navigation : `NavigationBase` object that hold the tools that - this `Toolbar` wants to communicate with + navigation : `NavigationBase` object that holds the tools that + this `ToolContainer` wants to communicate with. """ def __init__(self, navigation): @@ -3601,7 +3601,7 @@ def _tool_toggled_cbk(self, event): self.toggle_toolitem(event.tool.name, event.tool.toggled) def add_tools(self, tools): - """ Add multiple tools to `Navigation` + """ Add multiple tools to the container. Parameters ---------- @@ -3643,6 +3643,9 @@ def add_tool(self, tool, group, position=-1, name=None, **kwargs): warnings.warn('Tool %s unknown by our navigation.' % tool + ' To add a tool to navigation, give a name.') return + elif name: + warnings.warn('Tool %s already in navigation, ignored name=%s' % + (tool, name)) tool = t image = self._get_image_filename(tool.image) toggle = getattr(tool, 'toggled', None) is not None From 6a0b3ccb2e177bacf7a46d1ac4c177bd93846814 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Thu, 19 Feb 2015 22:44:12 +0100 Subject: [PATCH 7/8] More fixes --- lib/matplotlib/backend_bases.py | 71 ++++++++++++++------------------- lib/matplotlib/backend_tools.py | 30 +++++++------- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 0f493edd366c..1f24305deebd 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -3385,14 +3385,15 @@ def add_tools(self, tools): Parameters ---------- - tools : List - List in the form - [(Tool1, name1), (Tool2, name2) ...] - where Tool1, name1 represent the tool, and the respective name - of the tool which gets used as an id. + tools : {str: class_like} + The tools to add in the form of {name: tool}. + + See Also + -------- + add_tool : For definition of class_like. """ - for tool, name in tools: + for name, tool in six.iteritems(tools): self.add_tool(name, tool) def add_tool(self, name, tool, *args, **kwargs): @@ -3406,14 +3407,18 @@ def add_tool(self, name, tool, *args, **kwargs): Parameters ---------- - name : string + name : str Name of the tool, treated as the ID, has to be unique - tool : string or `matplotlib.backend_tools.ToolBase` derived class - Reference to find the class of the Tool to be added + tool : class_like, i.e. str or type + Reference to find the class of the Tool to added. Notes ----- args and kwargs get passed directly to the tools constructor. + + See Also + -------- + backend_tools.ToolBase : The base class for tools. """ tool_cls = self._get_cls_to_instantiate(tool) @@ -3424,7 +3429,7 @@ def add_tool(self, name, tool, *args, **kwargs): if name in self._tools: warnings.warn('A tool_cls with the same name already exist, ' 'not added') - return + return self._tools[name] self._tools[name] = tool_cls(self, name, *args, **kwargs) @@ -3577,7 +3582,6 @@ class ToolContainerBase(object): Attributes ---------- - manager : `FigureManager` object that integrates this `Toolbar` navigation : `NavigationBase` object that holds the tools that this `ToolContainer` wants to communicate with. """ @@ -3617,36 +3621,19 @@ def add_tools(self, tools): for position, tool in enumerate(grouptools): self.add_tool(tool, group, position) - def add_tool(self, tool, group, position=-1, name=None, **kwargs): - """Adds a tool to the toolbar + def add_tool(self, tool, group, position=-1): + """Adds a tool to this container Parameters ---------- - tool : string, tool - The name or the type of tool to add. - group : string + tool : tool_like + The tool to add, see NavigationBase.get_tool. + group : str The name of the group to add this tool to. - position : int - the relative position within the group to place this tool. - name : string (optional) - If given, and the above fails, we use this to create a new tool of - type given by tool, and use this as the name of the tool. - """ - t = self.navigation.get_tool(tool, False) - if t is None: - if not (isinstance(tool, str) or isinstance(tool, type)): - # if not string nor class, then object, we need a class. - tool = tool.__class__ - if name is not None: - t = self.navigation.add_tool(name, tool, **kwargs) - if t is None: - warnings.warn('Tool %s unknown by our navigation.' % tool + - ' To add a tool to navigation, give a name.') - return - elif name: - warnings.warn('Tool %s already in navigation, ignored name=%s' % - (tool, name)) - tool = t + position : int (optional) + The position within the group to place this tool. Defaults to end. + """ + tool = self.navigation.get_tool(tool) image = self._get_image_filename(tool.image) toggle = getattr(tool, 'toggled', None) is not None self.add_toolitem(tool.name, group, position, @@ -3676,13 +3663,13 @@ def trigger_tool(self, name): Parameters ---------- name : String - Name(id) of the tool triggered from within the toolbar + Name(id) of the tool triggered from within the container """ self.navigation.tool_trigger_event(name, sender=self) def add_toolitem(self, name, group, position, image, description, toggle): - """Add a toolitem to the toolbar + """Add a toolitem to the container This method must get implemented per backend @@ -3722,18 +3709,20 @@ def set_message(self, s): pass - def toggle_toolitem(self, name): + def toggle_toolitem(self, name, toggled): """Toggle the toolitem without firing event Parameters ---------- name : String Id of the tool to toggle + toggled : bool + Whether to set this tool as toggled or not. """ raise NotImplementedError def remove_toolitem(self, name): - """Remove a toolitem from the `Toolbar` + """Remove a toolitem from the `ToolContainer` This method must get implemented per backend diff --git a/lib/matplotlib/backend_tools.py b/lib/matplotlib/backend_tools.py index 0252657ce75f..41945d170e73 100644 --- a/lib/matplotlib/backend_tools.py +++ b/lib/matplotlib/backend_tools.py @@ -903,21 +903,21 @@ def _mouse_move(self, event): self.navigation.canvas.draw_idle() -tools = [(ToolHome, 'home'), (ToolBack, 'back'), (ToolForward, 'forward'), - (ToolZoom, 'zoom'), (ToolPan, 'pan'), - ('ToolConfigureSubplots', 'subplots'), - ('ToolSaveFigure', 'save'), - (ToolGrid, 'grid'), - (ToolFullScreen, 'fullscreen'), - (ToolQuit, 'quit'), - (ToolEnableAllNavigation, 'allnav'), - (ToolEnableNavigation, 'nav'), - (ToolXScale, 'xscale'), - (ToolYScale, 'yscale'), - (ToolCursorPosition, 'position'), - (ToolViewsPositions, 'viewpos'), - ('ToolSetCursor', 'cursor'), - ('ToolRubberband', 'rubberband')] +tools = {'home': ToolHome, 'back': ToolBack, 'forward': ToolForward, + 'zoom': ToolZoom, 'pan': ToolPan, + 'subplots': 'ToolConfigureSubplots', + 'save': 'ToolSaveFigure', + 'grid': ToolGrid, + 'fullscreen': ToolFullScreen, + 'quit': ToolQuit, + 'allnav': ToolEnableAllNavigation, + 'nav': ToolEnableNavigation, + 'xscale': ToolXScale, + 'yscale': ToolYScale, + 'position': ToolCursorPosition, + 'viewpos': ToolViewsPositions, + 'cursor': 'ToolSetCursor', + 'rubberband': 'ToolRubberband'} toolbar_tools = [['navigation', ['home', 'back', 'forward']], ['zoompan', ['zoom', 'pan']], ['layout', ['subplots']], From 2cde4219ca77b024dd65b75009ea5c3e530f3d28 Mon Sep 17 00:00:00 2001 From: OceanWolf Date: Fri, 20 Feb 2015 04:56:09 +0100 Subject: [PATCH 8/8] Changes --- lib/matplotlib/backend_bases.py | 26 ++++++++++++-------------- lib/matplotlib/backend_tools.py | 4 +++- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 1f24305deebd..6681cb34a972 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -3381,16 +3381,13 @@ def remove_tool(self, name): del self._tools[name] def add_tools(self, tools): - """ Add multiple tools to `Navigation` + """ Add multiple tools to `NavigationBase` Parameters ---------- tools : {str: class_like} - The tools to add in the form of {name: tool}. - - See Also - -------- - add_tool : For definition of class_like. + The tools to add in a {name: tool} dict, see `add_tool` for more + info. """ for name, tool in six.iteritems(tools): @@ -3418,7 +3415,7 @@ def add_tool(self, name, tool, *args, **kwargs): See Also -------- - backend_tools.ToolBase : The base class for tools. + matplotlib.backend_tools.ToolBase : The base class for tools. """ tool_cls = self._get_cls_to_instantiate(tool) @@ -3565,8 +3562,10 @@ def get_tool(self, name, warn=True): Parameters ----------- - name : String, ToolBase + name : str, ToolBase Name of the tool, or the tool itself + warn : bool + If this method should give warnings. """ if isinstance(name, tools.ToolBase) and name.name in self._tools: return name @@ -3609,12 +3608,11 @@ def add_tools(self, tools): Parameters ---------- - tools : List + tools : list List in the form - [[group1, [name1, name2 ...]][group2...]] - where group1 is the name of the group where the - Tool1, Tool2... are going to be added, and name1, name2... are the - names of the tools + [[group1, [tool1, tool2 ...]], [group2, [...]]] + Where the tools given by tool1, and tool2 will display in group1. + See `add_tool` for details. """ for group, grouptools in tools: @@ -3627,7 +3625,7 @@ def add_tool(self, tool, group, position=-1): Parameters ---------- tool : tool_like - The tool to add, see NavigationBase.get_tool. + The tool to add, see `NavigationBase.get_tool`. group : str The name of the group to add this tool to. position : int (optional) diff --git a/lib/matplotlib/backend_tools.py b/lib/matplotlib/backend_tools.py index 41945d170e73..16cd67f374f0 100644 --- a/lib/matplotlib/backend_tools.py +++ b/lib/matplotlib/backend_tools.py @@ -918,8 +918,10 @@ def _mouse_move(self, event): 'viewpos': ToolViewsPositions, 'cursor': 'ToolSetCursor', 'rubberband': 'ToolRubberband'} +"""Default tools""" + toolbar_tools = [['navigation', ['home', 'back', 'forward']], ['zoompan', ['zoom', 'pan']], ['layout', ['subplots']], ['io', ['save']]] -"""Default tools""" +"""Default tools in the toolbar"""