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

NAP-6: Updates after discussion and review #312

Merged
merged 27 commits into from
Jun 22, 2024
Merged
Changes from 13 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4b23f3c
Add contributable menus nap
DragaDoncila Dec 19, 2022
0743342
Update docs/naps/6-contributable-menus.md
DragaDoncila Dec 19, 2022
0857e76
Fixed header info
DragaDoncila Dec 20, 2022
e112629
Merge branch 'nap-6' of https://github.com/DragaDoncila/docs into nap-6
DragaDoncila Dec 20, 2022
f8618ab
Pull out Layers->Generate, move Layers->New
DragaDoncila Dec 28, 2023
4540e49
Add section on user configuration
DragaDoncila Jan 3, 2024
4625371
Add section on grouping and order
DragaDoncila Jan 3, 2024
b7cbbfe
Add bit about description of menu items and deprecating with preferen…
DragaDoncila Jan 3, 2024
64c89c3
Add link to discussions
DragaDoncila Jan 3, 2024
ec49754
merge main
DragaDoncila Jan 3, 2024
39cf099
Weasel out of submenu count
DragaDoncila Jan 3, 2024
bff2671
Merge branch 'main' into nap-6
DragaDoncila Jan 10, 2024
977617c
Merge branch 'main' into nap-6
DragaDoncila Feb 22, 2024
9da1ff9
Comments after review
DragaDoncila Jun 5, 2024
14c3641
Merge branch 'nap-6' of https://github.com/DragaDoncila/docs into nap-6
DragaDoncila Jun 5, 2024
b4f6a8a
Add detail about plugin's own submenu
DragaDoncila Jun 5, 2024
f13eb5c
Fix typo
DragaDoncila Jun 5, 2024
463ba83
remove a bunch of trailing whitespace
DragaDoncila Jun 7, 2024
2addabf
Update docs/naps/6-contributable-menus.md
DragaDoncila Jun 7, 2024
78e76c8
Update docs/naps/6-contributable-menus.md
DragaDoncila Jun 7, 2024
2b81fdf
Add example for visualize
DragaDoncila Jun 7, 2024
29615bc
Expand on what can be a contribution
DragaDoncila Jun 7, 2024
e15f5aa
Move Acquire into File
DragaDoncila Jun 7, 2024
bc99bbc
Get rid of Layers/edit menu
DragaDoncila Jun 21, 2024
5974716
Some more menu reorg
DragaDoncila Jun 21, 2024
62a8cf6
Add layer data and layer layer type
DragaDoncila Jun 21, 2024
888f8af
Add links to tracking issue and PR
DragaDoncila Jun 21, 2024
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
187 changes: 122 additions & 65 deletions docs/naps/6-contributable-menus.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,22 +153,28 @@ actions.

### The `Layers` Menu
Currently the foremost example of such an object is the napari `Layers`, and this
top level menu therefore contains five submenus organized by the types of processing
top level menu therefore contains a number of submenus organized by the types of processing
the user may wish to perform on the selected `Layer` or `Layers`.

The `Layers` submenus are organized to give the user an immediate
feeling of what might happen to their `Layers` as a result of clicking
one of these menu items.

1. `Visualization` - Items in this submenu allow you to generate visualizations from selected layer or layers.
1. `Visualize` - Items in this submenu allow you to generate visualizations from selected layer or layers.
They do not change the layer data.
2. `Measure` - Items in this submenu provide utilities for summarising information about your layer's data.
3. `Edit` - The items in this submenu change the data of your layer through `Filters` or `Transformations`.
3. `Edit` - The items in this submenu change the data of your layer through `Filters` or `Transformations`.
Additionally `Annotation Tools` provide a location for convenience layer editing tools e.g. `Labels` split/merge actions.
Items in this submenu **should not** generate new layers, but rather act upon the existing layer data.
3. `Generate` - Items in this submenu are the main *analysis* actions you can take on your layer.
These items should add new layers to the viewer based on analyses and processing of data in your selected layer(s).
The five proposed submenus are `Projection`, `Segmentation`, `Classification`, `Registration` and `Tracks`.

