Skip to content

Implement toggling colorbar and bounding box in layerlist context menu - #8319

Merged
TimMonko merged 5 commits into
napari:mainfrom
Czaki:colorbar_enable
Oct 1, 2025
Merged

TimMonko merged 5 commits into
napari:mainfrom
Czaki:colorbar_enable

Conversation

@Czaki

@Czaki Czaki commented Sep 30, 2025 •

Copy link
Copy Markdown
Collaborator

References and relevant issues

https://napari.zulipchat.com/#narrow/channel/215289-release/topic/0.2E6.2E5/near/542262710

Description

Add an option to control the visibility of colorbar and bounding box from layerlist context menu.

Screenshot 2025-09-30 at 17 23 13

@Czaki
Czaki requested a review from a team as a code owner September 30, 2025 15:22
@Czaki Czaki added the enhancement Improvement to pre-existing features label Sep 30, 2025
@TimMonko TimMonko changed the title Implement toggling colorbar and bounding box in layelist context menu Implement toggling colorbar and bounding box in layerlist context menu Sep 30, 2025
@Czaki Czaki added this to the 0.6.5 milestone Sep 30, 2025

@TimMonko TimMonko left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This works in the original PR as:
The right clicked layer must be the active layer (this is confusing to me!!!)

  1. bounding box enabled only when 1 layer selected
  2. colorbar enabled only when 1 layer selected and its an image or surface

I propose with my comments different behavior. I tested locally and found this to perform much closer to my expectation with both these features and similar layer list context items (which can perform on multiple layers)

  1. bounding box enabled when any layers are selected, and will be toggled for all selected layers
  2. colorbar enabled with any number of layers, as long as those layers are surface or image. will toggle for all selected layers

Even if we don't go with my proposed enablement, the callbacks can be used as I've proposed (though the for loop is unnecessary), because enablement already protects against the guards. We could add back the non-image/surface guard to present the warning and do enablement on any number of selected layers

Let me know if I'm missing something

Comment thread src/napari/_app_model/context/_layerlist_context.py Outdated
MenuId.LAYERLIST_CONTEXT,
SubmenuItem(
submenu=MenuId.LAYERS_CONTEXT_VISUALIZATION,
title=trans._('Visualization'),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could alternatively use "Overlays". I think either is ok, especially because we may want to add some kind of non-overlay visualization to this menu?

Comment thread src/napari/layers/_layer_actions.py Outdated
ll.append(new)


def _toogle_bounding_box(ll: LayerList) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
def _toogle_bounding_box(ll: LayerList) -> None:
def _toggle_bounding_box(ll: LayerList) -> None:

Action(
id='napari.layer.bounding_box',
title=trans._('Bounding Box'),
callback=_layer_actions._toogle_bounding_box,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
callback=_layer_actions._toogle_bounding_box,
callback=_layer_actions._toggle_bounding_box,

(method in _layer_actions needs updated as well)

Comment thread src/napari/layers/_layer_actions.py Outdated
Comment on lines +260 to +269
if not (layer := ll.selection.active):
return

if not isinstance(layer, Image | Surface):
raise NotImplementedError(
trans._(
'Colorbar is only implemented for Images and Surfaces',
deferred=True,
)
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is all unnecessary because of the enablement, right? Why would we want this?

Comment on lines +255 to +259
(LLSCK.num_selected_layers == 1)
& (
LLSCK.all_selected_layers_image
| LLSCK.all_selected_layers_surfaces
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
(LLSCK.num_selected_layers == 1)
& (
LLSCK.all_selected_layers_image
| LLSCK.all_selected_layers_surfaces
)
LLSCK.all_selected_layers_image
| LLSCK.all_selected_layers_surfaces

'id': MenuId.LAYERS_CONTEXT_VISUALIZATION,
}
],
enablement=LLSCK.num_selected_layers == 1,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
enablement=LLSCK.num_selected_layers == 1,
enablement=LLSCK.num_selected_layers > 0,

Comment thread src/napari/layers/_layer_actions.py Outdated
Comment on lines +260 to +270
if not (layer := ll.selection.active):
return

if not isinstance(layer, Image | Surface):
raise NotImplementedError(
trans._(
'Colorbar is only implemented for Images and Surfaces',
deferred=True,
)
)
layer.colorbar.visible = not layer.colorbar.visible

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if not (layer := ll.selection.active):
return
if not isinstance(layer, Image | Surface):
raise NotImplementedError(
trans._(
'Colorbar is only implemented for Images and Surfaces',
deferred=True,
)
)
layer.colorbar.visible = not layer.colorbar.visible
for layer in ll.selection:
layer.colorbar.visible = not layer.colorbar.visible

Comment thread src/napari/layers/_layer_actions.py Outdated
Comment on lines +254 to +256
if not (layer := ll.selection.active):
return
layer.bounding_box.visible = not layer.bounding_box.visible

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if not (layer := ll.selection.active):
return
layer.bounding_box.visible = not layer.bounding_box.visible
for layer in ll.selection
layer.bounding_box.visible = not layer.bounding_box.visible

@codecov

codecov Bot commented Sep 30, 2025 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.35294% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.08%. Comparing base (4d44acc) to head (3a52d19).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/napari/layers/_layer_actions.py 57.14% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8319      +/-   ##
==========================================
+ Coverage   93.03%   93.08%   +0.05%     
==========================================
  Files         710      710              
  Lines       63989    64006      +17     
==========================================
+ Hits        59529    59581      +52     
+ Misses       4460     4425      -35     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +261 to +266
raise NotImplementedError(
trans._(
'Colorbar is only implemented for Images and Surfaces',
deferred=True,
)
)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I keep this raise to have clean information about what goes wrong when our check do not properly limit layer selection.

Comment on lines +195 to +196
def _all_support_colorbar(s: LayerSel) -> bool:
return bool(s and all(hasattr(x, 'colorbar') for x in s))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

really like this addition -- will be much clearer to support and allow custom layers to access!!!!

Comment thread src/napari/_app_model/context/_layerlist_context.py Outdated
Comment thread src/napari/_app_model/context/_layerlist_context.py Outdated
@TimMonko TimMonko added the ready to merge Last chance for comments! Will be merged in ~24h label Sep 30, 2025
@TimMonko
TimMonko merged commit 626528f into napari:main Oct 1, 2025
38 checks passed
@github-actions github-actions Bot removed the ready to merge Last chance for comments! Will be merged in ~24h label Oct 1, 2025
@TimMonko TimMonko added the highlight PR that should be mentioned in next release notes label Oct 1, 2025
@TimMonko

TimMonko commented Oct 1, 2025

Copy link
Copy Markdown
Member

@brisvag I added highlight to this, I'll leave it up to you to add. We should at least add this new feature to the docs somewhere.

@brisvag

brisvag commented Oct 1, 2025 •

Copy link
Copy Markdown
Contributor

I added the whole overlays shebang to the docs, should have done this a while back :P napari/docs#857

@Czaki
Czaki deleted the colorbar_enable branch October 2, 2025 07:34
@imagesc-bot

Copy link
Copy Markdown

This pull request has been mentioned on Image.sc Forum. There might be relevant details there:

https://forum.image.sc/t/napari-v0-6-5-is-out/116715/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement to pre-existing features highlight PR that should be mentioned in next release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants