diff --git a/src/org/openstreetmap/josm/gui/preferences/SourceEditor.java b/src/org/openstreetmap/josm/gui/preferences/SourceEditor.java
index 9c83d9c1f3..e8d05084ad 100644
|
a
|
b
|
public abstract class SourceEditor extends JPanel {
|
| 1336 | 1336 | sourceEntry.active ? SOURCE_ENTRY_ACTIVE_BACKGROUND_COLOR.get() : SOURCE_ENTRY_INACTIVE_BACKGROUND_COLOR.get()); |
| 1337 | 1337 | } |
| 1338 | 1338 | final ImageSizes size = ImageSizes.TABLE; |
| 1339 | | setIcon(value.icon == null ? ImageProvider.getEmpty(size) : value.icon.getImageIconBounded(size.getImageDimension())); |
| | 1339 | setIcon(value.icon == null ? ImageProvider.getEmpty(size) : value.icon.getPaddedIcon(size.getImageDimension())); |
| 1340 | 1340 | } |
| 1341 | 1341 | return this; |
| 1342 | 1342 | } |
diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java b/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java
index fac625b775..651f30e17c 100644
|
a
|
b
|
public class TaggingPreset extends AbstractAction implements ActiveLayerChangeLi
|
| 290 | 290 | .thenAcceptAsync(result -> { |
| 291 | 291 | if (result != null) { |
| 292 | 292 | // Pre-render off EDT to avoid flooding the event queue with expensive SVG rendering |
| 293 | | ImageIcon small = result.getImageIcon(ImageProvider.ImageSizes.SMALLICON.getImageDimension()); |
| 294 | | ImageIcon large = result.getImageIcon(ImageProvider.ImageSizes.LARGEICON.getImageDimension()); |
| | 293 | ImageIcon small = result.getPaddedIcon(ImageProvider.ImageSizes.SMALLICON.getImageDimension()); |
| | 294 | ImageIcon large = result.getPaddedIcon(ImageProvider.ImageSizes.LARGEICON.getImageDimension()); |
| 295 | 295 | GuiHelper.runInEDT(() -> { |
| 296 | 296 | try { |
| 297 | 297 | putValue(Action.SMALL_ICON, small); |
diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItem.java b/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItem.java
index 737e2fd449..cc03e36299 100644
|
a
|
b
|
package org.openstreetmap.josm.gui.tagging.presets;
|
| 4 | 4 | import static org.openstreetmap.josm.tools.I18n.tr; |
| 5 | 5 | import static org.openstreetmap.josm.tools.I18n.trc; |
| 6 | 6 | |
| | 7 | import java.awt.Dimension; |
| 7 | 8 | import java.io.File; |
| 8 | 9 | import java.util.Arrays; |
| 9 | 10 | import java.util.Collection; |
| … |
… |
import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
|
| 28 | 29 | import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager; |
| 29 | 30 | import org.openstreetmap.josm.gui.util.LruCache; |
| 30 | 31 | import org.openstreetmap.josm.tools.ImageProvider; |
| | 32 | import org.openstreetmap.josm.tools.ImageProvider.ImageSizes; |
| | 33 | import org.openstreetmap.josm.tools.ImageResource; |
| 31 | 34 | import org.openstreetmap.josm.tools.Logging; |
| 32 | 35 | import org.openstreetmap.josm.tools.Utils; |
| 33 | 36 | import org.xml.sax.SAXException; |
| … |
… |
public abstract class TaggingPresetItem {
|
| 150 | 153 | * Loads a tagging preset icon |
| 151 | 154 | * @param iconName the icon name |
| 152 | 155 | * @param zipIcons zip file where the image is located |
| 153 | | * @param maxSize maximum image size (or null) |
| 154 | | * @return the requested image or null if the request failed |
| | 156 | * @param maxSize maximum image size (or null for the default small icon size) |
| | 157 | * @return the requested image, centered in a square of {@code maxSize}, or null if the request failed |
| 155 | 158 | */ |
| 156 | 159 | public static ImageIcon loadImageIcon(String iconName, File zipIcons, Integer maxSize) { |
| 157 | 160 | final Collection<String> s = TaggingPresets.ICON_SOURCES.get(); |
| 158 | | ImageProvider imgProv = new ImageProvider(iconName).setDirs(s).setId("presets").setArchive(zipIcons).setOptional(true); |
| 159 | | if (maxSize != null && maxSize > 0) { |
| 160 | | imgProv.setMaxSize(maxSize); |
| 161 | | } |
| 162 | | return imgProv.get(); |
| | 161 | final int size = maxSize != null && maxSize > 0 ? maxSize : ImageSizes.SMALLICON.getVirtualWidth(); |
| | 162 | ImageResource resource = new ImageProvider(iconName).setDirs(s).setId("presets").setArchive(zipIcons).setOptional(true) |
| | 163 | .getResource(); |
| | 164 | return resource == null ? null : resource.getPaddedIcon(new Dimension(size, size)); |
| 163 | 165 | } |
| 164 | 166 | |
| 165 | 167 | /** |
diff --git a/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java b/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java
index 541fb26114..5d43e2f7cc 100644
|
a
|
b
|
import static org.openstreetmap.josm.tools.I18n.tr;
|
| 5 | 5 | |
| 6 | 6 | import java.awt.Component; |
| 7 | 7 | import java.awt.Font; |
| | 8 | import java.awt.image.BufferedImage; |
| 8 | 9 | import java.lang.reflect.Method; |
| 9 | 10 | import java.lang.reflect.Modifier; |
| 10 | 11 | import java.util.ArrayList; |
| … |
… |
import java.util.Collection;
|
| 13 | 14 | import java.util.Collections; |
| 14 | 15 | import java.util.List; |
| 15 | 16 | import java.util.Map; |
| | 17 | import java.util.Objects; |
| 16 | 18 | import java.util.TreeMap; |
| 17 | 19 | import java.util.stream.Collectors; |
| 18 | 20 | |
| | 21 | import javax.swing.Icon; |
| | 22 | import javax.swing.ImageIcon; |
| 19 | 23 | import javax.swing.JLabel; |
| 20 | 24 | import javax.swing.JList; |
| 21 | 25 | import javax.swing.JPanel; |
| … |
… |
public abstract class ComboMultiSelect extends KeyedItem {
|
| 142 | 146 | if (value.getCount() > 0) { |
| 143 | 147 | l.setFont(l.getFont().deriveFont(Font.ITALIC + Font.BOLD)); |
| 144 | 148 | } |
| 145 | | l.setIcon(value.getIcon()); |
| | 149 | Icon icon = value.getIcon(); |
| | 150 | if (icon == null && value.cms != null) { |
| | 151 | // use a blank icon if other entries have one, so that all texts line up |
| | 152 | icon = value.cms.presetListEntries.stream().map(PresetListEntry::getIcon).filter(Objects::nonNull).findFirst() |
| | 153 | .map(i -> new ImageIcon(new BufferedImage(i.getIconWidth(), i.getIconHeight(), BufferedImage.TYPE_INT_ARGB))) |
| | 154 | .orElse(null); |
| | 155 | } |
| | 156 | l.setIcon(icon); |
| 146 | 157 | l.setToolTipText(value.getToolTipText(key)); |
| 147 | 158 | return l; |
| 148 | 159 | } |
diff --git a/src/org/openstreetmap/josm/tools/ImageResizeMode.java b/src/org/openstreetmap/josm/tools/ImageResizeMode.java
index 638c70f157..58036e555d 100644
|
a
|
b
|
enum ImageResizeMode {
|
| 94 | 94 | prepareGraphics(icon, bufferedImage, g); |
| 95 | 95 | renderer.accept(g); |
| 96 | 96 | } else if (sourceIcon != null) { |
| 97 | | sourceIcon = sourceIcon.getScaledInstance(real.width, real.height, Image.SCALE_SMOOTH); |
| 98 | | g.drawImage(sourceIcon, 0, 0, null); |
| | 97 | final Dimension scaled = this == PADDED ? AUTO.computeDimension(real, icon) : real; |
| | 98 | sourceIcon = sourceIcon.getScaledInstance(scaled.width, scaled.height, Image.SCALE_SMOOTH); |
| | 99 | g.drawImage(sourceIcon, (real.width - scaled.width) / 2, (real.height - scaled.height) / 2, null); |
| 99 | 100 | } else { |
| 100 | 101 | throw new IllegalArgumentException("renderer or sourceIcon"); |
| 101 | 102 | } |
diff --git a/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ComboTest.java b/test/unit/org/openstreetmap/josm/gui/tagging/presets/items/ComboTest.java
index 408adc4605..c0084ad860 100644
|
a
|
b
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
| 6 | 6 | |
| 7 | 7 | import java.awt.Color; |
| 8 | 8 | |
| | 9 | import javax.swing.JLabel; |
| | 10 | import javax.swing.JList; |
| 9 | 11 | import javax.swing.JPanel; |
| 10 | 12 | |
| 11 | 13 | import org.junit.jupiter.api.Test; |
| … |
… |
import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItemTest;
|
| 16 | 18 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences; |
| 17 | 19 | import org.openstreetmap.josm.testutils.annotations.I18n; |
| 18 | 20 | import org.openstreetmap.josm.testutils.annotations.Main; |
| | 21 | import org.openstreetmap.josm.tools.ImageProvider.ImageSizes; |
| 19 | 22 | |
| 20 | 23 | /** |
| 21 | 24 | * Unit tests of {@link Combo} class. |
| … |
… |
class ComboTest implements TaggingPresetItemTest {
|
| 123 | 126 | KeyedItem.LAST_VALUES.clear(); |
| 124 | 127 | } |
| 125 | 128 | |
| | 129 | /** |
| | 130 | * Entry icons are centered in a square and entries without an icon get a blank one, so that the texts line up. |
| | 131 | */ |
| | 132 | @Test |
| | 133 | void testIconAlignment() { |
| | 134 | final Combo combo = getInstance(); |
| | 135 | combo.key = "highway"; |
| | 136 | PresetListEntry trunk = new PresetListEntry("trunk", combo); |
| | 137 | trunk.icon = "presets/transport/way/way_trunk.svg"; |
| | 138 | combo.addListEntry(trunk); |
| | 139 | combo.addListEntry(new PresetListEntry("busway", combo)); |
| | 140 | combo.addToPanel(new JPanel(), TaggingPresetItemGuiSupport.create(false)); |
| | 141 | JList<PresetListEntry> list = new JList<>(); |
| | 142 | for (PresetListEntry entry : combo.presetListEntries) { |
| | 143 | JLabel label = (JLabel) combo.combobox.getRenderer().getListCellRendererComponent(list, entry, 0, false, false); |
| | 144 | assertEquals(ImageSizes.SMALLICON.getAdjustedWidth(), label.getIcon().getIconWidth(), entry.value); |
| | 145 | assertEquals(ImageSizes.SMALLICON.getAdjustedHeight(), label.getIcon().getIconHeight(), entry.value); |
| | 146 | } |
| | 147 | } |
| | 148 | |
| 126 | 149 | @Test |
| 127 | 150 | void testColor() { |
| 128 | 151 | final Combo combo = getInstance(); |
diff --git a/test/unit/org/openstreetmap/josm/tools/ImageResizeModeTest.java b/test/unit/org/openstreetmap/josm/tools/ImageResizeModeTest.java
index d67c040339..eb049e2938 100644
|
a
|
b
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
| 6 | 6 | import static org.junit.jupiter.api.Assertions.assertThrows; |
| 7 | 7 | |
| 8 | 8 | import java.awt.Dimension; |
| | 9 | import java.awt.image.BufferedImage; |
| 9 | 10 | |
| 10 | 11 | import org.junit.jupiter.api.Test; |
| 11 | 12 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences; |
| … |
… |
class ImageResizeModeTest {
|
| 67 | 68 | assertEquals(new Dimension(24, 32), ImageResizeMode.PADDED.computeDimension(new Dimension(24, 32), image)); |
| 68 | 69 | } |
| 69 | 70 | |
| | 71 | /** |
| | 72 | * Test method for {@link ImageResizeMode#createBufferedImage} using {@link ImageResizeMode#PADDED} on a raster image |
| | 73 | */ |
| | 74 | @Test |
| | 75 | void testCreateBufferedImagePaddedRaster() { |
| | 76 | BufferedImage source = new BufferedImage(16, 4, BufferedImage.TYPE_INT_RGB); // opaque black |
| | 77 | BufferedImage padded = ImageResizeMode.PADDED.createBufferedImage(new Dimension(32, 32), new Dimension(16, 4), null, source); |
| | 78 | assertEquals(32, padded.getWidth()); |
| | 79 | assertEquals(32, padded.getHeight()); |
| | 80 | // aspect ratio is kept: a 32x8 bar centered vertically |
| | 81 | assertEquals(0, padded.getRGB(16, 11) >>> 24); |
| | 82 | assertEquals(0xff, padded.getRGB(16, 12) >>> 24); |
| | 83 | assertEquals(0xff, padded.getRGB(16, 19) >>> 24); |
| | 84 | assertEquals(0, padded.getRGB(16, 20) >>> 24); |
| | 85 | } |
| | 86 | |
| 70 | 87 | /** |
| 71 | 88 | * Test method for {@link ImageResizeMode#cacheKey} |
| 72 | 89 | */ |