The remaining submenus under `Layers` deal with generating new layers based on processing of existing layers
or other information. They define common *analysis* actions users may want to take on their layers.

4. `Registration` - Commands that allow the user to perform image registration on one or more layers
5. `Projection` - Commands that generate various projections based on one or more layers
6. `Segmentation` - Commands that generate image segmentations
7. `Tracks` - Commands that take in an image or segmentation and produce timelapse tracks
8. `Classification` - ??
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved

Many of the actions in this menu exist in the right click layer context menu. These items
Copy link
Collaborator

Choose a reason for hiding this comment

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

Question - would all items in the layer context menu be replicated in the Layers menubar menu?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great question! I imagine they will all somehow be replicated either somewhere in the Layers menu or somewhere in the Edit menu? But again not super clear to me just now what the distinction between those should be, so I want to have a closer look at e.g. Photoshop

should be replicated in the `Layers` menu as needed, both to aid discoverability and
Expand Down Expand Up @@ -205,6 +211,13 @@ It is likely, therefore, that some plugins will always have bespoke interfaces f
exporting various file formats. These interfaces will be exposed via the new `File->I/O Utilities`
menu.

### The `File -> New Layer` Menu

This menu will contain built-in `napari` commands for creating new empty layers (similar to
the new layer buttons atop the layerlist), but also allow plugins to declare commands that
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved
open new empty layers with specific properties e.g. a `zarr`-backed `Labels` layer, an
`Image` layer with a specific `dtype`, or a `Points` layer with specific default features.

### Plugin Submenus

The goal of the newly proposed menus is to provide a natural place where generally applicable
Expand All @@ -224,44 +237,42 @@ Plugin developers can organize all contributions under this submenu as they see
```
File
├─ ...
├─ New Layer
├─ IO Utilities
Layers
├─ Visualization
├─ Visualize
├─ Measure
├─ Edit
│ ├─ Annotation Tools
│ ├─ Annotate
│ ├─ Filter
│ ├─ Transform
├─ Measure
├─ Generate
│ ├─ Registration
│ ├─ Projection
│ ├─ Segmentation
│ ├─ Tracks
│ ├─ Classification
├─ Registration
├─ Projection
├─ Segmentation
├─ Tracks # remove?
├─ Classification # remove?
Acquisition
Plugins/<my_plugin> # only individual plugins submenu contributable

Layers Context # already open for contribution
```

As a case study, we take four plugins offering between 9 and 14 widget contributions and arrange their widgets in these menus:
As a case study, we take four plugins offering between 9 and 14 widget contributions and arrange their widgets in these menus:
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved
`empanada-napari`, `napari-stracking`, `napari-mm3` and `napari-clemreg`. Where a plugin's widgets don't
naturally fit into one of the proposed menus, they are left in the plugin's own submenu.
Note that we have arranged these widgets purely based on title and cursory inspection of the documentation,
Note that we have arranged these widgets purely based on title and cursory inspection of the documentation,
so this should not be considered a concrete proposal for the structure of these plugins.

