Skip to content

Commit d64d131

Browse files
committed
Fix UX inconsistencies
1 parent 524dacc commit d64d131

8 files changed

Lines changed: 70 additions & 40 deletions

File tree

‎src/main/java/sc/fiji/snt/BookmarkManager.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ private JPopupMenu assembleTablePopupMenu(final BookmarkTable table) {
431431
pMenu.add(mi);
432432
pMenu.addSeparator();
433433
}
434+
434435
mi = new JMenuItem("Delete...", IconFactory.menuIcon(IconFactory.GLYPH.TRASH));
435436
mi.addActionListener(e -> {
436437
if (noBookmarksError()) return;

‎src/main/java/sc/fiji/snt/DelineationsManager.java‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,14 @@ label images, or neuropil annotations (e.g., cortical layers, biomarkers, or cou
122122
""";
123123
gbc.weighty = 0.1;
124124
container.add(GuiUtils.longSmallMsg(msg, container), gbc);
125-
gbc.weighty = 0;
125+
gbc.weighty = 0.5;
126126
final JScrollPane sp = new JScrollPane(delineationsPanel);
127127
sp.setMinimumSize(delineationsPanel.getPreferredSize());
128128
sp.setBorder(null);
129129
gbc.gridy++;
130130
container.add(sp, gbc);
131131
gbc.gridy++;
132+
gbc.weighty = 0.1;
132133
container.add(outsideColorAndAddMoreEntriesWidget(), gbc);
133134
gbc.insets = new Insets(5, 0, 5, 0);
134135
gbc.gridy++;
@@ -238,7 +239,7 @@ private JToolBar outsideColorAndAddMoreEntriesWidget() {
238239
delineationsPanel.repaint();
239240
});
240241

241-
final JLabel label = new JLabel(" Outside color:");
242+
final JLabel label = new JLabel("Non-delineating color:");
242243
label.setToolTipText("Fallback color for non-delineated sections");
243244
toolbar.add(label);
244245
final JButton fColorButton = new JButton(IconFactory.accentIcon(fallbackColor, true));

‎src/main/java/sc/fiji/snt/SNTUI.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import ij3d.ContentConstants;
3535
import ij3d.Image3DUniverse;
3636
import ij3d.ImageWindow3D;
37-
import net.imglib2.RandomAccessibleInterval;
3837
import org.apache.commons.lang3.StringUtils;
3938
import org.scijava.command.Command;
4039
import org.scijava.command.CommandModule;
@@ -2094,7 +2093,9 @@ private JPanel legacy3DViewerPanel() throws java.lang.NoClassDefFoundError {
20942093
final JButton applyUnivChoice = new JButton("Apply");
20952094
final JComboBox<String> displayChoice = new JComboBox<>();
20962095
final JButton applyDisplayChoice = new JButton("Apply");
2097-
final JButton refreshList = GuiUtils.Buttons.sync(null);
2096+
final JButton refreshList = GuiUtils.Buttons.sync(false);
2097+
refreshList.setToolTipText("Refresh list");
2098+
refreshList.setPreferredSize(new Dimension(refreshList.getPreferredSize().width, applyUnivChoice.getPreferredSize().height));
20982099
final JComboBox<String> actionChoice = new JComboBox<>();
20992100
final JButton applyActionChoice = new JButton("Apply");
21002101

@@ -4161,9 +4162,8 @@ private JPanel statusBar() {
41614162
toolbar.addSeparator();
41624163

41634164
// Quick Toggles dropdown
4164-
final JButton quickToggles = new JButton(IconFactory.menuIcon('\ue0b7', true, IconFactory.defaultColor()));
4165+
final JButton quickToggles = GuiUtils.Buttons.OptionsButton(GLYPH.BOLT, 1f,quickTogglesMenu() );
41654166
quickToggles.setToolTipText("Quick Toggles for common actions");
4166-
quickToggles.addActionListener(e -> quickTogglesMenu().show(quickToggles, 0, quickToggles.getHeight()));
41674167
toolbar.add(quickToggles);
41684168

41694169
// Status text (full width, below toolbar)

‎src/main/java/sc/fiji/snt/gui/GuiUtils.java‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4492,9 +4492,12 @@ public static JButton undo(final Action action) {
44924492
return button;
44934493
}
44944494

4495-
public static JButton sync(final Action action) {
4496-
final JButton button = (action == null) ? new JButton() : new JButton(action);
4497-
makeSmallBorderless(button, GLYPH.SYNC, UIManager.getColor("Spinner.buttonArrowColor"));
4495+
public static JButton sync(final boolean borderless) {
4496+
final JButton button = new JButton();
4497+
if (borderless)
4498+
makeSmallBorderless(button, GLYPH.SYNC, UIManager.getColor("Spinner.buttonArrowColor"));
4499+
else
4500+
IconFactory.assignIcon(button, GLYPH.SYNC, UIManager.getColor("Spinner.buttonArrowColor"), .8f);
44984501
return button;
44994502
}
45004503

‎src/main/java/sc/fiji/snt/gui/IconFactory.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public enum GLYPH {
5656
BEZIER_CURVE('\uf55b', true),//
5757
BINOCULARS('\uf1e5', true), //
5858
BOLD('\uf032', true),//
59+
BOLT('\ue0b7', true),//
5960
BOOKMARK('\uf02e', true), //
6061
BOOK_READER('\uf5da', true), //
6162
BRAIN('\uf5dc', true), //

‎src/main/java/sc/fiji/snt/viewer/AbstractBigViewer.java‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,39 @@ public Dimension getMinimumSize() {
117117
};
118118
}
119119

120+
void resizeCardPanelsAsNeeded(final JComponent refPanel) {
121+
// Ensure the card panel is wide enough to show all controls without clipping.
122+
// Use the Scene Controls panel's own preferred width since it's the widest,
123+
// and its GridBagLayout has already computed the correct natural width.
124+
final int cardPrefW = refPanel.getMinimumSize().width + 16; // minor padding
125+
SwingUtilities.invokeLater(() -> {
126+
final javax.swing.JSplitPane split = getViewerSplitPanel();
127+
if (split == null) return;
128+
final java.awt.Component cards = split.getRightComponent();
129+
if (cards == null) return;
130+
cards.setPreferredSize(new java.awt.Dimension(cardPrefW, cards.getPreferredSize().height));
131+
final JFrame frame = getViewerFrame();
132+
final int frameW = frame != null ? frame.getWidth() : 0;
133+
if (frameW > cardPrefW)
134+
split.setDividerLocation(frameW - cardPrefW - split.getDividerSize());
135+
if (frame != null) frame.revalidate();
136+
});
137+
}
138+
120139
/**
121-
* Returns the top-level Swing window for this viewer.
122-
* May be null if the viewer has not been opened yet.
140+
* Returns the top-level Swing window for this viewer, or null if not yet open.
123141
*/
124142
public abstract JFrame getViewerFrame();
125143

144+
/**
145+
* Returns the JSplitPane that separates the viewer canvas from the card panel.
146+
* Both BDV and BVV frames expose this via their own getSplitPanel() methods,
147+
* but those classes share no common supertype above JFrame, so this method
148+
* lets subclasses expose the split pane without the abstract method returning
149+
* a viewer-specific frame type.
150+
*/
151+
protected abstract javax.swing.JSplitPane getViewerSplitPanel();
152+
126153
/**
127154
* Returns the width of the viewer canvas in logical pixels,
128155
* or 0 if the viewer is not yet initialized.
@@ -515,7 +542,6 @@ protected void showCalibrationDialog(final java.awt.Component parent) {
515542
/**
516543
* Builds the shared scene-control toolbar: fit-source button, align-plane
517544
* buttons (XY, XZ, YZ), minimap toggle, text-overlay toggle, scale-bar toggle.
518-
*
519545
* Subclasses call this and may prepend or append viewer-specific buttons.
520546
*
521547
* @return a partially populated JToolBar ready for additional buttons

‎src/main/java/sc/fiji/snt/viewer/Bdv.java‎

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package sc.fiji.snt.viewer;
2424

2525
import bdv.tools.InitializeViewerState;
26+
import bdv.viewer.ViewerFrame;
2627
import mpicbg.spim.data.generic.AbstractSpimData;
2728
import net.imglib2.type.numeric.NumericType;
2829
import sc.fiji.snt.*;
@@ -147,11 +148,8 @@ public BdvStackSource<?> show(final ImagePlus imp) {
147148
final BdvOptions chOpts = (firstSrc == null)
148149
? baseOpts()
149150
: BdvOptions.options().addTo(bdvHandle);
150-
// BDV requires 3D sources; add singleton Z for 2D images
151-
RandomAccessibleInterval<?> chRai = ImpUtils.toImgPlus(ch);
152-
if (chRai.numDimensions() < 3) chRai = Views.addDimension(chRai, 0, 0);
153151
final BdvStackSource<?> cs = showCalibratedBdvSource(
154-
chRai, imp.getTitle() + " [C" + c + "]", chOpts);
152+
ImpUtils.toImgPlus(ch), imp.getTitle() + " [C" + c + "]", chOpts);
155153
if (firstSrc == null) {
156154
firstSrc = cs;
157155
if (bdvHandle == null) {
@@ -214,9 +212,7 @@ public <T extends RealType<T> & NativeType<T>> BdvStackSource<?> show(final ImgP
214212
BdvStackSource<?> firstSrc = null;
215213
final int nC = (int) img.dimension(chDim);
216214
for (int c = 0; c < nC; c++) {
217-
// BDV requires 3D sources; add singleton Z for 2D images
218-
RandomAccessibleInterval<T> ch = Views.hyperSlice(img, chDim, c);
219-
if (ch.numDimensions() < 3) ch = Views.addDimension(ch, 0, 0);
215+
final RandomAccessibleInterval<T> ch = Views.hyperSlice(img, chDim, c);
220216
final BdvOptions chOpts = (firstSrc == null)
221217
? baseOpts().sourceTransform(calToTransform())
222218
: BdvOptions.options().addTo(bdvHandle).sourceTransform(calToTransform());
@@ -324,9 +320,15 @@ public List<BdvStackSource<?>> show(final AbstractSpimData<?> spimData, final St
324320
}
325321

326322
@Override
327-
public JFrame getViewerFrame() {
328-
return (bdvHandle == null) ? null
329-
: bdvHandle.getSplitPanel().getTopLevelAncestor() instanceof JFrame f ? f : null;
323+
public ViewerFrame getViewerFrame() {
324+
if (bdvHandle == null) return null;
325+
final java.awt.Container top = bdvHandle.getSplitPanel().getTopLevelAncestor();
326+
return (top instanceof ViewerFrame f) ? f : null;
327+
}
328+
329+
@Override
330+
protected JSplitPane getViewerSplitPanel() {
331+
return (bdvHandle == null) ? null : bdvHandle.getSplitPanel();
330332
}
331333

332334
@Override
@@ -561,9 +563,12 @@ private BdvStackSource<?> showCalibratedBdvSource(
561563
final RandomAccessibleInterval<?> rai,
562564
final String name,
563565
final BdvOptions opts) {
566+
// BDV's renderer always calls realMax(2); add a singleton Z for 2D inputs
567+
final RandomAccessibleInterval<?> rai3d = (rai.numDimensions() < 3)
568+
? Views.addDimension(rai, 0, 0) : rai;
564569
final SpimDataUtils.CalibratedSource src =
565570
new SpimDataUtils.CalibratedSource(
566-
rai, (NumericType) rai.getType(), calToTransform(), name,
571+
rai3d, (NumericType) rai3d.getType(), calToTransform(), name,
567572
cal != null ? cal : new double[]{1, 1, 1},
568573
calUnit != null ? calUnit : "pixel");
569574
return BdvFunctions.show(src, 1, opts);
@@ -601,11 +606,12 @@ private void initializeCardPanel() {
601606
if (cp != null) {
602607
cp.addCard("Scene Controls", buildSceneControlToolbar(), true);
603608
cp.addCard("SNT Annotations", sntAnnotationsCard(actions), true);
604-
cp.setCardExpanded("Groups", false);
605609
SwingUtilities.invokeLater(() -> {
610+
cp.setCardExpanded("Groups", false);
606611
cp.setCardExpanded("Scene Controls", true);
607612
cp.setCardExpanded("SNT Annotations", true);
608613
});
614+
resizeCardPanelsAsNeeded(cp.getComponent());
609615
}
610616

611617
// M and H keys via BDV's keybindings system so the trigger layer sees them
@@ -874,7 +880,7 @@ public void actionPerformed(final java.awt.event.ActionEvent e) {
874880
}
875881

876882
Action syncPathManagerAction() {
877-
return new AbstractAction("Sync Path Manager Changes", IconFactory.menuIcon(IconFactory.GLYPH.REDO)) {
883+
return new AbstractAction("Sync Path Manager Changes", IconFactory.menuIcon(IconFactory.GLYPH.SYNC)) {
878884
@Override
879885
public void actionPerformed(final java.awt.event.ActionEvent e) {
880886
if (syncPathManagerList()) {

‎src/main/java/sc/fiji/snt/viewer/Bvv.java‎

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,20 +1194,7 @@ public void actionPerformed(final java.awt.event.ActionEvent e) {
11941194
bvvFrame.getKeybindings().addInputMap("snt", sntIMap);
11951195
bvvFrame.getKeybindings().addActionMap("snt", sntAMap);
11961196
SwingUtilities.invokeLater(bvv::expandAndFocusCardPanel);
1197-
// Ensure the card panel is wide enough to show all controls without clipping.
1198-
// Use the Scene Controls panel's own preferred width since it's the widest,
1199-
// and its GridBagLayout has already computed the correct natural width.
1200-
final int cardPrefW = sceneControlsCard.getMinimumSize().width + 16; // minor padding
1201-
SwingUtilities.invokeLater(() -> {
1202-
final javax.swing.JSplitPane split = bvv.getViewerFrame().getSplitPanel();
1203-
final java.awt.Component cards = split.getRightComponent();
1204-
if (cards == null) return;
1205-
cards.setPreferredSize(new java.awt.Dimension(cardPrefW, cards.getPreferredSize().height));
1206-
final int frameW = bvv.getViewerFrame().getWidth();
1207-
if (frameW > cardPrefW)
1208-
split.setDividerLocation(frameW - cardPrefW - split.getDividerSize());
1209-
bvv.getViewerFrame().revalidate();
1210-
});
1197+
resizeCardPanelsAsNeeded(sceneControlsCard);
12111198
}
12121199
// Initialize brightness from data percentiles (BVV doesn't do this automatically)
12131200
SwingUtilities.invokeLater(() ->
@@ -1838,6 +1825,11 @@ public VolumeViewerFrame getViewerFrame() {
18381825
return (currentBvv == null) ? null : currentBvv.getViewerFrame();
18391826
}
18401827

1828+
@Override
1829+
protected JSplitPane getViewerSplitPanel() {
1830+
return (currentBvv==null) ? null : currentBvv.getViewerFrame().getSplitPanel();
1831+
}
1832+
18411833
/**
18421834
* @return a reference to the viewer's options.
18431835
*/
@@ -4750,7 +4742,7 @@ public void actionPerformed(final java.awt.event.ActionEvent e) {
47504742
}
47514743

47524744
Action syncPathManagerAction() {
4753-
return new AbstractAction("Sync Path Manager Changes", IconFactory.menuIcon(IconFactory.GLYPH.REDO)) {
4745+
return new AbstractAction("Sync Path Manager Changes", IconFactory.menuIcon(IconFactory.GLYPH.SYNC)) {
47544746
@Override
47554747
public void actionPerformed(final java.awt.event.ActionEvent e) {
47564748
if (pathOverlay != null && syncPathManagerList()) {

0 commit comments

Comments
 (0)