8000 MEP22 Navigation toolbar coexistence TODELETE by fariza · Pull Request #2759 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

MEP22 Navigation toolbar coexistence TODELETE #2759

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

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
dda0cdc
navigation and toolbar coexistence
fariza Jan 23, 2014
10f5dc7
mod keypress in figuremanager
fariza Jan 23, 2014
08a6020
extra files
fariza Jan 23, 2014
c6c0ad3
helper methods in toolbar and navigation
fariza Jan 24, 2014
1fc29fa
Adding doc to base methods
fariza Jan 24, 2014
979875e
property for active_toggle
fariza Jan 26, 2014
c5c4f0f
simulate click
fariza Jan 27, 2014
97dfda7
pep8 backend_tools
fariza Jan 27, 2014
6b647ad
activate renamed to trigger
fariza Jan 28, 2014
99667aa
toggle tools using enable/disable from its trigger method
fariza Jan 29, 2014
6c19579
simplifying _handle_toggle
fariza Jan 29, 2014
0495aac
reducing number of locks
fariza Jan 29, 2014
fb46fc1
pep8 correction
fariza Jan 29, 2014
d49c431
changing toggle and persistent attributes for issubclass
fariza Feb 4, 2014
5ba6210
bug in combined key press
fariza Feb 4, 2014
7ca8626
untoggle zoom and pan from keypress while toggled
fariza Feb 4, 2014
dcc0f16
classmethods for default tools modification
fariza Feb 6, 2014
bc703e0
six fixes
fariza Apr 24, 2014
68dc711
adding zaxis and some pep8
fariza May 1, 2014
bb9f1c7
removing legacy method dynamic update
fariza May 6, 2014
2c2e649
tk backend
fariza May 6, 2014
a99367f
pep8
fariza May 6, 2014
3d1be34
example working with Tk
fariza May 6, 2014
afdd34c
cleanup
fariza May 7, 2014
5b49c7a
duplicate code in keymap tool initialization
fariza Jul 24, 2014
773db88
grammar corrections
fariza Jul 24, 2014
2ca6926
moving views and positions to tools
fariza Jul 24, 2014
661417d
The views positions mixin automatically adds the clear as axobserver
fariza Jul 25, 2014
90ab64f
bug when navigation was not defined
fariza Jul 25, 2014
55dd149
Small refactor so that we first initiate the Navigation (ToolManager)…
OceanWolf Jul 28, 2014
15ac091
Update for Sphinx documentation
OceanWolf Jul 28, 2014
8cd241c
Moved default_tool initilisation to FigureManagerBase and cleaned.
OceanWolf Jul 29, 2014
39f5b74
Fix navigation
OceanWolf Jul 29, 2014
b20dade
Temporary fix to backends
OceanWolf Jul 29, 2014
ff94301
Merge pull request #1 from OceanWolf/navigation-toolbar-coexistence-e…
fariza Jul 29, 2014
2cb4501
removing persistent tools
fariza Sep 3, 2014
9d3c977
removing unregister
fariza Sep 4, 2014
6e0b7e6
change cursor inmediately after toggle
fariza Sep 5, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
reducing number of locks
  • Loading branch information
fariza committed Apr 24, 2014
commit 0495aac084d459e77ea5413bdffc620d486b6a62
91 changes: 34 additions & 57 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -3190,11 +3190,9 @@ class NavigationBase(object):
----------
canvas : `FigureCanvas` instance
toolbar : `Toolbar` instance that is controlled by this `Navigation`
keypresslock : `LockDraw` to direct the `canvas` key_press_event
movelock : `LockDraw` to direct the `canvas` motion_notify_event
presslock : `LockDraw` to direct the `canvas` button_press_event
releaselock : `LockDraw` to direct the `canvas` button_release_event
canvaslock : shortcut to `canvas.widgetlock`
keypresslock : `LockDraw` to know if the `canvas` key_press_event is
locked
messagelock : `LockDraw` to know if the message is available to write
"""
_default_cursor = cursors.POINTER
_default_tools = [tools.ToolToggleGrid,
Expand Down Expand Up @@ -3224,11 +3222,6 @@ def __init__(self, canvas, toolbar=None):
self._idDrag = self.canvas.mpl_connect('motion_notify_event',
self._mouse 10000 _move)

self._idPress = self.canvas.mpl_connect('button_press_event',
self._press)
self._idRelease = self.canvas.mpl_connect('button_release_event',
self._release)

# a dict from axes index to a list of view limits
self.views = cbook.Stack()
self.positions = cbook.Stack() # stack of subplot positions
Expand All @@ -3240,11 +3233,7 @@ def __init__(self, canvas, toolbar=None):

#to communicate with tools and redirect events
self.keypresslock = widgets.LockDraw()
self.movelock = widgets.LockDraw()
self.presslock = widgets.LockDraw()
self.releaselock = widgets.LockDraw()
#just to group all the locks in one place
self.canvaslock = self.canvas.widgetlock
self.messagelock = widgets.LockDraw()

for tool in self._default_tools:
if tool is None:
Expand Down Expand Up @@ -3437,16 +3426,9 @@ def _trigger_tool(self, name, event, from_toolbar):
tool(self.canvas.figure, event)

def _key_press(self, event):
if event.key is None:
if event.key is None or self.keypresslock.locked():
return

#some tools may need to capture keypress, but they need to be toggle
if self._toggled:
instance = self._get_instance(self._toggled)
if self.keypresslock.isowner(instance):
instance.key_press(event)
return

name = self._keys.get(event.key, None)
self._trigger_tool(name, event, False)

Expand Down Expand Up @@ -3517,12 +3499,6 @@ def update(self):
# self.set_history_buttons()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason why this is commented out?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is only implemented in backend_wx.py, so I am not sure if it is worth it to continue to support it.


def _mouse_move(self, event):
if self._toggled:
instance = self._instances[self._toggled]
if self.movelock.isowner(instance):
instance.mouse_move(event)
return

if not event.inaxes or not self._toggled:
if self._last_cursor != self._default_cursor:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this if statement? Do we get a significant performance hit without it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, I don't know, it is a copy paste from NavigationToolbar2.
I would be inclined to leave it there, and check the performance impact, when it is merged.

self.set_cursor(self._default_cursor)
Expand All @@ -3534,7 +3510,7 @@ def _mouse_move(self, event):
self.set_cursor(cursor)
self._last_cursor = cursor

if self.toolbar is None:
if self.toolbar is None or self.messagelock.locked():
return

if event.inaxes and event.inaxes.get_navigate():
Expand All @@ -3551,30 +3527,6 @@ def _mouse_move(self, event):
else:
self.toolbar.set_message('')

def _release(self, event):
if self._toggled:
instance = self._instances[self._toggled]
if self.releaselock.isowner(instance):
instance.release(event)
return
self.release(event)

def release(self, event):
pass

def _press(self, event):
"""Called whenver a mouse button is pressed."""
if self._toggled:
instance = self._instances[self._toggled]
if self.presslock.isowner(instance):
instance.press(event)
return
self.press(event)

def press(self, event):
"""Called whenver a mouse button is pressed."""
pass

def draw(self):
"""Redraw the canvases, update the locators"""
for a in self.canvas.figure.get_axes():
Expand Down Expand Up @@ -3639,9 +3591,34 @@ def push_current(self):
self.positions.push(pos)
# self.set_history_buttons()

def draw_rubberband(self, event, x0, y0, x1, y1):
"""Draw a rectangle rubberband to indicate zoom limits"""
pass
def draw_rubberband(self, event, caller, x0, y0, x1, y1):
"""Draw a rectangle rubberband to indicate zoom limits

Draw a rectanlge in the canvas, if
`self.canvas.widgetlock` is available to **caller**

Parameters
----------
event : `FigureCanvas` event
caller : instance trying to draw the rubberband
x0, y0, x1, y1 : coordinates
"""
if not self.canvas.widgetlock.available(caller):
warnings.warn("%s doesn't own the canvas widgetlock" % caller)

def remove_rubberband(self, event, caller):
"""Remove the rubberband