```
File
├─ ...
├─ New Layer
├─ IO Utilities
│ ├─ Export 2D segmentations (empanada-napari)
│ ├─ Store training dataset (empanada-napari)
│ ├─ nd2ToTIFF (napari-mm3)
Layers
├─ Visualization
├─ Visualize
│ ├─ SFilterTrack (napari-stracking)
├─ Edit
│ ├─ Annotation Tools
│ ├─ Annotate
│ │ ├─ Merge Labels (empanada-napari)
│ │ ├─ Delete Labels (empanada-napari)
│ │ ├─ Split Labels (empanada-napari)
Expand All @@ -274,27 +285,26 @@ Layers
├─ Measure
│ ├─ SParticlesProperties (napari-stracking)
│ ├─ STracksFeatures (napari-stracking)
├─ Generate
│ ├─ Registration
│ ├─ Projection
│ ├─ Segmentation
│ │ ├─ 2D Inference (empanada-napari)
│ │ ├─ 3D Inference (empanada-napari)
│ │ ├─ make_log_segmentation (napari-clemreg)
│ │ ├─ make_clean_binary_segmentation (napari-clemreg)
│ │ ├─ SegmentOtsu (napari-mm3)
│ │ ├─ SegmentUnet (napari-mm3)
│ │ ├─ Foci (napari-mm3)
│ │ ├─ SDetectorDog (napari-stracking)
│ │ ├─ SDetectorDoh (napari-stracking)
│ │ ├─ SDetectorLog (napari-stracking)
│ │ ├─ SDetectorSeg (napari-stracking)
│ ├─ Tracks
│ │ ├─ SLinkerShortestPath (napari-stracking)
│ │ ├─ Tracks (napari-mm3)
│ ├─ Classification
│ ├─ make_point_cloud_sampling (napari-clemreg)
│ ├─ make_point_cloud_registration (napari-clemreg)
├─ Registration
├─ Projection
├─ Segmentation
│ ├─ 2D Inference (empanada-napari)
│ ├─ 3D Inference (empanada-napari)
│ ├─ make_log_segmentation (napari-clemreg)
│ ├─ make_clean_binary_segmentation (napari-clemreg)
│ ├─ SegmentOtsu (napari-mm3)
│ ├─ SegmentUnet (napari-mm3)
│ ├─ Foci (napari-mm3)
│ ├─ SDetectorDog (napari-stracking)
│ ├─ SDetectorDoh (napari-stracking)
│ ├─ SDetectorLog (napari-stracking)
│ ├─ SDetectorSeg (napari-stracking)
├─ Tracks
│ ├─ SLinkerShortestPath (napari-stracking)
│ ├─ Tracks (napari-mm3)
├─ Classification
├─ make_point_cloud_sampling (napari-clemreg)
├─ make_point_cloud_registration (napari-clemreg)
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved
Acquisition
Plugins
├─ empanada-napari
Expand All @@ -318,13 +328,38 @@ Plugins
│ ├─ predict_from_model
```

### Item Descriptions

To allow users to browse menus more effectively without having to click each
item to figure out what it does, menu contributions should be given a `description`
field that is available when the user is inspecting the menu. The `description`
should be required, so that
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved


### Item Grouping & Ordering

Previously, plugin contributions were limited to the `Plugins` menu and grouped
under the plugin's name. Now that plugin contributions can be colocated with
native napari actions, it's important that users are able to distinguish
the source of menu items.

To that end, napari items should always be grouped separately to plugin items
in all menus. Additionally, the plugin's name should also be listed with
each plugin contribution. Since plugin names can be quite long, future work should
consider more concise ways to indicate menu item sources, including using icons.
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved

Outside of a plugin's own submenu, the `order` and `group` keys will be ignored
for menu contributions. napari will make its own decisions about the grouping
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved
and ordering of plugin contributions in its native menus.


### Items that Don't Fit?

Where a plugin developer feels that none of the submenus of a given menu are suitable
for their purpose, they should add their item to the deepest applicable menu. For
example, a widget that takes a layer and produces a new layer through random perturbations
would not fit under `Layers -> Generate -> Segmentation` but could fit under
`Layers -> Generate`.
would not fit under `Layers -> Segmentation` but could fit under the top level
`Layers` menu.

Where a plugin developer feels no top level menu or submenu is suitable for their purpose,
they should add their item to their own plugin's submenu under `Plugins -> Your Plugin`,
Expand All @@ -344,15 +379,15 @@ As the number of plugins, types of contributions and `Viewer` interactions grows
it is important that the set of contributable menus is periodically assessed
to add new submenus as required.

