Skip to content

Commit e5c8c03

Browse files
committed
Fix UX inconsistencies
1 parent 7457521 commit e5c8c03

6 files changed

Lines changed: 44 additions & 36 deletions

File tree

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

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@ private void updateCmdsOneSelected(final Path p) {
888888
? "<html>Path has never been fitted:<br>Fit will be computed for the first time"
889889
: "<html>Path has already been fitted:\nCached properties will be applied");
890890
}
891-
colorMenu.selectSWCColor(new SNTColor(p.getColor(), p.getSWCType()));
891+
colorMenu.selectSWCColor(new SNTColor(p.getColor()));
892892
selectSWCTypeMenuEntry(p.getSWCType());
893893
}
894894

@@ -1714,11 +1714,11 @@ private static class NodeRender extends DefaultTreeCellRenderer {
17141714
final int arc = UIManager.getInt("Component.arc");
17151715
CHIP_ARC = (arc > 0) ? Math.min(arc, 8) : 4;
17161716
final Color fg = UIManager.getColor("Tree.textForeground"); // Tree.foreground is unused. See formdev.com/flatlaf/components/tree/
1717-
final Color base = (fg != null) ? fg : Color.GRAY;
1717+
final Color base = (fg != null) ? fg : Color.DARK_GRAY;
17181718
final int r = base.getRed(), gn = base.getGreen(), b = base.getBlue();
17191719
CHIP_BORDER = new Color(r, gn, b, 50);
17201720
CHIP_TEXT = base;
1721-
CHIP_FILL = new Color(r, gn, b, 10);
1721+
CHIP_FILL = new Color(r, gn, b, 8);
17221722
}
17231723

17241724
// Per-cell state populated in getTreeCellRendererComponent
@@ -2858,6 +2858,7 @@ public void actionPerformed(final ActionEvent e) {
28582858
final List<Path> selectedPaths = getSelectedPaths(true);
28592859
if (selectedPaths.isEmpty()) {
28602860
guiUtils.error("There are no traced paths.");
2861+
setSelected(false);
28612862
return;
28622863
}
28632864
removeOrReapplyDefaultTag(selectedPaths, getActionCommand(), isSelected(), true);
@@ -3921,7 +3922,7 @@ public void execute(List<Path> selectedPaths, String cmd) {
39213922
if (tags.isEmpty() && existingTags.isEmpty()) {
39223923
return;
39233924
} else if (tags.isEmpty()) {
3924-
deleteCustomTags(selectedPaths);
3925+
deleteCustomTags(selectedPaths, false);
39253926
return;
39263927
}
39273928

@@ -5183,7 +5184,7 @@ private void removeTagsThroughPrompt(final List<Path> selectedPaths) {
51835184
return;
51845185
}
51855186
if (choices[1].equals(choice)) {
5186-
deleteCustomTags(selectedPaths); // will call refreshManager
5187+
deleteCustomTags(selectedPaths, true); // will call refreshManager
51875188
return;
51885189
}
51895190
if (choices[2].equals(choice)) {
@@ -5214,8 +5215,8 @@ private void replaceTags(final List<Path> selectedPaths) {
52145215
guiUtils.centeredMsg(counter + " occurrence(s) replaced.", "Operation Completed");
52155216
}
52165217

5217-
private void deleteCustomTags(final List<Path> paths) {
5218-
if (!plugin.getUI().askUserConfirmation || guiUtils.getConfirmation("Remove custom tags from "
5218+
private void deleteCustomTags(final List<Path> paths, final boolean deleteWithoutConfirmation) {
5219+
if (deleteWithoutConfirmation || !plugin.getUI().askUserConfirmation || guiUtils.getConfirmation("Remove custom tags from "
52195220
+ ((paths.size() == pathAndFillManager.size()) ? "all " : "the selected ")
52205221
+ paths.size() + " paths?", "Confirm Tag Removal?")) {
52215222
paths.forEach(p -> p.setName(TAG_CUSTOM_PATTERN.matcher(p.getName()).replaceAll("")));
@@ -5726,7 +5727,7 @@ void sortArbors() {
57265727
}
57275728
final String[] choices = { "Arbor ID", "Cell label", "Primary path name", "Primary path length",
57285729
"Primary path mean radius", "Traced channel", "Traced frame" };
5729-
final String choice = guiUtils.getChoice("Sorting criterion:", "Sort Root-level Paths", choices, choices[0]);
5730+
final String choice = guiUtils.getChoice("Sort by:", "Sort Root-level Paths", choices, choices[0]);
57305731
if (choice == null)
57315732
return;
57325733
switch (choice) {
@@ -6061,19 +6062,27 @@ void addExtras() {
60616062
private void showColorCustomizationDialog() {
60626063
// Create the panel with color chooser buttons
60636064
final JPanel panel = new JPanel(new GridBagLayout());
6065+
panel.setBackground(ProofReadingTagsToolBar.this.getBackground());
60646066
final GridBagConstraints c = GuiUtils.defaultGbc();
6067+
// Align the component to the left edge of its cell
6068+
c.anchor = GridBagConstraints.WEST;
6069+
// Prevent the component from stretching horizontally
6070+
c.fill = GridBagConstraints.NONE;
60656071
// Create color selection components for each tag
60666072
c.insets = new Insets(0, 0, 5, 0);
60676073
final Map<String, ColorChooserButton> colorButtons = new HashMap<>();
60686074
tagsMap.forEach( (tagName, color) -> {
6069-
final ColorChooserButton colorButton = new ColorChooserButton(color, capitalized(tagName));
6075+
final ColorChooserButton colorButton = new ColorChooserButton(color, capitalized(tagName)
6076+
, 1f, ColorChooserButton.RIGHT);
6077+
GuiUtils.Buttons.makeBorderless(colorButton);
60706078
panel.add(colorButton, c);
60716079
colorButtons.put(tagName, colorButton);
60726080
c.gridy++;
60736081
});
60746082
// Add reset button
60756083
c.insets.top += 10;
6076-
final JButton resetButton = new JButton("Reset to Defaults");
6084+
final JButton resetButton = new JButton("Reset to Defaults", IconFactory.buttonIcon(IconFactory.GLYPH.UNDO, .9f));
6085+
GuiUtils.Buttons.makeBorderless(resetButton);
60776086
resetButton.addActionListener(e -> {
60786087
tagsMap.keySet().forEach( tagName -> saveTagColor(tagName, null));
60796088
tagsMap.clear();
@@ -6084,7 +6093,7 @@ private void showColorCustomizationDialog() {
60846093

60856094
// Show the option pane
60866095
final int result = JOptionPane.showConfirmDialog(PathManagerUI.this,
6087-
panel, "Proofreading Tag Colors", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
6096+
panel, "Proofreading Tags", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
60886097

60896098
// save the new colors if user pressed OK
60906099
if (result == JOptionPane.OK_OPTION) {
@@ -6190,13 +6199,12 @@ void summarizeTags() {
61906199
else
61916200
dataset.put("none", dataset.get("none")+1);
61926201
});
6193-
final SNTChart chart = AnalysisUtils.ringPlot(String.format("Tags (All %d Paths)", paths.size()), dataset, colors);
6202+
final SNTChart chart = AnalysisUtils.ringPlot(String.format("Proofreading Tags (All %d Paths)", paths.size()), dataset, colors);
61946203
if (ringChart != null && ringChart.isVisible()) {
61956204
ringChart.replace(chart);
6196-
ringChart.getFrame().setTitle(String.format("Tags (All %d Paths)", paths.size()));
61976205
ringChart.show();
61986206
} else {
6199-
chart.getFrame().setLocationRelativeTo(ProofReadingTagsToolBar.this);
6207+
chart.getFrame().setLocationRelativeTo(PathManagerUI.this);
62006208
chart.show();
62016209
ringChart = chart;
62026210
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class PathManagerUISearchableBar extends SNTSearchableBar {
6161
* @param pmui the PathManagerUI instance
6262
*/
6363
public PathManagerUISearchableBar(final PathManagerUI pmui) {
64-
super(pmui.getSearchable(), "Text filtering");
64+
super(pmui.getSearchable(), "Type to select");
6565
this.pmui = pmui;
6666
guiUtils = new GuiUtils(pmui);
6767
setGuiUtils(guiUtils);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public class SNTSearchableBar extends SearchableBar {
6464
protected boolean subFilteringEnabled;
6565

6666
public SNTSearchableBar(final Searchable searchable) {
67-
this(searchable, "Search");
67+
this(searchable, "Type to select");
6868
}
6969

7070
public SNTSearchableBar(final Searchable searchable, final String placeholder) {

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.formdev.flatlaf.icons.FlatSearchIcon;
2727
import com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon;
2828
import com.formdev.flatlaf.ui.FlatRoundBorder;
29+
import sc.fiji.snt.util.SNTColor;
2930

3031
import javax.swing.*;
3132
import java.awt.*;
@@ -154,12 +155,7 @@ public void enlarge(final float enlargeFactor) {
154155
public static Color iconColor() {
155156
if (iconColor == null) {
156157
iconColor = UIManager.getColor("SearchField.searchIconColor");
157-
if (iconColor == null) {
158-
iconColor = Color.DARK_GRAY;
159-
} else {
160-
// somehow transparency is not being set(!?), so we'll get it here
161-
iconColor = new Color(iconColor.getRed(), iconColor.getGreen(), iconColor.getBlue(), iconColor.getAlpha());
162-
}
158+
if (iconColor == null) iconColor = IconFactory.defaultColor();
163159
}
164160
return iconColor;
165161
}

‎src/main/java/sc/fiji/snt/plugin/BinaryTracerCommonCmd.java‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -381,17 +381,17 @@ protected void runCommand() {
381381
return;
382382
}
383383

384-
// Retrieve ROI. If not found, look for it in the image overlay or on second image
385-
final Roi roi = getRoi(chosenMaskImp, chosenOrigImp, (snt != null) ? snt.getImagePlus() : null);
386-
387384
// Aggregate unexpected settings for validation
388385
final boolean isSame = !isFileMode() && (maskImgChoice != null && maskImgChoice.equals(originalImgChoice));
389386
final boolean isSegmented = isSegmented(chosenMaskImp);
390387
final boolean isCompatible = chosenOrigImp == null || ImpUtils.sameCalibration(chosenMaskImp, chosenOrigImp);
391388
final boolean isSameDim = chosenOrigImp == null || ImpUtils.sameXYZDimensions(chosenOrigImp, chosenMaskImp);
392389
final boolean isValidConnectDist = maxConnectDist > 0d;
393-
final boolean isValidRoi = roi != null && roi.isArea();
394390
final boolean autoDetectSoma = ROI_AUTO_DETECT.equals(rootChoice);
391+
392+
// Retrieve ROI. If not found, look for it in the image overlay or on second image
393+
final Roi roi = (autoDetectSoma) ? null : getRoi(chosenMaskImp, chosenOrigImp, (snt != null) ? snt.getImagePlus() : null);
394+
final boolean isValidRoi = roi != null && roi.isArea();
395395
boolean inferRootFromRoi = !ROI_UNSET.equals(rootChoice) && !autoDetectSoma;
396396

397397
if (isSame || !isValidOrigImg || !isSegmented || !isSameDim || !isCompatible || (!isValidRoi && inferRootFromRoi)
@@ -409,7 +409,7 @@ protected void runCommand() {
409409
SNTUtils.log("Segmented image: " + chosenMaskImp.getTitle());
410410
SNTUtils.log("Segmented image thresholded/binarized: " + isSegmented);
411411
SNTUtils.log("Original image: " + ((chosenOrigImp == null) ? null : chosenOrigImp.getTitle()));
412-
SNTUtils.log("Root-defining strategy: " + rootChoice);
412+
SNTUtils.log("ROI strategy: " + rootChoice);
413413
SNTUtils.log("ROI: " + roi);
414414

415415
// Skeletonize all images again, just to ensure we are indeed dealing with skeletons
@@ -427,10 +427,14 @@ protected void runCommand() {
427427
final SomaUtils.SomaResult somaResult = SomaUtils.detectSoma(
428428
ImpUtils.toImgPlus(chosenMaskImp), -1d, -1);
429429
if (somaResult != null && somaResult.hasContour()) {
430-
final Roi somaRoi = somaResult.createContourRoi();
431-
if (somaRoi != null && somaResult.zSlice() >= 0) somaRoi.setPosition(somaResult.zSlice() + 1);
432-
converter.setRootRoi(somaRoi, BinaryTracer.ROI_CENTROID);
433430
SNTUtils.log("Auto-detected soma: " + somaResult);
431+
final Roi somaRoi = somaResult.createContourRoi();
432+
if (somaRoi != null && somaResult.zSlice() >= 0) {
433+
somaRoi.setPosition(somaResult.zSlice() + 1);
434+
converter.setRootRoi(somaRoi, BinaryTracer.ROI_CENTROID);
435+
chosenMaskImp.setRoi(somaRoi);
436+
}
437+
SNTUtils.log("Auto-detected soma ROI: " + somaRoi);
434438
} else {
435439
SNTUtils.log("Soma auto-detection did not find a soma. Using arbitrary root.");
436440
}
@@ -447,7 +451,6 @@ protected void runCommand() {
447451
converter.getPruneMode() == BinaryTracer.LOWEST_INTENSITY_VOXEL))
448452
SNTUtils.log("Intensity-based pruning failed (unsupported image type!?): Defaulting to fallback strategy");
449453
converter.setPruneMode(BinaryTracer.PERIPHERAL_SEGMENTS);
450-
451454
try {
452455
trees = converter.getTrees();
453456
} catch (final IllegalStateException ex) {
@@ -456,6 +459,10 @@ protected void runCommand() {
456459
SNTUtils.error("", ex);
457460
return;
458461
}
462+
} catch (final IllegalArgumentException iae) {
463+
error(iae.getMessage() +".");
464+
SNTUtils.error("", iae);
465+
return;
459466
}
460467
if (trees == null) {
461468
error("No paths could be extracted. No structures found in image!?");

‎src/main/java/sc/fiji/snt/plugin/PathMatcherCmd.java‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,9 @@ public void run() {
278278
"You can now run 'Grow Analysis...' on the dataset.", paths.size(), groupCounter,
279279
timePointsParsed), "Matching Completed");
280280
}
281-
if (ui != null) {
282-
ui.getPathManager().update();
283-
resetUI();
284-
}
281+
if (ui != null) ui.getPathManager().update();
285282
}
286-
283+
resetUI();
287284
}
288285

289286
/* null: consider all time-points; empty set: assume invalid input */

0 commit comments

Comments
 (0)