MEP22: Toolbar rewrite#

Status#

Progress

Branches and Pull requests#

Previous work:

Pull Requests:

Abstract#

The main goal of this MEP is to make it easier to modify (add, change,remove) the way the user interacts with the figures.

The user interaction with the figure is deeply integrated within theCanvas and Toolbar. Making extremely difficult to do any modification.

This MEP proposes the separation of this interaction into Toolbar,Navigation and Tools to provide independent access andreconfiguration.

This approach will make easier to create and share tools amongusers. In the far future, we can even foresee a kind of MarketplaceforTools where the most popular can be added into the maindistribution.

Detailed description#

The reconfiguration of the Toolbar is complex, most of the time itrequires a custom backend.

The creation of custom Tools sometimes interferes with the Toolbar, asexample seematplotlib/matplotlib#2694 alsothe shortcuts are hardcoded and again not easily modifiablematplotlib/matplotlib#2699

The proposed solution is to take the actions out of theToolbar and theshortcuts out of theCanvas. The actions and shortcuts will be in the formofTools.

A new classNavigation will be the bridge between the events from theCanvas andToolbar and redirect them to the appropriateTool.

At the end the user interaction will be divided into three classes:

  • NavigationBase: This class is instantiated for each FigureManagerand connect the all user interactions with the Tools

  • ToolbarBase: This existing class is relegated only as a GUI accessto Tools.

  • ToolBase: Is the basic definition of Tools.

Implementation#

ToolBase(object)#

Tools can have a graphical representation as theSubplotTool or not even bepresent in the Toolbar asQuit.

TheToolBase has the following class attributes for configuration at definition time

  • keymap = None: Key(s) to be used to trigger the tool

  • description = '': Small description of the tool

  • image = None: Image that is used in the toolbar

The following instance attributes are set at instantiation:

  • name

  • navigation

Methods#

  • trigger(self,event): This is the main method of the Tool, it is calledwhen the Tool is triggered by:

    • Toolbar button click

    • keypress associated with the Tool Keymap

    • Call to navigation.trigger_tool(name)

  • set_figure(self,figure): Set the figure and navigation attributes

  • destroy(self,*args): Destroy theTool graphical interface (ifexists)

Available Tools#

  • ToolQuit

  • ToolEnableAllNavigation

  • ToolEnableNavigation

  • ToolToggleGrid

  • ToolToggleFullScreen

  • ToolToggleYScale

  • ToolToggleXScale

  • ToolHome

  • ToolBack

  • ToolForward

  • SaveFigureBase

  • ConfigureSubplotsBase

ToolToggleBase(ToolBase)#

TheToolToggleBase has the following class attributes forconfiguration at definition time

  • radio_group = None: Attribute to group 'radio' like tools (mutuallyexclusive)

  • cursor = None: Cursor to use when the tool is active

TheToggleable Tools, can capture keypress, mouse moves, and mousebutton press

Methods#

  • enable(self,event): Called byToolToggleBase.trigger method

  • disable(self,event): Called when the tool is untoggled

  • toggled:Property True or False

Available Tools#

  • ToolZoom

  • ToolPan

NavigationBase#

Defines the following attributes:

  • canvas:

  • keypresslock: Lock to know if thecanvaskey_press_event isavailable and process it

  • messagelock: Lock to know if the message is available to write

Methods (intended for the end user)#

  • nav_connect(self,s,func): Connect to navigation for events

  • nav_disconnect(self,cid): Disconnect from navigation event

  • message_event(self,message,sender=None): Emit atool_message_event event

  • active_toggle(self):Property The currently toggled tools orNone

  • get_tool_keymap(self,name): Return a list of keys that areassociated with the tool

  • set_tool_keymap(self,name,``*keys)``: Set the keys for the given tool

  • remove_tool(self,name): Removes tool from the navigation control.

  • add_tools(self,tools): Add multiple tools toNavigation

  • add_tool(self,name,tool,group=None,position=None): Add a toolto theNavigation

  • tool_trigger_event(self,name,sender=None,canvasevent=None,data=None): Trigger a tool and fire the event

  • tools:Property A dict with available tools withcorresponding keymaps, descriptions and objects

  • get_tool(self,name): Return the tool object

ToolbarBase#

Methods (for backend implementation)#

  • add_toolitem(self,name,group,position,image,description,toggle):Add a toolitem to the toolbar. This method is a callback fromtool_added_event (emitted by navigation)

  • set_message(self,s): Display a message on toolbar or in status bar

  • toggle_toolitem(self,name): Toggle the toolitem without firing event.

  • remove_toolitem(self,name): Remove a toolitem from theToolbar

Backward compatibility#

For backward compatibility added 'navigation' to the list of valuessupported byrcParams["toolbar"] (default:'toolbar2'), that is used forNavigation classesinstantiation instead of the NavigationToolbar classes

With this parameter, it makes it transparent to anyone using theexisting backends.

[@pelson comment: This also gives us an opportunity to avoid needingto implement all of this in the same PR - some backends canpotentially exist without the new functionality for a short while (butit must be done at some point).]