Every 6 months to 1 year, the core developers will perform an analysis on
the total set of menu item and widget contributions of all plugins, and
derive new groupings to ensure that the length of each submenu remains
managable.
Every 6 months to 1 year, the core developers will perform an analysis on
the total set of menu item and widget contributions of all plugins, and
derive new groupings to ensure that the length of each submenu remains
managable.

For example, consider the `Layers -> Generate -> Segmentation` menu. If
For example, consider the `Layers -> Segmentation` menu. If
analysis of the plugin ecosystem reveals 40 different contributions
for Watershed Segmentation, a new `Watershed` submenu would be added
under `Layers -> Generate -> Segmentation -> Watershed`.
under `Layers -> Segmentation -> Watershed`.

#### User Request

Expand All @@ -372,6 +407,21 @@ a Pull Request will be raised opening up this menu for contribution.
The user proposing the menu is not responsible for opening this Pull
Request, though they may, if they wish.

### User Configuration

This document has so far discussed menu contributions exclusively from
the plugin developer's perspective. In general, napari will continue
to be opinionated about what plugin developers can and cannot change
about the napari interface through menu contributions. Our guiding principle
here is that users should never be surprised by the napari interface as a result
of standard plugin contributions - menus shouldn't move around, or be hidden, layer
controls should behave in the same way regardless of what plugins are installed, etc.

However, napari users **should** be able to freely customize their own napari installation
to a much greater extent. This should include contribution-level enablement control
for plugins, as well as building their own custom menus, whether this be a brand new top-level
Copy link
Collaborator

Choose a reason for hiding this comment

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

Naive question, how would users control plugin contribution enablement..?

Copy link
Member

Choose a reason for hiding this comment

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

I imagine, a tree selection widget like this one:

flutter tree view

I think there should be some internal npe2 data structure for this, but the UI itself should itself be a plugin. (Maybe built-ins.)

Copy link
Collaborator

@lucyleeow lucyleeow May 28, 2024

Choose a reason for hiding this comment

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

Would this be separate to our plugin manager (i.e. the install/uninstall/enable/disable dialog)?

