Skip to content

Commit d484ebd

Browse files
committed
moving set_cursor completely out of navigation
1 parent 411e6e2 commit d484ebd

File tree

3 files changed

+177
-132
lines changed

3 files changed

+177
-132
lines changed

examples/user_interfaces/navigation.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,39 @@
44
matplotlib.rcParams['toolbar'] = 'navigation'
55
import matplotlib.pyplot as plt
66
from matplotlib.backend_tools import ToolBase
7-
from pydispatch import dispatcher
7+
88

99
# Create a simple tool to list all the tools
1010
class ListTools(ToolBase):
1111
# keyboard shortcut
1212
keymap = 'm'
1313
description = 'List Tools'
14-
14+
1515
def trigger(self, *args, **kwargs):
16-
tools = self.navigation.get_tools()
17-
1816
print ('_' * 80)
1917
print ("{0:12} {1:45} {2}".format('Name (id)',
2018
'Tool description',
2119
'Keymap'))
22-
print ('_' * 80)
20+
print ('-' * 80)
21+
tools = self.navigation.tools
2322
for name in sorted(tools.keys()):
24-
keys = ', '.join(sorted(tools[name]['keymap']))
23+
if not tools[name].description:
24+
continue
25+
keys = ', '.join(sorted(self.navigation.get_tool_keymap(name)))
2526
print ("{0:12} {1:45} {2}".format(name,
26-
tools[name]['description'],
27+
tools[name].description,
2728
keys))
28-
print ('_' * 80)
29-
30-
29+
print ('_' * 80)
30+
31+
3132
# A simple example of copy canvas
3233
# ref: at https://github.com/matplotlib/matplotlib/issues/1987
3334
class CopyToolGTK3(ToolBase):
3435
keymap = 'ctrl+c'
3536
description = 'Copy canvas'
3637
# It is not added to the toolbar as a button
3738
intoolbar = False
38-
39+
3940
def trigger(self, *args, **kwargs):
4041
from gi.repository import Gtk, Gdk
4142
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
@@ -52,7 +53,7 @@ def trigger(self, *args, **kwargs):
5253
fig.canvas.manager.navigation.add_tool('List', ListTools)
5354
if matplotlib.rcParams['backend'] == 'GTK3Cairo':
5455
fig.canvas.manager.navigation.add_tool('copy', CopyToolGTK3)
55-
56+
5657
# Uncomment to remove the forward button
5758
# fig.canvas.manager.navigation.remove_tool('forward')
5859

lib/matplotlib/backend_bases.py

+72-64
Original file line numberDiff line numberDiff line change
@@ -3234,9 +3234,9 @@ def __init__(self, name, sender):
32343234

32353235
class ToolTriggerEvent(ToolEvent):
32363236
"""Event to inform that a tool has been triggered"""
3237-
def __init__(self, name, toolname, sender, canvasevent=None, data=None):
3237+
def __init__(self, name, tool, sender, canvasevent=None, data=None):
32383238
ToolEvent.__init__(self, name, sender)
3239-
self.toolname = toolname
3239+
self.tool = tool
32403240
self.canvasevent = canvasevent
32413241
self.data = data
32423242

