diff --git a/platform/core-api/src/com/intellij/ui/LayeredIcon.java b/platform/core-api/src/com/intellij/ui/LayeredIcon.java index 3d83c52893b6..cebd0f799dbe 100644 --- a/platform/core-api/src/com/intellij/ui/LayeredIcon.java +++ b/platform/core-api/src/com/intellij/ui/LayeredIcon.java @@ -17,6 +17,7 @@ package com.intellij.ui; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.ScalableIcon; +import com.intellij.util.ArrayUtil; import com.intellij.util.ui.JBUI; import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.NotNull; @@ -53,6 +54,46 @@ public class LayeredIcon extends JBUI.AuxScalableJBIcon { } } + protected LayeredIcon(LayeredIcon icon) { + super(icon); + myIcons = ArrayUtil.copyOf(icon.myIcons); + myScaledIcons = null; + myDisabledLayers = ArrayUtil.copyOf(icon.myDisabledLayers); + myHShifts = ArrayUtil.copyOf(icon.myHShifts); + myVShifts = ArrayUtil.copyOf(icon.myVShifts); + myXShift = icon.myXShift; + myYShift = icon.myYShift; + myWidth = icon.myWidth; + myHeight = icon.myHeight; + } + + @Override + protected LayeredIcon copy() { + return new LayeredIcon(this); + } + + private Icon[] myScaledIcons() { + if (myScaledIcons != null) { + return myScaledIcons; + } + if (getScale() == 1f) { + return myScaledIcons = myIcons; + } + for (Icon icon : myIcons) { + if (icon != null && !(icon instanceof ScalableIcon)) { + setScale(1f); + return myScaledIcons = myIcons; + } + } + myScaledIcons = new Icon[myIcons.length]; + for (int i = 0; i < myIcons.length; i++) { + if (myIcons[i] != null) { + myScaledIcons[i] = ((ScalableIcon)myIcons[i]).scale(getScale()); + } + } + return myScaledIcons; + } + @Override public LayeredIcon withJBUIPreScaled(boolean preScaled) { super.withJBUIPreScaled(preScaled); @@ -105,6 +146,7 @@ public class LayeredIcon extends JBUI.AuxScalableJBIcon { ((LayeredIcon)icon).checkIHaventIconInsideMe(this); } myIcons[layer] = icon; + myScaledIcons = null; myHShifts[layer] = scaleVal(hShift, Scale.JBUI); myVShifts[layer] = scaleVal(vShift, Scale.JBUI); updateSize(); @@ -179,33 +221,16 @@ public class LayeredIcon extends JBUI.AuxScalableJBIcon { @Override public void paintIcon(Component c, Graphics g, int x, int y) { if (updateJBUIScale()) updateSize(); - for (int i = 0; i < myIcons.length; i++) { - Icon icon = getOrScale(i); + int i = 0; + for (Icon icon : myScaledIcons()) { if (icon == null || myDisabledLayers[i]) continue; int xOffset = x + scaleVal(myXShift + myHShifts[i], Scale.ARBITRARY); int yOffset = y + scaleVal(myYShift + myVShifts[i], Scale.ARBITRARY); icon.paintIcon(c, g, xOffset, yOffset); + i++; } } - private Icon getOrScale(int i) { - if (getScale() == 1f) { - return myIcons[i]; - } - if (myScaledIcons == null) { - myScaledIcons = new Icon[myIcons.length]; - } - - Icon icon = myScaledIcons[i]; - if (icon == null && myIcons[i] != null) { - icon = myIcons[i]; - if (icon instanceof ScalableIcon) { - icon = myScaledIcons[i] = ((ScalableIcon)icon).scale(getScale()); - } - } - return icon; - } - public boolean isLayerEnabled(int layer) { return !myDisabledLayers[layer]; } @@ -268,13 +293,4 @@ public class LayeredIcon extends JBUI.AuxScalableJBIcon { public String toString() { return "Layered icon. myIcons=" + Arrays.asList(myIcons); } - - @Override - public Icon scale(float scale) { - if (scale == getScale()) return this; - - setScale(scale); - if (myScaledIcons != null) Arrays.fill(myScaledIcons, null); - return this; - } } diff --git a/platform/core-api/src/com/intellij/ui/RowIcon.java b/platform/core-api/src/com/intellij/ui/RowIcon.java index b853f2348d85..701aa254a9df 100644 --- a/platform/core-api/src/com/intellij/ui/RowIcon.java +++ b/platform/core-api/src/com/intellij/ui/RowIcon.java @@ -17,6 +17,7 @@ package com.intellij.ui; import com.intellij.openapi.util.ScalableIcon; +import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; @@ -54,34 +55,40 @@ public class RowIcon extends JBUI.AuxScalableJBIcon { updateSize(); } - - @Override - public Icon scale(float scale) { - if (scale == getScale()) return this; - - setScale(scale); - rescale(); - return this; + protected RowIcon(RowIcon icon) { + super(icon); + myAlignment = icon.myAlignment; + myWidth = icon.myWidth; + myHeight = icon.myHeight; + myIcons = ArrayUtil.copyOf(icon.myIcons); + myScaledIcons = null; } - private void rescale() { - if (getScale() == 1f) { - myScaledIcons = null; - return; - } + @Override + protected RowIcon copy() { + return new RowIcon(this); + } + private Icon[] myScaledIcons() { + if (myScaledIcons != null) { + return myScaledIcons; + } + if (getScale() == 1f) { + return myScaledIcons = myIcons; + } for (Icon icon : myIcons) { if (icon != null && !(icon instanceof ScalableIcon)) { - return; + setScale(1f); + return myScaledIcons = myIcons; } } - myScaledIcons = new Icon[myIcons.length]; for (int i = 0; i < myIcons.length; i++) { - ScalableIcon icon = (ScalableIcon)myIcons[i]; - myScaledIcons[i] = icon == null ? null : icon.scale(getScale()); + if (myIcons[i] != null) { + myScaledIcons[i] = ((ScalableIcon)myIcons[i]).scale(getScale()); + } } - updateSize(); + return myScaledIcons; } @TestOnly @@ -105,7 +112,7 @@ public class RowIcon extends JBUI.AuxScalableJBIcon { public void setIcon(Icon icon, int layer) { myIcons[layer] = icon; - rescale(); + myScaledIcons = null; updateSize(); } @@ -113,17 +120,12 @@ public class RowIcon extends JBUI.AuxScalableJBIcon { return myIcons[index]; } - public Icon[] getIcons() { - Icon[] icons = getScale() == 1f ? myIcons : myScaledIcons; - return icons == null ? myIcons : icons; - } - @Override public void paintIcon(Component c, Graphics g, int x, int y) { if (updateJBUIScale()) updateSize(); int _x = x; int _y = y; - for (Icon icon : getIcons()) { + for (Icon icon : myScaledIcons()) { if (icon == null) continue; switch (myAlignment) { case TOP: _y = y; @@ -154,7 +156,7 @@ public class RowIcon extends JBUI.AuxScalableJBIcon { private void updateSize() { int width = 0; int height = 0; - for (Icon icon : getIcons()) { + for (Icon icon : myIcons) { if (icon == null) continue; width += icon.getIconWidth(); //height += icon.getIconHeight(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java index 94ed27ed428e..68f32ec40cdb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/DefaultLookupItemRenderer.java @@ -22,6 +22,8 @@ import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.SizedIcon; import com.intellij.util.PlatformIcons; import com.intellij.util.ui.EmptyIcon; +import com.intellij.util.ui.JBUI.ScalableJBIcon; +import com.intellij.util.ui.JBUI.ScalableJBIcon.Scale; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -45,9 +47,11 @@ public class DefaultLookupItemRenderer extends LookupElementRenderer @Nullable public static Icon getRawIcon(final LookupElement item, boolean real) { - final Icon icon = _getRawIcon(item, real); - if (icon != null && icon.getIconHeight() > SAMPLE_ICON.getIconHeight()) { - return new SizedIcon(icon, icon.getIconWidth(), SAMPLE_ICON.getIconHeight()); + Icon icon = _getRawIcon(item, real); + // align SAMPLE_ICON.getIconHeight() with the 'icon' scale + int sampleIconHeight = ScalableJBIcon.scaleVal(icon, SAMPLE_ICON.getIconHeight(), Scale.ARBITRARY); + if (icon != null && icon.getIconHeight() > sampleIconHeight) { + return new SizedIcon(icon, icon.getIconWidth(), sampleIconHeight, true); } return icon; } diff --git a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java index c9e3555fc69b..e2a9b741118e 100644 --- a/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/DeferredIconImpl.java @@ -46,12 +46,13 @@ import java.util.LinkedHashSet; import java.util.Set; import java.util.concurrent.Executor; -public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, ScalableIcon { +public class DeferredIconImpl extends JBUI.CachingScalableJBIcon implements DeferredIcon, RetrievableIcon { private static final Logger LOG = Logger.getInstance("#com.intellij.ui.DeferredIconImpl"); private static final int MIN_AUTO_UPDATE_MILLIS = 950; private static final RepaintScheduler ourRepaintScheduler = new RepaintScheduler(); @NotNull private volatile Icon myDelegateIcon; + private volatile Icon myScaledDelegateIcon; private Function myEvaluator; private volatile boolean myIsScheduled; private T myParam; @@ -61,20 +62,39 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala private final boolean myAutoUpdatable; private long myLastCalcTime; private long myLastTimeSpent; - private float myScale = 1f; - private Icon myOriginalDeferredIcon = null; private static final Executor ourIconsCalculatingExecutor = AppExecutorUtil.createBoundedApplicationPoolExecutor("ourIconsCalculating pool",1); private final IconListener myEvalListener; private static final TransferToEDTQueue ourLaterInvocator = TransferToEDTQueue.createRunnableMerger("Deferred icon later invocator", 200); + protected DeferredIconImpl(DeferredIconImpl icon) { + super(icon); + myDelegateIcon = icon.myDelegateIcon; + myScaledDelegateIcon = icon.myDelegateIcon; + myEvaluator = icon.myEvaluator; + myIsScheduled = icon.myIsScheduled; + myParam = (T)icon.myParam; + myNeedReadAction = icon.myNeedReadAction; + myDone = icon.myDone; + myAutoUpdatable = icon.myAutoUpdatable; + myLastCalcTime = icon.myLastCalcTime; + myLastTimeSpent = icon.myLastTimeSpent; + myEvalListener = icon.myEvalListener; + } + @Override - public Icon scale(final float scaleFactor) { - if (scaleFactor != myScale && myDelegateIcon instanceof ScalableIcon) { - myDelegateIcon = ((ScalableIcon)myDelegateIcon).scale(myScale = scaleFactor); + protected DeferredIconImpl copy() { + return new DeferredIconImpl(this); + } + + @Override + public void setScale(float scale) { + if (getScale() != scale && myDelegateIcon instanceof ScalableIcon) { + myScaledDelegateIcon = ((ScalableIcon)myDelegateIcon).scale(scale); + super.setScale(scale); + return; } - return this; } private static class Holder { @@ -92,6 +112,7 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala private DeferredIconImpl(Icon baseIcon, T param, boolean needReadAction, @NotNull Function evaluator, @Nullable IconListener listener, boolean autoUpdatable) { myParam = param; myDelegateIcon = nonNull(baseIcon); + myScaledDelegateIcon = myDelegateIcon; myEvaluator = evaluator; myNeedReadAction = needReadAction; myEvalListener = listener; @@ -102,9 +123,9 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala private void checkDelegationDepth() { int depth = 0; DeferredIconImpl each = this; - while (each.myDelegateIcon instanceof DeferredIconImpl && depth < 50) { + while (each.myScaledDelegateIcon instanceof DeferredIconImpl && depth < 50) { depth++; - each = (DeferredIconImpl)each.myDelegateIcon; + each = (DeferredIconImpl)each.myScaledDelegateIcon; } if (depth >= 50) { LOG.error("Too deep deferred icon nesting"); @@ -118,8 +139,8 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala @Override public void paintIcon(final Component c, @NotNull final Graphics g, final int x, final int y) { - if (!(myDelegateIcon instanceof DeferredIconImpl && ((DeferredIconImpl)myDelegateIcon).myDelegateIcon instanceof DeferredIconImpl)) { - myDelegateIcon.paintIcon(c, g, x, y); //SOE protection + if (!(myScaledDelegateIcon instanceof DeferredIconImpl && ((DeferredIconImpl)myScaledDelegateIcon).myScaledDelegateIcon instanceof DeferredIconImpl)) { + myScaledDelegateIcon.paintIcon(c, g, x, y); //SOE protection } if (isDone() || myIsScheduled || PowerSaveMode.isEnabled()) { @@ -131,7 +152,7 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala final Component paintingParent = SwingUtilities.getAncestorOfClass(PaintingParent.class, c); final Rectangle paintingParentRec = paintingParent == null ? null : ((PaintingParent)paintingParent).getChildRec(c); ourIconsCalculatingExecutor.execute(() -> { - int oldWidth = myDelegateIcon.getIconWidth(); + int oldWidth = myScaledDelegateIcon.getIconWidth(); final Icon[] evaluated = new Icon[1]; final long startTime = System.currentTimeMillis(); @@ -156,11 +177,11 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala } } final Icon result = evaluated[0]; - myDelegateIcon = result; + myScaledDelegateIcon = result; checkDelegationDepth(); final boolean shouldRevalidate = - Registry.is("ide.tree.deferred.icon.invalidates.cache") && myDelegateIcon.getIconWidth() != oldWidth; + Registry.is("ide.tree.deferred.icon.invalidates.cache") && myScaledDelegateIcon.getIconWidth() != oldWidth; ourLaterInvocator.offer(() -> { setDone(result); @@ -243,7 +264,7 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala @Nullable @Override public Icon retrieveIcon() { - return isDone() ? myDelegateIcon : evaluate(); + return isDone() ? myScaledDelegateIcon : evaluate(); } @NotNull @@ -261,8 +282,8 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala checkDoesntReferenceThis(result); } - if (myScale != 1f && result instanceof ScalableIcon) { - result = ((ScalableIcon)result).scale(myScale); + if (getScale() != 1f && result instanceof ScalableIcon) { + result = ((ScalableIcon)result).scale(getScale()); } return result; } @@ -273,7 +294,7 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala } if (icon instanceof DeferredIconImpl) { - checkDoesntReferenceThis(((DeferredIconImpl)icon).myDelegateIcon); + checkDoesntReferenceThis(((DeferredIconImpl)icon).myScaledDelegateIcon); } else if (icon instanceof LayeredIcon) { for (Icon layer : ((LayeredIcon)icon).getAllLayers()) { @@ -291,12 +312,12 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala @Override public int getIconWidth() { - return myDelegateIcon.getIconWidth(); + return myScaledDelegateIcon.getIconWidth(); } @Override public int getIconHeight() { - return myDelegateIcon.getIconHeight(); + return myScaledDelegateIcon.getIconHeight(); } public boolean isDone() { @@ -367,11 +388,11 @@ public class DeferredIconImpl implements DeferredIcon, RetrievableIcon, Scala private boolean isDeferredAndEqual(Icon icon) { return icon instanceof DeferredIconImpl && Comparing.equal(myParam, ((DeferredIconImpl)icon).myParam) && - equalIcons(myDelegateIcon, ((DeferredIconImpl)icon).myDelegateIcon); + equalIcons(myScaledDelegateIcon, ((DeferredIconImpl)icon).myScaledDelegateIcon); } @Override public String toString() { - return "Deferred. Base=" + myDelegateIcon; + return "Deferred. Base=" + myScaledDelegateIcon; } } diff --git a/platform/platform-api/src/com/intellij/ui/SizedIcon.java b/platform/platform-api/src/com/intellij/ui/SizedIcon.java index 69907f6e6933..d2d718f74a63 100644 --- a/platform/platform-api/src/com/intellij/ui/SizedIcon.java +++ b/platform/platform-api/src/com/intellij/ui/SizedIcon.java @@ -24,27 +24,69 @@ import java.awt.*; /** * @author peter */ -public class SizedIcon extends JBUI.ScalableJBIcon { +public class SizedIcon extends JBUI.CachingScalableJBIcon { private final int myWidth; private final int myHeight; private final Icon myDelegate; private Icon myScaledDelegate; public SizedIcon(Icon delegate, int width, int height) { + this(delegate, width, height, false); + } + + /** + * @param delegate the delegate icon + * @param width this icon width + * @param height this icon height + * @param inDelegateScale whether to align this icon scale with the delegate icon scale + */ + public SizedIcon(Icon delegate, int width, int height, boolean inDelegateScale) { + float scale = 1f; + if (inDelegateScale && delegate instanceof ScalableIcon) { + setScale(scale = ((ScalableIcon)delegate).getScale()); + } myScaledDelegate = myDelegate = delegate; - myWidth = width; - myHeight = height; + myWidth = (int)(width / scale); + myHeight = (int)(height / scale); + } + + protected SizedIcon(SizedIcon icon) { + super(icon); + myWidth = icon.myWidth; + myHeight = icon.myHeight; + myDelegate = icon.myDelegate; + myScaledDelegate = null; + } + + @Override + protected SizedIcon copy() { + return new SizedIcon(this); + } + + private Icon myScaledIcon() { + if (myScaledDelegate != null) { + return myScaledDelegate; + } + if (getScale() == 1f) { + return myScaledDelegate = myDelegate; + } + if (!(myDelegate instanceof ScalableIcon)) { + setScale(1f); + return myScaledDelegate = myDelegate; + } + return myScaledDelegate = ((ScalableIcon)myDelegate).scale(getScale()); } @Override public void paintIcon(Component c, Graphics g, int x, int y) { - int dx = scaleVal(myWidth) - myScaledDelegate.getIconWidth(); - int dy = scaleVal(myHeight) - myScaledDelegate.getIconHeight(); + Icon icon = myScaledIcon(); + int dx = scaleVal(myWidth) - icon.getIconWidth(); + int dy = scaleVal(myHeight) - icon.getIconHeight(); if (dx > 0 || dy > 0) { - myScaledDelegate.paintIcon(c, g, x + dx/2, y + dy/2); + icon.paintIcon(c, g, x + dx / 2, y + dy / 2); } else { - myScaledDelegate.paintIcon(c, g, x, y); + icon.paintIcon(c, g, x, y); } } @@ -55,15 +97,4 @@ public class SizedIcon extends JBUI.ScalableJBIcon { public int getIconHeight() { return scaleVal(myHeight); } - - @Override - public Icon scale(float scale) { - if (scale == getScale()) return this; - - if (myDelegate instanceof ScalableIcon) { - setScale(scale); - myScaledDelegate = ((ScalableIcon)myDelegate).scale(scale); - } - return this; - } } diff --git a/platform/util/src/com/intellij/openapi/util/IconLoader.java b/platform/util/src/com/intellij/openapi/util/IconLoader.java index e1f1a0e9b47f..879b1de2dac5 100644 --- a/platform/util/src/com/intellij/openapi/util/IconLoader.java +++ b/platform/util/src/com/intellij/openapi/util/IconLoader.java @@ -455,6 +455,11 @@ public final class IconLoader { return myUrl.toString(); } + @Override + public float getScale() { + return 1f; + } + @Override public Icon scale(float scale) { if (scale == 1f) return this; @@ -519,7 +524,7 @@ public final class IconLoader { } } - public abstract static class LazyIcon extends JBUI.AuxScalableJBIcon { + public abstract static class LazyIcon extends JBUI.AuxJBIcon { private boolean myWasComputed; private Icon myIcon; private boolean isDarkVariant = USE_DARK_ICONS; @@ -577,18 +582,6 @@ public final class IconLoader { } return icon; } - - @Override - public Icon scale(float scale) { - if (scale == getScale()) return this; - - getOrComputeIcon(); - if (myIcon instanceof ScalableIcon) { - setScale(scale); - myIcon = ((ScalableIcon)myIcon).scale(scale); - } - return this; - } } private static class LabelHolder { diff --git a/platform/util/src/com/intellij/openapi/util/ScalableIcon.java b/platform/util/src/com/intellij/openapi/util/ScalableIcon.java index 86e1e8ce53cb..b215b6873790 100644 --- a/platform/util/src/com/intellij/openapi/util/ScalableIcon.java +++ b/platform/util/src/com/intellij/openapi/util/ScalableIcon.java @@ -23,13 +23,22 @@ import javax.swing.*; */ public interface ScalableIcon extends Icon { /** - * The method does either of the following: - * - creates/retrieves a scaled version of this icon and returns it. - * - scales this icon and returns it. - * The exact behavior is implementation dependant. + * @return the scale of the icon relative to its origin + */ + float getScale(); + + /** + * Creates and returns a scaled instance of the icon. + * The icon is scaled relative to its origin, that is {@code scale(1f)} will + * return the icon in its original scale. + * + * To scale this instance by {@code n} times: {@code scale(n * getScale())}. + * + * Note that the methods {@link #getIconWidth()} and {@link #getIconHeight()} + * should return the scaled size of the icon. * * @param scaleFactor scale - * @return scaled icon with width getIconWidth() * scaleFactor and height getIconHeight() * scaleFactor + * @return scaled icon instance */ Icon scale(float scaleFactor); } diff --git a/platform/util/src/com/intellij/util/ArrayUtil.java b/platform/util/src/com/intellij/util/ArrayUtil.java index e53224a85065..b5b5cd24d4eb 100644 --- a/platform/util/src/com/intellij/util/ArrayUtil.java +++ b/platform/util/src/com/intellij/util/ArrayUtil.java @@ -907,6 +907,24 @@ public class ArrayUtil extends ArrayUtilRt { } } + @Nullable + public static T[] copyOf(@Nullable T[] original) { + if (original == null) return null; + return (T[]) Arrays.copyOf(original, original.length, original.getClass()); + } + + @Nullable + public static boolean[] copyOf(@Nullable boolean[] original) { + if (original == null) return null; + return Arrays.copyOf(original, original.length); + } + + @Nullable + public static int[] copyOf(@Nullable int[] original) { + if (original == null) return null; + return Arrays.copyOf(original, original.length); + } + @NotNull public static T[] stripTrailingNulls(@NotNull T[] array) { return array.length != 0 && array[array.length-1] == null ? Arrays.copyOf(array, trailingNullsIndex(array)) : array; diff --git a/platform/util/src/com/intellij/util/ui/JBUI.java b/platform/util/src/com/intellij/util/ui/JBUI.java index 84b183b30221..2ebb1da1e8be 100644 --- a/platform/util/src/com/intellij/util/ui/JBUI.java +++ b/platform/util/src/com/intellij/util/ui/JBUI.java @@ -366,6 +366,7 @@ public class JBUI { EFFECTIVE // effective scale } + @Override public float getScale() { return myScale; } @@ -399,6 +400,23 @@ public class JBUI { return super.scaleVal(value * myScale); } } + + /** + * Scales the value in the icon's scale. + */ + public static int scaleVal(Icon icon, int value, Scale type) { + return (int)scaleVal(icon, (float)value, type); + } + + /** + * Scales the value in the icon's scale. + */ + public static float scaleVal(Icon icon, float value, Scale type) { + if (icon instanceof ScalableJBIcon) { + return ((ScalableJBIcon)icon).scaleVal(value, type); + } + return value; + } } /** @@ -422,9 +440,8 @@ public class JBUI { */ @Override public Icon scale(float scale) { - if (scale == 1f) return this; + if (scale == getScale()) return this; - scale = scaleVal(scale, Scale.ARBITRARY); // accumulate scale if (myScaledIconCache == null || myScaledIconCache.getScale() != scale) { myScaledIconCache = copy(); myScaledIconCache.setScale(scale); @@ -433,7 +450,7 @@ public class JBUI { } /** - * @return a deep copy of this icon instance + * @return a copy of this icon instance */ @NotNull protected abstract T copy(); @@ -481,9 +498,15 @@ public class JBUI { * * @author tav */ - public static abstract class AuxScalableJBIcon extends ScalableJBIcon implements AuxJBUIScale { + public static abstract class AuxScalableJBIcon extends CachingScalableJBIcon implements AuxJBUIScale { private float myCachedJBUIScale = JBUI.scale(1f); + protected AuxScalableJBIcon() {} + + protected AuxScalableJBIcon(AuxScalableJBIcon icon) { + super(icon); + } + @Override public boolean updateJBUIScale() { if (needUpdateJBUIScale()) {