/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package automenta.spacenet.space.widget; import automenta.spacenet.run.DemoDefaults; import automenta.spacenet.space.Space; import automenta.spacenet.space.control.Pressable; import automenta.spacenet.space.control.Zoomable; import automenta.spacenet.space.geom.Box; import automenta.spacenet.space.geom.Rect; import automenta.spacenet.space.geom.layout.ColRect; import automenta.spacenet.space.geom.layout.RowRect; import automenta.spacenet.space.geom.text3d.Font3D; import automenta.spacenet.space.surface.ColorSurface; import automenta.spacenet.space.widget.button.Button; import automenta.spacenet.space.widget.button.ButtonAction; import automenta.spacenet.space.widget.knob.CircleKnob; import automenta.spacenet.space.widget.panel.Panel; import automenta.spacenet.var.physical.Color; import automenta.spacenet.var.scalar.DoubleVar; import automenta.spacenet.var.scalar.DoubleVar.IfDoubleChanges; import com.ardor3d.intersection.PickData; import com.ardor3d.scenegraph.Spatial; /** * an empty fillable box surrounded by control widgets. * ex: control window icon expanders on each of the 8 corners of the box */ public class MetaBox extends Box { private final Space content; class IconExpander extends Box { private final Space content; private boolean expanded = false; private final IconExpanderBox iconBox; class IconExpanderBox extends Box implements Pressable, Zoomable { public IconExpanderBox() { super(BoxShape.Cubic); } @Override public void onPressStart(PickData pick) { } @Override public void onPressStop(PickData pick) { setExpanded(!isExpanded()); } @Override public boolean isTangible() { return true; } @Override public void onZoomStart() { } @Override public void onZoomStop() { } @Override public boolean isZoomable() { return true; } } double dz = 1.0; public IconExpander(Space content) { super(BoxShape.Empty); this.content = content; iconBox = add(new IconExpanderBox()); iconBox.color(Color.White); setExpanded(false); } public boolean isExpanded() { return expanded; } public synchronized void setExpanded(boolean e) { this.expanded = e; if (e) { iconBox.move(0, 0, -dz); add(content); } else { remove(content); iconBox.move(0, 0, 0); } } } //TODO abstract this into pluggalbe MetaBoxModel public MetaBox(Space content) { super(BoxShape.Empty); this.content = add(content); //TODO move this into a pluggable model for (double x = -0.5; x <= 0.5; x += 1.0) { for (double y = -0.5; y <= 0.5; y += 1.0) { for (double z = -0.5; z <= 0.5; z += 1.0) { Panel p = newControlPanel(); p.scale(4.0); add(new IconExpander(p).move(x, y, z).face(x, y, z).scale(0.05)); } } } } //TODO make this a pluggable model protected Panel newControlPanel() { final Panel p = new Panel() { boolean initializedPanel = false; @Override protected void afterAttached(Spatial newParent) { super.afterAttached(newParent); if (!initializedPanel) { initialize(); } } protected synchronized void initialize() { Font3D font = DemoDefaults.font; CircleKnob rotate1 = new CircleKnob(new ColorSurface(Color.GrayMinusMinus), new ColorSurface(Color.Purple)); rotate1.getAngle().add(new IfDoubleChanges() { @Override public void onDoubleChange(DoubleVar d) { rotateContent(d.d(), 0, 0); } }); CircleKnob rotate2 = new CircleKnob(new ColorSurface(Color.GrayMinusMinus), new ColorSurface(Color.Blue)); rotate2.getAngle().add(new IfDoubleChanges() { @Override public void onDoubleChange(DoubleVar d) { rotateContent(0, d.d(), 0); } }); //TODO replace with scale Spinner Button grow = new Button(font, "+"); grow.add(new ButtonAction() { @Override public void onButtonClicked(Button b) { MetaBox.this.getSize().multiplyLocal(1.5); } }); Button shrink = new Button(font, "-"); shrink.add(new ButtonAction() { @Override public void onButtonClicked(Button b) { MetaBox.this.getSize().multiplyLocal(0.7); } }); final Panel p = this; Button closeButton = new Button(font, "X"); closeButton.add(new ButtonAction() { @Override public void onButtonClicked(Button b) { //HACK find a better way to do this ((IconExpander)p.getParent()).setExpanded(false); } }); Button delete = new Button(font, "Delete"); delete.add(new ButtonAction() { @Override public void onButtonClicked(Button b) { close(); } }); add(new ColRect(0.1, new RowRect(0.1, rotate1, rotate2), new RowRect(0.1, grow, shrink), new RowRect(0.1, delete))).moveDZ(0.05); add(closeButton).span(0.5, 0.5, 0.6, 0.6); initializedPanel = true; } }; return p; } double contentR1 = 0; double contentR2 = 0; double contentR3 = 0; protected void rotateContent(double dr1, double dr2, double dr3) { if (dr1!=0) contentR1 = dr1; if (dr2!=0) contentR2 = dr2; if (dr3!=0) contentR3 = dr3; //TODO use interface Rotateable3 if (content instanceof Box) { ((Box) content).rotate(contentR1, contentR2, contentR3); } else if (content instanceof Rect) { ((Rect) content).rotate(contentR1, contentR2, contentR3); } } public void close() { getParent().detachChild(this); } }