Remove the rubberband if the `self.canvas.widgetlock` is
available to **caller**

Parameters
----------
event : `FigureCanvas` event
caller : instance trying to remove the rubberband
"""
if not self.canvas.widgetlock.available(caller):
warnings.warn("%s doesn't own the canvas widgetlock" % caller)


class ToolbarBase(object):
Expand Down
118 changes: 49 additions & 69 deletions lib/matplotlib/backend_tools.py
741A
Original file line number Diff line number Diff line change
Expand Up @@ -141,37 +141,13 @@ def unregister(self, *args):
class ToolToggleBase(ToolPersistentBase):
"""Toggleable tool

This tool is a Persistent Tool, that has the ability to capture
the keypress, press and release events, preventing other tools
to use the same events at the same time
This tool is a Persistent Tool that has a toggled state.
Every time it is triggered, it switches between enable and disable

"""
toggle = True
_toggled = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this here as a class-level attribute?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right, I forgot that one. _toggled belongs to the object


def mouse_move(self, event):
"""Mouse move event

Called when a motion_notify_event is emited by the `FigureCanvas` if
`navigation.movelock(self)` was setted
"""
pass

def press(self, event):
"""Mouse press event

Called when a button_press_event is emited by the `FigureCanvas` if
`navigation.presslock(self)` was setted
"""
pass

def release(self, event):
"""Mouse release event

Called when a button_release_event is emited by the `FigureCanvas` if
`navigation.releaselock(self)` was setted
"""
pass

def trigger(self, event):
if self._toggled:
self.disable(event)
Expand All @@ -182,26 +158,23 @@ def trigger(self, event):
def enable(self, event=None):
"""Enable the toggle tool

This method is called when the tool is triggered and not active
This method is called when the tool is triggered and not toggled
"""
pass

def disable(self, event=None):
"""Disable the toggle tool

This method is called when the tool is triggered and active.
* Second click on the toolbar button
This method is called when the tool is triggered and toggled.
* Second click on the toolbar tool button
* Another toogle tool is triggered (from the same `navigation`)
"""
pass

def key_press(self, event):
"""Key press event

