Skip to content

Commit dd92c71

Browse files
committed
Fix instance detection by BigDataLoader and minor fixes to Stream mode
1 parent 14cbd9d commit dd92c71

3 files changed

Lines changed: 55 additions & 22 deletions

File tree

‎src/main/java/sc/fiji/snt/gui/cmds/BigDataLoaderCmd.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ public void run() {
235235
final boolean threeD = viewerType != null && viewerType.toLowerCase().contains("bvv");
236236
final boolean tracer = tracingEnabled;
237237

238-
if (tracer && SNTUtils.getInstance() != null) {
238+
if (tracer && SNTUtils.getInstance() != null && SNTUtils.getInstance().getUI() != null) {
239239
error("SNT seems to be already running. Please close the current instance and re-run.");
240240
return;
241241
}

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,29 @@ public Dimension getMinimumSize() {
242242
};
243243
}
244244

245+
/** Recursively finds the widest preferred width among any JToolBar descendants of {@code c} */
246+
private static int widestToolbarPreferredWidth(final Container c) {
247+
int widest = 0;
248+
for (final Component comp : c.getComponents()) {
249+
if (comp instanceof JToolBar) {
250+
widest = Math.max(widest, comp.getPreferredSize().width);
251+
} else if (comp instanceof Container) {
252+
widest = Math.max(widest, widestToolbarPreferredWidth((Container) comp));
253+
}
254+
}
255+
return widest;
256+
}
257+
245258
void resizeCardPanelsAsNeeded(final JComponent refPanel) {
246259
// Ensure the card panel is wide enough to show all controls without clipping.
247260
// Use the Scene Controls panel's own preferred width since it's the widest,
248261
// and its GridBagLayout has already computed the correct natural width.
249-
final int cardPrefW = refPanel.getMinimumSize().width + 16; // minor padding
262+
// Toolbars built by createToolbar() report a zeroed minimum width by design (see its
263+
// javadoc), so GridBagLayout's minimum-size pass never sees their real button-row width.
264+
// Recover it from each toolbar's preferred width instead (glue there contributes zero)
265+
// and widen cardPrefW to fit the widest one too
266+
final int cardPrefW = Math.max(refPanel.getMinimumSize().width,
267+
widestToolbarPreferredWidth(refPanel)) + 16; // extra padding avoids clipping at frame edge
250268
SwingUtilities.invokeLater(() -> {
251269
final javax.swing.JSplitPane split = getViewerSplitPanel();
252270
if (split == null) return;
@@ -1095,7 +1113,7 @@ protected JButton autoBrightnessButton(final Actions actions) {
10951113
menu.add(new JMenuItem(actions.autoBrightnessAllAction()));
10961114
final JButton button = GuiUtils.Buttons.OptionsButton(IconFactory.GLYPH.ADJUST, 1f, menu);
10971115
button.setToolTipText("<html>Recompute brightness/contrast from data percentiles.<br>Useful to retry "
1098-
+ "after loading large/remote datasets, where the automatic estimate is bounded by a timeout "
1116+
+ "after loading large/remote datasets,<br>where the automatic estimate is bounded by a timeout<br>"
10991117
+ "and may fall back to a default range.</html>");
11001118
return button;
11011119
}
@@ -1651,6 +1669,8 @@ protected JToolBar buildBaseSceneControlToolbar() {
16511669
"Fit view to the current (selected) source"));
16521670
bar.add(autoBrightnessButton(actions));
16531671
bar.addSeparator();
1672+
bar.add(Box.createHorizontalGlue());
1673+
bar.addSeparator();
16541674
// Action names match those registered by BDV/BVV NavigationActions
16551675
final java.util.HashMap<String, List<IconFactory.GLYPH>> planes = new java.util.LinkedHashMap<>();
16561676
planes.put("align XY plane", List.of(IconFactory.GLYPH.X, IconFactory.GLYPH.Y));

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

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3176,6 +3176,9 @@ public void actionPerformed(final java.awt.event.ActionEvent e) {
31763176
// Guards posSlider.setValue() calls that are programmatic (not from the user
31773177
// dragging the slider), so slabListener does not fire a second applySlab().
31783178
final boolean[] updatingSlab = {false};
3179+
// Slab Paths defaults to following Slab View (activated whenever Slab View is turned
3180+
// on) until the user manually toggles Slab Paths themselves, at which point it decouples
3181+
final boolean[] slabPathsUserOverride = {false};
31793182

31803183
final VolumeViewerPanel viewerPanel = bvvInstance.currentBvv.getViewer();
31813184

@@ -3421,8 +3424,12 @@ public void mousePressed(final java.awt.event.MouseEvent e) {
34213424
slabAxis.set(axis0);
34223425
reconfigureAndApplySlab.run();
34233426
slabPathsToggle.setEnabled(true);
3424-
// Slab Paths' *selected* state is a persistent user preference (left alone on deactivation),
3425-
// but renderingOptions.isClipPathsToSlab() is the actual effective flag and was forced false
3427+
// Slab Paths defaults to activating alongside Slab View (synced) unless the user has
3428+
// manually toggled Slab Paths before (decoupled)
3429+
if (!slabPathsUserOverride[0]) {
3430+
slabPathsToggle.setSelected(true);
3431+
}
3432+
// renderingOptions.isClipPathsToSlab() is the actual effective flag and was forced false
34263433
// on deactivation since it's meaningless while there's no active slab. Re-sync it here to
34273434
// whatever the toggle currently shows, or re-activating slab would silently render all paths
34283435
// (front and back) despite Slab Paths still looking selected
@@ -3467,6 +3474,7 @@ public void mousePressed(final java.awt.event.MouseEvent e) {
34673474
thickSpinner.addChangeListener(slabListener);
34683475

34693476
slabPathsToggle.addActionListener(ev -> {
3477+
slabPathsUserOverride[0] = true; // user acted on it directly: decouple from Slab View's default
34703478
final boolean clip = slabPathsToggle.isSelected();
34713479
renderingOptions.setClipPathsToSlab(clip);
34723480
overlayRenderer.invalidateCache();
@@ -3507,29 +3515,34 @@ private JToolBar buildSceneControlToolbar(final BvvActions bvvActions) {
35073515
IconFactory.GLYPH.CROSSHAIR, IconFactory.GLYPH.CROSSHAIR);
35083516
crosshairToggle.setSelected(true);
35093517
bar.add(crosshairToggle);
3510-
final JToggleButton axesToggle = GuiUtils.Buttons.toolbarToggleButton(
3511-
BvvActions.overlayToggleAction("Axes", false, show -> {
3512-
if (sceneOverlay != null) { sceneOverlay.showAxes = show; bvvInstance.repaint(); }
3513-
}),
3514-
"Show/hide coordinate axes at the volume origin.\nX: Red; Y: Green; Z: Blue",
3515-
IconFactory.GLYPH.CHART_LINE, IconFactory.GLYPH.CHART_LINE);
3516-
axesToggle.setSelected(false);
3517-
bar.add(axesToggle);
3518-
final JToggleButton boxToggle = GuiUtils.Buttons.toolbarToggleButton(
3519-
BvvActions.overlayToggleAction("Volume Box", false, show -> {
3520-
if (sceneOverlay != null) { sceneOverlay.showBox = show; bvvInstance.repaint(); }
3521-
}),
3522-
"Show/hide bounding box around all loaded volumes",
3523-
IconFactory.GLYPH.CUBE, IconFactory.GLYPH.CUBE);
3524-
boxToggle.setSelected(false);
3525-
bar.add(boxToggle);
3518+
bar.add(axesButton());
35263519
bar.addSeparator();
35273520
bar.add(Box.createHorizontalGlue());
35283521
bar.addSeparator();
35293522
bar.add(optionsButton(bvvActions));
35303523
return bar;
35313524
}
35323525

3526+
private JButton axesButton() {
3527+
final JPopupMenu menu = new JPopupMenu();
3528+
final JButton button = GuiUtils.Buttons.OptionsButton(IconFactory.GLYPH.CUBE, 1f, menu);
3529+
final JCheckBoxMenuItem axesItem = new JCheckBoxMenuItem(
3530+
BvvActions.overlayToggleAction("Axes", false, show -> {
3531+
if (sceneOverlay != null) { sceneOverlay.showAxes = show; bvvInstance.repaint(); }
3532+
}));
3533+
axesItem.setToolTipText("Show/hide coordinate axes at the volume origin. X: Red; Y: Green; Z: Blue");
3534+
axesItem.setSelected(false);
3535+
menu.add(axesItem);
3536+
final JCheckBoxMenuItem boxItem = new JCheckBoxMenuItem(
3537+
BvvActions.overlayToggleAction("Volume Box", false, show -> {
3538+
if (sceneOverlay != null) { sceneOverlay.showBox = show; bvvInstance.repaint(); }
3539+
}));
3540+
boxItem.setToolTipText("Show/hide bounding box around all loaded volumes");
3541+
boxItem.setSelected(false);
3542+
menu.add(boxItem);
3543+
return button;
3544+
}
3545+
35333546
private JButton optionsButton(final BvvActions actions) {
35343547
final JPopupMenu menu = new JPopupMenu();
35353548
final JButton oButton = GuiUtils.Buttons.OptionsButton(IconFactory.GLYPH.OPTIONS, 1f, menu);
@@ -3796,7 +3809,7 @@ public void drawOverlays(final java.awt.Graphics g) {
37963809
final double x0 = b[0], y0 = b[1], z0 = b[2], x1 = b[3], y1 = b[4], z1 = b[5];
37973810

37983811
if (showAxes) {
3799-
g2.setStroke(new java.awt.BasicStroke(3f));
3812+
g2.setStroke(new java.awt.BasicStroke(4f));
38003813
final float axisLen = 0.20f * (float) Math.min(x1 - x0, Math.min(y1 - y0, z1 - z0));
38013814
drawLine3D(g2, project, new double[]{x0, y0, z0}, new double[]{x0 + axisLen, y0, z0}, new java.awt.Color(220, 60, 60));
38023815
drawLine3D(g2, project, new double[]{x0, y0, z0}, new double[]{x0, y0 + axisLen, z0}, new java.awt.Color(60, 200, 60));

0 commit comments

Comments
 (0)