mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Add JBValue.UpdateTracker to track for JBUI.scale change
+ unit test
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.util.ui;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests {@link JBValue}.
|
||||
*
|
||||
* @author tav
|
||||
*/
|
||||
public class JBValueTest extends TestScaleHelper {
|
||||
@Test
|
||||
public void testInt() {
|
||||
JBUI.setUserScaleFactor(1);
|
||||
|
||||
JBValue value1 = JBUI.intValue(2);
|
||||
JBValue.SelfCachedInteger value2 = new JBValue.SelfCachedInteger(2);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTracker() {
|
||||
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);
|
||||
|
||||
JBUI.setUserScaleFactor(2);
|
||||
|
||||
assertEquals(JBUI.scale(1), value1.get());
|
||||
assertEquals(JBUI.scale(2), value2.get());
|
||||
assertEquals(Math.round(JBUI.scale(3.6f)), value3.get());
|
||||
assertEquals(JBUI.scale(3.6f), value3.getFloat());
|
||||
|
||||
tracker.forget((JBValue.Cacheable)value3);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUIManagerInteger() {
|
||||
JBUI.setUserScaleFactor(1);
|
||||
String key = "JBValue.int";
|
||||
UIManager.put(key, 2);
|
||||
|
||||
JBValue.UIManagerInteger value = new JBValue.UIManagerInteger(key);
|
||||
|
||||
JBUI.setUserScaleFactor(2);
|
||||
|
||||
assertEquals(JBUI.scale(2), value.get());
|
||||
|
||||
UIManager.put(key, 3);
|
||||
|
||||
assertEquals(JBUI.scale(3), value.get());
|
||||
|
||||
UIManager.put(key, null);
|
||||
}
|
||||
}
|
||||
@@ -487,10 +487,18 @@ public class JBUI {
|
||||
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) {
|
||||
return new JBValue.Float(value);
|
||||
}
|
||||
|
||||
public static JBValue.Float floatValue(float value, JBValue.UpdateTracker tracker) {
|
||||
return new JBValue.CachedFloat(value, tracker);
|
||||
}
|
||||
|
||||
public static JBDimension size(int width, int height) {
|
||||
return new JBDimension(width, height);
|
||||
}
|
||||
|
||||
@@ -6,12 +6,28 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.ui.paint.PaintUtil.RoundingMode.ROUND;
|
||||
|
||||
/**
|
||||
* A wrapper over an unscaled value which lazily scales it via {@link JBUI#scale}.
|
||||
* 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.
|
||||
* <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.
|
||||
*
|
||||
* @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() {}
|
||||
@@ -36,11 +52,18 @@ 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 UIManager}.
|
||||
*/
|
||||
public static class UIManagerInteger extends JBValue {
|
||||
private final String key;
|
||||
private final @NotNull String key;
|
||||
|
||||
public UIManagerInteger(@NotNull String key) {
|
||||
this.key = key;
|
||||
@@ -103,4 +126,125 @@ public abstract class JBValue {
|
||||
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 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get() {
|
||||
return ROUND.round(cachedScaledValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat() {
|
||||
return cachedScaledValue;
|
||||
}
|
||||
|
||||
public void cache() {
|
||||
cachedScaledValue = JBUI.scale(getUnscaled());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CachedFloat with a dedicated UpdateTracker.
|
||||
*/
|
||||
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>();
|
||||
private final PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
for (Cacheable value : list) value.cache();
|
||||
}
|
||||
};
|
||||
|
||||
public UpdateTracker() {
|
||||
JBUI.addPropertyChangeListener(JBUI.USER_SCALE_FACTOR_PROPERTY, listener);
|
||||
}
|
||||
|
||||
public void track(Cacheable value) {
|
||||
list.add(value);
|
||||
}
|
||||
|
||||
public void forget(Cacheable value) {
|
||||
list.remove(value);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
JBUI.removePropertyChangeListener(JBUI.USER_SCALE_FACTOR_PROPERTY, listener);
|
||||
list.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user