mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[followup] Add/refactor JBUI.JBIcon/ScalableJBIcon/ValidatingScalableJBIcon
This commit is contained in:
@@ -54,8 +54,8 @@ public class LayeredIcon extends JBUI.AuxScalableJBIcon {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayeredIcon withPreScaled(boolean preScaled) {
|
||||
super.withPreScaled(preScaled);
|
||||
public LayeredIcon withJBUIPreScaled(boolean preScaled) {
|
||||
super.withJBUIPreScaled(preScaled);
|
||||
for (int i = 0; i < myIcons.length; i++) {
|
||||
myHShifts[i] = scaleVal(myHShifts[i], Scale.JBUI);
|
||||
myVShifts[i] = scaleVal(myVShifts[i], Scale.JBUI);
|
||||
@@ -271,11 +271,10 @@ public class LayeredIcon extends JBUI.AuxScalableJBIcon {
|
||||
|
||||
@Override
|
||||
public Icon scale(float scale) {
|
||||
if (getScale() != scale) {
|
||||
super.scale(scale);
|
||||
if (myScaledIcons!= null) Arrays.fill(myScaledIcons, null);
|
||||
updateSize();
|
||||
}
|
||||
if (scale == 1f) return this;
|
||||
|
||||
setScale(scaleVal(scale, Scale.ARBITRARY));
|
||||
if (myScaledIcons != null) Arrays.fill(myScaledIcons, null);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +57,10 @@ public class RowIcon extends JBUI.AuxScalableJBIcon {
|
||||
|
||||
@Override
|
||||
public Icon scale(float scale) {
|
||||
if (getScale() != scale || (getScale() != 1f && myScaledIcons == null)) {
|
||||
super.scale(scale);
|
||||
rescale();
|
||||
}
|
||||
if (scale == 1f) return this;
|
||||
|
||||
setScale(scaleVal(scale, Scale.ARBITRARY));
|
||||
rescale();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,12 @@ public class SizedIcon extends JBUI.ScalableJBIcon {
|
||||
|
||||
@Override
|
||||
public Icon scale(float scale) {
|
||||
if (scale == 1f) return this;
|
||||
|
||||
if (myDelegate instanceof ScalableIcon) {
|
||||
myScaledDelegate = ((ScalableIcon)myDelegate).scale(scale);
|
||||
setScale(scaleVal(scale, Scale.ARBITRARY));
|
||||
myScaledDelegate = ((ScalableIcon)myDelegate).scale(getScale());
|
||||
}
|
||||
return super.scale(scale);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +457,8 @@ public final class IconLoader {
|
||||
|
||||
@Override
|
||||
public Icon scale(float scale) {
|
||||
if (scale == 1f) return this;
|
||||
|
||||
if (!isValid()) getRealIcon(); // force state update & cache reset
|
||||
|
||||
Icon icon = myScaledIconsCache.getScaledIcon(scale);
|
||||
@@ -578,10 +580,12 @@ public final class IconLoader {
|
||||
|
||||
@Override
|
||||
public Icon scale(float scale) {
|
||||
if (scale == 1f) return this;
|
||||
|
||||
getOrComputeIcon();
|
||||
if (myIcon instanceof ScalableIcon) {
|
||||
myIcon = ((ScalableIcon)myIcon).scale(scale);
|
||||
return super.scale(scale);
|
||||
setScale(scaleVal(scale, Scale.ARBITRARY));
|
||||
myIcon = ((ScalableIcon)myIcon).scale(getScale());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,11 @@ 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.
|
||||
*
|
||||
* @param scaleFactor scale
|
||||
* @return scaled icon with width getIconWidth() * scaleFactor and height getIconHeight() * scaleFactor
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,18 @@ public class ColorIcon extends EmptyIcon {
|
||||
this(size, color, false);
|
||||
}
|
||||
|
||||
protected ColorIcon(ColorIcon icon) {
|
||||
super(icon);
|
||||
myColor = icon.myColor;
|
||||
myBorder = icon.myBorder;
|
||||
myColorSize = icon.myColorSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ColorIcon copy() {
|
||||
return new ColorIcon(this);
|
||||
}
|
||||
|
||||
public Color getIconColor() {
|
||||
return myColor;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.intellij.util.ui;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -32,9 +31,8 @@ import java.util.Map;
|
||||
*
|
||||
* @see ColorIcon
|
||||
*/
|
||||
public class EmptyIcon extends JBUI.ScalableJBIcon {
|
||||
private static final Map<Pair<Integer, Boolean>, EmptyIcon> cache =
|
||||
new HashMap<Pair<Integer, Boolean>, EmptyIcon>(); // (size, preScaled) -> (icon)
|
||||
public class EmptyIcon extends JBUI.CachingScalableJBIcon<EmptyIcon> {
|
||||
private static final Map<Integer, EmptyIcon> cache = new HashMap<Integer, EmptyIcon>();
|
||||
|
||||
public static final Icon ICON_16 = JBUI.scale(create(16));
|
||||
public static final Icon ICON_18 = JBUI.scale(create(18));
|
||||
@@ -43,13 +41,12 @@ public class EmptyIcon extends JBUI.ScalableJBIcon {
|
||||
|
||||
protected final int width;
|
||||
protected final int height;
|
||||
private EmptyIcon myScaledCache;
|
||||
private boolean myUseCache;
|
||||
|
||||
/**
|
||||
* Creates an icon of the provided size.
|
||||
*
|
||||
* Use {@link JBUI#scale(EmptyIcon)} to meet HiDPI.
|
||||
* Use {@link JBUI#scale(JBUI.JBIcon)} to meet HiDPI.
|
||||
*/
|
||||
public static EmptyIcon create(int size) {
|
||||
return create(size, size);
|
||||
@@ -58,7 +55,7 @@ public class EmptyIcon extends JBUI.ScalableJBIcon {
|
||||
/**
|
||||
* Creates an icon of the provided size.
|
||||
*
|
||||
* Use {@link JBUI#scale(EmptyIcon)} to meet HiDPI.
|
||||
* Use {@link JBUI#scale(JBUI.JBIcon)} to meet HiDPI.
|
||||
*/
|
||||
public static EmptyIcon create(int width, int height) {
|
||||
return create(width, height, true);
|
||||
@@ -98,39 +95,34 @@ public class EmptyIcon extends JBUI.ScalableJBIcon {
|
||||
myUseCache = icon.myUseCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EmptyIcon copy() {
|
||||
return new EmptyIcon(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmptyIcon withPreScaled(boolean preScaled) {
|
||||
if (myUseCache && isPreScaled() != preScaled) {
|
||||
Pair<Integer, Boolean> key = key(width, height, preScaled);
|
||||
public EmptyIcon withJBUIPreScaled(boolean preScaled) {
|
||||
if (myUseCache && isJBUIPreScaled() != preScaled) {
|
||||
Integer key = key(width, height, isJBUIPreScaled());
|
||||
if (key != null) cache.remove(key); // rather useless to keep it in cache
|
||||
return create(width, height, preScaled);
|
||||
}
|
||||
return (EmptyIcon)super.withPreScaled(preScaled);
|
||||
return (EmptyIcon)super.withJBUIPreScaled(preScaled);
|
||||
}
|
||||
|
||||
private static EmptyIcon create(int width, int height, boolean preScaled) {
|
||||
Pair<Integer, Boolean> key = key(width, height, preScaled);
|
||||
Integer key = key(width, height, preScaled);
|
||||
EmptyIcon icon = (key != null) ? cache.get(key) : null;
|
||||
if (icon == null) {
|
||||
icon = new EmptyIcon(width, height, true);
|
||||
icon.setPreScaled(preScaled);
|
||||
icon.setJBUIPreScaled(preScaled);
|
||||
if (key != null) cache.put(key, icon);
|
||||
}
|
||||
return icon;
|
||||
}
|
||||
|
||||
private static Pair<Integer, Boolean> key(int width, int height, boolean preScaled) {
|
||||
return (width == height && width < 129) ? Pair.create(width, preScaled) : null;
|
||||
}
|
||||
|
||||
private boolean isCached() {
|
||||
if (!myUseCache) return false;
|
||||
Pair<Integer, Boolean> key = key(width, height, isPreScaled());
|
||||
return key != null && cache.containsKey(key);
|
||||
private static Integer key(int width, int height, boolean preScaled) {
|
||||
return (width == height && width < 129) ? preScaled ? width : JBUI.scale(width) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,20 +146,18 @@ public class EmptyIcon extends JBUI.ScalableJBIcon {
|
||||
|
||||
final EmptyIcon icon = (EmptyIcon)o;
|
||||
|
||||
if (height != icon.height) return false;
|
||||
if (width != icon.width) return false;
|
||||
if (scaleVal(height, Scale.JBUI) != icon.scaleVal(height, Scale.JBUI)) return false;
|
||||
if (scaleVal(width, Scale.JBUI) != icon.scaleVal(width, Scale.JBUI)) return false;
|
||||
if (getScale() != icon.getScale()) return false;
|
||||
if (isPreScaled() != icon.isPreScaled()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = width;
|
||||
result = 31 * result + height;
|
||||
int result = scaleVal(width, Scale.JBUI);
|
||||
result = 31 * result + scaleVal(height, Scale.JBUI);
|
||||
result = 31 * result + (getScale() != +0.0f ? Float.floatToIntBits(getScale()) : 0);
|
||||
result = 31 * result + Boolean.valueOf(isPreScaled()).hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -175,17 +165,6 @@ public class EmptyIcon extends JBUI.ScalableJBIcon {
|
||||
return new EmptyIconUIResource(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmptyIcon scale(float scale) {
|
||||
if (getScale() == scale || !isCached()) {
|
||||
return (EmptyIcon)super.scale(scale);
|
||||
}
|
||||
if (myScaledCache == null || myScaledCache.getScale() != scale) {
|
||||
myScaledCache = copy(); // never cached
|
||||
}
|
||||
return myScaledCache.scale(scale);
|
||||
}
|
||||
|
||||
public static class EmptyIconUIResource extends EmptyIcon implements UIResource {
|
||||
protected EmptyIconUIResource(EmptyIcon icon) {
|
||||
super(icon);
|
||||
|
||||
@@ -166,7 +166,7 @@ public class JBUI {
|
||||
}
|
||||
|
||||
public static <T extends JBIcon> T scale(T icon) {
|
||||
return (T)icon.withPreScaled(false);
|
||||
return (T)icon.withJBUIPreScaled(false);
|
||||
}
|
||||
|
||||
public static JBDimension emptySize() {
|
||||
@@ -309,14 +309,14 @@ public class JBUI {
|
||||
/**
|
||||
* @return whether the icon size metrics are pre-scaled or not
|
||||
*/
|
||||
protected boolean isPreScaled() {
|
||||
protected boolean isJBUIPreScaled() {
|
||||
return myInitialJBUIScale != 1f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the icon size metrics to {@code preScaled}
|
||||
*/
|
||||
protected void setPreScaled(boolean preScaled) {
|
||||
protected void setJBUIPreScaled(boolean preScaled) {
|
||||
myInitialJBUIScale = preScaled ? scale(1f) : 1f;
|
||||
}
|
||||
|
||||
@@ -325,8 +325,8 @@ public class JBUI {
|
||||
*
|
||||
* @return the icon (this or new instance) with size metrics set to {@code preScaled}
|
||||
*/
|
||||
public JBIcon withPreScaled(boolean preScaled) {
|
||||
setPreScaled(preScaled);
|
||||
public JBIcon withJBUIPreScaled(boolean preScaled) {
|
||||
setJBUIPreScaled(preScaled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -399,12 +399,44 @@ public class JBUI {
|
||||
return super.scaleVal(value * myScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A ScalableJBIcon providing an immutable caching implementation of the {@link #scale(float)} method.
|
||||
*
|
||||
* @author tav
|
||||
* @author Aleksey Pivovarov
|
||||
*/
|
||||
public static abstract class CachingScalableJBIcon<T extends CachingScalableJBIcon> extends ScalableJBIcon {
|
||||
private CachingScalableJBIcon myScaledIconCache;
|
||||
|
||||
protected CachingScalableJBIcon() {}
|
||||
|
||||
protected CachingScalableJBIcon(CachingScalableJBIcon icon) {
|
||||
super(icon);
|
||||
myScaledIconCache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new scaled copy of this icon, or the cached instance of the provided scale
|
||||
*/
|
||||
@Override
|
||||
public Icon scale(float scale) {
|
||||
if (getScale() != scale) setScale(scale);
|
||||
return this;
|
||||
if (scale == 1f) return this;
|
||||
|
||||
scale = scaleVal(scale, Scale.ARBITRARY); // accumulate scale
|
||||
if (myScaledIconCache == null || myScaledIconCache.getScale() != scale) {
|
||||
myScaledIconCache = copy();
|
||||
myScaledIconCache.setScale(scale);
|
||||
}
|
||||
return myScaledIconCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a deep copy of this icon instance
|
||||
*/
|
||||
@NotNull
|
||||
protected abstract T copy();
|
||||
}
|
||||
|
||||
public interface AuxJBUIScale {
|
||||
|
||||
@@ -51,6 +51,16 @@ public class TwoColorsIcon extends ColorIcon {
|
||||
mySecondColor = secondColor != null ? secondColor : Gray.TRANSPARENT;
|
||||
}
|
||||
|
||||
protected TwoColorsIcon(TwoColorsIcon icon) {
|
||||
super(icon);
|
||||
mySecondColor = icon.mySecondColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TwoColorsIcon copy() {
|
||||
return new TwoColorsIcon(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(final Component component, Graphics g, int x, int y) {
|
||||
Graphics2D g2d = (Graphics2D)g.create();
|
||||
|
||||
+3
-3
@@ -331,9 +331,9 @@ class StructureFilterPopupComponent extends FilterPopupComponent<VcsLogFileFilte
|
||||
}
|
||||
|
||||
@Override
|
||||
public CheckboxColorIcon withPreScaled(boolean preScaled) {
|
||||
mySizedIcon = JBUI.scale(mySizedIcon);
|
||||
return (CheckboxColorIcon)super.withPreScaled(preScaled);
|
||||
public CheckboxColorIcon withJBUIPreScaled(boolean preScaled) {
|
||||
mySizedIcon = (SizedIcon)mySizedIcon.withJBUIPreScaled(preScaled);
|
||||
return (CheckboxColorIcon)super.withJBUIPreScaled(preScaled);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
@@ -34,6 +34,18 @@ public final class ColorIcon extends EmptyIcon {
|
||||
myColorSize = colorSize;
|
||||
}
|
||||
|
||||
protected ColorIcon(ColorIcon icon) {
|
||||
super(icon);
|
||||
myColorSize = icon.myColorSize;
|
||||
myColor = icon.myColor;
|
||||
myShowRedLine = icon.myShowRedLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ColorIcon copy() {
|
||||
return new ColorIcon(this);
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return myShowRedLine ? null : myColor;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -67,6 +68,17 @@ public class ColorIconCache {
|
||||
myColours = colours;
|
||||
}
|
||||
|
||||
protected ColorIcon(ColorIcon icon) {
|
||||
super(icon);
|
||||
myColor = icon.myColor;
|
||||
if (icon.myColours != null) myColours = Arrays.copyOf(icon.myColours, icon.myColours.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ColorIcon copy() {
|
||||
return new ColorIcon(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(final Component component, final Graphics g, final int i, final int j) {
|
||||
final int iconWidth = getIconWidth();
|
||||
|
||||
Reference in New Issue
Block a user