New LX fixes FlashEffect bug
[SugarCubes.git] / UIImplementation.pde
CommitLineData
d626bc9b
MS
1/**
2 * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND
3 *
4 * //\\ //\\ //\\ //\\
5 * ///\\\ ///\\\ ///\\\ ///\\\
6 * \\\/// \\\/// \\\/// \\\///
7 * \\// \\// \\// \\//
8 *
9 * EXPERTS ONLY!! EXPERTS ONLY!!
10 *
11 * Custom UI components using the framework.
12 */
b5d6d7a0
BM
13
14import java.nio.*;
7d60f6f6 15import java.util.Arrays;
36e19b7b 16class UICubesLayer extends UICameraComponent {
b5d6d7a0
BM
17
18int nvert = 200000;
19int SIZEOF_INT = Integer.SIZE / 8;
20int SIZEOF_FLOAT = Float.SIZE / 8;
21
22PGL pgl;
23PShader sh;
24
25int vertLoc;
26int colorLoc;
27
28IntBuffer vboName;
29FloatBuffer vertData;
30
31 boolean initted = false;
32 PShape sha1;
33 int numPoints = 10000;
34
35 void initme()
36 {
37 nvert = model.points.size();
38 sh = loadShader("frag.glsl", "vert.glsl");
39 /*color[] simulationColors = lx.getColors();
40 sha1= createShape();
41 sha1.beginShape(POINTS);
42 for (LXPoint p : model.points) {
43 stroke(simulationColors[p.index]);
44 //pointColor(simulationColors[p.index]);
45 gl2.glPointColor=100;
46 sha1.vertex(p.x, p.y, p.z);
47 }
48 sha1.endShape();*/
49 float[] temp = new float[nvert * 7];
50 for (LXPoint p : model.points) {
51 // position
52 temp[p.index * 7 + 0] = p.x;
53 temp[p.index * 7 + 1] = p.y;
54 temp[p.index * 7 + 2] = p.z;
55
56 // color
57 temp[p.index * 7 + 3] = 0.0;
58 temp[p.index * 7 + 4] = 0.0;
59 temp[p.index * 7 + 5] = 0.0;
60 temp[p.index * 7 + 6] = 1.0;
61 }
62
63 vertData = allocateDirectFloatBuffer(nvert * 7);
64 vertData.rewind();
65 vertData.put(temp);
66 vertData.position(0);
67 vboName = allocateDirectIntBuffer(1);
68 initVBO();
69 }
36e19b7b 70 void onDraw(UI ui) {
b5d6d7a0
BM
71 if(!initted)
72 {
73 initted=true;
74 initme();
75 }
36e19b7b
MS
76 color[] simulationColors = lx.getColors();
77 String displayMode = uiCrossfader.getDisplayMode();
78 if (displayMode == "A") {
79 simulationColors = lx.engine.getDeck(LEFT_DECK).getColors();
80 } else if (displayMode == "B") {
81 simulationColors = lx.engine.getDeck(RIGHT_DECK).getColors();
d626bc9b 82 }
36e19b7b
MS
83
84 long simulationStart = System.nanoTime();
85 if (simulationOn) {
30673de2 86 hint(DISABLE_DEPTH_TEST);
36e19b7b 87 drawSimulation(simulationColors);
30673de2 88 hint(ENABLE_DEPTH_TEST);
36e19b7b
MS
89 }
90 simulationNanos = System.nanoTime() - simulationStart;
b5d6d7a0 91 camera();
36e19b7b 92 strokeWeight(1);
d626bc9b 93 }
30673de2 94
36e19b7b
MS
95 void drawSimulation(color[] simulationColors) {
96 translate(0, 30, 0);
b5d6d7a0 97
36e19b7b 98 fill(#141414);
30673de2 99 drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.);
36e19b7b
MS
100 fill(#070707);
101 stroke(#222222);
102 beginShape();
103 vertex(0, 0, 0);
104 vertex(TRAILER_WIDTH, 0, 0);
105 vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH);
106 vertex(0, 0, TRAILER_DEPTH);
107 endShape();
108
109 // Draw the logo on the front of platform
110 pushMatrix();
111 translate(0, 0, -1);
112 float s = .07;
113 scale(s, -s, s);
114 image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s);
115 popMatrix();
d626bc9b 116
36e19b7b 117 noStroke();
bffb6a80
MS
118 if (structureOn) {
119 for (Cube c : model.cubes) {
120 drawCube(c);
121 }
d626bc9b 122 }
b5d6d7a0 123
36e19b7b 124 noFill();
b5d6d7a0
BM
125 //strokeWeight(2);
126 int count=0;
127
128 ///magic:
129
130 pgl = beginPGL();
131
132
133 sh.bind();
134
135 vertLoc = pgl.getAttribLocation(sh.glProgram, "vertex");
136 colorLoc = pgl.getAttribLocation(sh.glProgram, "color");
137
138 pgl.bindBuffer(PGL.ARRAY_BUFFER, vboName.get(0));
139 pgl.enableVertexAttribArray(vertLoc);
140 pgl.enableVertexAttribArray(colorLoc);
141
142 pgl.vertexAttribPointer(vertLoc, 3, PGL.FLOAT, false, 7 * SIZEOF_FLOAT, 0);
143 pgl.vertexAttribPointer(colorLoc, 4, PGL.FLOAT, false, 7 * SIZEOF_FLOAT, 3 * SIZEOF_FLOAT);
0298d256
MS
144 javax.media.opengl.GL2 gl2 = (javax.media.opengl.GL2) ((PJOGL)pgl).gl;
145 gl2.glPointSize(2f);
b5d6d7a0
BM
146 pgl.drawArrays(PGL.POINTS, 0, nvert);
147
148 pgl.disableVertexAttribArray(vertLoc);
149 pgl.disableVertexAttribArray(colorLoc);
150 pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
151
152 sh.unbind();
153 endPGL();
154 createGeometry(simulationColors);
155 pgl.bindBuffer(PGL.ARRAY_BUFFER, vboName.get(0));
156 pgl.bufferData(PGL.ARRAY_BUFFER, nvert * 7 * SIZEOF_FLOAT, vertData, PGL.STATIC_DRAW);
157 }
158
159 void createGeometry(color[] simulationColors) {
36e19b7b 160 for (LXPoint p : model.points) {
b5d6d7a0
BM
161 vertData.put(p.index * 7 + 3, ((simulationColors[p.index] >> 16) & 0xFF)/255.0);
162 vertData.put(p.index * 7 + 4, ((simulationColors[p.index] >> 8) & 0xFF)/255.0);
163 vertData.put(p.index * 7 + 5, (simulationColors[p.index]& 0xFF)/255.0);
164 }
36e19b7b 165 }
b5d6d7a0
BM
166void initVBO() {
167
168 pgl = beginPGL();
169 pgl.genBuffers(1, vboName);
170 pgl.bindBuffer(PGL.ARRAY_BUFFER, vboName.get(0));
171 pgl.bufferData(PGL.ARRAY_BUFFER, nvert * 7 * SIZEOF_FLOAT, vertData, PGL.DYNAMIC_DRAW);
172 pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
173 endPGL();
174}
175
176IntBuffer allocateDirectIntBuffer(int n) {
177 return ByteBuffer.allocateDirect(n * SIZEOF_INT).order(ByteOrder.nativeOrder()).asIntBuffer();
178}
179
180FloatBuffer allocateDirectFloatBuffer(int n) {
181 return ByteBuffer.allocateDirect(n * SIZEOF_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
182}
36e19b7b
MS
183
184 void drawCube(Cube c) {
185 float in = .15;
186 noStroke();
187 fill(#393939);
bffb6a80 188 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);
36e19b7b
MS
189 }
190
191 void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) {
192 pushMatrix();
193 translate(x, y, z);
194 rotate(rx / 180. * PI, -1, 0, 0);
195 rotate(ry / 180. * PI, 0, -1, 0);
196 rotate(rz / 180. * PI, 0, 0, -1);
197 for (int i = 0; i < 4; ++i) {
198 float wid = (i % 2 == 0) ? xd : zd;
199
200 beginShape();
201 vertex(0, 0);
202 vertex(wid, 0);
203 vertex(wid, yd);
204 vertex(wid - sw, yd);
205 vertex(wid - sw, sw);
206 vertex(0, sw);
207 endShape();
208 beginShape();
209 vertex(0, sw);
210 vertex(0, yd);
211 vertex(wid - sw, yd);
212 vertex(wid - sw, yd - sw);
213 vertex(sw, yd - sw);
214 vertex(sw, sw);
215 endShape();
216
217 translate(wid, 0, 0);
218 rotate(HALF_PI, 0, -1, 0);
d626bc9b 219 }
36e19b7b 220 popMatrix();
d626bc9b
MS
221 }
222}
223
a8d55ade
MS
224class UIBlendMode extends UIWindow {
225 public UIBlendMode(float x, float y, float w, float h) {
4e6626a9 226 super(lx.ui, "BLEND MODE", x, y, w, h);
30624e97 227 List<UIItemList.Item> items = new ArrayList<UIItemList.Item>();
3f16fd02 228 for (LXTransition t : transitions) {
30624e97 229 items.add(new TransitionItem(t));
a898d79b 230 }
30624e97
MS
231 final UIItemList tList;
232 (tList = new UIItemList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 60)).setItems(items).addToContainer(this);
a8d55ade 233
0c7bfdb5 234 lx.engine.getDeck(RIGHT_DECK).addListener(new LXDeck.AbstractListener() {
42a424d7 235 public void faderTransitionDidChange(LXDeck deck, LXTransition transition) {
a898d79b 236 tList.redraw();
d626bc9b 237 }
a898d79b
MS
238 });
239 }
a8d55ade 240
30624e97 241 class TransitionItem extends UIItemList.AbstractItem {
a8d55ade 242 private final LXTransition transition;
3f16fd02 243 private final String label;
a8d55ade 244
30624e97 245 TransitionItem(LXTransition transition) {
a8d55ade 246 this.transition = transition;
3f16fd02 247 this.label = className(transition, "Transition");
a8d55ade
MS
248 }
249
250 public String getLabel() {
251 return label;
252 }
253
254 public boolean isSelected() {
0c7bfdb5 255 return this.transition == lx.engine.getDeck(RIGHT_DECK).getFaderTransition();
a8d55ade
MS
256 }
257
258 public boolean isPending() {
259 return false;
260 }
261
262 public void onMousePressed() {
0c7bfdb5 263 lx.engine.getDeck(RIGHT_DECK).setFaderTransition(this.transition);
a8d55ade 264 }
d626bc9b 265 }
a8d55ade 266
d626bc9b
MS
267}
268
a8d55ade 269class UICrossfader extends UIWindow {
d626bc9b 270
a8d55ade 271 private final UIToggleSet displayMode;
d626bc9b 272
a8d55ade 273 public UICrossfader(float x, float y, float w, float h) {
4e6626a9 274 super(lx.ui, "CROSSFADER", x, y, w, h);
a8d55ade 275
0c7bfdb5 276 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-9, 32).setParameter(lx.engine.getDeck(RIGHT_DECK).getFader()).addToContainer(this);
4e6626a9 277 (displayMode = new UIToggleSet(4, UIWindow.TITLE_LABEL_HEIGHT + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this);
d626bc9b
MS
278 }
279
88a3dd9e
MS
280 public UICrossfader setDisplayMode(String value) {
281 displayMode.setValue(value);
282 return this;
283 }
284
a8d55ade
MS
285 public String getDisplayMode() {
286 return displayMode.getValue();
d626bc9b
MS
287 }
288}
289
290class UIEffects extends UIWindow {
291 UIEffects(float x, float y, float w, float h) {
4e6626a9 292 super(lx.ui, "FX", x, y, w, h);
d626bc9b 293
4e6626a9 294 int yp = UIWindow.TITLE_LABEL_HEIGHT;
30624e97 295 List<UIItemList.Item> items = new ArrayList<UIItemList.Item>();
0c7bfdb5
MS
296 int i = 0;
297 for (LXEffect fx : effectsArr) {
298 items.add(new FXScrollItem(fx, i++));
d626bc9b 299 }
30624e97 300 final UIItemList effectsList = new UIItemList(1, yp, w-2, 60).setItems(items);
d626bc9b 301 effectsList.addToContainer(this);
4e6626a9 302 yp += effectsList.getHeight() + 10;
d626bc9b 303
4e6626a9 304 final UIKnob[] parameterKnobs = new UIKnob[4];
d626bc9b 305 for (int ki = 0; ki < parameterKnobs.length; ++ki) {
4e6626a9 306 parameterKnobs[ki] = new UIKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
d626bc9b
MS
307 parameterKnobs[ki].addToContainer(this);
308 }
309
0c7bfdb5
MS
310 LXParameterListener fxListener = new LXParameterListener() {
311 public void onParameterChanged(LXParameter parameter) {
d626bc9b 312 int i = 0;
0c7bfdb5 313 for (LXParameter p : getSelectedEffect().getParameters()) {
d626bc9b
MS
314 if (i >= parameterKnobs.length) {
315 break;
316 }
4e6626a9
MS
317 if (p instanceof BasicParameter) {
318 parameterKnobs[i++].setParameter((BasicParameter) p);
319 }
d626bc9b
MS
320 }
321 while (i < parameterKnobs.length) {
322 parameterKnobs[i++].setParameter(null);
323 }
324 }
325 };
326
0c7bfdb5
MS
327 selectedEffect.addListener(fxListener);
328 fxListener.onParameterChanged(null);
d626bc9b
MS
329
330 }
331
30624e97 332 class FXScrollItem extends UIItemList.AbstractItem {
d626bc9b 333
0c7bfdb5
MS
334 private final LXEffect effect;
335 private final int index;
336 private final String label;
d626bc9b 337
0c7bfdb5 338 FXScrollItem(LXEffect effect, int index) {
d626bc9b 339 this.effect = effect;
0c7bfdb5
MS
340 this.index = index;
341 this.label = className(effect, "Effect");
d626bc9b
MS
342 }
343
344 public String getLabel() {
345 return label;
346 }
347
348 public boolean isSelected() {
0c7bfdb5 349 return !effect.isEnabled() && (effect == getSelectedEffect());
d626bc9b
MS
350 }
351
352 public boolean isPending() {
353 return effect.isEnabled();
354 }
355
d626bc9b 356 public void onMousePressed() {
0c7bfdb5 357 if (effect == getSelectedEffect()) {
d626bc9b
MS
358 if (effect.isMomentary()) {
359 effect.enable();
360 } else {
361 effect.toggle();
362 }
8f7f055d 363 } else {
0c7bfdb5 364 selectedEffect.setValue(index);
d626bc9b
MS
365 }
366 }
367
368 public void onMouseReleased() {
369 if (effect.isMomentary()) {
370 effect.disable();
371 }
372 }
373
374 }
375
376}
377
378class UIOutput extends UIWindow {
bffb6a80 379 public UIOutput(IPOutput[] outputs, float x, float y, float w, float h) {
4e6626a9
MS
380 super(lx.ui, "OUTPUT", x, y, w, h);
381 float yp = UIWindow.TITLE_LABEL_HEIGHT;
1f42cce7 382
bffb6a80 383 final UIItemList itemList = new UIItemList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 80);
1f42cce7 384
30624e97 385 List<UIItemList.Item> items = new ArrayList<UIItemList.Item>();
bffb6a80
MS
386 for (IPOutput output : outputs) {
387 items.add(new OutputItem(output));
388 output.enabled.addListener(new LXParameterListener() {
e037f60f 389 public void onParameterChanged(LXParameter parameter) {
bffb6a80 390 itemList.redraw();
d626bc9b
MS
391 }
392 });
d626bc9b 393 }
bffb6a80 394 itemList.setItems(items).addToContainer(this);
1f42cce7
MS
395 }
396
bffb6a80
MS
397 class OutputItem extends UIItemList.AbstractItem {
398 final IPOutput output;
e037f60f 399
bffb6a80 400 OutputItem(IPOutput output) {
e037f60f 401 this.output = output;
1f42cce7
MS
402 }
403
404 public String getLabel() {
e037f60f 405 return output.ipAddress;
1f42cce7
MS
406 }
407
408 public boolean isSelected() {
e037f60f 409 return output.enabled.isOn();
1f42cce7
MS
410 }
411
8f7f055d 412 public void onMousePressed() {
4749563e 413 output.enabled.setValue(!isSelected());
1f42cce7
MS
414 }
415 }
d626bc9b
MS
416}
417
418class UITempo extends UIWindow {
419
420 private final UIButton tempoButton;
421
422 UITempo(float x, float y, float w, float h) {
4e6626a9
MS
423 super(lx.ui, "TEMPO", x, y, w, h);
424 tempoButton = new UIButton(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20) {
d626bc9b
MS
425 protected void onToggle(boolean active) {
426 if (active) {
427 lx.tempo.tap();
428 }
429 }
430 }.setMomentary(true);
431 tempoButton.addToContainer(this);
4e6626a9 432 new UITempoBlipper(8, UIWindow.TITLE_LABEL_HEIGHT + 5, 12, 12).addToContainer(this);
d626bc9b
MS
433 }
434
4e6626a9
MS
435 class UITempoBlipper extends UIObject {
436 UITempoBlipper(float x, float y, float w, float h) {
437 super(x, y, w, h);
438 }
d626bc9b 439
4e6626a9
MS
440 void onDraw(UI ui, PGraphics pg) {
441 tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.);
442
443 // Overlay tempo thing with openGL, redraw faster than button UI
444 pg.fill(color(0, 0, 24 - 8*lx.tempo.rampf()));
445 pg.noStroke();
446 pg.rect(0, 0, width, height);
447
448 redraw();
449 }
d626bc9b 450 }
4e6626a9 451
d626bc9b
MS
452}
453
454class UIMapping extends UIWindow {
455
456 private static final String MAP_MODE_ALL = "ALL";
457 private static final String MAP_MODE_CHANNEL = "CHNL";
458 private static final String MAP_MODE_CUBE = "CUBE";
459
460 private static final String CUBE_MODE_ALL = "ALL";
461 private static final String CUBE_MODE_STRIP = "SNGL";
462 private static final String CUBE_MODE_PATTERN = "PTRN";
463
464 private final MappingTool mappingTool;
465
bffb6a80 466 private final UILabel cubeLabel;
d626bc9b
MS
467 private final UIIntegerBox cubeBox;
468 private final UIIntegerBox stripBox;
469
470 UIMapping(MappingTool tool, float x, float y, float w, float h) {
4e6626a9 471 super(lx.ui, "MAPPING", x, y, w, h);
d626bc9b
MS
472 mappingTool = tool;
473
4e6626a9 474 int yp = UIWindow.TITLE_LABEL_HEIGHT;
78a44a1b 475 new UIToggleSet(4, yp, w-10, 20) {
d626bc9b
MS
476 protected void onToggle(String value) {
477 if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL;
478 else if (value == MAP_MODE_CHANNEL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_CHANNEL;
479 else if (value == MAP_MODE_CUBE) mappingTool.mappingMode = mappingTool.MAPPING_MODE_SINGLE_CUBE;
480 }
bffb6a80 481 }.setOptions(new String[] { MAP_MODE_ALL, MAP_MODE_CUBE }).addToContainer(this);
d626bc9b 482 yp += 24;
bffb6a80 483 new UILabel(4, yp+8, w-10, 20).setLabel("CUBE ID").addToContainer(this);
d626bc9b 484 yp += 24;
bffb6a80
MS
485 (cubeLabel = new UILabel(4, yp, w-10, 20))
486 .setAlignment(CENTER, CENTER)
487 .setLabel(model.cubes.get(0).id)
488 .setBackgroundColor(#222222)
489 .setBorderColor(#666666)
490 .addToContainer(this);
d626bc9b
MS
491 yp += 24;
492
bffb6a80 493 new UILabel(4, yp+8, w-10, 20).setLabel("CUBE NUMBER").addToContainer(this);
d626bc9b 494 yp += 24;
78a44a1b 495 (cubeBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
496 protected void onValueChange(int value) {
497 mappingTool.setCube(value-1);
498 }
b9b7b3d4 499 }).setRange(1, model.cubes.size()).addToContainer(this);
d626bc9b
MS
500 yp += 24;
501
a8d55ade
MS
502 yp += 10;
503
30624e97 504 new UIItemList(1, yp, w-2, 60).setItems(Arrays.asList(new UIItemList.Item[] {
d626bc9b
MS
505 new ColorScrollItem(ColorScrollItem.COLOR_RED),
506 new ColorScrollItem(ColorScrollItem.COLOR_GREEN),
507 new ColorScrollItem(ColorScrollItem.COLOR_BLUE),
508 })).addToContainer(this);
509 yp += 64;
510
78a44a1b 511 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP MODE").addToContainer(this);
d626bc9b
MS
512 yp += 24;
513
78a44a1b 514 new UIToggleSet(4, yp, w-10, 20) {
d626bc9b
MS
515 protected void onToggle(String value) {
516 if (value == CUBE_MODE_ALL) mappingTool.cubeMode = mappingTool.CUBE_MODE_ALL;
517 else if (value == CUBE_MODE_STRIP) mappingTool.cubeMode = mappingTool.CUBE_MODE_SINGLE_STRIP;
518 else if (value == CUBE_MODE_PATTERN) mappingTool.cubeMode = mappingTool.CUBE_MODE_STRIP_PATTERN;
519 }
520 }.setOptions(new String[] { CUBE_MODE_ALL, CUBE_MODE_STRIP, CUBE_MODE_PATTERN }).addToContainer(this);
521
522 yp += 24;
78a44a1b 523 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP ID").addToContainer(this);
d626bc9b
MS
524
525 yp += 24;
78a44a1b 526 (stripBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
527 protected void onValueChange(int value) {
528 mappingTool.setStrip(value-1);
529 }
530 }).setRange(1, Cube.STRIPS_PER_CUBE).addToContainer(this);
531
532 }
533
d626bc9b
MS
534 public void setCubeID(int value) {
535 cubeBox.setValue(value);
bffb6a80 536 cubeLabel.setLabel(model.getCubeByRawIndex(value).id);
d626bc9b
MS
537 }
538
539 public void setStripID(int value) {
540 stripBox.setValue(value);
541 }
542
30624e97 543 class ColorScrollItem extends UIItemList.AbstractItem {
d626bc9b
MS
544
545 public static final int COLOR_RED = 1;
546 public static final int COLOR_GREEN = 2;
547 public static final int COLOR_BLUE = 3;
548
549 private final int colorChannel;
550
551 ColorScrollItem(int colorChannel) {
552 this.colorChannel = colorChannel;
553 }
554
555 public String getLabel() {
556 switch (colorChannel) {
557 case COLOR_RED: return "Red";
558 case COLOR_GREEN: return "Green";
559 case COLOR_BLUE: return "Blue";
560 }
561 return "";
562 }
563
564 public boolean isSelected() {
565 switch (colorChannel) {
566 case COLOR_RED: return mappingTool.channelModeRed;
567 case COLOR_GREEN: return mappingTool.channelModeGreen;
568 case COLOR_BLUE: return mappingTool.channelModeBlue;
569 }
570 return false;
571 }
572
a8d55ade 573 public void onMousePressed() {
d626bc9b
MS
574 switch (colorChannel) {
575 case COLOR_RED: mappingTool.channelModeRed = !mappingTool.channelModeRed; break;
576 case COLOR_GREEN: mappingTool.channelModeGreen = !mappingTool.channelModeGreen; break;
577 case COLOR_BLUE: mappingTool.channelModeBlue = !mappingTool.channelModeBlue; break;
578 }
579 }
580 }
581}
582
583class UIDebugText extends UIContext {
584
585 private String line1 = "";
586 private String line2 = "";
587
588 UIDebugText(float x, float y, float w, float h) {
4e6626a9 589 super(lx.ui, x, y, w, h);
d626bc9b
MS
590 }
591
592 public UIDebugText setText(String line1) {
593 return setText(line1, "");
594 }
595
596 public UIDebugText setText(String line1, String line2) {
597 if (!line1.equals(this.line1) || !line2.equals(this.line2)) {
598 this.line1 = line1;
599 this.line2 = line2;
600 setVisible(line1.length() + line2.length() > 0);
601 redraw();
602 }
603 return this;
604 }
605
4e6626a9
MS
606 protected void onDraw(UI ui, PGraphics pg) {
607 super.onDraw(ui, pg);
d626bc9b
MS
608 if (line1.length() + line2.length() > 0) {
609 pg.noStroke();
610 pg.fill(#444444);
4e6626a9
MS
611 pg.rect(0, 0, width, height);
612 pg.textFont(ui.getItemFont());
a8d55ade 613 pg.textSize(10);
d626bc9b
MS
614 pg.textAlign(LEFT, TOP);
615 pg.fill(#cccccc);
616 pg.text(line1, 4, 4);
617 pg.text(line2, 4, 24);
618 }
619 }
620}
621
34327c96 622class UISpeed extends UIWindow {
fa4f822d
MS
623
624 final BasicParameter speed;
625
34327c96 626 UISpeed(float x, float y, float w, float h) {
4e6626a9 627 super(lx.ui, "SPEED", x, y, w, h);
fa4f822d 628 speed = new BasicParameter("SPEED", 0.5);
4e6626a9 629 speed.addListener(new LXParameterListener() {
34327c96
MS
630 public void onParameterChanged(LXParameter parameter) {
631 lx.setSpeed(parameter.getValuef() * 2);
632 }
4e6626a9
MS
633 });
634 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20).setParameter(speed).addToContainer(this);
34327c96
MS
635 }
636}
637
a8d55ade
MS
638class UIMidi extends UIWindow {
639
9692dc7b
MS
640 private final UIToggleSet deckMode;
641 private final UIButton logMode;
a8d55ade 642
d6ac1ee8 643 UIMidi(final MidiEngine midiEngine, float x, float y, float w, float h) {
4e6626a9 644 super(lx.ui, "MIDI", x, y, w, h);
d6ac1ee8 645
a8d55ade 646 // Processing compiler doesn't seem to get that list of class objects also conform to interface
30624e97 647 List<UIItemList.Item> scrollItems = new ArrayList<UIItemList.Item>();
d6ac1ee8 648 for (SCMidiInput mc : midiEngine.getControllers()) {
30bf6510 649 scrollItems.add(mc);
a8d55ade 650 }
30624e97
MS
651 final UIItemList scrollList;
652 (scrollList = new UIItemList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 100)).setItems(scrollItems).addToContainer(this);
d6ac1ee8
MS
653 (deckMode = new UIToggleSet(4, 130, 90, 20) {
654 protected void onToggle(String value) {
655 midiEngine.setFocusedDeck(value == "A" ? 0 : 1);
656 }
657 }).setOptions(new String[] { "A", "B" }).addToContainer(this);
4df91daf 658 (logMode = new UIButton(98, 130, w-103, 20)).setLabel("LOG").addToContainer(this);
30bf6510
MS
659
660 SCMidiInputListener listener = new SCMidiInputListener() {
661 public void onEnabled(SCMidiInput controller, boolean enabled) {
662 scrollList.redraw();
663 }
664 };
d6ac1ee8 665 for (SCMidiInput mc : midiEngine.getControllers()) {
30bf6510
MS
666 mc.addListener(listener);
667 }
d6ac1ee8
MS
668
669 midiEngine.addListener(new MidiEngineListener() {
670 public void onFocusedDeck(int deckIndex) {
671 deckMode.setValue(deckIndex == 0 ? "A" : "B");
672 }
673 });
30bf6510 674
9692dc7b
MS
675 }
676
677 public boolean logMidi() {
678 return logMode.isActive();
a8d55ade
MS
679 }
680
42a424d7 681 public LXDeck getFocusedDeck() {
0c7bfdb5 682 return lx.engine.getDeck(deckMode.getValue() == "A" ? LEFT_DECK : RIGHT_DECK);
a8d55ade
MS
683 }
684}
685
d626bc9b
MS
686String className(Object p, String suffix) {
687 String s = p.getClass().getName();
688 int li;
689 if ((li = s.lastIndexOf(".")) > 0) {
690 s = s.substring(li + 1);
691 }
692 if (s.indexOf("SugarCubes$") == 0) {
693 s = s.substring("SugarCubes$".length());
694 }
695 if ((suffix != null) && ((li = s.indexOf(suffix)) != -1)) {
696 s = s.substring(0, li);
697 }
698 return s;
699}