@@ -3254,10 +3254,10 @@ class NavigationBase(object):
32543254
32553255
Attributes
32563256
----------
3257-
manager : `FigureManager` instance
3258-
keypresslock : `LockDraw` to know if the `canvas` key_press_event is
3259-
locked
3260-
messagelock : `LockDraw` to know if the message is available to write
3257+
manager: `FigureManager` instance
3258+
keypresslock: `LockDraw` to know if the `canvas` key_press_event is
3259+
locked
3260+
messagelock: `LockDraw` to know if the message is available to write
32613261
"""
32623262

32633263
def __init__(self, manager):
@@ -3270,7 +3270,7 @@ def __init__(self, manager):
32703270
self._tools = {}
32713271
self._keys = {}
32723272
self._toggled = None
3273-
self.callbacks = cbook.CallbackRegistry()
3273+
self._callbacks = cbook.CallbackRegistry()
32743274

32753275
# to process keypress event
32763276
self.keypresslock = widgets.LockDraw()
@@ -3279,22 +3279,24 @@ def __init__(self, manager):
32793279
def mpl_connect(self, s, func):
32803280
"""Connect event with string *s* to *func*.
32813281
3282-
Parameters:
3282+
Parameters
32833283
-----------
3284-
s: String
3284+
s : String
32853285
Name of the event
3286+
32863287
The following events are recognized
3287-
- 'tool_message_even'
3288+
3289+
- 'tool_message_event'
32883290
- 'tool_removed_event'
32893291
- 'tool_added_event'
32903292
For every tool added a new event is created
32913293
- 'tool_trigger_TOOLNAME
32923294
Where TOOLNAME is the id of the tool.
3293-
func: function
3295+
func : function
32943296
Function to be called with signature
32953297
def func(event)
32963298
"""
3297-
return self.callbacks.connect(s, func)
3299+
return self._callbacks.connect(s, func)
32983300

32993301
def mpl_disconnect(self, cid):
33003302
"""Disconnect callback id cid
@@ -3305,16 +3307,16 @@ def mpl_disconnect(self, cid):
33053307
#...later
33063308
navigation.mpl_disconnect(cid)
33073309
"""
3308-
return self.callbacks.disconnect(cid)
3310+
return self._callbacks.disconnect(cid)
33093311

33103312
def message_event(self, message, sender=None):
3311-
""" Send a tool_message_event event"""
3313+
""" Emit a tool_message_event event"""
33123314
if sender is None:
33133315
sender = self
33143316

33153317
s = 'tool_message_event'
33163318
event = NavigationEvent(s, sender, message=message)
3317-
self.callbacks.process(s, event)
3319+
self._callbacks.process(s, event)
33183320

33193321
@property
33203322
def active_toggle(self):
@@ -3369,7 +3371,7 @@ def set_tool_keymap(self, name, *keys):
33693371
self._keys[k] = name
33703372

33713373
def remove_tool(self, name):
3372-
"""Remove tool from the `Navigation`
3374+
"""Remove tool from `Navigation`
33733375
33743376
Parameters
33753377
----------
@@ -3387,7 +3389,7 @@ def remove_tool(self, name):
33873389

33883390
s = 'tool_removed_event'
33893391
event = NavigationEvent(s, self, tool=tool)
3390-
self.callbacks.process(s, event)
3392+
self._callbacks.process(s, event)
33913393

33923394
del self._tools[name]
33933395

@@ -3396,33 +3398,37 @@ def add_tools(self, tools):
33963398
33973399
Parameters
33983400
----------
3399-
tools : a list of tuples which contains the id of the tool and
3400-
a either a reference to the tool Tool class itself, or None to
3401-
insert a spacer. See :func:`add_tool`.
3401+
tools : List
3402+
List in the form
3403+
[[group1, [(Tool1, name1), (Tool2, name2) ...]][group2...]]
3404+
where group1 is the name of the group where the
3405+
Tool1, Tool2... are going to be added, and name1, name2... are the
3406+
names of the tools
34023407
"""
34033408

34043409
for group, grouptools in tools:
34053410
for position, tool in enumerate(grouptools):
34063411
self.add_tool(tool[1], tool[0], group, position)
34073412

