Apat and added acos to spherycolor, not included in color yet but working
[SugarCubes.git] / _UIFramework.pde
index 7ed25850346f1a9ce7b67c33e8b9eec17cb5c194..8ecb7e9a59c91e10b0dd683e04b59b1f02909425 100644 (file)
@@ -21,6 +21,8 @@ final PFont defaultTitleFont = createFont("Myriad Pro", 10);
 
 public abstract class UIObject {
   
+  protected final static int DOUBLE_CLICK_THRESHOLD = 300;
+  
   protected final List<UIObject> children = new ArrayList<UIObject>();  
 
   protected boolean needsRedraw = true;
@@ -314,15 +316,39 @@ public class UILabel extends UIObject {
   }
 }
 
+public class UICheckbox extends UIButton {
+  
+  private boolean firstDraw = true;
+  
+  public UICheckbox(float x, float y, float w, float h) {
+    super(x, y, w, h);
+    setMomentary(false);
+  }
+  
+  public void onDraw(PGraphics pg) {
+    pg.stroke(borderColor);
+    pg.fill(active ? activeColor : inactiveColor);
+    pg.rect(0, 0, h, h);
+    if (firstDraw) {
+      pg.fill(labelColor);
+      pg.textFont(defaultItemFont);
+      pg.textAlign(LEFT, CENTER);
+      pg.text(label, h + 4, h/2);
+      firstDraw = false;
+    }
+  }
+      
+}
+
 public class UIButton extends UIObject {
 
-  private boolean active = false;
-  private boolean isMomentary = false;
-  private color borderColor = #666666;
-  private color inactiveColor = #222222;
-  private color activeColor = #669966;
-  private color labelColor = #999999;
-  private String label = "";
+  protected boolean active = false;
+  protected boolean isMomentary = false;
+  protected color borderColor = #666666;
+  protected color inactiveColor = #222222;
+  protected color activeColor = #669966;
+  protected color labelColor = #999999;
+  protected String label = "";
    
   public UIButton(float x, float y, float w, float h) {
     super(x, y, w, h);
@@ -359,6 +385,10 @@ public class UIButton extends UIObject {
     }
   }
   
+  public boolean isActive() {
+    return active;
+  }
+  
   public UIButton setActive(boolean active) {
     this.active = active;
     onToggle(active);
@@ -497,7 +527,7 @@ public class UIToggleSet extends UIObject {
 }
 
 
-public abstract class UIParameterControl extends UIObject implements LXParameter.Listener {
+public abstract class UIParameterControl extends UIObject implements LXParameterListener {
   protected LXParameter parameter = null;
     
   protected UIParameterControl(float x, float y, float w, float h) {
@@ -508,6 +538,27 @@ public abstract class UIParameterControl extends UIObject implements LXParameter
     redraw();
   }
   
+  protected float getNormalized() {
+    if (parameter != null) {
+      if (parameter instanceof BasicParameter) {
+        return ((BasicParameter)parameter).getNormalizedf();
+      }
+      return parameter.getValuef();
+    }
+    return 0;
+  }
+  
+  protected UIParameterControl setNormalized(float value) {
+    if (parameter != null) {
+      if (parameter instanceof BasicParameter) {
+        ((BasicParameter)parameter).setNormalized(value);
+      } else {
+        parameter.setValue(value);
+      }
+    }
+    return this;
+  }
+  
   public UIParameterControl setParameter(LXParameter parameter) {
     if (this.parameter != null) {
       if (this.parameter instanceof LXListenableParameter) {
@@ -529,6 +580,7 @@ public class UIParameterKnob extends UIParameterControl {
   private int knobSize = 28;
   private final float knobIndent = .4;  
   private final int knobLabelHeight = 14;
+  private boolean showValue = false;
     
   public UIParameterKnob(float x, float y) {
     this(x, y, 0, 0);
@@ -540,7 +592,7 @@ public class UIParameterKnob extends UIParameterControl {
   }
 
   protected void onDraw(PGraphics pg) {    
-    float knobValue = (parameter != null) ? parameter.getValuef() : 0;
+    float knobValue = getNormalized();
     
     pg.ellipseMode(CENTER);
     pg.noStroke();
@@ -560,7 +612,12 @@ public class UIParameterKnob extends UIParameterControl {
     pg.fill(#333333);
     pg.ellipse(knobSize/2, knobSize/2, knobSize/2, knobSize/2);
 
-    String knobLabel = (parameter != null) ? parameter.getLabel() : null;
+    String knobLabel;
+    if (showValue) {
+      knobLabel = (parameter != null) ? ("" + parameter.getValue()) : null;
+    } else {
+      knobLabel = (parameter != null) ? parameter.getLabel() : null;
+    }
     if (knobLabel == null) {
       knobLabel = "-";
     } else if (knobLabel.length() > 4) {
@@ -574,11 +631,28 @@ public class UIParameterKnob extends UIParameterControl {
     pg.text(knobLabel, knobSize/2, knobSize + knobLabelHeight - 2);
   }
   
-  public void onMouseDragged(float mx, float my, float dx, float dy) {
-    if (parameter != null) {
-      float value = constrain(parameter.getValuef() - dy / 100., 0, 1);
-      parameter.setValue(value);
+  private long lastMousePress = 0;
+  public void onMousePressed(float mx, float my) {
+    super.onMousePressed(mx, my);
+    long now = millis();
+    if (now - lastMousePress < DOUBLE_CLICK_THRESHOLD) {
+      parameter.reset();
+      lastMousePress = 0;
+    } else {
+      lastMousePress = now;
     }
+    showValue = true;
+    redraw();    
+  }
+  
+  public void onMouseReleased(float mx, float my) {
+    showValue = false;
+    redraw();
+  }
+  
+  public void onMouseDragged(float mx, float my, float dx, float dy) {
+    float value = constrain(getNormalized() - dy / 100., 0, 1);
+    setNormalized(value);
   }
 }
 
@@ -602,11 +676,28 @@ public class UIParameterSlider extends UIParameterControl {
   }
   
   private boolean editing = false;
+  private long lastClick = 0;
+  private float doubleClickMode = 0;
+  private float doubleClickX = 0;
   protected void onMousePressed(float mx, float my) {
-    float handleLeft = 4 + parameter.getValuef() * (w-8-handleWidth);
+    long now = millis();
+    float handleLeft = 4 + getNormalized() * (w-8-handleWidth);
     if (mx >= handleLeft && mx < handleLeft + handleWidth) {
       editing = true;
+    } else {
+      if ((now - lastClick) < DOUBLE_CLICK_THRESHOLD && abs(mx - doubleClickX) < 3) {
+        setNormalized(doubleClickMode);  
+      }
+      doubleClickX = mx;
+      if (mx < w*.25) {
+        doubleClickMode = 0;
+      } else if (mx > w*.75) {
+        doubleClickMode = 1;
+      } else {
+        doubleClickMode = 0.5;
+      }
     }
+    lastClick = now;
   }
   
   protected void onMouseReleased(float mx, float my) {
@@ -615,7 +706,7 @@ public class UIParameterSlider extends UIParameterControl {
   
   protected void onMouseDragged(float mx, float my, float dx, float dy) {
     if (editing) {
-      parameter.setValue(constrain((mx - handleWidth/2. - 4) / (w-8-handleWidth), 0, 1));
+      setNormalized(constrain((mx - handleWidth/2. - 4) / (w-8-handleWidth), 0, 1));
     }
   }
 }
@@ -655,8 +746,11 @@ public class UIScrollList extends UIObject {
         itemColor = pendingColor;
       } else {
         labelColor = #000000;
-        itemColor = even ? #666666 : #777777;
+        itemColor = #707070;
       }
+      float factor = even ? .92 : 1.08;
+      itemColor = lx.scaleBrightness(itemColor, factor);
+      
       pg.noStroke();
       pg.fill(itemColor);
       pg.rect(0, yp, w, itemHeight);
@@ -670,7 +764,7 @@ public class UIScrollList extends UIObject {
     }
     if (hasScroll) {
       pg.noStroke();
-      pg.fill(color(0, 0, 100, 15));
+      pg.fill(0x26ffffff);
       pg.rect(w-12, 0, 12, h);
       pg.fill(#333333);
       pg.rect(w-12, scrollYStart, 12, scrollYHeight);
@@ -693,7 +787,6 @@ public class UIScrollList extends UIObject {
       if (scrollOffset + index < items.size()) {
         pressedItem = items.get(scrollOffset + index);
         pressedItem.onMousePressed();
-        pressedItem.select();
         redraw();
       }
     }
@@ -731,9 +824,9 @@ public class UIScrollList extends UIObject {
   }
   
   public void setScrollOffset(int offset) {
-    scrollOffset = constrain(offset, 0, items.size() - numVisibleItems);
-    scrollYStart = (int) (scrollOffset * h / items.size());
-    scrollYHeight = (int) (numVisibleItems * h / (float) items.size());
+    scrollOffset = constrain(offset, 0, max(0, items.size() - numVisibleItems));
+    scrollYStart = round(scrollOffset * h / items.size());
+    scrollYHeight = round(numVisibleItems * h / items.size());
     redraw();
   }
   
@@ -751,7 +844,6 @@ public interface ScrollItem {
   public boolean isSelected();
   public boolean isPending();
   public String getLabel();
-  public void select();
   public void onMousePressed();
   public void onMouseReleased();  
 }