+++ /dev/null
-/**
- * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND
- *
- * //\\ //\\ //\\ //\\
- * ///\\\ ///\\\ ///\\\ ///\\\
- * \\\/// \\\/// \\\/// \\\///
- * \\// \\// \\// \\//
- *
- * EXPERTS ONLY!! EXPERTS ONLY!!
- *
- * Little UI framework in progress to handle mouse events, layout,
- * redrawing, etc.
- */
-
-final color lightGreen = #669966;
-final color lightBlue = #666699;
-final color bgGray = #444444;
-final color defaultTextColor = #999999;
-final PFont defaultItemFont = createFont("Lucida Grande", 11);
-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;
- protected boolean childNeedsRedraw = true;
-
- protected float x=0, y=0, w=0, h=0;
-
- public UIContainer parent = null;
-
- protected boolean visible = true;
-
- public UIObject() {}
-
- public UIObject(float x, float y, float w, float h) {
- this.x = x;
- this.y = y;
- this.w = w;
- this.h = h;
- }
-
- public boolean isVisible() {
- return visible;
- }
-
- public UIObject setVisible(boolean visible) {
- if (visible != this.visible) {
- this.visible = visible;
- redraw();
- }
- return this;
- }
-
- public final UIObject setPosition(float x, float y) {
- this.x = x;
- this.y = y;
- redraw();
- return this;
- }
-
- public final UIObject setSize(float w, float h) {
- this.w = w;
- this.h = h;
- redraw();
- return this;
- }
-
- public final UIObject addToContainer(UIContainer c) {
- c.children.add(this);
- this.parent = c;
- return this;
- }
-
- public final UIObject removeFromContainer(UIContainer c) {
- c.children.remove(this);
- this.parent = null;
- return this;
- }
-
- public final UIObject redraw() {
- _redraw();
- UIObject p = this.parent;
- while (p != null) {
- p.childNeedsRedraw = true;
- p = p.parent;
- }
- return this;
- }
-
- private final void _redraw() {
- needsRedraw = true;
- for (UIObject child : children) {
- childNeedsRedraw = true;
- child._redraw();
- }
- }
-
- public final void draw(PGraphics pg) {
- if (!visible) {
- return;
- }
- if (needsRedraw) {
- needsRedraw = false;
- onDraw(pg);
- }
- if (childNeedsRedraw) {
- childNeedsRedraw = false;
- for (UIObject child : children) {
- if (needsRedraw || child.needsRedraw || child.childNeedsRedraw) {
- pg.pushMatrix();
- pg.translate(child.x, child.y);
- child.draw(pg);
- pg.popMatrix();
- }
- }
- }
- }
-
- public final boolean contains(float x, float y) {
- return
- (x >= this.x && x < (this.x + this.w)) &&
- (y >= this.y && y < (this.y + this.h));
- }
-
- protected void onDraw(PGraphics pg) {}
- protected void onMousePressed(float mx, float my) {}
- protected void onMouseReleased(float mx, float my) {}
- protected void onMouseDragged(float mx, float my, float dx, float dy) {}
- protected void onMouseWheel(float mx, float my, float dx) {}
-}
-
-public class UIContainer extends UIObject {
-
- private UIObject focusedChild = null;
-
- public UIContainer() {}
-
- public UIContainer(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- public UIContainer(UIObject[] children) {
- for (UIObject child : children) {
- child.addToContainer(this);
- }
- }
-
- protected void onMousePressed(float mx, float my) {
- for (int i = children.size() - 1; i >= 0; --i) {
- UIObject child = children.get(i);
- if (child.contains(mx, my)) {
- child.onMousePressed(mx - child.x, my - child.y);
- focusedChild = child;
- break;
- }
- }
- }
-
- protected void onMouseReleased(float mx, float my) {
- if (focusedChild != null) {
- focusedChild.onMouseReleased(mx - focusedChild.x, my - focusedChild.y);
- }
- focusedChild = null;
- }
-
- protected void onMouseDragged(float mx, float my, float dx, float dy) {
- if (focusedChild != null) {
- focusedChild.onMouseDragged(mx - focusedChild.x, my - focusedChild.y, dx, dy);
- }
- }
-
- protected void onMouseWheel(float mx, float my, float delta) {
- for (UIObject child : children) {
- if (child.contains(mx, my)) {
- child.onMouseWheel(mx - child.x, mx - child.y, delta);
- }
- }
- }
-
-}
-
-public class UIContext extends UIContainer {
-
- final public PGraphics pg;
-
- UIContext(float x, float y, float w, float h) {
- super(x, y, w, h);
- pg = createGraphics((int)w, (int)h, JAVA2D);
- pg.smooth();
- }
-
- public void draw() {
- if (!visible) {
- return;
- }
- if (needsRedraw || childNeedsRedraw) {
- pg.beginDraw();
- draw(pg);
- pg.endDraw();
- }
- image(pg, x, y);
- }
-
- private float px, py;
- private boolean dragging = false;
-
- public boolean mousePressed(float mx, float my) {
- if (!visible) {
- return false;
- }
- if (contains(mx, my)) {
- dragging = true;
- px = mx;
- py = my;
- onMousePressed(mx - x, my - y);
- return true;
- }
- return false;
- }
-
- public boolean mouseReleased(float mx, float my) {
- if (!visible) {
- return false;
- }
- dragging = false;
- onMouseReleased(mx - x, my - y);
- return true;
- }
-
- public boolean mouseDragged(float mx, float my) {
- if (!visible) {
- return false;
- }
- if (dragging) {
- float dx = mx - px;
- float dy = my - py;
- onMouseDragged(mx - x, my - y, dx, dy);
- px = mx;
- py = my;
- return true;
- }
- return false;
- }
-
- public boolean mouseWheel(float mx, float my, float delta) {
- if (!visible) {
- return false;
- }
- if (contains(mx, my)) {
- onMouseWheel(mx - x, my - y, delta);
- return true;
- }
- return false;
- }
-}
-
-public class UIWindow extends UIContext {
-
- protected final static int titleHeight = 24;
-
- public UIWindow(String label, float x, float y, float w, float h) {
- super(x, y, w, h);
- new UILabel(6, 8, w-6, titleHeight-8) {
- protected void onMouseDragged(float mx, float my, float dx, float dy) {
- parent.x = constrain(parent.x + dx, 0, width - w);
- parent.y = constrain(parent.y + dy, 0, height - h);
- }
- }.setLabel(label).setFont(defaultTitleFont).addToContainer(this);
- }
-
- protected void onDraw(PGraphics pg) {
- pg.noStroke();
- pg.fill(#444444);
- pg.stroke(#292929);
- pg.rect(0, 0, w-1, h-1);
- }
-}
-
-public class UILabel extends UIObject {
-
- private PFont font = defaultTitleFont;
- private color fontColor = #CCCCCC;
- private String label = "";
-
- public UILabel(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- protected void onDraw(PGraphics pg) {
- pg.textAlign(LEFT, TOP);
- pg.textFont(font);
- pg.fill(fontColor);
- pg.text(label, 0, 0);
- }
-
- public UILabel setFont(PFont font) {
- this.font = font;
- redraw();
- return this;
- }
-
- public UILabel setFontColor(color fontColor) {
- this.fontColor = fontColor;
- redraw();
- return this;
- }
-
- public UILabel setLabel(String label) {
- this.label = label;
- redraw();
- return this;
- }
-}
-
-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 {
-
- 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);
- }
-
- public UIButton setMomentary(boolean momentary) {
- isMomentary = momentary;
- return this;
- }
-
- protected void onDraw(PGraphics pg) {
- pg.stroke(borderColor);
- pg.fill(active ? activeColor : inactiveColor);
- pg.rect(0, 0, w, h);
- if (label != null && label.length() > 0) {
- pg.fill(active ? #FFFFFF : labelColor);
- pg.textFont(defaultItemFont);
- pg.textAlign(CENTER);
- pg.text(label, w/2, h-5);
- }
- }
-
- protected void onMousePressed(float mx, float my) {
- if (isMomentary) {
- setActive(true);
- } else {
- setActive(!active);
- }
- }
-
- protected void onMouseReleased(float mx, float my) {
- if (isMomentary) {
- setActive(false);
- }
- }
-
- public boolean isActive() {
- return active;
- }
-
- public UIButton setActive(boolean active) {
- this.active = active;
- onToggle(active);
- redraw();
- return this;
- }
-
- public UIButton toggle() {
- return setActive(!active);
- }
-
- protected void onToggle(boolean active) {}
-
- public UIButton setBorderColor(color borderColor) {
- if (this.borderColor != borderColor) {
- this.borderColor = borderColor;
- redraw();
- }
- return this;
- }
-
- public UIButton setActiveColor(color activeColor) {
- if (this.activeColor != activeColor) {
- this.activeColor = activeColor;
- if (active) {
- redraw();
- }
- }
- return this;
- }
-
- public UIButton setInactiveColor(color inactiveColor) {
- if (this.inactiveColor != inactiveColor) {
- this.inactiveColor = inactiveColor;
- if (!active) {
- redraw();
- }
- }
- return this;
- }
-
- public UIButton setLabelColor(color labelColor) {
- if (this.labelColor != labelColor) {
- this.labelColor = labelColor;
- redraw();
- }
- return this;
- }
-
- public UIButton setLabel(String label) {
- if (!this.label.equals(label)) {
- this.label = label;
- redraw();
- }
- return this;
- }
-
- public void onMousePressed() {
- setActive(!active);
- }
-}
-
-public class UIToggleSet extends UIObject {
-
- private String[] options;
- private int[] boundaries;
- private String value;
-
- public UIToggleSet(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- public UIToggleSet setOptions(String[] options) {
- this.options = options;
- boundaries = new int[options.length];
- int totalLength = 0;
- for (String s : options) {
- totalLength += s.length();
- }
- int lengthSoFar = 0;
- for (int i = 0; i < options.length; ++i) {
- lengthSoFar += options[i].length();
- boundaries[i] = (int) (lengthSoFar * w / totalLength);
- }
- value = options[0];
- redraw();
- return this;
- }
-
- public String getValue() {
- return value;
- }
-
- public UIToggleSet setValue(String option) {
- value = option;
- onToggle(value);
- redraw();
- return this;
- }
-
- public void onDraw(PGraphics pg) {
- pg.stroke(#666666);
- pg.fill(#222222);
- pg.rect(0, 0, w, h);
- for (int b : boundaries) {
- pg.line(b, 1, b, h-1);
- }
- pg.noStroke();
- pg.textAlign(CENTER);
- pg.textFont(defaultItemFont);
- int leftBoundary = 0;
-
- for (int i = 0; i < options.length; ++i) {
- boolean isActive = options[i] == value;
- if (isActive) {
- pg.fill(lightGreen);
- pg.rect(leftBoundary + 1, 1, boundaries[i] - leftBoundary - 1, h-1);
- }
- pg.fill(isActive ? #FFFFFF : #999999);
- pg.text(options[i], (leftBoundary + boundaries[i]) / 2., h-6);
- leftBoundary = boundaries[i];
- }
- }
-
- public void onMousePressed(float mx, float my) {
- for (int i = 0; i < boundaries.length; ++i) {
- if (mx < boundaries[i]) {
- setValue(options[i]);
- break;
- }
- }
- }
-
- protected void onToggle(String option) {}
-
-}
-
-
-public abstract class UIParameterControl extends UIObject implements LXParameterListener {
- protected LXParameter parameter = null;
-
- protected UIParameterControl(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- public void onParameterChanged(LXParameter parameter) {
- 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) {
- ((LXListenableParameter)this.parameter).removeListener(this);
- }
- }
- this.parameter = parameter;
- if (this.parameter != null) {
- if (this.parameter instanceof LXListenableParameter) {
- ((LXListenableParameter)this.parameter).addListener(this);
- }
- }
- redraw();
- return this;
- }
-}
-
-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);
- setSize(knobSize, knobSize + knobLabelHeight);
- }
-
- public UIParameterKnob(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- protected void onDraw(PGraphics pg) {
- float knobValue = getNormalized();
-
- pg.ellipseMode(CENTER);
- pg.noStroke();
-
- pg.fill(bgGray);
- pg.rect(0, 0, knobSize, knobSize);
-
- // Full outer dark ring
- pg.fill(#222222);
- pg.arc(knobSize/2, knobSize/2, knobSize, knobSize, HALF_PI + knobIndent, HALF_PI + knobIndent + (TWO_PI-2*knobIndent));
-
- // Light ring indicating value
- pg.fill(lightGreen);
- pg.arc(knobSize/2, knobSize/2, knobSize, knobSize, HALF_PI + knobIndent, HALF_PI + knobIndent + knobValue*(TWO_PI-2*knobIndent));
-
- // Center circle of knob
- pg.fill(#333333);
- pg.ellipse(knobSize/2, knobSize/2, knobSize/2, knobSize/2);
-
- 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) {
- knobLabel = knobLabel.substring(0, 4);
- }
- pg.fill(#000000);
- pg.rect(0, knobSize + 2, knobSize, knobLabelHeight - 2);
- pg.fill(#999999);
- pg.textAlign(CENTER);
- pg.textFont(defaultTitleFont);
- pg.text(knobLabel, knobSize/2, knobSize + knobLabelHeight - 2);
- }
-
- 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);
- }
-}
-
-public class UIParameterSlider extends UIParameterControl {
-
- private static final float handleWidth = 12;
-
- UIParameterSlider(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- protected void onDraw(PGraphics pg) {
- pg.noStroke();
- pg.fill(#333333);
- pg.rect(0, 0, w, h);
- pg.fill(#222222);
- pg.rect(4, h/2-2, w-8, 4);
- pg.fill(#666666);
- pg.stroke(#222222);
- pg.rect((int) (4 + parameter.getValuef() * (w-8-handleWidth)), 4, handleWidth, h-8);
- }
-
- private boolean editing = false;
- private long lastClick = 0;
- private float doubleClickMode = 0;
- private float doubleClickX = 0;
- protected void onMousePressed(float mx, float my) {
- 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) {
- editing = false;
- }
-
- protected void onMouseDragged(float mx, float my, float dx, float dy) {
- if (editing) {
- setNormalized(constrain((mx - handleWidth/2. - 4) / (w-8-handleWidth), 0, 1));
- }
- }
-}
-
-public class UIScrollList extends UIObject {
-
- private List<ScrollItem> items = new ArrayList<ScrollItem>();
-
- private PFont itemFont = defaultItemFont;
- private int itemHeight = 20;
- private color selectedColor = lightGreen;
- private color pendingColor = lightBlue;
- private int scrollOffset = 0;
- private int numVisibleItems = 0;
-
- private boolean hasScroll;
- private float scrollYStart;
- private float scrollYHeight;
-
- public UIScrollList(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- protected void onDraw(PGraphics pg) {
- int yp = 0;
- boolean even = true;
- for (int i = 0; i < numVisibleItems; ++i) {
- if (i + scrollOffset >= items.size()) {
- break;
- }
- ScrollItem item = items.get(i + scrollOffset);
- color itemColor;
- color labelColor = #FFFFFF;
- if (item.isSelected()) {
- itemColor = selectedColor;
- } else if (item.isPending()) {
- itemColor = pendingColor;
- } else {
- labelColor = #000000;
- itemColor = #707070;
- }
- float factor = even ? .92 : 1.08;
- itemColor = lx.scaleBrightness(itemColor, factor);
-
- pg.noStroke();
- pg.fill(itemColor);
- pg.rect(0, yp, w, itemHeight);
- pg.fill(labelColor);
- pg.textFont(itemFont);
- pg.textAlign(LEFT, TOP);
- pg.text(item.getLabel(), 6, yp+4);
-
- yp += itemHeight;
- even = !even;
- }
- if (hasScroll) {
- pg.noStroke();
- pg.fill(0x26ffffff);
- pg.rect(w-12, 0, 12, h);
- pg.fill(#333333);
- pg.rect(w-12, scrollYStart, 12, scrollYHeight);
- }
-
- }
-
- private boolean scrolling = false;
- private ScrollItem pressedItem = null;
-
- public void onMousePressed(float mx, float my) {
- pressedItem = null;
- if (hasScroll && mx >= w-12) {
- if (my >= scrollYStart && my < (scrollYStart + scrollYHeight)) {
- scrolling = true;
- dAccum = 0;
- }
- } else {
- int index = (int) my / itemHeight;
- if (scrollOffset + index < items.size()) {
- pressedItem = items.get(scrollOffset + index);
- pressedItem.onMousePressed();
- redraw();
- }
- }
- }
-
- public void onMouseReleased(float mx, float my) {
- scrolling = false;
- if (pressedItem != null) {
- pressedItem.onMouseReleased();
- redraw();
- }
- }
-
- private float dAccum = 0;
- public void onMouseDragged(float mx, float my, float dx, float dy) {
- if (scrolling) {
- dAccum += dy;
- float scrollOne = h / items.size();
- int offset = (int) (dAccum / scrollOne);
- if (offset != 0) {
- dAccum -= offset * scrollOne;
- setScrollOffset(scrollOffset + offset);
- }
- }
- }
-
- private float wAccum = 0;
- public void onMouseWheel(float mx, float my, float delta) {
- wAccum += delta;
- int offset = (int) (wAccum / 5);
- if (offset != 0) {
- wAccum -= offset * 5;
- setScrollOffset(scrollOffset + offset);
- }
- }
-
- public void setScrollOffset(int offset) {
- scrollOffset = constrain(offset, 0, max(0, items.size() - numVisibleItems));
- scrollYStart = round(scrollOffset * h / items.size());
- scrollYHeight = round(numVisibleItems * h / items.size());
- redraw();
- }
-
- public UIScrollList setItems(List<ScrollItem> items) {
- this.items = items;
- numVisibleItems = (int) (h / itemHeight);
- hasScroll = items.size() > numVisibleItems;
- setScrollOffset(0);
- redraw();
- return this;
- }
-}
-
-public interface ScrollItem {
- public boolean isSelected();
- public boolean isPending();
- public String getLabel();
- public void onMousePressed();
- public void onMouseReleased();
-}
-
-public abstract class AbstractScrollItem implements ScrollItem {
- public boolean isPending() {
- return false;
- }
- public void select() {}
- public void onMousePressed() {}
- public void onMouseReleased() {}
-}
-
-public class UIIntegerBox extends UIObject {
-
- private int minValue = 0;
- private int maxValue = MAX_INT;
- private int value = 0;
-
- UIIntegerBox(float x, float y, float w, float h) {
- super(x, y, w, h);
- }
-
- public UIIntegerBox setRange(int minValue, int maxValue) {
- this.minValue = minValue;
- this.maxValue = maxValue;
- setValue(constrain(value, minValue, maxValue));
- return this;
- }
-
- protected void onDraw(PGraphics pg) {
- pg.stroke(#666666);
- pg.fill(#222222);
- pg.rect(0, 0, w, h);
- pg.textAlign(CENTER, CENTER);
- pg.textFont(defaultItemFont);
- pg.fill(#999999);
- pg.text("" + value, w/2, h/2);
- }
-
- protected void onValueChange(int value) {}
-
- float dAccum = 0;
- protected void onMousePressed(float mx, float my) {
- dAccum = 0;
- }
-
- protected void onMouseDragged(float mx, float my, float dx, float dy) {
- dAccum -= dy;
- int offset = (int) (dAccum / 5);
- dAccum = dAccum - (offset * 5);
- setValue(value + offset);
- }
-
- public int getValue() {
- return value;
- }
-
- public UIIntegerBox setValue(int value) {
- if (this.value != value) {
- int range = (maxValue - minValue + 1);
- while (value < minValue) {
- value += range;
- }
- this.value = minValue + (value - minValue) % range;
- this.onValueChange(this.value);
- redraw();
- }
- return this;
- }
-}