/* ******************************************************************************
* Copyright (c) 2014 - 2015 Fabian Prasser.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Fabian Prasser - initial API and implementation
******************************************************************************/
package de.linearbits.swt.widgets;
/**
* A range for SWTKnob
* @author Fabian Prasser
*
* @param <T>
*/
public abstract class KnobRange<T> {
/**
* A char range
*
* @author Fabian Prasser
*/
public static class Character extends KnobRange<java.lang.Character> {
/**
* Default constructor. Range is Character.MIN_VALUE -
* Character.MAX_VALUE
*
* @param minimum
* @param maximum
*/
public Character() {
this(java.lang.Character.MIN_VALUE, java.lang.Character.MAX_VALUE);
}
/**
* Defines minimum and maximum values
*
* @param minimum
* @param maximum
*/
public Character(java.lang.Character minimum, java.lang.Character maximum) {
super(minimum, maximum);
if (minimum >= maximum) {
throw new IllegalArgumentException("Minimum (" + minimum + ") must be < maximum (" + maximum + ")");
}
}
@Override
protected double getStepping() {
return toInternal((char)(minimum + 1)) - toInternal(minimum);
}
@Override
protected java.lang.Character toExternal(double value) {
return (char) Math.round(((double) value * ((double)maximum - (double)minimum) + (double) minimum));
}
@Override
protected double toInternal(java.lang.Character value) {
if (value < minimum) {
throw new IllegalArgumentException("Value (" + value + ") must be >= minimum (" + minimum + ")");
} else if (value > maximum) {
throw new IllegalArgumentException("Value (" + value + ") must be <= maximum (" + maximum + ")");
}
return ((double)value - (double)minimum) / ((double)maximum - (double)minimum);
}
@Override
protected double toNearestInternal(double value) {
char extValue = toExternal(value);
return ((double)extValue - (double)minimum) / ((double)maximum - (double)minimum);
}
}
/**
* A double range
*
* @author Fabian Prasser
*/
public static class Double extends KnobRange<java.lang.Double> {
/**
* Default constructor. Range is -Double.MAX_VALUE - Double.MAX_VALUE
*
* @param minimum
* @param maximum
*/
public Double() {
this(-java.lang.Double.MAX_VALUE, java.lang.Double.MAX_VALUE);
}
/**
* Defines minimum and maximum values
*
* @param minimum
* @param maximum
*/
public Double(java.lang.Double minimum, java.lang.Double maximum) {
super(minimum, maximum);
if (minimum >= maximum) {
throw new IllegalArgumentException("Minimum (" + minimum + ") must be < maximum (" + maximum + ")");
}
}
@Override
protected double getStepping() {
return 0;
}
@Override
protected java.lang.Double toExternal(double value) {
return value * (maximum - minimum) + minimum;
}
@Override
protected double toInternal(java.lang.Double value) {
if (value < minimum) {
throw new IllegalArgumentException("Value (" + value + ") must be >= minimum (" + minimum + ")");
} else if (value > maximum) {
throw new IllegalArgumentException("Value (" + value + ") must be <= maximum (" + maximum + ")");
}
return (value - minimum) / (maximum - minimum);
}
@Override
protected double toNearestInternal(double value) {
return value;
}
}
/**
* A float range
*
* @author Fabian Prasser
*/
public static class Float extends KnobRange<java.lang.Float> {
/**
* Default constructor. Range is Float.MIN_VALUE - Float.MAX_VALUE
*
* @param minimum
* @param maximum
*/
public Float() {
this(java.lang.Float.MIN_VALUE, java.lang.Float.MAX_VALUE);
}
/**
* Defines minimum and maximum values
*
* @param minimum
* @param maximum
*/
public Float(java.lang.Float minimum, java.lang.Float maximum) {
super(minimum, maximum);
if (minimum >= maximum) {
throw new IllegalArgumentException("Minimum (" + minimum + ") must be < maximum (" + maximum + ")");
}
}
@Override
protected double getStepping() {
return 0;
}
@Override
protected java.lang.Float toExternal(double value) {
return (float) ((double) value * ((double)maximum - (double)minimum) + (double) minimum);
}
@Override
protected double toInternal(java.lang.Float value) {
if (value < minimum) {
throw new IllegalArgumentException("Value (" + value + ") must be >= minimum (" + minimum + ")");
} else if (value > maximum) {
throw new IllegalArgumentException("Value (" + value + ") must be <= maximum (" + maximum + ")");
}
return ((double)value - (double)minimum) / ((double)maximum - (double)minimum);
}
@Override
protected double toNearestInternal(double value) {
return value;
}
}
/**
* An integer range
*
* @author Fabian Prasser
*/
public static class Integer extends KnobRange<java.lang.Integer> {
/**
* Default constructor. Range is Integer.MIN_VALUE - Integer.MAX_VALUE
*
* @param minimum
* @param maximum
*/
public Integer() {
this(java.lang.Integer.MIN_VALUE, java.lang.Integer.MAX_VALUE);
}
/**
* Defines minimum and maximum values
*
* @param minimum
* @param maximum
*/
public Integer(java.lang.Integer minimum, java.lang.Integer maximum) {
super(minimum, maximum);
if (minimum >= maximum) {
throw new IllegalArgumentException("Minimum (" + minimum + ") must be < maximum (" + maximum + ")");
}
}
@Override
protected double getStepping() {
return toInternal(minimum + 1) - toInternal(minimum);
}
@Override
protected java.lang.Integer toExternal(double value) {
return (int) Math.round(((double) value * ((double)maximum - (double)minimum) + (double) minimum));
}
@Override
protected double toInternal(java.lang.Integer value) {
if (value < minimum) {
throw new IllegalArgumentException("Value (" + value + ") must be >= minimum (" + minimum + ")");
} else if (value > maximum) {
throw new IllegalArgumentException("Value (" + value + ") must be <= maximum (" + maximum + ")");
}
return ((double)value - (double)minimum) / ((double)maximum - (double)minimum);
}
@Override
protected double toNearestInternal(double value) {
int extValue = toExternal(value);
return ((double)extValue - (double)minimum) / ((double)maximum - (double)minimum);
}
}
/**
* A long range
*
* @author Fabian Prasser
*/
public static class Long extends KnobRange<java.lang.Long> {
/**
* Default constructor. Range is Long.MIN_VALUE - Long.MAX_VALUE
*
* @param minimum
* @param maximum
*/
public Long() {
this(java.lang.Long.MIN_VALUE, java.lang.Long.MAX_VALUE);
}
/**
* Defines minimum and maximum values
*
* @param minimum
* @param maximum
*/
public Long(java.lang.Long minimum, java.lang.Long maximum) {
super(minimum, maximum);
if (minimum >= maximum) {
throw new IllegalArgumentException("Minimum (" + minimum + ") must be < maximum (" + maximum + ")");
}
}
@Override
protected double getStepping() {
return toInternal(minimum + 1l) - toInternal(minimum);
}
@Override
protected java.lang.Long toExternal(double value) {
return (long) Math.round(((double) value * ((double)maximum - (double)minimum) + (double) minimum));
}
@Override
protected double toInternal(java.lang.Long value) {
if (value < minimum) {
throw new IllegalArgumentException("Value (" + value + ") must be >= minimum (" + minimum + ")");
} else if (value > maximum) {
throw new IllegalArgumentException("Value (" + value + ") must be <= maximum (" + maximum + ")");
}
return ((double)value - (double)minimum) / ((double)maximum - (double)minimum);
}
@Override
protected double toNearestInternal(double value) {
long extValue = toExternal(value);
return ((double)extValue - (double)minimum) / ((double)maximum - (double)minimum);
}
}
/** Minimum sensitivity*/
private static final double MIN_SENSITIVITY = 1000d;
/** Maximum sensitivity*/
private static final double MAX_SENSITIVITY = 10000d;
/** The minimum*/
protected final T minimum;
/** The maximum*/
protected final T maximum;
/**
* Creates a new range
* @param minimum
* @param maximum
*/
protected KnobRange(T minimum, T maximum) {
this.minimum = minimum;
this.maximum = maximum;
}
/**
* Returns the maximum
* @return
*/
public T getMaximum() {
return maximum;
}
/**
* Returns the minimum
* @return
*/
public T getMinimum() {
return minimum;
}
/**
* Returns the sensitivity
* @return
*/
public double getSensitivity() {
double result = (double)(toInternal(maximum) - toInternal(minimum));
result = result < MIN_SENSITIVITY ? MIN_SENSITIVITY : result;
result = result > MAX_SENSITIVITY ? MAX_SENSITIVITY : result;
return result;
}
/**
* Returns the stepping
* @return
*/
protected abstract double getStepping();
/**
* Converts the internal to an external value
* @param value
* @return
*/
protected abstract T toExternal(double value);
/**
* Creates an external value to the internal value
* @param value
* @return
*/
protected abstract double toInternal(T value);
/**
* Returns the nearest internal representation for the given external value
* @param value
* @return
*/
protected abstract double toNearestInternal(double value);
}