mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Refactor JBValue
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
package com.intellij.util.ui;
|
||||
|
||||
import com.intellij.ui.RestoreScaleRule;
|
||||
import com.intellij.ui.paint.PaintUtil.RoundingMode;
|
||||
import com.intellij.util.ui.JBValue.JBValueGroup;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExternalResource;
|
||||
@@ -20,41 +22,30 @@ public class JBValueTest {
|
||||
public static final ExternalResource manageState = new RestoreScaleRule();
|
||||
|
||||
@Test
|
||||
public void testInt() {
|
||||
public void testSeparateValue() {
|
||||
JBUI.setUserScaleFactor(1);
|
||||
|
||||
JBValue value1 = JBUI.intValue(2);
|
||||
JBValue.SelfCachedInteger value2 = new JBValue.SelfCachedInteger(2);
|
||||
JBValue value1 = JBUI.value(2);
|
||||
JBValue value2 = JBUI.value(2.6f);
|
||||
JBValue value3 = JBUI.value(2.9f);
|
||||
|
||||
JBUI.setUserScaleFactor(2);
|
||||
|
||||
assertEquals(JBUI.scale(2), value1.get());
|
||||
assertEquals(JBUI.scale(2), value2.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloat() {
|
||||
JBUI.setUserScaleFactor(1);
|
||||
|
||||
JBValue.Float value1 = JBUI.floatValue(2.6f);
|
||||
JBValue.SelfCachedFloat value2 = new JBValue.SelfCachedFloat(2.6f);
|
||||
|
||||
JBUI.setUserScaleFactor(2);
|
||||
|
||||
assertEquals(Math.round(JBUI.scale(2.6f)), value1.get());
|
||||
assertEquals(Math.round(JBUI.scale(2.6f)), value2.get());
|
||||
assertEquals(JBUI.scale(2.6f), value1.getFloat());
|
||||
assertEquals(JBUI.scale(2.6f), value2.getFloat());
|
||||
assertEquals((int)Math.ceil(JBUI.scale(2.6f)), value2.get(RoundingMode.CEIL));
|
||||
assertEquals((int)Math.floor(JBUI.scale(2.6f)), value3.get(RoundingMode.FLOOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTracker() {
|
||||
public void testGroup() {
|
||||
JBUI.setUserScaleFactor(1);
|
||||
|
||||
JBValue.UpdateTracker tracker = new JBValue.UpdateTracker();
|
||||
JBValue value1 = JBUI.intValue(1, tracker);
|
||||
JBValue value2 = JBUI.intValue(2, tracker);
|
||||
JBValue.Float value3 = JBUI.floatValue(3.6f, tracker);
|
||||
JBValueGroup values = new JBValueGroup();
|
||||
JBValue value1 = values.add(1);
|
||||
JBValue value2 = values.add(2);
|
||||
JBValue value3 = values.add(3.6f);
|
||||
|
||||
JBUI.setUserScaleFactor(2);
|
||||
|
||||
@@ -63,38 +54,35 @@ public class JBValueTest {
|
||||
assertEquals(Math.round(JBUI.scale(3.6f)), value3.get());
|
||||
assertEquals(JBUI.scale(3.6f), value3.getFloat());
|
||||
|
||||
tracker.forget((JBValue.Cacheable)value3);
|
||||
values.dispose();
|
||||
|
||||
int scale = JBUI.scale(1);
|
||||
JBUI.setUserScaleFactor(3);
|
||||
|
||||
assertEquals(Math.round(scale * 3.6f), value3.get());
|
||||
assertEquals(scale * 3.6f, value3.getFloat());
|
||||
|
||||
tracker.dispose();
|
||||
|
||||
scale = JBUI.scale(1);
|
||||
JBUI.setUserScaleFactor(1);
|
||||
|
||||
assertEquals(scale, value1.get());
|
||||
assertEquals(scale * 2, value2.get());
|
||||
assertEquals(Math.round(scale * 3.6f), value3.get());
|
||||
assertEquals(scale * 3.6f, value3.getFloat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUIDefaultsInteger() {
|
||||
public void testUIInteger() {
|
||||
JBUI.setUserScaleFactor(1);
|
||||
String key = "JBValue.int";
|
||||
String absentKey = "JBValue.absent";
|
||||
UIManager.put(key, 2);
|
||||
|
||||
JBValue.UIDefaultsInteger value = new JBValue.UIDefaultsInteger(key);
|
||||
JBValue value1 = JBUI.uiIntValue(key, 1);
|
||||
JBValue value2 = JBUI.uiIntValue(absentKey, 1);
|
||||
|
||||
JBUI.setUserScaleFactor(2);
|
||||
|
||||
assertEquals(JBUI.scale(2), value.get());
|
||||
assertEquals(JBUI.scale(2), value1.get());
|
||||
assertEquals(JBUI.scale(1), value2.get());
|
||||
|
||||
UIManager.put(key, 3);
|
||||
|
||||
assertEquals(JBUI.scale(3), value.get());
|
||||
assertEquals(JBUI.scale(3), value1.get());
|
||||
|
||||
UIManager.put(key, null);
|
||||
}
|
||||
|
||||
@@ -483,20 +483,13 @@ public class JBUI {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JBValue.Integer intValue(int value) {
|
||||
return new JBValue.Integer(value);
|
||||
}
|
||||
|
||||
public static JBValue.Integer intValue(int value, JBValue.UpdateTracker tracker) {
|
||||
return new JBValue.CachedInteger(value, tracker);
|
||||
}
|
||||
|
||||
public static JBValue.Float floatValue(float value) {
|
||||
public static JBValue value(float value) {
|
||||
return new JBValue.Float(value);
|
||||
}
|
||||
|
||||
public static JBValue.Float floatValue(float value, JBValue.UpdateTracker tracker) {
|
||||
return new JBValue.CachedFloat(value, tracker);
|
||||
@NotNull
|
||||
public static JBValue uiIntValue(@NotNull String key, int defValue) {
|
||||
return new JBValue.UIInteger(key, defValue);
|
||||
}
|
||||
|
||||
public static JBDimension size(int width, int height) {
|
||||
|
||||
@@ -16,21 +16,15 @@ import static com.intellij.ui.paint.PaintUtil.RoundingMode.ROUND;
|
||||
/**
|
||||
* A wrapper over an unscaled numeric value, auto-scaled via {@link JBUI#scale}.
|
||||
* <p>
|
||||
* Use {@link Integer} or {@link Float} classes for on-demand value scaling.
|
||||
* {@code JBValue} can be used separately or in a group, see {@link JBValueGroup}.
|
||||
* <p>
|
||||
* If the same JBValue object is used multiple times in a code block, then in order to save scaling ops,
|
||||
* a {@link CachedInteger} or {@link CachedFloat} classes can be used instead. Either with a separate
|
||||
* {@link UpdateTracker} (better to use for many JBValue objects), or with a dedicated one (for a single
|
||||
* JBValue object) as in the {@link SelfCachedInteger} or {@link SelfCachedFloat} classes.
|
||||
* <p>
|
||||
* Also, the {@link UIDefaultsInteger} class can be used for auto-scaling an integer value stored in
|
||||
* {@link UIDefaults}.
|
||||
* Also, a {@link UIInteger} value can be used as a wrapper over an integer value stored in {@link UIDefaults}.
|
||||
*
|
||||
* @see JBUI#value(float)
|
||||
* @see JBValueGroup#add(float)
|
||||
* @see JBUI#uiIntValue(String, int)
|
||||
*
|
||||
* @author tav
|
||||
* @see JBUI#intValue(int)
|
||||
* @see JBUI#intValue(int,UpdateTracker)
|
||||
* @see JBUI#floatValue(float)
|
||||
* @see JBUI#floatValue(float,UpdateTracker)
|
||||
*/
|
||||
public abstract class JBValue {
|
||||
protected JBValue() {}
|
||||
@@ -39,8 +33,14 @@ public abstract class JBValue {
|
||||
* Returns scaled rounded to int value.
|
||||
*/
|
||||
public int get() {
|
||||
// for backward compatibility rely on the rounding mode applied in JBUI.scale(int)
|
||||
return JBUI.scale((int)getUnscaled());
|
||||
return ROUND.round(JBUI.scale(getUnscaled()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scaled float value.
|
||||
*/
|
||||
public float getFloat() {
|
||||
return JBUI.scale(getUnscaled());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,143 +55,53 @@ public abstract class JBValue {
|
||||
*/
|
||||
protected abstract float getUnscaled();
|
||||
|
||||
public interface Cacheable {
|
||||
/**
|
||||
* Scales and caches the value.
|
||||
*/
|
||||
void cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* JBValue wrapper over an integer value in {@link UIDefaults}.
|
||||
*
|
||||
* @see JBUI#uiIntValue(String,int)
|
||||
*/
|
||||
public static class UIDefaultsInteger extends JBValue {
|
||||
public static class UIInteger extends JBValue {
|
||||
private final @NotNull String key;
|
||||
private final int defValue;
|
||||
|
||||
public UIDefaultsInteger(@NotNull String key) {
|
||||
public UIInteger(@NotNull String key, int defValue) {
|
||||
this.key = key;
|
||||
this.defValue = defValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getUnscaled() {
|
||||
return UIManager.getInt(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JBValue wrapper over an integer.
|
||||
*/
|
||||
public static class Integer extends JBValue {
|
||||
private final int value;
|
||||
|
||||
/**
|
||||
* @param value unscaled value
|
||||
* @see JBUI#intValue(int)
|
||||
*/
|
||||
public Integer(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getUnscaled() {
|
||||
return value;
|
||||
return JBUI.getInt(key, defValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JBValue wrapper over a float.
|
||||
*
|
||||
* @see JBUI#value(float)
|
||||
*/
|
||||
public static class Float extends JBValue {
|
||||
private final float value;
|
||||
|
||||
/**
|
||||
* @param value unscaled value
|
||||
* @see JBUI#floatValue(float)
|
||||
*/
|
||||
public Float(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get() {
|
||||
return ROUND.round(JBUI.scale(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales the value and returns.
|
||||
*/
|
||||
public float getFloat() {
|
||||
return JBUI.scale(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getUnscaled() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer JBValue which caches its scaled value on JBUI.scale change.
|
||||
*/
|
||||
public static class CachedInteger extends Integer implements Cacheable {
|
||||
private int cachedScaledValue;
|
||||
|
||||
protected CachedInteger(int value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value unscaled value
|
||||
* @param tracker updates the value
|
||||
* @see JBUI#intValue(int, UpdateTracker)
|
||||
*/
|
||||
public CachedInteger(int value, @NotNull UpdateTracker tracker) {
|
||||
super(value);
|
||||
cachedScaledValue = JBUI.scale(value);
|
||||
tracker.track(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get() {
|
||||
return cachedScaledValue;
|
||||
}
|
||||
|
||||
public void cache() {
|
||||
cachedScaledValue = JBUI.scale((int)getUnscaled());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CachedInteger with a dedicated UpdateTracker.
|
||||
*/
|
||||
public static class SelfCachedInteger extends CachedInteger {
|
||||
private final @NotNull UpdateTracker tracker = new UpdateTracker();
|
||||
|
||||
public SelfCachedInteger(int value) {
|
||||
super(value);
|
||||
this.tracker.track(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Float JBValue which caches its scaled value on JBUI.scale change.
|
||||
*/
|
||||
public static class CachedFloat extends Float implements Cacheable {
|
||||
private static class CachedFloat extends Float {
|
||||
private float cachedScaledValue;
|
||||
|
||||
protected CachedFloat(float value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value unscaled value
|
||||
* @param tracker updates the value
|
||||
* @see JBUI#floatValue(float, UpdateTracker)
|
||||
*/
|
||||
public CachedFloat(float value, UpdateTracker tracker) {
|
||||
super(value);
|
||||
cachedScaledValue = JBUI.scale(value);
|
||||
tracker.track(this);
|
||||
scaleAndCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -204,50 +114,46 @@ public abstract class JBValue {
|
||||
return cachedScaledValue;
|
||||
}
|
||||
|
||||
public void cache() {
|
||||
@Override
|
||||
public int get(@NotNull RoundingMode rm) {
|
||||
return rm.round(cachedScaledValue);
|
||||
}
|
||||
|
||||
public void scaleAndCache() {
|
||||
cachedScaledValue = JBUI.scale(getUnscaled());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CachedFloat with a dedicated UpdateTracker.
|
||||
* A group of values, utilizing caching strategy per value. The group listens to the global user scale factor change and updates
|
||||
* all of the values. The {@link JBValue#get()} method of a value returns a cached scaled value, saving recalculation.
|
||||
* This can be a better choice when values are used multiple times in a code block.
|
||||
*/
|
||||
public static class SelfCachedFloat extends CachedFloat {
|
||||
private final @NotNull UpdateTracker tracker = new UpdateTracker();
|
||||
|
||||
public SelfCachedFloat(float value) {
|
||||
super(value);
|
||||
this.tracker.track(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks for a list of {@link Cacheable} values and auto-updates them on {@link JBUI#USER_SCALE_FACTOR_PROPERTY}} change.
|
||||
*/
|
||||
public static class UpdateTracker {
|
||||
private final List<Cacheable> list = new LinkedList<Cacheable>();
|
||||
public static class JBValueGroup {
|
||||
private final List<CachedFloat> group = new LinkedList<CachedFloat>();
|
||||
private final PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
for (Cacheable value : list) value.cache();
|
||||
for (CachedFloat value : group) value.scaleAndCache();
|
||||
}
|
||||
};
|
||||
|
||||
public UpdateTracker() {
|
||||
public JBValueGroup() {
|
||||
JBUI.addPropertyChangeListener(JBUI.USER_SCALE_FACTOR_PROPERTY, listener);
|
||||
}
|
||||
|
||||
public void track(Cacheable value) {
|
||||
list.add(value);
|
||||
}
|
||||
|
||||
public void forget(Cacheable value) {
|
||||
list.remove(value);
|
||||
/**
|
||||
* Creates {@link JBValue} and adds it to this group.
|
||||
*/
|
||||
public JBValue add(float value) {
|
||||
CachedFloat v = new CachedFloat(value);
|
||||
group.add(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
JBUI.removePropertyChangeListener(JBUI.USER_SCALE_FACTOR_PROPERTY, listener);
|
||||
list.clear();
|
||||
group.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user