FSLeyes plugin architecture
The File -> Add plugin menu option
Allows the user to choose a .py
file which contains sub-classes of:
-
fsleyes.views.viewpanel.ViewPanel
. These will be added as options under the View menu. -
fsleyes.actions.Action
. These will be added as options under the Tools menu. -
fsleyes.panel.FSLeyesPanel
. These are assumed to be control panels, and will be added as options under the Settings -> [view] menus. It is assumed that the control is compatible with all FSLeyes views, or at least gracefully fails (e.g. with an error message) if an attempt is made to add it to an incompatible view.
The user will be asked if they would like to install the plugin. If they agree, the .py
file will be saved
under [fsleyes_settings_dir]/plugins/
, and made available the next time FSLeyes is started.
Example
# myplugin.py
import fsleyes.panel as fsleyespanel
import fsleyes.views.viewpanel as viewpanel
import fsleyes.actions as actions
# An option to add a MyControl panel
# to a view will be added in the
# Settings -> [view] menus
class MyControl(fsleyespanel.FSLeyesPanel):
pass
# An option to add a MyView panel
# will be added to the View menu
class MyView(viewpanel.ViewPanel):
pass
# An option to invoke the MyTool
# action will be added to the
# Tools menu.
class MyTool(actions.Action):
pass
Issues
Display names
Where do we get display names (for e.g. menu items and title bars) from? Display names for built-in controls/views/tools are hard-coded in fsleyes.strings
. Prompt the user? Define semantics allowing display names to be specified in the plugin file? e.g.
# myplugin.py
__FSLEYES_NAMES__ = {
'MyControl' : 'My control',
'MyView' : 'My view',
'MyTool' : 'My tool',
}
import fsleyes.panel as fsleyespanel
import fsleyes.views.viewpanel as viewpanel
import fsleyes.actions as actions
class MyControl(fsleyespanel.FSLeyesPanel):
pass
...
Or perhaps the plugin file could add entries to fsleyes.strings
, e.g.:
import fsleyes.panel as fsleyespanel
import fsleyes.strings as strings
class MyControl(fsleyespanel.FSLeyesPanel):
pass
strings.titles[MyControl] = 'My control'
Or - better than both of the above - use the setuptools
entry point name, e.g. in plugin.py
:
class MyControl(fsleyespanel.FSLeyesPanel):
pass
Then in setup.py
:
setup(
entry_points={
'fsleyes_views' : [
'My super control = plugin:MyControl'
]
Interaction profiles
What about custom interaction profiles, e.g. as used by Tools -> Crop ? Allow sub-classes of fsleyes.profiles.Profile
, and add it as an option under Tools
? This might take a bit of work/thought, because the profiles supported by a view are currently quite tightly-coupled to the view implementation.