/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package automenta.spacenet.space.widget.spinner;
import automenta.spacenet.space.Repeat;
import automenta.spacenet.space.geom.text3d.Font3D;
import automenta.spacenet.space.geom.text3d.Text3D;
import automenta.spacenet.space.widget.button.Button;
import automenta.spacenet.space.widget.panel.Panel;
import automenta.spacenet.var.physical.Color;
import automenta.spacenet.var.scalar.DoubleRange;
import automenta.spacenet.var.scalar.DoubleVar;
import automenta.spacenet.var.scalar.DoubleVar.IfDoubleChanges;
import com.ardor3d.intersection.PickData;
import com.ardor3d.scenegraph.Spatial;
import java.text.DecimalFormat;
/**
* TODO spin up & down according to how long the buttons are pressed (not per click)
* @author seh
*/
public class Spinner extends Panel implements IfDoubleChanges {
protected final Button upButton;
protected final Button downButton;
protected final Text3D numberButton;
public final DoubleRange range;
public final DoubleVar increment;
private Color textColor = Color.Black;
private Repeat accel;
private DoubleVar spinPeriod = new DoubleVar(0.25);
DecimalFormat dec = new DecimalFormat("###.##");
public class SpinButton extends Button {
private final int direction;
public SpinButton(Font3D font, String label, int direction) {
super(font, label);
this.direction = direction;
}
@Override public void onPressStart(PickData pick) {
startAccel(direction);
}
@Override public void onPressStop(PickData pick) {
stopAccel();
}
}
public Spinner(Font3D font, DoubleRange range, double increment) {
this(font, range, new DoubleVar(increment));
}
public Spinner(Font3D font, DoubleRange range, DoubleVar increment) {
super();
this.range = range;
this.increment = increment;
//TODO trigger change on range.getValue() changes
//Rect r = add(new Rect(RectShape.Empty));
//r.scale(0.85);
upButton = add(new SpinButton(font, "^", 1));
// upButton.add(new ButtonAction() {
//
// @Override public void onButtonClicked(Button b) {
// spin(+1);
// }
// });
downButton = add(new SpinButton(font, "v", -1));
// downButton.add(new ButtonAction() {
//
// @Override public void onButtonClicked(Button b) {
// spin(-1);
// }
// });
numberButton = add(new Text3D(font, "0.0"));
arrange();
}
@Override public void onDoubleChange(DoubleVar d) {
valueChanged();
}
protected void arrange() {
upButton.span(0.25, 0, 0.5, 0.5).moveDZ(0.1);
downButton.span(0.25, 0, 0.5, -0.5).moveDZ(0.1);
numberButton.span(-0.5, 0.5, 0.25, -0.5).moveDZ(0.1);
numberButton.color(textColor);
}
protected void startAccel(final int direction) {
if (accel != null) {
stopAccel();
}
accel = add(new Repeat(getSpinPeriod().d()) {
@Override protected void update(double t, double dt, Spatial s) {
spin(direction);
}
});
}
@Override
protected void afterAttached(Spatial newParent) {
super.afterAttached(newParent);
getValue().add((IfDoubleChanges)this);
valueChanged();
}
@Override
protected void beforeDetached(Spatial parent) {
stopAccel();
getValue().remove((IfDoubleChanges)this);
super.beforeDetached(parent);
}
public DoubleVar getSpinPeriod() {
return spinPeriod;
}
protected void stopAccel() {
remove(accel);
accel = null;
}
protected void spin(int direction) {
double change = getIncrement().d() * ((double) direction);
double nextValue = getValue().d() + change;
nextValue = Math.min(nextValue, getMax().d());
nextValue = Math.max(nextValue, getMin().d());
getValue().set(nextValue);
}
protected void valueChanged() {
String ds = dec.format(getValue().d()); //Double.toString(getValue().d());
numberButton.setText(ds);
}
public DoubleVar getMin() {
return range.getMin();
}
public DoubleVar getMax() {
return range.getMax();
}
public DoubleVar getValue() {
return range.getValue();
}
public DoubleVar getIncrement() {
return increment;
}
}