redo with new anti-GLucose
[SugarCubes.git] / UIImplementation.pde
index 0ea8073ddb57d6701a6a0a1b55df6fc88c89bbe8..7750ab930c365a3322d635b6f82728483f0bca7c 100644 (file)
  *
  * Custom UI components using the framework.
  */
-class UIPatternDeck extends UIWindow {
-    
-  LXDeck deck;
-  
-  public UIPatternDeck(LXDeck deck, String label, float x, float y, float w, float h) {
-    super(label, x, y, w, h);
-    this.deck = deck;
-    int yp = titleHeight;
-        
-    List<ScrollItem> items = new ArrayList<ScrollItem>();
-    for (LXPattern p : deck.getPatterns()) {
-      items.add(new PatternScrollItem(p));
-    }    
-    final UIScrollList patternList = new UIScrollList(1, yp, w-2, 140).setItems(items);
-    patternList.addToContainer(this);
-    yp += patternList.h + 10;
-    
-    final UIParameterKnob[] parameterKnobs = new UIParameterKnob[12];
-    for (int ki = 0; ki < parameterKnobs.length; ++ki) {
-      parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
-      parameterKnobs[ki].addToContainer(this);
+import java.util.Arrays;
+class UICubesLayer extends UICameraComponent {
+  void onDraw(UI ui) {
+    color[] simulationColors = lx.getColors();
+    String displayMode = uiCrossfader.getDisplayMode();
+    if (displayMode == "A") {
+      simulationColors = lx.engine.getDeck(LEFT_DECK).getColors();
+    } else if (displayMode == "B") {
+      simulationColors = lx.engine.getDeck(RIGHT_DECK).getColors();
     }
+
+    long simulationStart = System.nanoTime();
+    if (simulationOn) {
+      drawSimulation(simulationColors);
+    }
+    simulationNanos = System.nanoTime() - simulationStart;
     
-    LXDeck.Listener lxListener = new LXDeck.AbstractListener() {
-      public void patternWillChange(LXDeck deck, LXPattern pattern, LXPattern nextPattern) {
-        patternList.redraw();
-      }
-      public void patternDidChange(LXDeck deck, LXPattern pattern) {
-        patternList.redraw();
-        int pi = 0;
-        for (LXParameter parameter : pattern.getParameters()) {
-          if (pi >= parameterKnobs.length) {
-            break;
-          }
-          parameterKnobs[pi++].setParameter(parameter);
-        }
-        while (pi < parameterKnobs.length) {
-          parameterKnobs[pi++].setParameter(null);
-        }
-      }
-    };
-    
-    deck.addListener(lxListener);
-    lxListener.patternDidChange(deck, deck.getActivePattern());
-    
+    camera();
+    PGraphicsOpenGL gl = (PGraphicsOpenGL) g;  
+    strokeWeight(1);
   }
   
-  class PatternScrollItem extends AbstractScrollItem {
-    
-    private LXPattern pattern;
-    private String label;
-    
-    PatternScrollItem(LXPattern pattern) {
-      this.pattern = pattern;
-      label = className(pattern, "Pattern");
-    }
-    
-    public String getLabel() {
-      return label;
-    }
-    
-    public boolean isSelected() {
-      return deck.getActivePattern() == pattern;
-    }
+  void drawSimulation(color[] simulationColors) {
+    translate(0, 30, 0);
+  
+    noStroke();
+    fill(#141414);
+    drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.);
+    fill(#070707);
+    stroke(#222222);
+    beginShape();
+    vertex(0, 0, 0);
+    vertex(TRAILER_WIDTH, 0, 0);
+    vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH);
+    vertex(0, 0, TRAILER_DEPTH);
+    endShape();
+  
+    // Draw the logo on the front of platform  
+    pushMatrix();
+    translate(0, 0, -1);
+    float s = .07;
+    scale(s, -s, s);
+    image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s);
+    popMatrix();
     
-    public boolean isPending() {
-      return deck.getNextPattern() == pattern;
+    noStroke();
+    for (Cube c : model.cubes) {
+      drawCube(c);
     }
-    
-    public void onMousePressed() {
-      deck.goPattern(pattern);
+  
+    noFill();
+    strokeWeight(2);
+    beginShape(POINTS);
+    for (LXPoint p : model.points) {
+      stroke(simulationColors[p.index]);
+      vertex(p.x, p.y, p.z);
+    }
+    endShape();
+  }
+  
+  void drawCube(Cube c) {
+    float in = .15;
+    noStroke();
+    fill(#393939);  
+    drawBox(c.x+in, c.y+in, c.z+in, c.rx, c.ry, c.rz, Cube.EDGE_WIDTH-in*2, Cube.EDGE_HEIGHT-in*2, Cube.EDGE_WIDTH-in*2, Cube.CHANNEL_WIDTH-in);
+  }
+  
+  void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) {
+    pushMatrix();
+    translate(x, y, z);
+    rotate(rx / 180. * PI, -1, 0, 0);
+    rotate(ry / 180. * PI, 0, -1, 0);
+    rotate(rz / 180. * PI, 0, 0, -1);
+    for (int i = 0; i < 4; ++i) {
+      float wid = (i % 2 == 0) ? xd : zd;
+      
+      beginShape();
+      vertex(0, 0);
+      vertex(wid, 0);
+      vertex(wid, yd);
+      vertex(wid - sw, yd);
+      vertex(wid - sw, sw);
+      vertex(0, sw);
+      endShape();
+      beginShape();
+      vertex(0, sw);
+      vertex(0, yd);
+      vertex(wid - sw, yd);
+      vertex(wid - sw, yd - sw);
+      vertex(sw, yd - sw);
+      vertex(sw, sw);
+      endShape();
+  
+      translate(wid, 0, 0);
+      rotate(HALF_PI, 0, -1, 0);
     }
+    popMatrix();
   }
 }
 
 class UIBlendMode extends UIWindow {
   public UIBlendMode(float x, float y, float w, float h) {
-    super("BLEND MODE", x, y, w, h);
-    List<ScrollItem> items = new ArrayList<ScrollItem>();
-    for (LXTransition t : glucose.getTransitions()) {
+    super(lx.ui, "BLEND MODE", x, y, w, h);
+    List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
+    for (LXTransition t : transitions) {
       items.add(new TransitionScrollItem(t));
     }
     final UIScrollList tList;
-    (tList = new UIScrollList(1, titleHeight, w-2, 60)).setItems(items).addToContainer(this);
+    (tList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 60)).setItems(items).addToContainer(this);
 
-    lx.engine.getDeck(GLucose.RIGHT_DECK).addListener(new LXDeck.AbstractListener() {
+    lx.engine.getDeck(RIGHT_DECK).addListener(new LXDeck.AbstractListener() {
       public void faderTransitionDidChange(LXDeck deck, LXTransition transition) {
         tList.redraw();
       }
     });
   }
 
-  class TransitionScrollItem extends AbstractScrollItem {
+  class TransitionScrollItem extends UIScrollList.AbstractItem {
     private final LXTransition transition;
-    private String label;
+    private final String label;
     
     TransitionScrollItem(LXTransition transition) {
       this.transition = transition;
-      label = className(transition, "Transition");
+      this.label = className(transition, "Transition");
     }
     
     public String getLabel() {
@@ -117,7 +141,7 @@ class UIBlendMode extends UIWindow {
     }
     
     public boolean isSelected() {
-      return transition == glucose.getSelectedTransition();
+      return this.transition == lx.engine.getDeck(RIGHT_DECK).getFaderTransition();
     }
     
     public boolean isPending() {
@@ -125,7 +149,7 @@ class UIBlendMode extends UIWindow {
     }
     
     public void onMousePressed() {
-      glucose.setSelectedTransition(transition);
+      lx.engine.getDeck(RIGHT_DECK).setFaderTransition(this.transition);
     }
   }
 
@@ -136,10 +160,10 @@ class UICrossfader extends UIWindow {
   private final UIToggleSet displayMode;
   
   public UICrossfader(float x, float y, float w, float h) {
-    super("CROSSFADER", x, y, w, h);
+    super(lx.ui, "CROSSFADER", x, y, w, h);
 
-    new UIParameterSlider(4, titleHeight, w-9, 32).setParameter(lx.engine.getDeck(GLucose.RIGHT_DECK).getFader()).addToContainer(this);
-    (displayMode = new UIToggleSet(4, titleHeight + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this);
+    new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-9, 32).setParameter(lx.engine.getDeck(RIGHT_DECK).getFader()).addToContainer(this);
+    (displayMode = new UIToggleSet(4, UIWindow.TITLE_LABEL_HEIGHT + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this);
   }
   
   public UICrossfader setDisplayMode(String value) {
@@ -154,31 +178,34 @@ class UICrossfader extends UIWindow {
 
 class UIEffects extends UIWindow {
   UIEffects(float x, float y, float w, float h) {
-    super("FX", x, y, w, h);
+    super(lx.ui, "FX", x, y, w, h);
 
-    int yp = titleHeight;
-    List<ScrollItem> items = new ArrayList<ScrollItem>();
-    for (LXEffect fx : glucose.lx.getEffects()) {
-      items.add(new FXScrollItem(fx));
+    int yp = UIWindow.TITLE_LABEL_HEIGHT;
+    List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
+    int i = 0;
+    for (LXEffect fx : effectsArr) {
+      items.add(new FXScrollItem(fx, i++));
     }    
     final UIScrollList effectsList = new UIScrollList(1, yp, w-2, 60).setItems(items);
     effectsList.addToContainer(this);
-    yp += effectsList.h + 10;
+    yp += effectsList.getHeight() + 10;
     
-    final UIParameterKnob[] parameterKnobs = new UIParameterKnob[4];
+    final UIKnob[] parameterKnobs = new UIKnob[4];
     for (int ki = 0; ki < parameterKnobs.length; ++ki) {
-      parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
+      parameterKnobs[ki] = new UIKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
       parameterKnobs[ki].addToContainer(this);
     }
     
-    GLucose.EffectListener fxListener = new GLucose.EffectListener() {
-      public void effectSelected(LXEffect effect) {
+    LXParameterListener fxListener = new LXParameterListener() {
+      public void onParameterChanged(LXParameter parameter) {
         int i = 0;
-        for (LXParameter p : effect.getParameters()) {
+        for (LXParameter p : getSelectedEffect().getParameters()) {
           if (i >= parameterKnobs.length) {
             break;
           }
-          parameterKnobs[i++].setParameter(p);
+          if (p instanceof BasicParameter) {
+            parameterKnobs[i++].setParameter((BasicParameter) p);
+          }
         }
         while (i < parameterKnobs.length) {
           parameterKnobs[i++].setParameter(null);
@@ -186,19 +213,21 @@ class UIEffects extends UIWindow {
       }
     };
     
-    glucose.addEffectListener(fxListener);
-    fxListener.effectSelected(glucose.getSelectedEffect());
+    selectedEffect.addListener(fxListener);
+    fxListener.onParameterChanged(null);
 
   }
   
-  class FXScrollItem extends AbstractScrollItem {
+  class FXScrollItem extends UIScrollList.AbstractItem {
     
-    private LXEffect effect;
-    private String label;
+    private final LXEffect effect;
+    private final int index;
+    private final String label;
     
-    FXScrollItem(LXEffect effect) {
+    FXScrollItem(LXEffect effect, int index) {
       this.effect = effect;
-      label = className(effect, "Effect");
+      this.index = index;
+      this.label = className(effect, "Effect");
     }
     
     public String getLabel() {
@@ -206,7 +235,7 @@ class UIEffects extends UIWindow {
     }
     
     public boolean isSelected() {
-      return !effect.isEnabled() && (glucose.getSelectedEffect() == effect);
+      return !effect.isEnabled() && (effect == getSelectedEffect());
     }
     
     public boolean isPending() {
@@ -214,14 +243,14 @@ class UIEffects extends UIWindow {
     }
     
     public void onMousePressed() {
-      if (glucose.getSelectedEffect() == effect) {
+      if (effect == getSelectedEffect()) {
         if (effect.isMomentary()) {
           effect.enable();
         } else {
           effect.toggle();
         }
       } else {
-        glucose.setSelectedEffect(effect);
+        selectedEffect.setValue(index);
       }
     }
     
@@ -236,17 +265,17 @@ class UIEffects extends UIWindow {
 }
 
 class UIOutput extends UIWindow {
-  public UIOutput(float x, float y, float w, float h) {
-    super("OUTPUT", x, y, w, h);
-    float yp = titleHeight;
+  public UIOutput(GrizzlyOutput[] grizzlies, float x, float y, float w, float h) {
+    super(lx.ui, "OUTPUT", x, y, w, h);
+    float yp = UIWindow.TITLE_LABEL_HEIGHT;
     
-    final UIScrollList outputs = new UIScrollList(1, titleHeight, w-2, 80);
+    final UIScrollList outputs = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 80);
     
-    List<ScrollItem> items = new ArrayList<ScrollItem>();
-    for (final PandaDriver panda : pandaBoards) {
-      items.add(new PandaScrollItem(panda));
-      panda.setListener(new PandaDriver.Listener() {
-        public void onToggle(boolean active) {
+    List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
+    for (GrizzlyOutput grizzly : grizzlies) {
+      items.add(new GrizzlyScrollItem(grizzly));
+      grizzly.enabled.addListener(new LXParameterListener() {
+        public void onParameterChanged(LXParameter parameter) {
            outputs.redraw();
         }
       });
@@ -254,22 +283,23 @@ class UIOutput extends UIWindow {
     outputs.setItems(items).addToContainer(this);
   } 
  
-  class PandaScrollItem extends AbstractScrollItem {
-    final PandaDriver panda;
-    PandaScrollItem(PandaDriver panda) {
-      this.panda = panda;
+  class GrizzlyScrollItem extends UIScrollList.AbstractItem {
+    final GrizzlyOutput output;
+
+    GrizzlyScrollItem(GrizzlyOutput output) {
+      this.output = output;
     }
     
     public String getLabel() {
-      return panda.ip;
+      return output.ipAddress;
     }
     
     public boolean isSelected() {
-      return panda.isEnabled();
+      return output.enabled.isOn();
     }
     
     public void onMousePressed() {
-      panda.toggle();
+      output.enabled.setValue(!isSelected());
     }
   } 
 }
@@ -279,8 +309,8 @@ class UITempo extends UIWindow {
   private final UIButton tempoButton;
   
   UITempo(float x, float y, float w, float h) {
-    super("TEMPO", x, y, w, h);
-    tempoButton = new UIButton(4, titleHeight, w-10, 20) {
+    super(lx.ui, "TEMPO", x, y, w, h);
+    tempoButton = new UIButton(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20) {
       protected void onToggle(boolean active) {
         if (active) {
           lx.tempo.tap();
@@ -288,17 +318,26 @@ class UITempo extends UIWindow {
       }
     }.setMomentary(true);
     tempoButton.addToContainer(this);
+    new UITempoBlipper(8, UIWindow.TITLE_LABEL_HEIGHT + 5, 12, 12).addToContainer(this);
   }
   
-  public void draw() {
-    tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.);
-    super.draw();
+  class UITempoBlipper extends UIObject {
+    UITempoBlipper(float x, float y, float w, float h) {
+      super(x, y, w, h);
+    }
     
-    // Overlay tempo thing with openGL, redraw faster than button UI
-    fill(color(0, 0, 24 - 8*lx.tempo.rampf()));
-    noStroke();
-    rect(x + 8, y + titleHeight + 5, 12, 12);
+    void onDraw(UI ui, PGraphics pg) {
+      tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.);
+    
+      // Overlay tempo thing with openGL, redraw faster than button UI
+      pg.fill(color(0, 0, 24 - 8*lx.tempo.rampf()));
+      pg.noStroke();
+      pg.rect(0, 0, width, height);
+      
+      redraw();
+    }
   }
+  
 }
 
 class UIMapping extends UIWindow {
@@ -318,10 +357,10 @@ class UIMapping extends UIWindow {
   private final UIIntegerBox stripBox;
   
   UIMapping(MappingTool tool, float x, float y, float w, float h) {
-    super("MAPPING", x, y, w, h);
+    super(lx.ui, "MAPPING", x, y, w, h);
     mappingTool = tool;
     
-    int yp = titleHeight;
+    int yp = UIWindow.TITLE_LABEL_HEIGHT;
     new UIToggleSet(4, yp, w-10, 20) {
       protected void onToggle(String value) {
         if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL;
@@ -345,12 +384,12 @@ class UIMapping extends UIWindow {
       protected void onValueChange(int value) {
         mappingTool.setCube(value-1);
       }
-    }).setRange(1, glucose.model.cubes.size()).addToContainer(this);
+    }).setRange(1, model.cubes.size()).addToContainer(this);
     yp += 24;
     
     yp += 10;
         
-    new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new ScrollItem[] {
+    new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new UIScrollList.Item[] {
       new ColorScrollItem(ColorScrollItem.COLOR_RED),
       new ColorScrollItem(ColorScrollItem.COLOR_GREEN),
       new ColorScrollItem(ColorScrollItem.COLOR_BLUE),
@@ -392,7 +431,7 @@ class UIMapping extends UIWindow {
     stripBox.setValue(value);
   }
   
-  class ColorScrollItem extends AbstractScrollItem {
+  class ColorScrollItem extends UIScrollList.AbstractItem {
     
     public static final int COLOR_RED = 1;
     public static final int COLOR_GREEN = 2;
@@ -438,7 +477,7 @@ class UIDebugText extends UIContext {
   private String line2 = "";
   
   UIDebugText(float x, float y, float w, float h) {
-    super(x, y, w, h);
+    super(lx.ui, x, y, w, h);
   }
 
   public UIDebugText setText(String line1) {
@@ -455,13 +494,13 @@ class UIDebugText extends UIContext {
     return this;
   }
   
-  protected void onDraw(PGraphics pg) {
-    super.onDraw(pg);
+  protected void onDraw(UI ui, PGraphics pg) {
+    super.onDraw(ui, pg);
     if (line1.length() + line2.length() > 0) {
       pg.noStroke();
       pg.fill(#444444);
-      pg.rect(0, 0, w, h);
-      pg.textFont(defaultItemFont);
+      pg.rect(0, 0, width, height);
+      pg.textFont(ui.getItemFont());
       pg.textSize(10);
       pg.textAlign(LEFT, TOP);
       pg.fill(#cccccc);
@@ -476,14 +515,14 @@ class UISpeed extends UIWindow {
   final BasicParameter speed;
   
   UISpeed(float x, float y, float w, float h) {
-    super("SPEED", x, y, w, h);
+    super(lx.ui, "SPEED", x, y, w, h);
     speed = new BasicParameter("SPEED", 0.5);
-    new UIParameterSlider(4, titleHeight, w-10, 20)
-    .setParameter(speed.addListener(new LXParameterListener() {
+    speed.addListener(new LXParameterListener() {
       public void onParameterChanged(LXParameter parameter) {
         lx.setSpeed(parameter.getValuef() * 2);
       }
-    })).addToContainer(this);
+    });
+    new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20).setParameter(speed).addToContainer(this);
   }
 }
 
@@ -493,15 +532,15 @@ class UIMidi extends UIWindow {
   private final UIButton logMode;
   
   UIMidi(final MidiEngine midiEngine, float x, float y, float w, float h) {
-    super("MIDI", x, y, w, h);
+    super(lx.ui, "MIDI", x, y, w, h);
 
     // Processing compiler doesn't seem to get that list of class objects also conform to interface
-    List<ScrollItem> scrollItems = new ArrayList<ScrollItem>();
+    List<UIScrollList.Item> scrollItems = new ArrayList<UIScrollList.Item>();
     for (SCMidiInput mc : midiEngine.getControllers()) {
       scrollItems.add(mc);
     }
     final UIScrollList scrollList;
-    (scrollList = new UIScrollList(1, titleHeight, w-2, 100)).setItems(scrollItems).addToContainer(this);
+    (scrollList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 100)).setItems(scrollItems).addToContainer(this);
     (deckMode = new UIToggleSet(4, 130, 90, 20) {
       protected void onToggle(String value) {
         midiEngine.setFocusedDeck(value == "A" ? 0 : 1);
@@ -531,7 +570,7 @@ class UIMidi extends UIWindow {
   }
   
   public LXDeck getFocusedDeck() {
-    return lx.engine.getDeck(deckMode.getValue() == "A" ? GLucose.LEFT_DECK : GLucose.RIGHT_DECK);
+    return lx.engine.getDeck(deckMode.getValue() == "A" ? LEFT_DECK : RIGHT_DECK);
   }
 }