(plugin manager has several meanings in napari: #321 (comment) 🙈 )

Copy link
Member

Choose a reason for hiding this comment

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

I'm ambivalent about it, and would leave that decision to whoever ends up implementing it.

On the one hand, it can be an independent dialog — enablement of contributions only needs npe2 and stuff already installed, and doesn't need to depend on conda, pip, etc. So you eliminate a lot of complexity. Additionally, I personally would never use the plugin manager (I directly install things with micromamba as needed), but I would probably use the enablement UI because the alternative, I think, is editing some random yaml or something? 😂 Which I'm not super excited about.

On the other hand, I can imagine a user being in the enablement UI and thinking hmm, I really don't use this plugin, I should remove it. And they would probably be grateful if that can be done in the same widget rather than have to launch a totally different interface.

menu or rearranging things within existing menus.

## Related Work

<!-- This section should list relevant and/or similar technologies, possibly in
Expand Down Expand Up @@ -423,9 +473,9 @@ can simply maintain logic for migrating old IDs to new ones.
If a contributable `napari` submenu is removed, this should be highlighted
first by a deprecation warning. Once the submenu is deprecated, contributions
that refer to this submenu should instead be placed in the higher level
menu. For example, if `Layers -> Generate -> Segmentation` is removed,
menu. For example, if `Layers -> Segmentation` is removed,
existing contributions referring to this ID will be placed under
`Layers -> Generate`.
`Layers`.

If a contributable `napari` top level menu is removed, this should be highlighted
first by a deprecation warning. Before the submenu is deprecated, core developers
Expand All @@ -441,40 +491,45 @@ in the plugin's submenu at the top level.

## Future Work

As mentioned above, a key feature to support rapid browsing for actions is the
**Command paltte:** As mentioned above, a key feature to support rapid browsing for actions is the
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved
search functionality via the command palette. This is actively being worked
on and is essential for navigation.

Once more contribution types are exposed for users, it's important that users
**Context dependent enablement:** Once more contribution types are exposed for users, it's important that users
are aware why certain actions are disabled when the user doesn't meet the
requisite context declared in the contribution's `enablement` clause. Since
the syntax for declaring these contexts is strictly defined, we should be
able to surface information to suers about what is required for the action
to be enabled and functional. For example, an action could declare itself
enabled only when a points layer *and* an image layer are selected. If
enabled only when a points layer *and* an image layer are selected. If
the user has only selected an image layer, we could indicate the missing
context to the user e.g. "Action takes a points and image layer, but no
points layer is selected".
points layer is selected".
DragaDoncila marked this conversation as resolved.
Show resolved Hide resolved

A desired attribute of these menu items is that users always know what
**Making actions predictable:** A desired attribute of these menu items is that users always know what
will happen when they click a menu item. Does a widget open? Is the layer
edited? Is a new layer added to the `Viewer`? Once more contribution
types are exposed, we should be able to either add this information
as metadata in the manifest file, or infer it from return type
edited? Is a new layer added to the `Viewer`? Once more contribution
types are exposed, we should be able to either add this information
as metadata in the manifest file, or infer it from return type
annotations of contribution commands, and also expose this to the user.

Finally, the number of actions in each menu is heavily dependent on
**Dynamic menus:** The number of actions in each menu is heavily dependent on
the plugins installed in the user's environment. Given a complete set of
contributable menus, we could dynamically inspect how many menu items
each submenu contains, and group them appropriately for the user while
limiting unnecessary depth. For example, if the user's environment has
six plugins installed that each provide a `Watershed` segmentation,
we could display a `Layers -> Generate -> Segmentation -> Watershed`
submenu. If the user has just one `Watershed` segmentation plugin
installed, this submenu would not appear. This would require very careful
submenu. If the user has just one `Watershed` segmentation plugin
installed, this submenu would not appear. This would require very careful
design to ensure the user still knows what to expect when they load up
the `Viewer`.

**Location preferences:** One option to consider when moving/removing
menus is allowing plugin developers to declare a preference list of
menu locations, such that if one location is no longer available,
the menu item is placed in the next location on the preference list.

## Alternatives

The main alternative is the proposed `Tools` menu from [npe2 #161](https://github.com/napari/npe2/pull/161).
Expand All @@ -499,7 +554,9 @@ interactions and plugin contributions e.g. multi canvas
- **Jun 2 2022: npe2 #161** After further discussion (on zulip and in PR), this schema is identified as potentialy too limiting and there is mention that #160 may need to be reverted. A NAP is once again suggested as this is an influential decision with lots of opinions.
- **Jun 13 2022: npe2 #161** is closed and #160 is reverted, with comment for follow up over in the napari repo.
- **[Sep 30 2022: napari #5153](https://github.com/napari/napari/pull/5153)** opened with same list as in npe2, minimal discussion and input.
- **Oct 28 2022: napari #5153** discussion on core devs zulip stream begins. Developers mostly agree on the inidividual menu items but don't like how deep the `Tools` menu already is, and the lack of semantic meaning in its structure.
- **Oct 28 2022: napari #5153** discussion on core devs zulip stream begins. Developers mostly agree on the inidividual menu items but don't like how deep the `Tools` menu already is, and the lack of semantic meaning in its structure.
- **[Dec 22 2022: NAP6 PR](https://github.com/napari/docs/pull/77)** is opened and there is much discussion. Implementation is blocked by `app-model` work, so focus turns to that.
- **[Oct 04 2023: Hackathon](https://hackmd.io/fmKp0If5RkiwWIxYYRdKpg)** is held and Draga demos working branch of menu contributions. Core devs present discuss various outstanding items. This discussion is summarised in the linked notes.

## References and Footnotes

Expand Down
Loading