Called when a key_press_event is emited by the `FigureCanvas` if
`navigation.keypresslock(self)` was setted
"""
pass
@property
def toggled(self):
"""State of the toggled tool"""
return self._toggled


class ToolQuit(ToolBase):
Expand Down Expand Up @@ -391,26 +364,29 @@ def __init__(self, *args):
self._ids_zoom = []
self._button_pressed = None
self._xypress = None
self._idPress = None
self._idRelease = None

def enable(self, event):
self.navigation.canvaslock(self)
self.navigation.presslock(self)
self.navigation.releaselock(self)
self.figure.canvas.widgetlock(self)
self._idPress = self.figure.canvas.mpl_connect(
'button_press_event', self._press)
self._idRelease = self.figure.canvas.mpl_connect(
'button_release_event', self._release)

def disable(self, event):
self.navigation.canvaslock.release(self)
self.navigation.presslock.release(self)
self.navigation.releaselock.release(self)
self.figure.canvas.widgetlock.release(self)
self.figure.canvas.mpl_disconnect(self._idPress)
self.figure.canvas.mpl_disconnect(self._idRelease)

def press(self, event):
"""the press mouse button in zoom to rect mode callback"""
def _press(self, event):
"""the _press mouse button in zoom to rect mode callback"""
# If we're already in the middle of a zoom, pressing another
# button works to "cancel"
if self._ids_zoom != []:
self.navigation.movelock.release(self)
for zoom_id in self._ids_zoom:
self.figure.canvas.mpl_disconnect(zoom_id)
self.navigation.release(event)
self.navigation.remove_rubberband(event, self)
self.navigation.draw()
self._xypress = None
self._button_pressed = None
Expand Down Expand Up @@ -439,17 +415,16 @@ def press(self, event):
self._xypress.append((x, y, a, i, a.viewLim.frozen(),
a.transData.frozen()))

self.navigation.movelock(self)
id1 = self.figure.canvas.mpl_connect(
'motion_notify_event', self.mouse_move)
id2 = self.figure.canvas.mpl_connect('key_press_event',
self._switch_on_zoom_mode)
id3 = self.figure.canvas.mpl_connect('key_release_event',
self._switch_off_zoom_mode)

self._ids_zoom = id2, id3
self._ids_zoom 97AE = id1, id2, id3
self._zoom_mode = event.key

self.navigation.press(event)

def _switch_on_zoom_mode(self, event):
self._zoom_mode = event.key
self.mouse_move(event)
Expand All @@ -476,11 +451,10 @@ def mouse_move(self, event):
x1, y1, x2, y2 = a.bbox.extents
x, lastx = x1, x2

self.navigation.draw_rubberband(event, x, y, lastx, lasty)
self.navigation.draw_rubberband(event, self, x, y, lastx, lasty)

def release(self, event):
def _release(self, event):
"""the release mouse button callback in zoom to rect mode"""
self.navigation.movelock.release(self)
for zoom_id in self._ids_zoom:
self.figure.canvas.mpl_disconnect(zoom_id)
self._ids_zoom = []
Expand All @@ -496,7 +470,7 @@ def release(self, event):
# ignore singular clicks - 5 pixels is a threshold
if abs(x - lastx) < 5 or abs(y - lasty) < 5:
self._xypress = None
self.navigation.release(event)
self.navigation.remove_rubberband(event, self)
self.navigation.draw()
return

Expand Down Expand Up @@ -604,7 +578,7 @@ def release(self, event):
self._zoom_mode = None

self.navigation.push_current()
self.navigation.release(event)
self.navigation.remove_rubberband(event, self)


class ToolPan(ToolToggleBase):
Expand All @@ -620,18 +594,23 @@ def __init__(self, *args):
ToolToggleBase.__init__(self, *args)
self._button_pressed = None
self._xypress = None
self._idPress = None
self._idRelease = None
self._idDrag = None

def enable(self, event):
self.navigation.canvaslock(self)
self.navigation.presslock(self)
self.navigation.releaselock(self)
self.figure.canvas.widgetlock(self)
self._idPress = self.figure.canvas.mpl_connect(
'button_press_event', self._press)
self._idRelease = self.figure.canvas.mpl_connect(
'button_release_event', self._release)

def disable(self, event):
self.navigation.canvaslock.release(self)
self.navigation.presslock.release(self)
self.navigation.releaselock.release(self)
self.figure.canvas.widgetlock.release(self)
self.figure.canvas.mpl_disconnect(self._idPress)
self.figure.canvas.mpl_disconnect(self._idRelease)

def press(self, event):
def _press(self, event):
if event.button == 1:
self._button_pressed = 1
elif event.button == 3:
Expand All @@ -653,14 +632,16 @@ def press(self, event):
a.get_navigate() and a.can_pan()):
a.start_pan(x, y, event.button)
self._xypress.append((a, i))
self.navigation.movelock(self)
self.navigation.press(event)
self.navigation.messagelock(self)
self._idDrag = self.figure.canvas.mpl_connect(
'motion_notify_event', self.mouse_move)

def release(self, event):
def _release(self, event):
if self._button_pressed is None:
return

self.navigation.movelock.release(self)
self.figure.canvas.mpl_disconnect(self._idDrag)
self.navigation.messagelock.release(self)

for a, _ind in self._xypress:
a.end_pan()
Expand All @@ -669,12 +650,11 @@ def release(self, event):
self._xypress = []
self._button_pressed = None
self.navigation.push_current()
self.navigation.release(event)
self.navigation.draw()

def mouse_move(self, event):
for a, _ind in self._xypress:
#safer to use the recorded button at the press than current button:
#safer to use the recorded button at the _press than current button:
#multiple button can get pressed during motion...
a.drag_pan(self._button_pressed, event.key, event.x, event.y)
self.navigation.dynamic_update()
Loading
0