+abstract class OverlayUI {
+ protected final PFont titleFont = createFont("Myriad Pro", 10);
+ protected final color titleColor = #AAAAAA;
+ protected final PFont itemFont = createFont("Lucida Grande", 11);
+ protected final PFont knobFont = titleFont;
+ protected final int w = 140;
+ protected final int leftPos;
+ protected final int leftTextPos;
+ protected final int lineHeight = 20;
+ protected final int sectionSpacing = 12;
+ protected final int controlSpacing = 18;
+ protected final int tempoHeight = 20;
+ protected final int knobSize = 28;
+ protected final float knobIndent = .4;
+ protected final int knobSpacing = 6;
+ protected final int knobLabelHeight = 14;
+ protected final int scrollWidth = 14;
+ protected final color lightBlue = #666699;
+ protected final color lightGreen = #669966;
+ protected final int toggleButtonSize = 10;
+
+ private PImage logo;
+
+ protected final int STATE_DEFAULT = 0;
+ protected final int STATE_ACTIVE = 1;
+ protected final int STATE_PENDING = 2;
+
+ protected int[] pandaLeft = new int[pandaBoards.length];
+ protected final int pandaWidth = 56;
+ protected final int pandaHeight = 13;
+ protected final int pandaTop = height-16;
+
+ protected int eligibleLeft;
+
+ protected OverlayUI() {
+ leftPos = width - w;
+ leftTextPos = leftPos + 4;
+ logo = loadImage("logo-sm.png");
+ }
+
+ protected void drawLogoAndBackground() {
+ image(logo, 4, 4);
+ stroke(color(0, 0, 100));
+ // fill(color(0, 0, 50, 50)); // alpha is bad for perf
+ fill(color(0, 0, 30));
+ rect(leftPos-1, -1, w+2, height+2);
+ }
+
+ protected void drawToggleTip(String s) {
+ fill(#999999);
+ textFont(itemFont);
+ textAlign(LEFT);
+ text(s, leftTextPos, height-6);
+ }
+
+ protected void drawHelpTip() {
+ textFont(itemFont);
+ textAlign(RIGHT);
+ text("Tap 'u' to restore UI", width-4, height-6);
+ }
+
+ public void drawFPS() {
+ textFont(titleFont);
+ textAlign(LEFT);
+ fill(#666666);
+ text("FPS: " + (((int)(frameRate * 10)) / 10.), 4, height-6);
+ text("Target (-/+):", 50, height-6);
+ fill(#000000);
+ rect(104, height-16, 20, 13);
+ fill(#666666);
+ text("" + targetFramerate, 108, height-6);
+ text("PandaOutput (p):", 134, height-6);
+ int lPos = 214;
+ int pi = 0;
+ for (PandaDriver p : pandaBoards) {
+ pandaLeft[pi++] = lPos;
+ fill(p.enabled ? #666666 : #000000);
+ rect(lPos, pandaTop, pandaWidth, pandaHeight);
+ fill(p.enabled ? #000000 : #666666);
+ text(p.ip, lPos + 4, height-6);
+ lPos += 60;
+ }
+
+ }
+
+ protected int drawObjectList(int yPos, String title, Object[] items, Method stateMethod) {
+ int sz = (items != null) ? items.length : 0;
+ return drawObjectList(yPos, title, items, stateMethod, sz, 0);
+ }
+
+ protected int drawObjectList(int yPos, String title, Object[] items, Method stateMethod, int scrollLength, int scrollPos) {
+ return drawObjectList(yPos, title, items, classNameArray(items, null), stateMethod, scrollLength, scrollPos);
+ }
+
+ protected int drawObjectList(int yPos, String title, Object[] items, String[] names, Method stateMethod) {
+ int sz = (items != null) ? items.length : 0;
+ return drawObjectList(yPos, title, items, names, stateMethod, sz, 0);
+ }
+
+ protected void drawToggleButton(float x, float y, boolean eligible, color textColor) {
+ noFill();
+ stroke(textColor);
+ rect(x, y, toggleButtonSize, toggleButtonSize);
+ if (eligible) {
+ noStroke();
+ fill(textColor);
+ rect(x + 2, y + 2, toggleButtonSize - 4, toggleButtonSize - 4);
+ }
+ }
+
+ protected int drawObjectList(int yPos, String title, Object[] items, String[] names, Method stateMethod, int scrollLength, int scrollPos) {
+ noStroke();
+ fill(titleColor);
+ textFont(titleFont);
+ textAlign(LEFT);
+ text(title, leftTextPos, yPos += lineHeight);
+ if (items != null) {
+ boolean hasScroll = (scrollPos > 0) || (scrollLength < items.length);
+ textFont(itemFont);
+ color textColor;
+ boolean even = true;
+ int yTop = yPos+6;
+ for (int i = scrollPos; i < items.length && i < (scrollPos + scrollLength); ++i) {
+ Object o = items[i];
+ int state = STATE_DEFAULT;
+ try {
+ state = ((Integer) stateMethod.invoke(this, o)).intValue();
+ } catch (Exception x) {
+ throw new RuntimeException(x);
+ }
+ switch (state) {
+ case STATE_ACTIVE:
+ fill(lightGreen);
+ textColor = #eeeeee;
+ break;
+ case STATE_PENDING:
+ fill(lightBlue);
+ textColor = color(0, 0, 75 + 15*sin(millis()/200.));;
+ break;
+ default:
+ textColor = 0;
+ fill(even ? #666666 : #777777);
+ break;
+ }
+ noStroke();
+ rect(leftPos, yPos+6, w, lineHeight);
+ fill(textColor);
+ text(names[i], leftTextPos, yPos += lineHeight);
+ if (lx.isAutoTransitionEnabled() && items[i] instanceof LXPattern) {
+ boolean eligible = ((LXPattern)items[i]).isEligible();
+ eligibleLeft = leftPos + w - (hasScroll ? scrollWidth : 0) - 15;
+ drawToggleButton(eligibleLeft, yPos-8, eligible, textColor);
+ }
+ even = !even;
+ }
+ if (hasScroll) {
+ int yHere = yPos+6;
+ noStroke();
+ fill(color(0, 0, 0, 50));
+ rect(leftPos + w - scrollWidth, yTop, scrollWidth, yHere - yTop);
+ fill(#666666);
+ rect(leftPos + w - scrollWidth + 2, yTop + (yHere-yTop) * (scrollPos / (float)items.length), scrollWidth - 4, (yHere - yTop) * (scrollLength / (float)items.length));
+
+ }
+
+ }
+ return yPos;
+ }
+
+ protected String[] classNameArray(Object[] objects, String suffix) {
+ if (objects == null) {
+ return null;
+ }
+ String[] names = new String[objects.length];
+ for (int i = 0; i < objects.length; ++i) {
+ names[i] = className(objects[i], suffix);
+ }
+ return names;
+ }