1 import java.lang.reflect.*;
4 * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND
7 * ///\\\ ///\\\ ///\\\ ///\\\
8 * \\\/// \\\/// \\\/// \\\///
11 * EXPERTS ONLY!! EXPERTS ONLY!!
13 * Overlay UI that indicates pattern control, etc. This will be moved
14 * into the Processing library once it is stabilized and need not be
17 abstract class OverlayUI {
18 protected final PFont titleFont = createFont("Myriad Pro", 10);
19 protected final color titleColor = #AAAAAA;
20 protected final PFont itemFont = createFont("Lucida Grande", 11);
21 protected final PFont knobFont = titleFont;
22 protected final int w = 140;
23 protected final int leftPos;
24 protected final int leftTextPos;
25 protected final int lineHeight = 20;
26 protected final int sectionSpacing = 12;
27 protected final int controlSpacing = 18;
28 protected final int tempoHeight = 20;
29 protected final int knobSize = 28;
30 protected final float knobIndent = .4;
31 protected final int knobSpacing = 6;
32 protected final int knobLabelHeight = 14;
33 protected final int scrollWidth = 14;
34 protected final color lightBlue = #666699;
35 protected final color lightGreen = #669966;
39 protected final int STATE_DEFAULT = 0;
40 protected final int STATE_ACTIVE = 1;
41 protected final int STATE_PENDING = 2;
43 protected OverlayUI() {
45 leftTextPos = leftPos + 4;
46 logo = loadImage("logo-sm.png");
49 protected void drawLogoAndBackground() {
51 stroke(color(0, 0, 100));
52 // fill(color(0, 0, 50, 50)); // alpha is bad for perf
53 fill(color(0, 0, 30));
54 rect(leftPos-1, -1, w+2, height+2);
57 protected void drawToggleTip(String s) {
61 text(s, leftTextPos, height-6);
64 protected void drawHelpTip() {
67 text("Tap 'u' to restore UI", width-4, height-6);
70 public void drawFPS() {
74 text("FPS: " + (((int)(frameRate * 10)) / 10.), 4, height-6);
75 text("Target (-/+):", 50, height-6);
77 rect(104, height-16, 20, 12);
79 text("" + targetFramerate, 108, height-6);
80 text("PandaOutput (p):", 134, height-6);
82 rect(214, height-16, 26, 12);
84 text(pandaBoardsEnabled ? "ON" : "OFF", 218, height-6);
88 protected int drawObjectList(int yPos, String title, Object[] items, Method stateMethod) {
89 int sz = (items != null) ? items.length : 0;
90 return drawObjectList(yPos, title, items, stateMethod, sz, 0);
93 protected int drawObjectList(int yPos, String title, Object[] items, Method stateMethod, int scrollLength, int scrollPos) {
94 return drawObjectList(yPos, title, items, classNameArray(items, null), stateMethod, scrollLength, scrollPos);
97 protected int drawObjectList(int yPos, String title, Object[] items, String[] names, Method stateMethod) {
98 int sz = (items != null) ? items.length : 0;
99 return drawObjectList(yPos, title, items, names, stateMethod, sz, 0);
102 protected int drawObjectList(int yPos, String title, Object[] items, String[] names, Method stateMethod, int scrollLength, int scrollPos) {
107 text(title, leftTextPos, yPos += lineHeight);
113 for (int i = scrollPos; i < items.length && i < (scrollPos + scrollLength); ++i) {
115 int state = STATE_DEFAULT;
117 state = ((Integer) stateMethod.invoke(this, o)).intValue();
118 } catch (Exception x) {
119 throw new RuntimeException(x);
128 textColor = color(0, 0, 75 + 15*sin(millis()/200.));;
132 fill(even ? #666666 : #777777);
135 rect(leftPos, yPos+6, w, lineHeight);
137 text(names[i], leftTextPos, yPos += lineHeight);
140 if ((scrollPos > 0) || (scrollLength < items.length)) {
143 fill(color(0, 0, 0, 50));
144 rect(leftPos + w - scrollWidth, yTop, scrollWidth, yHere - yTop);
146 rect(leftPos + w - scrollWidth + 2, yTop + (yHere-yTop) * (scrollPos / (float)items.length), scrollWidth - 4, (yHere - yTop) * (scrollLength / (float)items.length));
154 protected String[] classNameArray(Object[] objects, String suffix) {
155 if (objects == null) {
158 String[] names = new String[objects.length];
159 for (int i = 0; i < objects.length; ++i) {
160 names[i] = className(objects[i], suffix);
165 protected String className(Object p, String suffix) {
166 String s = p.getClass().getName();
168 if ((li = s.lastIndexOf(".")) > 0) {
169 s = s.substring(li + 1);
171 if (s.indexOf("SugarCubes$") == 0) {
172 s = s.substring("SugarCubes$".length());
174 if ((suffix != null) && ((li = s.indexOf(suffix)) != -1)) {
175 s = s.substring(0, li);
180 protected int objectClickIndex(int firstItemY) {
181 return (mouseY - firstItemY) / lineHeight;
184 abstract public void draw();
185 abstract public void mousePressed();
186 abstract public void mouseDragged();
187 abstract public void mouseReleased();
188 abstract public void mouseWheel(int delta);
192 * UI for control of patterns, transitions, effects.
194 class ControlUI extends OverlayUI {
195 private final String[] patternNames;
196 private final String[] transitionNames;
197 private final String[] effectNames;
199 private int firstPatternY;
200 private int firstPatternKnobY;
201 private int firstTransitionY;
202 private int firstTransitionKnobY;
203 private int firstEffectY;
204 private int firstEffectKnobY;
206 private final int PATTERN_LIST_LENGTH = 8;
207 private int patternScrollPos = 0;
211 private Method patternStateMethod;
212 private Method transitionStateMethod;
213 private Method effectStateMethod;
216 patternNames = classNameArray(patterns, "Pattern");
217 transitionNames = classNameArray(transitions, "Transition");
218 effectNames = classNameArray(effects, "Effect");
221 patternStateMethod = getClass().getMethod("getState", LXPattern.class);
222 effectStateMethod = getClass().getMethod("getState", LXEffect.class);
223 transitionStateMethod = getClass().getMethod("getState", LXTransition.class);
224 } catch (Exception x) {
225 throw new RuntimeException(x);
230 drawLogoAndBackground();
232 firstPatternY = yPos + lineHeight + 6;
233 yPos = drawObjectList(yPos, "PATTERN", patterns, patternNames, patternStateMethod, PATTERN_LIST_LENGTH, patternScrollPos);
234 yPos += controlSpacing;
235 firstPatternKnobY = yPos;
236 int xPos = leftTextPos;
237 for (int i = 0; i < glucose.NUM_PATTERN_KNOBS/2; ++i) {
238 drawKnob(xPos, yPos, knobSize, glucose.patternKnobs.get(i));
239 drawKnob(xPos, yPos + knobSize + knobSpacing + knobLabelHeight, knobSize, glucose.patternKnobs.get(glucose.NUM_PATTERN_KNOBS/2 + i));
240 xPos += knobSize + knobSpacing;
242 yPos += 2*(knobSize + knobLabelHeight) + knobSpacing;
244 yPos += sectionSpacing;
245 firstTransitionY = yPos + lineHeight + 6;
246 yPos = drawObjectList(yPos, "TRANSITION", transitions, transitionNames, transitionStateMethod);
247 yPos += controlSpacing;
248 firstTransitionKnobY = yPos;
250 for (VirtualTransitionKnob knob : glucose.transitionKnobs) {
251 drawKnob(xPos, yPos, knobSize, knob);
252 xPos += knobSize + knobSpacing;
254 yPos += knobSize + knobLabelHeight;
256 yPos += sectionSpacing;
257 firstEffectY = yPos + lineHeight + 6;
258 yPos = drawObjectList(yPos, "FX", effects, effectNames, effectStateMethod);
259 yPos += controlSpacing;
260 firstEffectKnobY = yPos;
262 for (VirtualEffectKnob knob : glucose.effectKnobs) {
263 drawKnob(xPos, yPos, knobSize, knob);
264 xPos += knobSize + knobSpacing;
266 yPos += knobSize + knobLabelHeight;
268 yPos += sectionSpacing;
269 yPos = drawObjectList(yPos, "TEMPO", null, null, null);
273 fill(tempoDown ? lightGreen : color(0, 0, 35 - 8*lx.tempo.rampf()));
274 rect(leftPos + 4, yPos, w - 8, tempoHeight);
277 text("" + ((int)(lx.tempo.bpmf() * 100) / 100.), leftPos + w/2., yPos + tempoHeight - 6);
280 drawToggleTip("Tap 'u' to hide");
283 public LXParameter getOrNull(List<LXParameter> items, int index) {
284 if (index < items.size()) {
285 return items.get(index);
290 public int getState(LXPattern p) {
291 if (p == lx.getPattern()) {
293 } else if (p == lx.getNextPattern()) {
294 return STATE_PENDING;
296 return STATE_DEFAULT;
299 public int getState(LXEffect e) {
301 return STATE_PENDING;
302 } else if (e == glucose.getSelectedEffect()) {
305 return STATE_DEFAULT;
308 public int getState(LXTransition t) {
309 if (t == lx.getTransition()) {
310 return STATE_PENDING;
311 } else if (t == glucose.getSelectedTransition()) {
314 return STATE_DEFAULT;
317 private void drawKnob(int xPos, int yPos, int knobSize, LXParameter knob) {
318 final float knobValue = knob.getValuef();
319 String knobLabel = knob.getLabel();
320 if (knobLabel == null) {
322 } else if (knobLabel.length() > 4) {
323 knobLabel = knobLabel.substring(0, 4);
329 // For some reason this arc call really crushes drawing performance. Presumably
330 // because openGL is drawing it and when we overlap the second set of arcs it
331 // does a bunch of depth buffer intersection tests? Ellipse with a trapezoid cut out is faster
332 // arc(xPos + knobSize/2, yPos + knobSize/2, knobSize, knobSize, HALF_PI + knobIndent, HALF_PI + knobIndent + (TWO_PI-2*knobIndent));
333 ellipse(xPos + knobSize/2, yPos + knobSize/2, knobSize, knobSize);
335 float endArc = HALF_PI + knobIndent + (TWO_PI-2*knobIndent)*knobValue;
337 arc(xPos + knobSize/2, yPos + knobSize/2, knobSize, knobSize, HALF_PI + knobIndent, endArc);
339 // Mask notch out of knob
340 fill(color(0, 0, 30));
342 vertex(xPos + knobSize/2, yPos + knobSize/2.);
343 vertex(xPos + knobSize/2 - 6, yPos + knobSize);
344 vertex(xPos + knobSize/2 + 6, yPos + knobSize);
347 // Center circle of knob
349 ellipse(xPos + knobSize/2, yPos + knobSize/2, knobSize/2, knobSize/2);
352 rect(xPos, yPos + knobSize + 2, knobSize, knobLabelHeight - 2);
356 text(knobLabel, xPos + knobSize/2, yPos + knobSize + knobLabelHeight - 2);
359 private int patternKnobIndex = -1;
360 private int transitionKnobIndex = -1;
361 private int effectKnobIndex = -1;
362 private boolean patternScrolling = false;
365 private int releaseEffect = -1;
366 private boolean tempoDown = false;
368 public void mousePressed() {
370 patternKnobIndex = transitionKnobIndex = effectKnobIndex = -1;
372 patternScrolling = false;
373 if (mouseY > tempoY) {
374 if (mouseY - tempoY < tempoHeight) {
378 } else if ((mouseY >= firstEffectKnobY) && (mouseY < firstEffectKnobY + knobSize + knobLabelHeight)) {
379 effectKnobIndex = (mouseX - leftTextPos) / (knobSize + knobSpacing);
380 } else if (mouseY > firstEffectY) {
381 int effectIndex = objectClickIndex(firstEffectY);
382 if (effectIndex < effects.length) {
383 if (effects[effectIndex] == glucose.getSelectedEffect()) {
384 effects[effectIndex].enable();
385 releaseEffect = effectIndex;
387 glucose.setSelectedEffect(effectIndex);
389 } else if ((mouseY >= firstTransitionKnobY) && (mouseY < firstTransitionKnobY + knobSize + knobLabelHeight)) {
390 transitionKnobIndex = (mouseX - leftTextPos) / (knobSize + knobSpacing);
391 } else if (mouseY > firstTransitionY) {
392 int transitionIndex = objectClickIndex(firstTransitionY);
393 if (transitionIndex < transitions.length) {
394 glucose.setSelectedTransition(transitionIndex);
396 } else if ((mouseY >= firstPatternKnobY) && (mouseY < firstPatternKnobY + 2*(knobSize+knobLabelHeight) + knobSpacing)) {
397 patternKnobIndex = (mouseX - leftTextPos) / (knobSize + knobSpacing);
398 if (mouseY >= firstPatternKnobY + knobSize + knobLabelHeight + knobSpacing) {
399 patternKnobIndex += glucose.NUM_PATTERN_KNOBS / 2;
401 } else if (mouseY > firstPatternY) {
402 if ((patterns.length > PATTERN_LIST_LENGTH) && (mouseX > width - scrollWidth)) {
403 patternScrolling = true;
405 int patternIndex = objectClickIndex(firstPatternY);
406 if (patternIndex < patterns.length) {
407 lx.goIndex(patternIndex + patternScrollPos);
414 public void mouseDragged() {
415 int dy = lastY - mouseY;
418 if (patternKnobIndex >= 0 && patternKnobIndex < glucose.NUM_PATTERN_KNOBS) {
419 LXParameter p = glucose.patternKnobs.get(patternKnobIndex);
420 p.setValue(constrain(p.getValuef() + dy*.01, 0, 1));
421 } else if (effectKnobIndex >= 0 && effectKnobIndex < glucose.NUM_EFFECT_KNOBS) {
422 LXParameter p = glucose.effectKnobs.get(effectKnobIndex);
423 p.setValue(constrain(p.getValuef() + dy*.01, 0, 1));
424 } else if (transitionKnobIndex >= 0 && transitionKnobIndex < glucose.NUM_TRANSITION_KNOBS) {
425 LXParameter p = glucose.transitionKnobs.get(transitionKnobIndex);
426 p.setValue(constrain(p.getValuef() + dy*.01, 0, 1));
427 } else if (patternScrolling) {
428 int scroll = scrolldy / lineHeight;
429 scrolldy = scrolldy % lineHeight;
430 patternScrollPos = constrain(patternScrollPos - scroll, 0, patterns.length - PATTERN_LIST_LENGTH);
434 public void mouseReleased() {
435 patternScrolling = false;
437 if (releaseEffect >= 0) {
438 effects[releaseEffect].trigger();
443 public void mouseWheel(int delta) {
444 if (mouseY > firstPatternY) {
445 int patternIndex = objectClickIndex(firstPatternY);
446 if (patternIndex < PATTERN_LIST_LENGTH) {
447 patternScrollPos = constrain(patternScrollPos + delta, 0, patterns.length - PATTERN_LIST_LENGTH);
455 * UI for control of mapping.
457 class MappingUI extends OverlayUI {
459 private MappingTool mappingTool;
461 private final String MAPPING_MODE_ALL = "All On";
462 private final String MAPPING_MODE_CHANNEL = "Channel";
463 private final String MAPPING_MODE_SINGLE_CUBE = "Single Cube";
465 private final String[] mappingModes = {
467 MAPPING_MODE_CHANNEL,
468 MAPPING_MODE_SINGLE_CUBE
470 private final Method mappingModeStateMethod;
472 private final String CUBE_MODE_ALL = "All Strips";
473 private final String CUBE_MODE_SINGLE_STRIP = "Single Strip";
474 private final String CUBE_MODE_STRIP_PATTERN = "Strip Pattern";
475 private final String[] cubeModes = {
477 CUBE_MODE_SINGLE_STRIP,
478 CUBE_MODE_STRIP_PATTERN
480 private final Method cubeModeStateMethod;
482 private final String CHANNEL_MODE_RED = "Red";
483 private final String CHANNEL_MODE_GREEN = "Green";
484 private final String CHANNEL_MODE_BLUE = "Blue";
485 private final String[] channelModes = {
490 private final Method channelModeStateMethod;
492 private int firstMappingY;
493 private int firstCubeY;
494 private int firstChannelY;
495 private int channelFieldY;
496 private int cubeFieldY;
497 private int stripFieldY;
499 private boolean dragCube;
500 private boolean dragStrip;
501 private boolean dragChannel;
503 MappingUI(MappingTool mappingTool) {
504 this.mappingTool = mappingTool;
506 mappingModeStateMethod = getClass().getMethod("getMappingState", Object.class);
507 channelModeStateMethod = getClass().getMethod("getChannelState", Object.class);
508 cubeModeStateMethod = getClass().getMethod("getCubeState", Object.class);
509 } catch (Exception x) {
510 throw new RuntimeException(x);
514 public int getMappingState(Object mappingMode) {
515 boolean active = false;
516 if (mappingMode == MAPPING_MODE_ALL) {
517 active = mappingTool.mappingMode == mappingTool.MAPPING_MODE_ALL;
518 } else if (mappingMode == MAPPING_MODE_CHANNEL) {
519 active = mappingTool.mappingMode == mappingTool.MAPPING_MODE_CHANNEL;
520 } else if (mappingMode == MAPPING_MODE_SINGLE_CUBE) {
521 active = mappingTool.mappingMode == mappingTool.MAPPING_MODE_SINGLE_CUBE;
523 return active ? STATE_ACTIVE : STATE_DEFAULT;
526 public int getChannelState(Object channelMode) {
527 boolean active = false;
528 if (channelMode == CHANNEL_MODE_RED) {
529 active = mappingTool.channelModeRed;
530 } else if (channelMode == CHANNEL_MODE_GREEN) {
531 active = mappingTool.channelModeGreen;
532 } else if (channelMode == CHANNEL_MODE_BLUE) {
533 active = mappingTool.channelModeBlue;
535 return active ? STATE_ACTIVE : STATE_DEFAULT;
538 public int getCubeState(Object cubeMode) {
539 boolean active = false;
540 if (cubeMode == CUBE_MODE_ALL) {
541 active = mappingTool.cubeMode == mappingTool.CUBE_MODE_ALL;
542 } else if (cubeMode == CUBE_MODE_SINGLE_STRIP) {
543 active = mappingTool.cubeMode == mappingTool.CUBE_MODE_SINGLE_STRIP;
544 } else if (cubeMode == CUBE_MODE_STRIP_PATTERN) {
545 active = mappingTool.cubeMode == mappingTool.CUBE_MODE_STRIP_PATTERN;
547 return active ? STATE_ACTIVE : STATE_DEFAULT;
551 drawLogoAndBackground();
553 firstMappingY = yPos + lineHeight + 6;
554 yPos = drawObjectList(yPos, "MAPPING MODE", mappingModes, mappingModes, mappingModeStateMethod);
555 yPos += sectionSpacing;
557 firstCubeY = yPos + lineHeight + 6;
558 yPos = drawObjectList(yPos, "CUBE MODE", cubeModes, cubeModes, cubeModeStateMethod);
559 yPos += sectionSpacing;
561 firstChannelY = yPos + lineHeight + 6;
562 yPos = drawObjectList(yPos, "CHANNELS", channelModes, channelModes, channelModeStateMethod);
563 yPos += sectionSpacing;
565 channelFieldY = yPos + lineHeight + 6;
566 yPos = drawValueField(yPos, "CHANNEL ID", mappingTool.channelIndex + 1);
567 yPos += sectionSpacing;
569 cubeFieldY = yPos + lineHeight + 6;
570 yPos = drawValueField(yPos, "CUBE ID", glucose.model.getRawIndexForCube(mappingTool.cubeIndex));
571 yPos += sectionSpacing;
573 stripFieldY = yPos + lineHeight + 6;
574 yPos = drawValueField(yPos, "STRIP ID", mappingTool.stripIndex + 1);
576 drawToggleTip("Tap 'm' to return");
579 private int drawValueField(int yPos, String label, int value) {
584 text(label, leftTextPos, yPos);
587 rect(leftTextPos, yPos, w-8, lineHeight);
593 text("" + value, leftTextPos + (w-8)/2, yPos - 5);
600 public void mousePressed() {
601 dragCube = dragStrip = dragChannel = false;
603 if (mouseY >= stripFieldY) {
604 if (mouseY < stripFieldY + lineHeight) {
607 } else if (mouseY >= cubeFieldY) {
608 if (mouseY < cubeFieldY + lineHeight) {
611 } else if (mouseY >= channelFieldY) {
612 if (mouseY < channelFieldY + lineHeight) {
615 } else if (mouseY >= firstChannelY) {
616 int index = objectClickIndex(firstChannelY);
618 case 0: mappingTool.channelModeRed = !mappingTool.channelModeRed; break;
619 case 1: mappingTool.channelModeGreen = !mappingTool.channelModeGreen; break;
620 case 2: mappingTool.channelModeBlue = !mappingTool.channelModeBlue; break;
622 } else if (mouseY >= firstCubeY) {
623 int index = objectClickIndex(firstCubeY);
625 case 0: mappingTool.cubeMode = mappingTool.CUBE_MODE_ALL; break;
626 case 1: mappingTool.cubeMode = mappingTool.CUBE_MODE_SINGLE_STRIP; break;
627 case 2: mappingTool.cubeMode = mappingTool.CUBE_MODE_STRIP_PATTERN; break;
629 } else if (mouseY >= firstMappingY) {
630 int index = objectClickIndex(firstMappingY);
632 case 0: mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL; break;
633 case 1: mappingTool.mappingMode = mappingTool.MAPPING_MODE_CHANNEL; break;
634 case 2: mappingTool.mappingMode = mappingTool.MAPPING_MODE_SINGLE_CUBE; break;
639 public void mouseReleased() {}
640 public void mouseWheel(int delta) {}
642 public void mouseDragged() {
643 final int DRAG_THRESHOLD = 5;
644 int dy = lastY - mouseY;
645 if (abs(dy) >= DRAG_THRESHOLD) {
649 mappingTool.decCube();
651 mappingTool.incCube();
653 } else if (dragStrip) {
655 mappingTool.decStrip();
657 mappingTool.incStrip();
659 } else if (dragChannel) {
661 mappingTool.decChannel();
663 mappingTool.incChannel();
673 final int[][] channelList;
674 final int debugX = 10;
675 final int debugY = 42;
676 final int debugXSpacing = 28;
677 final int debugYSpacing = 22;
678 final int[][] debugState = new int[17][6];
680 final int DEBUG_STATE_ANIM = 0;
681 final int DEBUG_STATE_WHITE = 1;
682 final int DEBUG_STATE_OFF = 2;
684 DebugUI(int[][] frontChannels, int[][] rearChannels) {
685 channelList = new int[frontChannels.length + rearChannels.length][];
686 int channelIndex = 0;
687 for (int[] channel : frontChannels) {
688 channelList[channelIndex++] = channel;
690 for (int[] channel : rearChannels) {
691 channelList[channelIndex++] = channel;
693 for (int i = 0; i < debugState.length; ++i) {
694 for (int j = 0; j < debugState[i].length; ++j) {
695 debugState[i][j] = DEBUG_STATE_ANIM;
705 fill(color(0, 0, 0, 80));
706 rect(4, 32, 172, 388);
709 for (int[] channel : channelList) {
711 drawNumBox(xPos, yPos, channelNum+1, debugState[channelNum][0]);
713 boolean first = true;
715 for (int cube : channel) {
719 xPos += debugXSpacing;
724 line(xPos - 12, yPos + 8, xPos, yPos + 8);
726 drawNumBox(xPos, yPos, cube, debugState[channelNum][cubeNum+1]);
730 yPos += debugYSpacing;
733 drawNumBox(xBase, yPos, "A", debugState[channelNum][0]);
736 void drawNumBox(int xPos, int yPos, int label, int state) {
737 drawNumBox(xPos, yPos, "" + label, state);
740 void drawNumBox(int xPos, int yPos, String label, int state) {
742 color textColor = #cccccc;
744 case DEBUG_STATE_ANIM:
747 rect(xPos, yPos, 16, 8);
749 rect(xPos, yPos+8, 16, 8);
752 rect(xPos, yPos, 16, 16);
754 case DEBUG_STATE_WHITE:
757 rect(xPos, yPos, 16, 16);
760 case DEBUG_STATE_OFF:
762 rect(xPos, yPos, 16, 16);
768 text(label, xPos + 2, yPos + 12);
772 void maskColors(color[] colors) {
773 color white = #FFFFFF;
775 int channelIndex = 0;
776 for (int[] channel : channelList) {
778 for (int rawCubeIndex : channel) {
779 if (rawCubeIndex > 0) {
780 int state = debugState[channelIndex][cubeIndex];
781 if (state != DEBUG_STATE_ANIM) {
782 color debugColor = (state == DEBUG_STATE_WHITE) ? white : off;
783 Cube cube = glucose.model.getCubeByRawIndex(rawCubeIndex);
784 for (Point p : cube.points) {
785 colors[p.index] = debugColor;
795 void mousePressed() {
796 int dx = (mouseX - debugX) / debugXSpacing;
797 int dy = (mouseY - debugY) / debugYSpacing;
798 if ((dy >= 0) && (dy < debugState.length)) {
799 if ((dx >= 0) && (dx < debugState[dy].length)) {
800 int newState = debugState[dy][dx] = (debugState[dy][dx] + 1) % 3;
802 for (int[] states : debugState) {
803 for (int i = 0; i < states.length; ++i) {
804 states[i] = newState;
807 } else if (dx == 0) {
808 for (int i = 0; i < debugState[dy].length; ++i) {
809 debugState[dy][i] = newState;