Skip to content
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

Proof of Concept approach for plugins providing actions #103

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

sofroniewn
Copy link
Collaborator

Here is a potential approach for allowing plugins to providing actions such as keybindings that could then be registered by the action manager that @tlambert03 and I came up with. The big goal was to remove to explicit calls to viewer.bind_key and the need for the plugin to clean up its own keybindings and have the "bind" and "unbind" be done by napari through the actions manager, so the shortcut can be changed etc.

The main idea is that there is a new hook_specification napari_register_actions that allows a list of actions to be passed. This approach was a little more inspired by how we used to think about providing defaults with the actions themselves, but we should really follow the APIs that @Carreau has already been developing and using in napari, but now just be able to pass plugin dock widgets to these functions and register shortcuts to them.

What we wrote could look something like this

from napari_animation._qt import AnimationWidget


@napari_hook_implementation
def napari_register_actions():
    return [
        (AnimationWidget, "Alt-f", AnimationWidget._capture_keyframe_callback)
        (AnimationWidget, "Alt-r", AnimationWidget._replace_keyframe_callback)
        (AnimationWidget, "Alt-d", AnimationWidget._capture_keyframe_callback)
        (AnimationWidget, "Alt-a", lambda w: w.animation.key_frames.select_next())
        (AnimationWidget, "Alt-b", lambda w: w.animation.key_frames.select_previous())
        # ('napari.Viewer', 'alt-f', viewer_function) # To register action to viewer (not used in this repo, but illustrative)
        # ('napari.layers.Points', 'alt-p', points_function) # To register action to points layer (not used in this repo, but illustrative)
    ]

We will need to think about how napari can receive these actions, and how/ when they will get called, but that is on the napari side, not the plugin side.

Curious what @Carreau thinks about this. Might probably be good to have a dedicated meeting with @Carreau @ppwadhwa @goanpeca too to discuss this as we start thinking about it more!! cc @jni @alisterburt

Copy link
Collaborator

@alisterburt alisterburt left a comment

Choose a reason for hiding this comment

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

this looks really interesting, definitely a goal we want to push for!
I'm not sure why some of the actions are lambda functions whilst others are the callback method itself - is this a bind to the instance vs. class thing?

@sofroniewn
Copy link
Collaborator Author

I'm not sure why some of the actions are lambda functions whilst others are the callback method itself - is this a bind to the instance vs. class thing?

It was just using what was there before, wasn't thought out beyond that. We could standardize and make it a little more readable

@tlambert03
Copy link
Contributor

to expand on that a bit:
we're imagining that the third item in the list is a callback that will get called with an instance of the first item in the list. Calling AnimationWidget._capture_keyframe_callback(widget_instance) is the same thing as calling widget_instance._capture_keyframe_callback(), so it could have been expressed either using the unbound method, or using a lambda function: lambda w: w._capture_keyframe_callback().
The last two methods (select_next and select_previous) do not, however, accept an argument, so a lambda is necessary to "consume" the argument that the action manager is going to provide. (but, they could have all been expressed with a lambda too ... perhaps it would have been clearer, but this is also educational :)

@alisterburt
Copy link
Collaborator

very useful @tlambert03 - made me realise a few things, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants