-
Notifications
You must be signed in to change notification settings - Fork 1
Navigation decoupling using events #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3212,7 +3212,6 @@ def __init__(self, manager): | |
|
||
self._tools = {} | ||
self._keys = {} | ||
self._instances = {} | ||
self._toggled = None | ||
|
||
# to process keypress event | ||
|
@@ -3231,15 +3230,6 @@ def active_toggle(self): | |
|
||
return self._toggled | ||
|
||
@property | ||
def instances(self): | ||
"""Active tools instances | ||
|
||
**dictionary** : Contains the active instances that are registered | ||
""" | ||
|
||
return self._instances | ||
|
||
def get_tool_keymap(self, name): | ||
"""Get the keymap associated with a tool | ||
|
||
|
@@ -3280,6 +3270,10 @@ def set_tool_keymap(self, name, *keys): | |
(k, self._keys[k], name)) | ||
self._keys[k] = name | ||
|
||
def unregister_all(self): | ||
for name in self._tools.keys(): | ||
self.unregister(name) | ||
|
||
def unregister(self, name): | ||
"""Unregister the tool from the active instances | ||
|
||
|
@@ -3300,9 +3294,10 @@ def unregister(self, name): | |
""" | ||
|
||
if self._toggled == name: | ||
self._handle_toggle(name, from_toolbar=False) | ||
if name in self._instances: | ||
del self._instances[name] | ||
self._handle_toggle(name) | ||
if name in self._tools: | ||
self._tools[name].destroy() | ||
del self._tools[name] | ||
|
||
def remove_tool(self, name): | ||
"""Remove tool from the `Navigation` | ||
|
@@ -3314,7 +3309,6 @@ def remove_tool(self, name): | |
""" | ||
|
||
self.unregister(name) | ||
del self._tools[name] | ||
keys = [k for k, v in six.iteritems(self._keys) if v == name] | ||
for k in keys: | ||
del self._keys[k] | ||
|
@@ -3361,24 +3355,12 @@ def add_tool(self, name, tool, position=None): | |
'not added') | ||
return | ||
|
||
self._tools[name] = tool_cls | ||
self._tools[name] = tool_cls(self.canvas.figure, name) | ||
if tool_cls.keymap is not None: | ||
self.set_tool_keymap(name, tool_cls.keymap) | ||
|
||
if self.toolbar and tool_cls.intoolbar: | ||
# TODO: better search for images, they are not always in the | ||
# datapath | ||
basedir = os.path.join(rcParams['datapath'], 'images') | ||
if tool_cls.image is not None: | ||
fname = os.path.join(basedir, tool_cls.image) | ||
else: | ||
fname = None | ||
toggle = issubclass(tool_cls, tools.ToolToggleBase) | ||
self.toolbar._add_toolitem(name, | ||
tool_cls.description, | ||
fname, | ||
position, | ||
toggle) | ||
self.toolbar.add_tool(name, self._tools[name], position) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want users adding tools to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree, though not an issue for here after my rebase splitting. When I put this patch in (a different PR) I shall put it in as private and as and when I have figured out my preferred way of adding tools (on paper it looks almost done), I can make it public again (for you to comment on), if it still feels right. |
||
|
||
def _get_cls_to_instantiate(self, callback_class): | ||
if isinstance(callback_class, six.string_types): | ||
|
@@ -3400,21 +3382,17 @@ def trigger_tool(self, name): | |
Method to programatically "click" on Tools | ||
""" | ||
|
||
self._trigger_tool(name, None, False) | ||
self._trigger_tool(name, None) | ||
|
||
def _trigger_tool(self, name, event, from_toolbar): | ||
def _trigger_tool(self, name, event): | ||
if name not in self._tools: | ||
raise AttributeError('%s not in Tools' % name) | ||
|
||
tool = self._tools[name] | ||
if issubclass(tool, tools.ToolToggleBase): | ||
self._handle_toggle(name, event=event, from_toolbar=from_toolbar) | ||
elif issubclass(tool, tools.ToolPersistentBase): | ||
instance = self._get_instance(name) | ||
instance.trigger(event) | ||
if isinstance(tool, tools.ToolToggleBase): | ||
self._handle_toggle(name, event=event) | ||
else: | ||
# Non persistent tools, are instantiated and forgotten | ||
tool(self.canvas.figure, event) | ||
tool.trigger(event) | ||
|
||
def _key_press(self, event): | ||
if event.key is None or self.keypresslock.locked(): | ||
|
@@ -3423,15 +3401,13 @@ def _key_press(self, event): | |
name = self._keys.get(event.key, None) | ||
if name is None: | ||
return | ||
self._trigger_tool(name, event, False) | ||
self._trigger_tool(name, event) | ||
|
||
def _get_instance(self, name): | ||
if name not in self._instances: | ||
instance = self._tools[name](self.canvas.figure, name) | ||
# register instance | ||
self._instances[name] = instance | ||
if name not in self._tools: | ||
warning.warn('Tool with name %s, not registered with Navigation' % name) | ||
|
||
return self._instances[name] | ||
return self._tools[name] | ||
|
||
def _toolbar_callback(self, name): | ||
"""Callback for the `Toolbar` | ||
|
@@ -3446,14 +3422,9 @@ def _toolbar_callback(self, name): | |
toolbar | ||
""" | ||
|
||
self._trigger_tool(name, None, True) | ||
|
||
def _handle_toggle(self, name, event=None, from_toolbar=False): | ||
# toggle toolbar without callback | ||
if not from_toolbar and self.toolbar: | ||
self.toolbar._toggle(name, False) | ||
self._trigger_tool(name, None) | ||
|
||
instance = self._get_instance(name) | ||
def _handle_toggle(self, name, event=None): | ||
if self._toggled is None: | ||
# first trigger of tool | ||
self._toggled = name | ||
|
@@ -3462,13 +3433,10 @@ def _handle_toggle(self, name, event=None, from_toolbar=False): | |
self._toggled = None | ||
else: | ||
# other tool is triggered so trigger toggled tool | ||
if self.toolbar: | ||
# untoggle the previous toggled tool | ||
self.toolbar._toggle(self._toggled, False) | ||
self._get_instance(self._toggled).trigger(event) | ||
self._get_instance(self._toggled)._trigger(event) | ||
self._toggled = name | ||
|
||
instance.trigger(event) | ||
self._get_instance(name)._trigger(event) | ||
|
||
for a in self.canvas.figure.get_axes(): | ||
a.set_navigate_mode(self._toggled) | ||
|
@@ -3492,7 +3460,7 @@ def _mouse_move(self, event): | |
self._last_cursor = self._default_cursor | ||
else: | ||
if self._toggled: | ||
cursor = self._instances[self._toggled].cursor | ||
cursor = self._tools[self._toggled].cursor | ||
if cursor and self._last_cursor != cursor: | ||
self.set_cursor(cursor) | ||
self._last_cursor = cursor | ||
|
@@ -3553,6 +3521,8 @@ def remove_rubberband(self, event, caller): | |
if not self.canvas.widgetlock.available(caller): | ||
warnings.warn("%s doesn't own the canvas widgetlock" % caller) | ||
|
||
def __del__(self): | ||
self.unregister_all() | ||
|
||
class ToolbarBase(object): | ||
"""Base class for `Toolbar` implementation | ||
|
@@ -3570,6 +3540,20 @@ def __init__(self, manager): | |
""" | ||
|
||
self.manager = manager | ||
self.change_events = {} | ||
|
||
def add_tool(self, name, tool, position=None): | ||
# TODO: better search for images, they are not always in the | ||
# datapath | ||
basedir = os.path.join(rcParams['datapath'], 'images') | ||
if tool.image is not None: | ||
fname = os.path.join(basedir, tool.image) | ||
else: | ||
fname = None | ||
toggle = isinstance(tool, tools.ToolToggleBase) | ||
self._add_toolitem(name, tool.description, fname, position, toggle) | ||
|
||
self.change_events[name] = tool.mpl_connect('tool_state_changed_event', self._tool_state_change) | ||
|
||
def _add_toolitem(self, name, description, image_file, position, | ||
toggle): | ||
|
@@ -3616,16 +3600,16 @@ def set_message(self, s): | |
|
||
pass | ||
|
||
def _toggle(self, name, callback=False): | ||
"""Toogle a button | ||
def _set_state(self, name, toggled): | ||
"""Set the state of a button | ||
|
||
Parameters | ||
---------- | ||
name : string | ||
Name of the button to toggle | ||
callback : bool | ||
* `True`: call the button callback during toggle | ||
* `False`: toggle the button without calling the callback | ||
toggled : bool | ||
* `True`: set the pressed/checked state of the button | ||
* `False`: set the unpressed/unchecked state of the button | ||
|
||
""" | ||
|
||
|
@@ -3671,3 +3655,7 @@ def set_toolitem_visibility(self, name, visible): | |
""" | ||
|
||
pass | ||
|
||
def _tool_state_change(self, event): | ||
if isinstance(event.tool, tools.ToolToggleBase): | ||
self._set_state(event.tool.name, event.tool.toggled) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what case, name is not present in
self._tools
?