fsleyes.profiles
¶
The profiles
package contains logic for mouse/keyboard interaction
with ViewPanel
panels.
This logic is encapsulated in four classes:
The
Profile
class is intended to be subclassed. AProfile
instance contains the mouse/keyboard event handlers for a particular type ofViewPanel
to allow the user to interact with the view in a particular way. For example, theOrthoViewProfile
class allows the user to navigate through the display space in anOrthoPanel
canvas, whereas theOrthoEditProfile
class contains interaction logic for selecting and editingImage
voxels in anOrthoPanel
.The
CanvasPanelEventManager
manageswx
GUI events on theSliceCanvas
instances contained inCanvasPanel
views.The
PlotPanelEventManager
managesmatplotlib
GUI events on thematplotlib Canvas
instances contained inPlotPanel
views.The
ProfileManager
class is used byViewPanel
instances to create and change theProfile
instance currently in use.
The profiles
package is also home to the shortcuts
module, which
defines global FSLeyes keyboard shortcuts.
- class fsleyes.profiles.ProfileManager(viewPanel, overlayList, displayCtx, maxprofiles)[source]¶
Bases:
__main__.docbuilder.run.<locals>.MockClass
Manages creation/registration/de-registration of
Profile
instances for aViewPanel
instance.A
ProfileManager
instance is created and used by everyViewPanel
instance. TheProfileManager
manages a stack ofProfile
instances - profiles can be activated and deactivated via theactivateProfile()
anddeactivateProfile()
methods.The
ProfileManager
uses theNotifier
interface to notify any interested listeners when the current profile is changed, using the topic name'profile'
. Registered listeners are passed a tuple containing the types (Profile
sub-classes) of the de-registered and newly registered profiles.- __init__(viewPanel, overlayList, displayCtx, maxprofiles)[source]¶
Create a
ProfileManager
.- Parameters
viewPanel – The
ViewPanel
instance which thisProfileManager
is to manage.overlayList – The
OverlayList
instance containing the overlays that are being displayed.displayCtx – The
DisplayContext
instance which defines how overlays are being displayed.maxprofiles – Maximum numbe of profiles which can be in the profile stack.
- destroy()[source]¶
This method must be called by the owning
ViewPanel
when it is about to be destroyed (or when it no longer needs aProfileManager
).This method destroys all class:Profile instances, and clears some internal object references to avoid memory leaks.
- deactivateProfile(notify=True)[source]¶
Deactivates and destroys the current profile, and re-activates the previous one.
- Parameters
notify – If
True
(the default), a notification is emitted via theNotifier
interface.- Returns
A reference to the re-activated profile.
- activateProfile(profileCls, notify=True)[source]¶
Deregisters the current
Profile
instance, and creates and registers a new instance of typeprofileCls
.- Parameters
notify – If
True
(the default), a notification is emitted via theNotifier
interface.- Returns
A reference to the newly registered profile.
- __annotations__ = {}¶
- __module__ = 'fsleyes.profiles'¶
- class fsleyes.profiles.Profile(viewPanel, overlayList, displayCtx, modes=None)[source]¶
Bases:
__main__.docbuilder.run.<locals>.MockClass
,fsleyes.actions.ActionProvider
A
Profile
class implements keyboard/mouse interaction behaviour for aViewPanel
instance.Subclasses should specify at least one mode of operation, which defines a sort of sub-profile. The current mode can be changed with the
mode
property.Subclasses must also override the
getEventTargets()
method, to return thewx
objects that are to be the targets for mouse/keyboard interaction.The
Profile
class currently only supportsCanvasPanel
andPlotPanel
views.Profile
instances use aCanvasPanelEventManager
instance to manage GUI events onCanvasPanel
instances, or a:class:.PlotPanelEventManager to manage GUI events onmatplotlib Canvas
objects.Receiving events
In order to receive mouse or keyboard events, subclasses simply need to implement methods which handle the events of interest for the relevant mode, and name them appropriately. The name of a method handler must be of the form:
_[modeName]Mode[eventName]
where
modeName
is an identifier for the profile mode (see the__init__()
method), andeventName
is one of the following:LeftMouseMove
LeftMouseDown
LeftMouseDrag
LeftMouseUp
RightMouseMove
RightMouseDown
RightMouseDrag
RightMouseUp
MiddleMouseMove
MiddleMouseDown
MiddleMouseDrag
MiddleMouseUp
MouseWheel
Char
Profiles for
CanvasPanel
views may also implement handlers for these events:MouseEnter
MouseLeave
And
PlotPanel
views may implement handlers for these events:LeftMouseArtistPick
RightMouseArtistPick
Note
The
MouseEnter
andMouseLeave
events are not supported onPlotPanel
views due to bugs inmatplotlib
.For example, if a particular profile has defined a mode called
nav
, and is interested in left clicks, the profile class must provide a method called_navModeLeftMouseDown
. Then, whenever the profile is in thenav
mode, this method will be called on left mouse clicks.Handler methods
The parameters that are passed to these methods differs slightly depending on the type of event:
All mouse events, with the exception of
MouseWheel
must have the following signature:def _[modeName]Mode[eventName](ev, canvas, mouseLoc, canvasLoc)
where:
ev
is thewx.Event
objectcanvas
is the source canvas,mouseLoc
is the(x, y)
mouse coordinates,canvasLoc
is the coordinates in the display/data coordinate system.
The
MouseWheel
handler must have the following signature:def _[modeName]ModeMouseWheel(ev, canvas, wheel, mouseLoc, canvasLoc)
where
wheel
is a positive or negative number indicating how much the mouse wheel was moved.Char
events must have the following signature:def _[modeName]ModeChar(ev, canvas, key)
where
key
is the key code of the key that was pressed.Pick event handlers (only on
PlotPanel
views) must have the following signature:def _[modeName]Mode[eventType](ev, canvas, artist, mouseLoc, canvasLoc)
where
artist
is thematplotlib
artist that was picked.
All handler methods should return
True
to indicate that the event was handled, orFalse
if the event was not handled. This is particularly important forChar
event handlers - we don’t wantProfile
sub-classes to be eating global keyboard shortcuts. A return value ofNone
is interpreted asTrue
. If a handler returnsFalse
, and a fallback handler is defined (see below), then that fallback handler will be called.Extra handlers
Additional handlers can be registered for any event type via the
registerHandler()
method. These handlers do not have to be methods of theProfile
sub-class, and will be called for every occurrence of the event, regardless of the current mode. These handlers will be called after the standard handler method.When an extra handler is no longer needed, it must be removed via the
deregisterHandler()
method.Pre- and post- methods
A couple of other methods may be defined which, if they are present, will be called on all handled events:
_preEvent
_postEvent
The
_preEvent
method will get called just before an event is passed to the handler. Likewise, the_postEvent
method will get called just after the handler has been called. If no handlers for a particular event are defined, neither of these methods will be called.Temporary, alternate and fallback handlers
The
tempModes()
function may be overridden to define a keyboard modifier which may be used to temporarily redirect mouse/keyboard events to the handlers for a different mode. For example, if while innav
mode, you would like the user to be able to switch tozoom
mode with the control key, you can add a temporary mode map in the dictionary returned bytempModes
. Additional temporary modes can be added via theaddTempMode()
method.The
altHandlers()
function may be overridden to allow the re-use of event handlers that have been defined for one mode in another mode. For example, if you would like right clicks inzoom
mode to behave like left clicks innav
mode, you can return such a mapping from thealtHandler
function. Additional alternate handlers can be added via theaddAltHandler()
method.The
fallbackHandlers()
function may be overridden to define fallback handlers - if the default handler for a specific mode/event type returns a value ofFalse
, the event will be forwarded to the fallback handler instead. Additional fallback handlers can be added via theaddFallbackHandler()
method.Actions and attributes
As the
Profile
class derives from theActionProvider
class,Profile
subclasses may define properties and actions for the user to configure the profile behaviour, and/or to perform any relevant actions.The following instance attributes are present on a
Profile
instance, intended to be accessed by sub-classes:viewPanel
The
ViewPanel
which is using thisProfile
.overlayList
A
OverlayList
instance.displayCtx
A
DisplayContext
instance.name
A unique name for this
Profile
instance.- static supportedView()[source]¶
Returns the
ViewPanel
type that is supported by thisProfile
. Must be implemented by sub-classes.
- static tempModes()[source]¶
May be overridden by sub-classes. Should return a dictionary defining temporary modes which, when in a given mode, can be accessed with a keyboard modifer (e.g. Control, Shift, etc). For example, a temporary mode map of:
('view', wx.WXK_SHIFT) : 'zoom'
states that when the
Profile
is in'view'
mode, and the shift key is held down, theProfile
should temporarily switch to'zoom'
mode.For multi-key combinations, the modifier key IDs must be provided as a tuple, in alphabetical order. For example, to specify shift+ctrl, the tuple must be (wx.WXK_CTRL, wx.WXK_SHIFT)
Important: Any temporary modes which use CTRL, ALT, or CTRL+ALT must not handle character events, as these modifiers are reserved for global shortcuts.
Temporary modes honour the
Profile
class hierarchy, so if you sub-class an existingProfile
class, your class will inherit all of the temporary modes defined on the base class.
- static altHandlers()[source]¶
May be overridden by sub-classes. Should return a dictionary defining alternate handlers for a given mode and event type. Entries in this dictionary allow a
Profile
sub-class to define a handler for a single mode and event type, but to re-use that handler for other modes and event types. For example, the following alternate handler mapping:('zoom', 'MiddleMouseDrag') : ('pan', 'LeftMouseDrag')
states that when the
Profile
is in'zoom'
mode, and aMiddleMouseDrag
event occurs, theLeftMouseDrag
handler for the'pan'
mode should be called.Alternate handlers honour the
Profile
class hierarchy, so if you sub-class an existingProfile
class, your class will inherit all of the alternate handlers defined on the base class.Note
Event bindings defined by
altHandlers
take precdence over the event bindings defined in theProfile
sub-class. So you can use thealtHandlers
to override the default behaviour of aProfile
.
- static fallbackHandlers()[source]¶
May be overridden by sub-classes. Should return a dictionary defining handlers for a given mode and event type which will be called if the handler for that mode/event type returns a value of
False
, indicating that it has not been handled. For example, the following fallback handler mapping:(('pick', 'LeftMouseDown'), ('nav', 'LeftMouseDown')),
states that when the profile is in
'pick'
mode, and theLeftMouseDown
handler for'pick'
mode returnsFalse
, theLeftMouseDown
handler for'nav'
mode will be called.Fallback handlers honour the
Profile
class hierarchy, so if you sub-class an existingProfile
class, your class will inherit all of the fallback handlers defined on the base class.
- __init__(viewPanel, overlayList, displayCtx, modes=None)[source]¶
Create a
Profile
instance.- Parameters
viewPanel – The
ViewPanel
instance for which thisProfile
instance defines mouse/keyboard interaction behaviour.overlayList – The
OverlayList
instance which contains the list of overlays being displayed.displayCtx – The
DisplayContext
instance which defines how the overlays are to be displayed.modes – A sequence of strings, containing the mode identifiers for this profile. These are added as options on the
mode
property.
- mode = <MagicMock name='mock.Choice()' id='140604702016944'>¶
The current profile mode - by default this is empty, but subclasses may specify the choice options in the
__init__
method.
- destroy()[source]¶
This method must be called when this
Profile
is no longer needed - it is typically called by aProfileManager
.Clears references to the display context, view panel, and overlay list, and calls
ActionProvider.destroy()
.
- property name¶
Returns the name of this
Profile
.
- getEventTargets()[source]¶
Must be overridden by subclasses, to return a sequence of
wx
objects that are the targets of mouse/keyboard interaction.Note
It is currently assumed that all of the objects in the sequence derive from the
SliceCanvas
class.
- getMouseDownLocation()[source]¶
If the mouse is currently down, returns a 2-tuple containing the x/y mouse coordinates, and the corresponding 3D display space coordinates, of the mouse down event. Otherwise, returns
(None, None)
.
- getLastMouseLocation()[source]¶
Returns a 2-tuple containing the most recent x/y mouse coordinates, and the corresponding 3D display space coordinates.
- getLastMouseUpLocation()[source]¶
Returns a 2-tuple containing the most recent x/y mouse up event coordinates, and the corresponding 3D display space coordinates.
- getLastMouseUpHandler()[source]¶
Returns a tuple of two strings specifying the
(mode, eventType)
of the most recent mouse up event that was handled. If no events have been handled, returns(None, None)
.
- getLastHandler()[source]¶
Returns a tuple of two strings specifying the
(mode, eventType)
of the most recent event that was handled. If no events have been handled, returns(None, None)
.
- getLastCanvas()[source]¶
Returns a reference to the canvas which most recently generated a mouse down or up event.
- getMplEvent()[source]¶
If this
Profile
object is associated with aPlotPanel
, this method will return the lastmatplotlib
event that was generated. Otherwise, this method returnsNone
.This method can be called from within an event handler to retrieve the current
matplotlib
event. See thePlotPanelEventManager.getMplEvent()
method.
- addTempMode(mode, modifier, tempMode)[source]¶
Add a temporary mode to this
Profile
, in addition to those defined by thetempModes()
function.- Parameters
mode – The mode to change from.
modifier – A keyboard modifier which will temporarily change the mode from
mode
totempMode
.tempMode – The temporary mode which the
modifier
key will change into.
- addAltHandler(mode, event, altMode, altEvent)[source]¶
Add an alternate handler to this
Profile
, in addition to those already defined by thealtHandlers()
function.- Parameters
mode – The source mode.
event – Name of the event to handle (e.g.
LeftMouseDown
).altMode – The mode for which the handler is defined.
altEvent – The event name for which the handler is defined.
- addFallbackHandler(mode, event, fbMode, fbEvent)[source]¶
Add a fallback handler to this
Profile
, in addition to those already defined by thefallbackHandlers()
function.- Parameters
mode – The source mode.
event – Name of the event to handle (e.g.
LeftMouseDown
).fbMode – The mode for which the handler is defined.
fbEvent – The event name for which the handler is defined.
- register()[source]¶
This method must be called to register this
Profile
instance as the target for mouse/keyboard events. This method is called by theProfileManager
.Subclasses may override this method to performa any initialisation, but must make sure to call this implementation.
- deregister()[source]¶
This method de-registers this
Profile
instance from receiving mouse/keybouard events. This method is called by theProfileManager
.Subclasses may override this method to performa any initialisation, but must make sure to call this implementation.
- registerHandler(event, name, handler)[source]¶
Add an extra handler for the specified event.
When the event occurs, The
handler
function will be called after the default handler, provided by theProfie
sub-class, is called.- Parameters
event – The event type (e.g.
LeftMouseDown
).name – A unique name for the handler. A
KeyError
will be raised if a handler withname
is already registered.handler – Function to call when the event occurs. See the class documentation for details on the required signature.
- deregisterHandler(event, name)[source]¶
Remove an extra handler from the specified event, that was previously added via
registerHandler()
- Parameters
event – The event type (e.g.
LeftMouseDown
).name – A unique name for the handler. A
KeyError
will be raised if a handler withname
is already registered.
- handleEvent(ev)[source]¶
Called by the event manager when any event occurs on any of the
ViewPanel
targets. Delegates the event to one of the handler functions.- Parameters
ev – The
wx.Event
that occurred.
- handlePickEvent(ev)[source]¶
Called by the
PlotPanelEventManager
when amatplotlib
pick_event
occurs.
- __getTempMode(ev)¶
Checks the temporary mode map to see if a temporary mode should be applied. Returns the mode identifier, or
None
if no temporary mode is applicable.
- __getMouseLocation(ev)¶
Returns two tuples; the first contains the x/y coordinates of the given
wx.MouseEvent
, and the second contains the corresponding x/y/z display space coordinates (forCanvasPanel
views), or x/y data coordinates (forPlotPanel
views).See the
CanvasPanelEventManager.getMouseLocation()
andPlotPanelEventManager.getMouseLocation()
methods.
- __getMouseButton(ev)¶
Returns a string describing the mouse button associated with the given
wx.MouseEvent
.
- __getMode(ev)¶
Returns the current profile mode - either the value of
mode
, or a temporary mode if one is active.
- __getHandler(ev, evType, mode=None, origEvType=None, direct=False)¶
Returns a function which will handle the given
wx.MouseEvent
orwx.KeyEvent
(theev
argument), orNone
if no handlers are found.If an alternate handler for the mode/event has been specified, it is returned.
- Parameters
ev – The event object
evType – The event type (e.g.
'LeftMouseDown'
)mode – Override the default mode with this one. If not provided, the handler for the current mode (or temporary mode, if one is active) will be used.
origEvType – If the
evType
is not the actual event that occurred (e.g. this method has been called to look up an alternate or fallback handler), the original event type must be passed in here.direct – If
False
(the default), the returned function will call the standard event handler (a method of theProfile
sub-class), its fallback handler if it returnsFalse
and a fallback has been specfiied, any extra handlers that have been registered for the event type, and will also call the pre- and post- event methods. Otherwise, the returned function will just be the sub-class handler method for the specified forevType/ ``mode
.
- __onMouseWheel(ev)¶
Called when the mouse wheel is moved.
Delegates to a mode specific handler if one is present.
- __onMouseEnter(ev)¶
Called when the mouse enters a canvas target.
Delegates to a mode specific handler if one is present.
- __onMouseLeave(ev)¶
Called when the mouse leaves a canvas target.
Delegates to a mode specific handler if one is present.
- __onMouseDown(ev)¶
Called when any mouse button is pushed.
Delegates to a mode specific handler if one is present.
- __onMouseUp(ev)¶
Called when any mouse button is released.
Delegates to a mode specific handler if one is present.
- __onMouseMove(ev)¶
Called on mouse motion. If a mouse button is down, delegates to
__onMouseDrag()
.Otherwise, delegates to a mode specific handler if one is present.
- __onMouseDrag(ev)¶
Called on mouse drags.
Delegates to a mode specific handler if one is present.
- __onChar(ev)¶
Called on keyboard key presses.
Delegates to a mode specific handler if one is present.
- __onPick(ev)¶
Called by the
handlePickEvent()
. Delegates the event to a suitable handler, if one exists.
- __annotations__ = {}¶
- __module__ = 'fsleyes.profiles'¶
- class fsleyes.profiles.CanvasPanelEventManager(profile)[source]¶
Bases:
object
This class manages
wx
mouse/keyboard events originating fromSliceCanvas
instances contained withinCanvasPanel
views.- __init__(profile)[source]¶
Create a
CanvasPanelEventManager
.- Parameters
profile – The
Profile
instance that owns this event manager.
- register()[source]¶
This method must be called to register event listeners on mouse/ keyboard events. This method is called by meth :Profile.register.
- deregister()[source]¶
This method de-registers mouse/keybouard event listeners. This method is called by the
Profile.deregister()
method.
- getMouseLocation(ev)[source]¶
Returns two tuples; the first contains the x/y coordinates of the given
wx.MouseEvent
, and the second contains the corresponding x/y/z display space coordinates.
- __onEvent(ev)¶
Event handler. Passes the event to
Profile.handleEvent
.
- __dict__ = mappingproxy({'__module__': 'fsleyes.profiles', '__doc__': 'This class manages ``wx`` mouse/keyboard events originating from\n :class:`.SliceCanvas` instances contained within :class:`.CanvasPanel`\n views.\n ', '__init__': <function CanvasPanelEventManager.__init__>, 'register': <function CanvasPanelEventManager.register>, 'deregister': <function CanvasPanelEventManager.deregister>, 'getMouseLocation': <function CanvasPanelEventManager.getMouseLocation>, '_CanvasPanelEventManager__onEvent': <function CanvasPanelEventManager.__onEvent>, '__dict__': <attribute '__dict__' of 'CanvasPanelEventManager' objects>, '__weakref__': <attribute '__weakref__' of 'CanvasPanelEventManager' objects>, '__annotations__': {}})¶
- __module__ = 'fsleyes.profiles'¶
- __weakref__¶
list of weak references to the object (if defined)
- class fsleyes.profiles.PlotPanelEventManager(profile)[source]¶
Bases:
object
This class manages events originating from
matplotlib
Canvas
objects contained withinPlotPanel
views.Note
This class has no support for
figure_enter_event
,figure_leave_event
,axis_enter_event
, oraxis_leave_event
events. There appears to be some bugs lurking in thematplotlib/backend_bases.py
file (something to do with theLocationEvent.lastevent
property) which cause FSLeyes to seg-fault onfigure_enter_event
events.- __init__(profile)[source]¶
Create a
PlotPanelEventManager
.- Parameters
profile – The
Profile
instance that owns this event manager.
- register()[source]¶
Register listeners on all relevant
matplotlib
events. This method is called byProfile.register()
.
- deregister()[source]¶
De-register listeners on all relevant
matplotlib
events. This method is called byProfile.deregister()
.
- getMouseLocation(ev=None)[source]¶
Returns two tuples; the first contains the x/y coordinates of the most recent
matplotlib
event, and the second contains the corresponding x/y data coordinates.If an event has not yet occurred, or if the mouse position is not on any event target, this method returns
(None, None)
.- Parameters
ev – Ignored.
- __dict__ = mappingproxy({'__module__': 'fsleyes.profiles', '__doc__': 'This class manages events originating from ``matplotlib`` ``Canvas``\n objects contained within :class:`.PlotPanel` views.\n\n\n .. note:: This class has no support for ``figure_enter_event``,\n ``figure_leave_event``, ``axis_enter_event``, or\n ``axis_leave_event`` events. There appears to be some bugs\n lurking in the ``matplotlib/backend_bases.py`` file (something\n to do with the ``LocationEvent.lastevent`` property) which\n cause FSLeyes to seg-fault on ``figure_enter_event`` events.\n ', '__init__': <function PlotPanelEventManager.__init__>, 'register': <function PlotPanelEventManager.register>, 'deregister': <function PlotPanelEventManager.deregister>, 'getMouseLocation': <function PlotPanelEventManager.getMouseLocation>, 'getPickedArtist': <function PlotPanelEventManager.getPickedArtist>, 'getMplEvent': <function PlotPanelEventManager.getMplEvent>, '_PlotPanelEventManager__onEvent': <function PlotPanelEventManager.__onEvent>, '__dict__': <attribute '__dict__' of 'PlotPanelEventManager' objects>, '__weakref__': <attribute '__weakref__' of 'PlotPanelEventManager' objects>, '__annotations__': {}})¶
- __module__ = 'fsleyes.profiles'¶
- __weakref__¶
list of weak references to the object (if defined)
- getPickedArtist()[source]¶
Returns the
matplotlib.Artist
that was most recently picked (clicked on) by the user.
- getMplEvent()[source]¶
Returns the most recent
matplotlib
event that occurred, orNone
if no events have occurred yet.
- __onEvent(ev)¶
Handler for
matplotlib
events. Passes the correspondingwx
event to theProfile.handleEvent()
method.