From e0e8372d4c1a2a802dbf50879a6e838e91eee866 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Sat, 30 Jan 2016 17:51:56 +0300 Subject: [PATCH] make all AbstractSizeAdjustingIcon icons scalable --- .../ui/AbstractSizeAdjustingIcon.java | 5 +- .../src/com/intellij/ui/LayeredIcon.java | 51 +++++++++++++++++-- .../core-api/src/com/intellij/ui/RowIcon.java | 45 ++++++++++++++-- 3 files changed, 91 insertions(+), 10 deletions(-) diff --git a/platform/core-api/src/com/intellij/ui/AbstractSizeAdjustingIcon.java b/platform/core-api/src/com/intellij/ui/AbstractSizeAdjustingIcon.java index 6cd9ee6d4a7a..ccc7688f86d4 100644 --- a/platform/core-api/src/com/intellij/ui/AbstractSizeAdjustingIcon.java +++ b/platform/core-api/src/com/intellij/ui/AbstractSizeAdjustingIcon.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.ui; +import com.intellij.openapi.util.ScalableIcon; import com.intellij.util.ui.JBUI; import javax.swing.*; @@ -22,7 +23,7 @@ import javax.swing.*; /** * @author tav */ -abstract class AbstractSizeAdjustingIcon implements Icon { +abstract class AbstractSizeAdjustingIcon implements Icon, ScalableIcon { protected int myWidth; protected int myHeight; private float scale; diff --git a/platform/core-api/src/com/intellij/ui/LayeredIcon.java b/platform/core-api/src/com/intellij/ui/LayeredIcon.java index 3e55536dde34..a649a57c9ab9 100644 --- a/platform/core-api/src/com/intellij/ui/LayeredIcon.java +++ b/platform/core-api/src/com/intellij/ui/LayeredIcon.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.ui; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.ScalableIcon; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -25,6 +26,8 @@ import java.util.Arrays; public class LayeredIcon extends AbstractSizeAdjustingIcon { private static final Logger LOG = Logger.getInstance("#com.intellij.ui.LayeredIcon"); private final Icon[] myIcons; + private Icon[] myScaledIcons; + private float myScale = 1f; private final boolean[] myDisabledLayers; private final int[] myHShifts; private final int[] myVShifts; @@ -74,6 +77,7 @@ public class LayeredIcon extends AbstractSizeAdjustingIcon { if (!Arrays.equals(myHShifts, icon.myHShifts)) return false; if (!Arrays.equals(myIcons, icon.myIcons)) return false; if (!Arrays.equals(myVShifts, icon.myVShifts)) return false; + if (myScale != icon.myScale) return false; return true; } @@ -166,12 +170,36 @@ public class LayeredIcon extends AbstractSizeAdjustingIcon { @Override public void paintIcon(Component c, Graphics g, int x, int y) { for (int i = 0; i < myIcons.length; i++) { - Icon icon = myIcons[i]; + Icon icon = getOrScale(i); if (icon == null || myDisabledLayers[i]) continue; - icon.paintIcon(c, g, myXShift + x + myHShifts[i], myYShift + y + myVShifts[i]); + int xOffset = myXShift + x + myHShifts[i]; + int yOffset = myYShift + y + myVShifts[i]; + icon.paintIcon(c, g, xOffset, yOffset); } } + private Icon getOrScale(int i) { + if (myScale == 1f) { + return myIcons[i]; + } + if (myScaledIcons == null) { + myScaledIcons = new Icon[myIcons.length]; + } + + Icon icon = myScaledIcons[i]; + if (icon == null && myIcons[i] != null) { + myScaledIcons[i] = icon; + if (myScaledIcons[i] instanceof ScalableIcon) { + myScaledIcons[i] = ((ScalableIcon)myScaledIcons[i]).scale(myScale); + } + } + return icon; + } + + private Icon[] getIcons() { + return myScaledIcons != null && myScale != 1f ? myScaledIcons : myIcons; + } + public boolean isLayerEnabled(int layer) { return !myDisabledLayers[layer]; } @@ -184,7 +212,7 @@ public class LayeredIcon extends AbstractSizeAdjustingIcon { public int getIconWidth() { if (myWidth <= 1) { //icon is not loaded yet adjustSize(); - return myWidth; + return scale(myWidth); } return super.getIconWidth(); } @@ -193,11 +221,15 @@ public class LayeredIcon extends AbstractSizeAdjustingIcon { public int getIconHeight() { if (myHeight <= 1) { //icon is not loaded yet adjustSize(); - return myHeight; + return scale(myHeight); } return super.getIconHeight(); } + private int scale(int n) { + return myScale == 1f ? n : (int)(n * myScale); + } + @Override protected void adjustSize() { int minX = Integer.MAX_VALUE; @@ -237,4 +269,13 @@ public class LayeredIcon extends AbstractSizeAdjustingIcon { public String toString() { return "Layered icon. myIcons=" + Arrays.asList(myIcons); } + + @Override + public Icon scale(float scaleFactor) { + if (myScale != scaleFactor) { + myScale = scaleFactor; + adjustSize(); + } + 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 75da6f64094e..18fa5a5c3b0c 100644 --- a/platform/core-api/src/com/intellij/ui/RowIcon.java +++ b/platform/core-api/src/com/intellij/ui/RowIcon.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.ui; +import com.intellij.openapi.util.ScalableIcon; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; @@ -27,10 +28,12 @@ import java.util.List; public class RowIcon extends AbstractSizeAdjustingIcon { private final Alignment myAlignment; + private float myScale = 1f; public enum Alignment {TOP, CENTER, BOTTOM} private final Icon[] myIcons; + private Icon[] myScaledIcons; public RowIcon(int iconCount/*, int orientation*/) { this(iconCount, Alignment.TOP); @@ -48,6 +51,36 @@ public class RowIcon extends AbstractSizeAdjustingIcon { adjustSize(); } + + @Override + public Icon scale(float scale) { + if (myScale != scale || (myScale != 1f && myScaledIcons == null)) { + myScale = scale; + rescale(); + } + return this; + } + + private void rescale() { + if (myScale == 1f) { + myScaledIcons = null; + return; + } + + for (Icon icon : myIcons) { + if (icon != null && !(icon instanceof ScalableIcon)) { + return; + } + } + + 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(myScale); + } + adjustSize(); + } + @TestOnly @NotNull Icon[] getAllIcons() { @@ -69,6 +102,7 @@ public class RowIcon extends AbstractSizeAdjustingIcon { public void setIcon(Icon icon, int layer) { myIcons[layer] = icon; + rescale(); adjustSize(); } @@ -76,11 +110,16 @@ public class RowIcon extends AbstractSizeAdjustingIcon { return myIcons[index]; } + public Icon[] getIcons() { + Icon[] icons = myScale == 1f ? myIcons : myScaledIcons; + return icons == null ? myIcons : icons; + } + @Override public void paintIcon(Component c, Graphics g, int x, int y) { int _x = x; int _y = y; - for (Icon icon : myIcons) { + for (Icon icon : getIcons()) { if (icon == null) continue; switch (myAlignment) { case TOP: _y = y; @@ -100,7 +139,7 @@ public class RowIcon extends AbstractSizeAdjustingIcon { protected void adjustSize() { int width = 0; int height = 0; - for (Icon icon : myIcons) { + for (Icon icon : getIcons()) { if (icon == null) continue; width += icon.getIconWidth(); //height += icon.getIconHeight();