Skip to content

Conversation

@seankmartin
Copy link
Contributor

@seankmartin seankmartin commented May 13, 2025

Summary

This PR introduces a horizontal stacking option to tool palettes, which can be toggled by clicking the button in the palette menu topbar on a per-palette basis. This allows a bit more customisation, and can be particularly helpful if the tool palette is below the viewer like in the below (cases like dimension slider widgets which might be familiar to some users as shown here come to mind):

image

image

User interaction

In neuroglancer, this setting is available on all tool palettes. Palettes stack in "auto" mode by default. In this mode, the stacking direction is determined by the aspect ratio of the panel. However, the button in the UI can be clicked to override this auto, and manually set it to be vertically or horizontally stacked.

Implementation

The primary change is to the tool palette menu, to introduce a setting which changes the widget stacking direction. In addition, there is a slight change to where the tool palette drop zone is positioned. This is so that the horizontal stacking can take up the full space of the element along the x-direction. In horizontal stacking, the drop-zone remains at the bottom of the palette menu, the same as for vertical stacking.
The state for the stacking mode is either auto, vertical, or horizontal

seankmartin and others added 30 commits January 3, 2025 12:20
CC-212 Tool palette UI improvements
@jbms
Copy link
Collaborator

jbms commented May 14, 2025

The vertical line at the left side shown when hovering over a group does not have full height when in horizontal mode and there is a vertical scroll bar.

image

@jbms
Copy link
Collaborator

jbms commented May 14, 2025

In general a horizontal layout seems really useful. But the fact that it is only horizontal across layer groups but not within a layer group seems kind of unfortunate. For example, if all controls are in the same layer then both layouts are the same.

It isn't clear exactly how to make the layout work the best, but one possibility to consider would be to allow a layer group to be a variable number of columns, if it would overflow the available vertical height --- i.e. controls fill top to bottom, then left to right. The width of controls would be (approximately) some fixed number of CSS pixels (rather than equal to total width divided by number of groups, as you have it currently). The end result would be that in horizontal stacking mode, there is almost never a vertical scroll bar (only if the panel is too short for a single control), just a horizontal scroll bar if needed. I think this could potentially be accomplished using css grid auto-fit or auto-fill to allow the browser to determine the layout rather than needing JavaScript code.

For symmetry it would make sense to apply the same auto-fill logic in vertical stacking mode --- if the tool palette is sufficiently wide, there may be two or more columns of controls that fill left to right, then top to bottom. As currently, there would generally be no horizontal scroll bar (only if the panel is too narrow for a single control), only a vertical scroll bar.

@seankmartin
Copy link
Contributor Author

This makes sense, thanks for the thougthful feedback and the ideas Jeremy

I tried a quick hacky version of this by just flattening out the entire div inside the tool palette just to see and directly using the css grid auto fill just to get an idea:

Screencast.from.2025-05-14.17-21-29.mp4

At https://github.com/MetaCell/neuroglancer/tree/feat/grid-auto-flow-palette-experiment

Will have a look later at doing a very similar thing (and less hacky) but instead doing it within a layer group, I think with some consideration of a few little things it could work pretty nicely -- will keep you posted

@jbms
Copy link
Collaborator

jbms commented May 20, 2025

Thanks.

From your example I see that grid may not do entirely what we want, since it indeed forces a grid meaning if we have a tall control in one cell, like the invlerp control, it wastes space in the rest of the row.

Maybe instead it can be done with css multi-column layout.

@seankmartin
Copy link
Contributor Author

Thanks Jeremy, looked into using CSS multi-column, and you can have something like this by manually setting the number of columns and width on the layer group content in css:
image

So it definitely seems closer to what would be desired than the multi-grid layout. You can still get something reasonable with lots of columns for a very low height panel by setting the width of the layer-group-content to be approx tool-width * num-tools and having a high column-count and removing the layer-group width (note, suggesting a column-width also possible instead of count), like this:

Screencast.from.2025-05-30.17-09-02.mp4

The main problems I'd see right now then would be that it might be less visually distinct to a user which controls belong to which layer. Possibly we could do something like this and alternate the background of the layer groups for that:

CleanShot 2025-05-29 at 10 34 29@2x (1)

The other thing would be that right now I think we need to compute that width of each tool palette in typescript for the multi-col layout. Which would involve monitoring the panel for resizes from it, the window, or other parts of the viewer being resized that also resize this panel. It's possible I'm missing some pure CSS solution to this, so I'm very open to suggestions.

One last thing for multi-col layout, I ran into an issue where large controls (like an inverlp or transfer function) would break across cols. If we go the multi-col route maybe we could consider setting those widgets break-inside prop to avoid breaking over columns

@jbms
Copy link
Collaborator

jbms commented Oct 20, 2025

Yes, seems like break-inside: avoid should be set on all widgets.

You can monitor resizes reliably with ResizeObserver, so having to handle the sizing in javascript is not a big deal if we are just setting css properties that depend on the overall size of the palette. If it needs to examine the size of each individual tool that would be more annoying.

I assume we want to try to avoid having both vertical and horizontal scroll bars except if the user has made the height too small for even a single widget to fit.

In general you could imagine multi-column layout would be used automatically any time width exceeds some fixed number of pixels, however there are some caveats:

  • It looks like css multi-column always fills top to bottom before left to right, and that is the only thing that makes sense to accommodate variable-height tools. That makes it awkward to scroll vertically, though --- so that would mean that any time we use multi-column layout we should scroll horizontally.

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