Skip to content

Commit 5ab5c64

Browse files
committed
Fix gremlin characters, hidden icons, and title case inconsistencies
1 parent 02890c9 commit 5ab5c64

7 files changed

Lines changed: 107 additions & 51 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3833,7 +3833,7 @@ public PathAndFillManager transformPaths(final PathTransformer transformation,
38333833
}
38343834

38353835
/**
3836-
* Downsamples alls path using Ramer–Douglas–Peucker simplification.
3836+
* Downsamples alls path using Ramer-Douglas-Peucker simplification.
38373837
* Downsampling occurs only between branch points and terminal points.
38383838
*
38393839
* @param maximumPermittedDistance the maximum permitted distance between

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ private <T extends RealType<T>> void fitCircles() {
527527

528528
if (Math.abs(scale_a - scale_b) / scale_iso > 0.1) {
529529
SNTUtils.log(String.format(
530-
" Node %d: Anisotropic tangent plane (%.3f vs %.3f µm). Using %.3f µm.",
530+
" Node %d: Anisotropic tangent plane (%.3f vs %.3f µm). Using %.3f µm.",
531531
i, scale_a, scale_b, scale_iso
532532
));
533533
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ public PathManagerUI(final SNT plugin) {
217217

218218
jmi = new JMenuItem(MultiPathActionListener.SPECIFY_CT_POSITION_CMD);
219219
jmi.setToolTipText("Changes CT position of selected path(s)");
220-
jmi.setIcon(IconFactory.menuIcon(IconFactory.GLYPH.LAYERS));
220+
IconFactory.assignDoubleLetterIcon(jmi, 'C', 'T', true);
221221
jmi.addActionListener(multiPathListener);
222222
editMenu.add(jmi);
223223
jmi = new JMenuItem(MultiPathActionListener.SPECIFY_RADIUS_CMD);

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,20 @@ private static Font loadFont(final String fontName) {
7979
}
8080

8181
@Override
82-
public void paintIcon(final Component ignored, final Graphics g, final int x, final int y) {
82+
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
8383
final Graphics2D graphics = (Graphics2D) g;
8484
GuiUtils.setRenderingHints(graphics);
8585
final Font previousFont = graphics.getFont();
86+
final Paint previousPaint = graphics.getPaint();
8687
graphics.setFont(font);
87-
graphics.setPaint(color);
88+
// Graphics2D#setPaint(null) is a documented no-op: it would otherwise silently keep whatever Paint the caller
89+
// last set, e.g. a selection/hover background fill painted immediately before this icon
90+
// (see BasicMenuItemUI/FlatLaf), making a null-colored glyph disappear into it. Fall back to the component's
91+
// own foreground, which is the conventional meaning of a null icon color
92+
graphics.setPaint((color != null) ? color : (c != null) ? c.getForeground() : IconFactory.defaultColor());
8893
graphics.drawString(symbol, x, y + ascent);
8994
graphics.setFont(previousFont);
95+
graphics.setPaint(previousPaint);
9096
}
9197

9298
protected ImageIcon asImage() {

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

Lines changed: 83 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
* it under the terms of the GNU General Public License as
99
* published by the Free Software Foundation, either version 3 of the
1010
* License, or (at your option) any later version.
11-
*
11+
*
1212
* This program is distributed in the hope that it will be useful,
1313
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1414
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515
* GNU General Public License for more details.
16-
*
16+
*
1717
* You should have received a copy of the GNU General Public
1818
* License along with this program. If not, see
1919
* <http://www.gnu.org/licenses/gpl-3.0.html>.
@@ -377,9 +377,56 @@ public static Icon doubleIcon(final GLYPH entry1, final GLYPH entry2, final floa
377377
return dropdownIcon(entry1, scalingFactor, color, rightIcon);
378378
}
379379

380+
/**
381+
* Creates a two-letter icon (e.g., "CT"), analogous to {@link #doubleIcon(GLYPH, GLYPH, float, Color)} but
382+
* built from two plain characters rather than {@link GLYPH} entries. Useful for {@link JMenuItem} icons that
383+
* combine single-letter tags, such as the "C"(hannel)/"T"(frame) Path Manager tags.
384+
*
385+
* @param letter1 the first (left) letter, e.g., 'C'
386+
* @param letter2 the second (right) letter, e.g., 'T'
387+
* @param solid whether the letters are rendered using the solid (vs. regular) weight font
388+
* @param scalingFactor the icon's scaling factor relative to the default size
389+
* @param color the icon's color
390+
* @return the icon
391+
*/
392+
public static Icon doubleLetterIcon(final char letter1, final char letter2, final boolean solid,
393+
final float scalingFactor, final Color color) {
394+
final float size = scalingFactor * FADerivedIcon.defSize();
395+
final Icon leftIcon = cachedIcon(letter1, size, color, solid);
396+
final Icon rightIcon = cachedIcon(letter2, size, color, solid);
397+
return new DropdownIcon(leftIcon, rightIcon);
398+
}
399+
400+
/**
401+
* Convenience method for {@link #doubleLetterIcon(char, char, boolean, float, Color)} using a scaling
402+
* factor of 1f and solid font weight.
403+
*
404+
* @param letter1 the first (left) letter, e.g., 'C'
405+
* @param letter2 the second (right) letter, e.g., 'T'
406+
* @param color the icon's color
407+
* @return the icon
408+
*/
409+
public static Icon doubleLetterIcon(final char letter1, final char letter2, final Color color) {
410+
return doubleLetterIcon(letter1, letter2, true, 1f, color);
411+
}
412+
413+
/**
414+
* Assigns a two-letter icon (see {@link #doubleLetterIcon(char, char, Color)}) to a menu item, including
415+
* its disabled state.
416+
*
417+
* @param item the menu item to be assigned an icon
418+
* @param letter1 the first (left) letter, e.g., 'C'
419+
* @param letter2 the second (right) letter, e.g., 'T'
420+
* @param solid whether the letters are rendered using the solid (vs. regular) weight font
421+
*/
422+
public static void assignDoubleLetterIcon(final JMenuItem item, final char letter1, final char letter2, final boolean solid) {
423+
item.setIcon(doubleLetterIcon(letter1, letter2, solid, .75f, defaultColor()));
424+
item.setDisabledIcon(doubleLetterIcon(letter1, letter2, solid, .75f, disabledColor()));
425+
}
426+
380427
/**
381428
* Overlays a small notification dot on an icon's upper right corner within the icon's own bounds
382-
* (the icon's reported size is unchanged).
429+
* (the icon's reported size is unchanged).
383430
*
384431
* @param icon the source icon
385432
* @param dotColor the dot's fill color
@@ -425,39 +472,37 @@ public static Icon dropdownMenuIcon(final GLYPH entry, final float scalingFactor
425472
}
426473

427474
private static Icon dropdownIcon(final GLYPH entry, final float scalingFactor, final Color color, final Icon rightIcon) {
428-
class DropdownIcon implements Icon {
475+
return new DropdownIcon(entry, scalingFactor, rightIcon, color);
476+
}
429477

430-
static final int ICON_GAP = 2;
431-
final Icon leftIcon;
432-
final Icon rightIcon;
478+
private record DropdownIcon(Icon leftIcon, Icon rightIcon) implements Icon {
433479

434-
DropdownIcon(final GLYPH entry, final float scalingFactor, final Icon rightIcon) {
435-
leftIcon = cachedIcon(entry.id, scalingFactor * FADerivedIcon.defSize(), color, entry.solid);
436-
this.rightIcon = rightIcon;
437-
}
480+
static final int ICON_GAP = 2;
438481

439-
@Override
440-
public void paintIcon(final Component c, final Graphics g, int x, int y) {
441-
final Graphics2D g2 = (Graphics2D) g;
442-
GuiUtils.setRenderingHints(g2);
443-
final int mid = getIconHeight() / 2;
444-
final int y1 = y + mid - leftIcon.getIconHeight() / 2;
445-
final int y2 = y + mid - rightIcon.getIconHeight() / 2;
446-
leftIcon.paintIcon(c, g2, x, y1);
447-
rightIcon.paintIcon(c, g2, x + leftIcon.getIconWidth() + ICON_GAP, y2);
448-
}
482+
DropdownIcon(final GLYPH entry, final float scalingFactor, final Icon rightIcon, final Color color) {
483+
this(cachedIcon(entry.id, scalingFactor * FADerivedIcon.defSize(), color, entry.solid), rightIcon);
484+
}
449485

450-
@Override
451-
public int getIconWidth() {
452-
return leftIcon.getIconWidth() + rightIcon.getIconWidth() + ICON_GAP;
453-
}
486+
@Override
487+
public void paintIcon(final Component c, final Graphics g, int x, int y) {
488+
final Graphics2D g2 = (Graphics2D) g;
489+
GuiUtils.setRenderingHints(g2);
490+
final int mid = getIconHeight() / 2;
491+
final int y1 = y + mid - leftIcon.getIconHeight() / 2;
492+
final int y2 = y + mid - rightIcon.getIconHeight() / 2;
493+
leftIcon.paintIcon(c, g2, x, y1);
494+
rightIcon.paintIcon(c, g2, x + leftIcon.getIconWidth() + ICON_GAP, y2);
495+
}
454496

455-
@Override
456-
public int getIconHeight() {
457-
return Math.max(leftIcon.getIconHeight(), rightIcon.getIconHeight());
458-
}
497+
@Override
498+
public int getIconWidth() {
499+
return leftIcon.getIconWidth() + rightIcon.getIconWidth() + ICON_GAP;
500+
}
501+
502+
@Override
503+
public int getIconHeight() {
504+
return Math.max(leftIcon.getIconHeight(), rightIcon.getIconHeight());
459505
}
460-
return new DropdownIcon(entry, scalingFactor, rightIcon);
461506
}
462507

463508
// Returns an icon whose pixels are the average of src's pixels and tint, achieved by overlaying tint at 50%
@@ -551,9 +596,13 @@ public static void assignDoubleIcon(final JMenuItem menuItem, final GLYPH defaul
551596
menuItem.setDisabledIcon(disabledIcon);
552597
return;
553598
}
554-
final Icon rawSelectedIcon = doubleIcon(selectedIcon, secondaryIcon, .9f, selectedColor());
555-
final Icon rawDisabledSelectedIcon = doubleIcon(selectedIcon, secondaryIcon, .9f,
556-
SNTColor.average(List.of(disabledColor(), selectedColor())));
599+
// NB: FlatLaf swaps to getSelectedIcon() whenever the item is armed (highlighted by the cursor), not only when
600+
// a JCheckBoxMenuItem is actually checked, and paints it right after filling the hover highlight.
601+
// selectedColor() is a background swatch (List.selectionBackground); using it here would color the glyph the
602+
// same as that highlight, making it disappear on hover. Keep the same foreground colors as the default/disabled
603+
// icons so the swapped glyph stays legible while armed
604+
final Icon rawSelectedIcon = doubleIcon(selectedIcon, secondaryIcon, .9f, defaultColor());
605+
final Icon rawDisabledSelectedIcon = doubleIcon(selectedIcon, secondaryIcon, .9f, disabledColor());
557606
// defaultIcon/selectedIcon glyphs (e.g., EYE vs EYE_SLASH) rarely share the same font-metrics
558607
final int refWidth = Math.max(icon.getIconWidth(), rawSelectedIcon.getIconWidth());
559608
final Icon fixedIcon = fixedWidthIcon(icon, refWidth);
@@ -577,7 +626,7 @@ public static void assignDoubleIcon(final JMenuItem menuItem, final GLYPH defaul
577626
*
578627
* @param button the button to decorate
579628
* @param dotColor the dot's fill color (e.g., Color.RED)
580-
* @see #notificationIcon(Icon, Color, Color)
629+
* @see #notificationIcon(Icon, Color, Color)
581630
*/
582631
public static void assignNotification(final AbstractButton button, final Color dotColor) {
583632
final Color bkgColor = button.getBackground();

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
package sc.fiji.snt.gui;
2424

25+
import org.apache.commons.lang.WordUtils;
2526
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
2627
import org.scijava.command.CommandModule;
2728
import org.scijava.command.CommandService;
@@ -97,20 +98,20 @@ private JMenu getImageFilterMenu() {
9798
final JMenu imgFilteringMenu = new JMenu("Select by Image Property");
9899
imgFilteringMenu.setIcon(IconFactory.menuIcon(
99100
IconFactory.GLYPH.IMAGE));
100-
JMenuItem mi1 = new JMenuItem("Traced channel...");
101-
mi1.addActionListener(e -> doImageFiltering("Traced channel"));
101+
JMenuItem mi1 = new JMenuItem("Traced Channel...");
102+
mi1.addActionListener(e -> doImageFiltering("traced channel"));
102103
mi1.setIcon(IconFactory.menuIcon('C', false));
103104
imgFilteringMenu.add(mi1);
104-
mi1 = new JMenuItem("Traced frame...");
105-
mi1.addActionListener(e -> doImageFiltering("Traced frame"));
105+
mi1 = new JMenuItem("Traced Frame...");
106+
mi1.addActionListener(e -> doImageFiltering("traced frame"));
106107
mi1.setIcon(IconFactory.menuIcon('T', false));
107108
imgFilteringMenu.add(mi1);
108-
mi1 = new JMenuItem("Z-slice of first node...");
109-
mi1.addActionListener(e -> doImageFiltering("Z-slice of first node"));
109+
mi1 = new JMenuItem("Z-slice Of First Node...");
110+
mi1.addActionListener(e -> doImageFiltering("z-slice of first node"));
110111
mi1.setIcon(IconFactory.menuIcon('Z', false));
111112
imgFilteringMenu.add(mi1);
112-
mi1 = new JMenuItem("Z-slice of last node...");
113-
mi1.addActionListener(e -> doImageFiltering("Z-slice of last node"));
113+
mi1 = new JMenuItem("Z-slice Of Last Node...");
114+
mi1.addActionListener(e -> doImageFiltering("z-slice of last node"));
114115
mi1.setIcon(IconFactory.menuIcon('Z', true));
115116
imgFilteringMenu.add(mi1);
116117
return imgFilteringMenu;
@@ -182,7 +183,7 @@ private JMenuItem angleFilterMenuItem() {
182183
}
183184

184185
private JMenuItem morphoFilterMenuItem(final String pathAnalyzerMetric, final String unit) {
185-
final JMenuItem mi = new JMenuItem(pathAnalyzerMetric + "...");
186+
final JMenuItem mi = new JMenuItem(WordUtils.capitalizeFully(pathAnalyzerMetric, new char[]{'/', ' '}) + "...");
186187
mi.addActionListener(e -> doMorphoFiltering(pathAnalyzerMetric, unit));
187188
switch (pathAnalyzerMetric) {
188189
case PathStatistics.N_CHILDREN:

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ private CategoryChart getSingleTreeChart(final StrahlerData sd) throws IllegalAr
206206
series.setValues(sd.analyzer.getAvgFragmentations());
207207
series.setStyle(plotService.newSeriesStyle(colors[4], LineStyle.SOLID, MarkerStyle.CIRCLE));
208208
series = chart.addLineSeries();
209-
series.setLabel("Avg. ext. angle (°)");
209+
series.setLabel("Avg. ext. angle (°)");
210210
series.setValues(sd.analyzer.getAvgExtensionAngles(false));
211211
series.setStyle(plotService.newSeriesStyle(colors[5], LineStyle.SOLID, MarkerStyle.CIRCLE));
212212
series = chart.addLineSeries();
213-
series.setLabel("Avg. ext.angle (Rel.) (°)");
213+
series.setLabel("Avg. ext.angle (Rel.) (°)");
214214
series.setValues(sd.analyzer.getAvgExtensionAngles(true));
215215
series.setStyle(plotService.newSeriesStyle(colors[6], LineStyle.SOLID, MarkerStyle.CIRCLE));
216216
return chart;
@@ -493,7 +493,7 @@ else if (metric.contains("frag"))
493493
else if (metric.contains("contract"))
494494
return "Avg. contraction";
495495
else if (metric.contains("extension") || metric.contains("angle"))
496-
return "Avg. relative extension angle (°)";
496+
return "Avg. relative extension angle (°)";
497497
else
498498
throw new IllegalArgumentException("Unrecognized metric");
499499
}

0 commit comments

Comments
 (0)