improves the "input shape value drag" implementation

This commit is contained in:
hneemann 2021-01-24 15:08:49 +01:00
parent 42c74f3fcc
commit 722abd7436
3 changed files with 69 additions and 45 deletions

View File

@ -15,43 +15,43 @@ public enum IntFormat {
/**
* the default format
*/
def(ValueFormatterDefault.INSTANCE, false),
def(ValueFormatterDefault.INSTANCE),
/**
* decimal
*/
dec(new ValueFormatterDecimal(false), false),
dec(new ValueFormatterDecimal(false)),
/**
* decimal signed
*/
decSigned(new ValueFormatterDecimal(true), true),
decSigned(new ValueFormatterDecimal(true)),
/**
* hex
*/
hex(ValueFormatterHex.INSTANCE, false),
hex(ValueFormatterHex.INSTANCE),
/**
* binary
*/
bin(new ValueFormatterBinary(), false),
bin(new ValueFormatterBinary()),
/**
* octal
*/
oct(new ValueFormatterOctal(), false),
oct(new ValueFormatterOctal()),
/**
* ascii
*/
ascii(new ValueFormatterAscii(), false),
ascii(new ValueFormatterAscii()),
/**
* fixed point
*/
fixed(attributes -> new ValueFormatterFixedPoint(attributes, false), false),
fixed(attributes -> new ValueFormatterFixedPoint(attributes, false)),
/**
* fixed point signed
*/
fixedSigned(attributes -> new ValueFormatterFixedPoint(attributes, true), true),
fixedSigned(attributes -> new ValueFormatterFixedPoint(attributes, true)),
/**
* floating point
*/
floating(new ValueFormatterFloat(), true);
floating(new ValueFormatterFloat());
/**
* The default formatter
@ -63,20 +63,18 @@ public enum IntFormat {
public static final ValueFormatter HEX_FORMATTER = ValueFormatterHex.INSTANCE;
private final Factory factory;
private final boolean signed;
private final boolean dependsOnAttributes;
IntFormat(ValueFormatter instance, boolean signed) {
this(attributes -> instance, signed, false);
IntFormat(ValueFormatter instance) {
this(attributes -> instance, false);
}
IntFormat(Factory factory, boolean signed) {
this(factory, signed, true);
IntFormat(Factory factory) {
this(factory, true);
}
IntFormat(Factory factory, boolean signed, boolean dependsOnAttributes) {
IntFormat(Factory factory, boolean dependsOnAttributes) {
this.factory = factory;
this.signed = signed;
this.dependsOnAttributes = dependsOnAttributes;
}
@ -90,13 +88,6 @@ public enum IntFormat {
return factory.create(attributes);
}
/**
* @return true if this formatter takes the sign of the value into account
*/
public boolean isSigned() {
return signed;
}
/**
* @return true if this type depends on elements attributes
*/
@ -145,6 +136,28 @@ public enum IntFormat {
public boolean isSuitedForAddresses() {
return false; // difficult to read in a table
}
@Override
public long dragValue(long initial, int bits, double inc) {
return dragValueSigned(initial, bits, inc, false);
}
}
private static long dragValueSigned(long initial, int bits, double inc, boolean signed) {
long max;
long min;
if (signed) {
long mask = Bits.mask(bits);
long signedFlag = Bits.signedFlagMask(bits);
if ((initial & signedFlag) != 0) initial |= ~mask;
max = mask >>> 1;
min = -max - 1;
} else {
max = Bits.mask(bits);
min = 0;
}
return Math.max(min, Math.min(max, initial + Math.round(max * inc)));
}
/**
@ -179,6 +192,11 @@ public enum IntFormat {
}
protected abstract String format(Value value);
@Override
public long dragValue(long initial, int bits, double inc) {
return dragValueSigned(initial, bits, inc, false);
}
}
/**
@ -353,6 +371,11 @@ public enum IntFormat {
else
return Long.toString(value.getValue());
}
@Override
public long dragValue(long initial, int bits, double inc) {
return dragValueSigned(initial, bits, inc, signed);
}
}
private static int decStrLen(int bits) {
@ -423,6 +446,11 @@ public enum IntFormat {
else
return Double.toString(inValue.getValue() / divisor);
}
@Override
public long dragValue(long initial, int bits, double inc) {
return dragValueSigned(initial, bits, inc, signed);
}
}
/**
@ -480,8 +508,14 @@ public enum IntFormat {
}
@Override
public boolean isProportional() {
return false;
public long dragValue(long initial, int bits, double inc) {
double dif = Math.signum(inc) * (Math.exp(Math.abs(inc * 10)) - 1);
if (bits == 32)
return Float.floatToIntBits((float) (Float.intBitsToFloat((int) initial) + dif));
else if (bits == 64)
return Double.doubleToLongBits(Double.longBitsToDouble(initial) + dif);
else
return initial;
}
}

View File

@ -46,12 +46,12 @@ public interface ValueFormatter {
boolean isSuitedForAddresses();
/**
* If the represented value is proportional to the underlying integer value.
* This is not the case at float values.
* Moves the given value
*
* @return true if represented valueis proportional to the underlying integer value
* @param initial the initial value
* @param bits the bits used of the initial value
* @param inc the increment, is i between -1 and 1
* @return the modified value
*/
default boolean isProportional() {
return true;
}
long dragValue(long initial, int bits, double inc);
}

View File

@ -38,8 +38,6 @@ public class InputShape implements Shape {
private final ValueFormatter formatter;
private final boolean isHighZ;
private final boolean avoidLow;
private final long min;
private final long max;
private final int bits;
private IOState ioState;
private SingleValueDialog dialog;
@ -68,13 +66,6 @@ public class InputShape implements Shape {
avoidLow = isHighZ && attr.get(Keys.AVOID_ACTIVE_LOW);
bits = attr.getBits();
if (attr.get(Keys.INT_FORMAT).isSigned()) {
max = Bits.mask(bits) >>> 1;
min = -max - 1;
} else {
min = 0;
max = Bits.mask(bits);
}
}
@Override
@ -183,16 +174,15 @@ public class InputShape implements Shape {
@Override
public void dragged(CircuitComponent cc, Point posOnScreen, Vector pos, Transform transform, IOState ioState, Element element, SyncAccess modelSync) {
ObservableValue value = ioState.getOutput(0);
if (bits > 1 && !value.isHighZ() && formatter.isProportional()) {
if (bits > 1 && !value.isHighZ()) {
if (!isDrag) {
isDrag = true;
startPos = posOnScreen;
startValue = value.getValue();
lastValueSet = startValue;
} else {
int delta = startPos.y - posOnScreen.y;
long v = startValue + (delta * max) / SLIDER_HEIGHT;
long val = Math.max(min, Math.min(v, max));
double inc = ((double) (startPos.y - posOnScreen.y)) / SLIDER_HEIGHT;
long val = formatter.dragValue(startValue, value.getBits(), inc);
if (val != lastValueSet) {
modelSync.modify(() -> value.setValue(val));
lastValueSet = val;