34083413
def add_tool(self, name, tool, group=None, position=None):
3409-
"""Add tool to `Navigation`
3414+
"""Add tool to `NavigationBase`
34103415
34113416
Add a tool to the tools controlled by Navigation
3412-
If successful adds a new event `tool_trigger_name` where name is
3413-
the name of the tool, this event is fired everytime
3417+
3418+
If successful adds a new event `tool_trigger_name` where **name** is
3419+
the **name** of the tool, this event is fired everytime
34143420
the tool is triggered.
34153421
34163422
Parameters
34173423
----------
34183424
name : string
34193425
Name of the tool, treated as the ID, has to be unique
3420-
tool : string or `Tool` class
3426+
tool : string or `matplotlib.backend_tools.ToolBase` derived class
34213427
Reference to find the class of the Tool to be added
34223428
group: String
34233429
Group to position the tool in
34243430
position : int or None (default)
3425-
Position in the toolbar, if None, is positioned at the end
3431+
Position within its group in the toolbar, if None, is positioned at the end
34263432
"""
34273433

34283434
tool_cls = self._get_cls_to_instantiate(tool)
@@ -3447,7 +3453,7 @@ def _tool_added_event(self, tool, group, position):
34473453
tool=tool,
34483454
group=group,
34493455
position=position)
3450-
self.callbacks.process(s, event)
3456+
self._callbacks.process(s, event)
34513457

34523458
def _handle_toggle(self, name, sender, canvasevent, data):
34533459
# Toggle tools, need to be untoggled before other Toggle tool is used
@@ -3466,8 +3472,6 @@ def _handle_toggle(self, name, sender, canvasevent, data):
34663472
for a in self.canvas.figure.get_axes():
34673473
a.set_navigate_mode(self._toggled)
34683474

3469-
self._set_cursor(canvasevent)
3470-
34713475
def _get_cls_to_instantiate(self, callback_class):
34723476
# Find the class that corresponds to the tool
34733477
if isinstance(callback_class, six.string_types):
@@ -3485,17 +3489,17 @@ def _get_cls_to_instantiate(self, callback_class):
34853489

34863490
def tool_trigger_event(self, name, sender=None, canvasevent=None,
34873491
data=None):
3488-
"""Trigger a tool and fire the tool-trigger-[name] event
3492+
"""Trigger a tool and emit the tool-trigger-[name] event
34893493
34903494
Parameters
34913495
----------
34923496
name : string
34933497
Name of the tool
34943498
sender: object
34953499
Object that wish to trigger the tool
3496-
canvasevent: Event
3500+
canvasevent : Event
34973501
Original Canvas event or None
3498-
data: Object
3502+
data : Object
34993503
Extra data to pass to the tool when triggering
35003504
"""
35013505
if name not in self._tools:
@@ -3508,8 +3512,8 @@ def tool_trigger_event(self, name, sender=None, canvasevent=None,
35083512
self._trigger_tool(name, sender, canvasevent, data)
35093513

35103514
s = 'tool-trigger-%s' % name
3511-
event = ToolTriggerEvent(s, name, sender, canvasevent, data)
3512-
self.callbacks.process(s, event)
3515+
event = ToolTriggerEvent(s, self._tools[name], sender, canvasevent, data)
3516+
self._callbacks.process(s, event)
35133517

35143518
def _trigger_tool(self, name, sender=None, canvasevent=None, data=None):
35153519
"""Trigger on a tool
@@ -3534,45 +3538,31 @@ def _key_press(self, event):
35343538
return
35353539
self.tool_trigger_event(name, canvasevent=event)
35363540

3537-
def get_tools(self):
3541+
@property
3542+
def tools(self):
35383543
"""Return the tools controlled by `Navigation`"""
35393544

3540-
d = {}
3541-
for name in sorted(self._tools.keys()):
3542-
tool = self._tools[name]
3543-
keys = [k for k, i in six.iteritems(self._keys) if i == name]
3544-
d[name] = {'obj': tool,
3545-
'description': tool.description,
3546-
'keymap': keys}
3547-
return d
3545+
return self._tools
35483546

35493547
def get_tool(self, name):
35503548
"""Return the tool object
35513549
3552-
Parameters:
3550+
Parameters
35533551
-----------
3554-
name: String
3552+
name : String
35553553
Name of the tool
35563554
"""
35573555
return self._tools[name]
35583556

3559-
def _set_cursor(self, canvasevent):
3560-
"""Sets the current cursor in ToolSetCursor"""
3561-
3562-
if self._toggled:
3563-
cursor = self._tools[self._toggled].cursor
3564-
else:
3565-
cursor = None
3566-
3567-
self.tool_trigger_event('cursor', self, canvasevent, data=cursor)
3568-
35693557

35703558
class ToolbarBase(object):
35713559
"""Base class for `Toolbar` implementation
35723560
35733561
Attributes
35743562
----------
3575-
manager : `FigureManager` instance that integrates this `Toolbar`
3563+
manager : `FigureManager` object that integrates this `Toolbar`
3564+
navigation : `NavigationBase` object that hold the tools that
3565+
this `Toolbar` wants to communicate with
35763566
"""
35773567

35783568
def __init__(self, manager):
@@ -3596,12 +3586,12 @@ def _tool_triggered_cbk(self, event):
35963586
if event.sender is self:
35973587
return
35983588

3599-
self.toggle_toolitem(event.toolname)
3589+
self.toggle_toolitem(event.tool.name)
36003590

36013591
def _add_tool_cbk(self, event):
36023592
"""Captures 'tool_added_event' and add the tool to the toolbar"""
36033593
image = self._get_image_filename(event.tool.image)
3604-
toggle = isinstance(event.tool, tools.ToolToggleBase)
3594+
toggle = getattr(event.tool, 'toggled', None) is not None
36053595
self.add_toolitem(event.tool.name,
36063596
event.group,
36073597
event.position,
@@ -3641,6 +3631,8 @@ def trigger_tool(self, name):
36413631
def add_toolitem(self, name, group, position, image, description, toggle):
36423632
"""Add a toolitem to the toolbar
36433633
3634+
This method has to be implemented per backend
3635+
36443636
The callback associated with the button click event,
36453637
must be **EXACTLY** `self.trigger_tool(name)`
36463638
@@ -3653,31 +3645,47 @@ def add_toolitem(self, name, group, position, image, description, toggle):
36533645
Name of the group that the tool belongs to
36543646
position : Int
36553647
Position of the tool whthin its group if -1 at the End
3656-
image_file : string
3648+
image_file : String
36573649
Filename of the image for the button or `None`
3658-
description : string
3650+
description : String
36593651
Description of the tool, used for the tooltips
3660-
toggle : bool
3652+
toggle : Bool
36613653
* `True` : The button is a toggle (change the pressed/unpressed
3662-
state between consecutive clicks)
3654+
state between consecutive clicks)
36633655
* `False` : The button is a normal button (returns to unpressed
3664-
state after release)
3656+
state after release)
36653657
"""
36663658

36673659
raise NotImplementedError
36683660

36693661
def set_message(self, s):
3670-
"""Display a message on toolbar or in status bar"""
3662+
"""Display a message on toolbar or in status bar
3663+
3664+
Parameters
3665+
----------
3666+
s : String
3667+
Message text
3668+
"""
36713669

36723670
pass
36733671

36743672
def toggle_toolitem(self, name):
3675-
"""Toggle the toolitem without firing event"""
3673+
"""Toggle the toolitem without firing event
3674+
3675+
Parameters
3676+
----------
3677+
name : String
3678+
Id of the tool to toggle
3679+
"""
36763680
raise NotImplementedError
36773681

36783682
def remove_toolitem(self, name):
36793683
"""Remove a toolitem from the `Toolbar`
36803684
3685+
This method has to be implemented per backend
3686+
3687+
Called when `tool_removed_event` is emited by `NavigationBase`
3688+
36813689
Parameters
36823690
----------
36833691
name : string

0 commit comments

Comments
 (0)