2 * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND
5 * ///\\\ ///\\\ ///\\\ ///\\\
6 * \\\/// \\\/// \\\/// \\\///
9 * EXPERTS ONLY!! EXPERTS ONLY!!
11 * Custom UI components using the framework.
15 import java.util.Arrays;
16 class UICubesLayer extends UICameraComponent {
19 int SIZEOF_INT = Integer.SIZE / 8;
20 int SIZEOF_FLOAT = Float.SIZE / 8;
31 boolean initted = false;
33 int numPoints = 10000;
37 nvert = model.points.size();
38 sh = loadShader("frag.glsl", "vert.glsl");
39 /*color[] simulationColors = lx.getColors();
41 sha1.beginShape(POINTS);
42 for (LXPoint p : model.points) {
43 stroke(simulationColors[p.index]);
44 //pointColor(simulationColors[p.index]);
46 sha1.vertex(p.x, p.y, p.z);
49 float[] temp = new float[nvert * 7];
50 for (LXPoint p : model.points) {
52 temp[p.index * 7 + 0] = p.x;
53 temp[p.index * 7 + 1] = p.y;
54 temp[p.index * 7 + 2] = p.z;
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;
63 vertData = allocateDirectFloatBuffer(nvert * 7);
67 vboName = allocateDirectIntBuffer(1);
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();
84 long simulationStart = System.nanoTime();
86 hint(DISABLE_DEPTH_TEST);
87 drawSimulation(simulationColors);
88 hint(ENABLE_DEPTH_TEST);
90 simulationNanos = System.nanoTime() - simulationStart;
95 void drawSimulation(color[] simulationColors) {
99 drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.);
104 vertex(TRAILER_WIDTH, 0, 0);
105 vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH);
106 vertex(0, 0, TRAILER_DEPTH);
109 // Draw the logo on the front of platform
114 image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s);
118 for (Cube c : model.cubes) {
133 vertLoc = pgl.getAttribLocation(sh.glProgram, "vertex");
134 colorLoc = pgl.getAttribLocation(sh.glProgram, "color");
136 pgl.bindBuffer(PGL.ARRAY_BUFFER, vboName.get(0));
137 pgl.enableVertexAttribArray(vertLoc);
138 pgl.enableVertexAttribArray(colorLoc);
140 pgl.vertexAttribPointer(vertLoc, 3, PGL.FLOAT, false, 7 * SIZEOF_FLOAT, 0);
141 pgl.vertexAttribPointer(colorLoc, 4, PGL.FLOAT, false, 7 * SIZEOF_FLOAT, 3 * SIZEOF_FLOAT);
142 javax.media.opengl.GL2 gl2 = (javax.media.opengl.GL2) ((PJOGL)pgl).gl;
144 pgl.drawArrays(PGL.POINTS, 0, nvert);
146 pgl.disableVertexAttribArray(vertLoc);
147 pgl.disableVertexAttribArray(colorLoc);
148 pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
152 createGeometry(simulationColors);
153 pgl.bindBuffer(PGL.ARRAY_BUFFER, vboName.get(0));
154 pgl.bufferData(PGL.ARRAY_BUFFER, nvert * 7 * SIZEOF_FLOAT, vertData, PGL.STATIC_DRAW);
157 void createGeometry(color[] simulationColors) {
158 for (LXPoint p : model.points) {
159 vertData.put(p.index * 7 + 3, ((simulationColors[p.index] >> 16) & 0xFF)/255.0);
160 vertData.put(p.index * 7 + 4, ((simulationColors[p.index] >> 8) & 0xFF)/255.0);
161 vertData.put(p.index * 7 + 5, (simulationColors[p.index]& 0xFF)/255.0);
167 pgl.genBuffers(1, vboName);
168 pgl.bindBuffer(PGL.ARRAY_BUFFER, vboName.get(0));
169 pgl.bufferData(PGL.ARRAY_BUFFER, nvert * 7 * SIZEOF_FLOAT, vertData, PGL.DYNAMIC_DRAW);
170 pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);
174 IntBuffer allocateDirectIntBuffer(int n) {
175 return ByteBuffer.allocateDirect(n * SIZEOF_INT).order(ByteOrder.nativeOrder()).asIntBuffer();
178 FloatBuffer allocateDirectFloatBuffer(int n) {
179 return ByteBuffer.allocateDirect(n * SIZEOF_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer();
182 void drawCube(Cube c) {
186 // 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);
189 void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) {
192 rotate(rx / 180. * PI, -1, 0, 0);
193 rotate(ry / 180. * PI, 0, -1, 0);
194 rotate(rz / 180. * PI, 0, 0, -1);
195 for (int i = 0; i < 4; ++i) {
196 float wid = (i % 2 == 0) ? xd : zd;
202 vertex(wid - sw, yd);
203 vertex(wid - sw, sw);
209 vertex(wid - sw, yd);
210 vertex(wid - sw, yd - sw);
215 translate(wid, 0, 0);
216 rotate(HALF_PI, 0, -1, 0);
222 class UIBlendMode extends UIWindow {
223 public UIBlendMode(float x, float y, float w, float h) {
224 super(lx.ui, "BLEND MODE", x, y, w, h);
225 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
226 for (LXTransition t : transitions) {
227 items.add(new TransitionScrollItem(t));
229 final UIScrollList tList;
230 (tList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 60)).setItems(items).addToContainer(this);
232 lx.engine.getDeck(RIGHT_DECK).addListener(new LXDeck.AbstractListener() {
233 public void faderTransitionDidChange(LXDeck deck, LXTransition transition) {
239 class TransitionScrollItem extends UIScrollList.AbstractItem {
240 private final LXTransition transition;
241 private final String label;
243 TransitionScrollItem(LXTransition transition) {
244 this.transition = transition;
245 this.label = className(transition, "Transition");
248 public String getLabel() {
252 public boolean isSelected() {
253 return this.transition == lx.engine.getDeck(RIGHT_DECK).getFaderTransition();
256 public boolean isPending() {
260 public void onMousePressed() {
261 lx.engine.getDeck(RIGHT_DECK).setFaderTransition(this.transition);
267 class UICrossfader extends UIWindow {
269 private final UIToggleSet displayMode;
271 public UICrossfader(float x, float y, float w, float h) {
272 super(lx.ui, "CROSSFADER", x, y, w, h);
274 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-9, 32).setParameter(lx.engine.getDeck(RIGHT_DECK).getFader()).addToContainer(this);
275 (displayMode = new UIToggleSet(4, UIWindow.TITLE_LABEL_HEIGHT + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this);
278 public UICrossfader setDisplayMode(String value) {
279 displayMode.setValue(value);
283 public String getDisplayMode() {
284 return displayMode.getValue();
288 class UIEffects extends UIWindow {
289 UIEffects(float x, float y, float w, float h) {
290 super(lx.ui, "FX", x, y, w, h);
292 int yp = UIWindow.TITLE_LABEL_HEIGHT;
293 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
295 for (LXEffect fx : effectsArr) {
296 items.add(new FXScrollItem(fx, i++));
298 final UIScrollList effectsList = new UIScrollList(1, yp, w-2, 60).setItems(items);
299 effectsList.addToContainer(this);
300 yp += effectsList.getHeight() + 10;
302 final UIKnob[] parameterKnobs = new UIKnob[4];
303 for (int ki = 0; ki < parameterKnobs.length; ++ki) {
304 parameterKnobs[ki] = new UIKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
305 parameterKnobs[ki].addToContainer(this);
308 LXParameterListener fxListener = new LXParameterListener() {
309 public void onParameterChanged(LXParameter parameter) {
311 for (LXParameter p : getSelectedEffect().getParameters()) {
312 if (i >= parameterKnobs.length) {
315 if (p instanceof BasicParameter) {
316 parameterKnobs[i++].setParameter((BasicParameter) p);
319 while (i < parameterKnobs.length) {
320 parameterKnobs[i++].setParameter(null);
325 selectedEffect.addListener(fxListener);
326 fxListener.onParameterChanged(null);
330 class FXScrollItem extends UIScrollList.AbstractItem {
332 private final LXEffect effect;
333 private final int index;
334 private final String label;
336 FXScrollItem(LXEffect effect, int index) {
337 this.effect = effect;
339 this.label = className(effect, "Effect");
342 public String getLabel() {
346 public boolean isSelected() {
347 return !effect.isEnabled() && (effect == getSelectedEffect());
350 public boolean isPending() {
351 return effect.isEnabled();
354 public void onMousePressed() {
355 if (effect == getSelectedEffect()) {
356 if (effect.isMomentary()) {
362 selectedEffect.setValue(index);
366 public void onMouseReleased() {
367 if (effect.isMomentary()) {
376 class UIOutput extends UIWindow {
377 public UIOutput(GrizzlyOutput[] grizzlies, float x, float y, float w, float h) {
378 super(lx.ui, "OUTPUT", x, y, w, h);
379 float yp = UIWindow.TITLE_LABEL_HEIGHT;
381 final UIScrollList outputs = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 80);
383 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
384 for (GrizzlyOutput grizzly : grizzlies) {
385 items.add(new GrizzlyScrollItem(grizzly));
386 grizzly.enabled.addListener(new LXParameterListener() {
387 public void onParameterChanged(LXParameter parameter) {
392 outputs.setItems(items).addToContainer(this);
395 class GrizzlyScrollItem extends UIScrollList.AbstractItem {
396 final GrizzlyOutput output;
398 GrizzlyScrollItem(GrizzlyOutput output) {
399 this.output = output;
402 public String getLabel() {
403 return output.ipAddress;
406 public boolean isSelected() {
407 return output.enabled.isOn();
410 public void onMousePressed() {
411 output.enabled.setValue(!isSelected());
416 class UITempo extends UIWindow {
418 private final UIButton tempoButton;
420 UITempo(float x, float y, float w, float h) {
421 super(lx.ui, "TEMPO", x, y, w, h);
422 tempoButton = new UIButton(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20) {
423 protected void onToggle(boolean active) {
428 }.setMomentary(true);
429 tempoButton.addToContainer(this);
430 new UITempoBlipper(8, UIWindow.TITLE_LABEL_HEIGHT + 5, 12, 12).addToContainer(this);
433 class UITempoBlipper extends UIObject {
434 UITempoBlipper(float x, float y, float w, float h) {
438 void onDraw(UI ui, PGraphics pg) {
439 tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.);
441 // Overlay tempo thing with openGL, redraw faster than button UI
442 pg.fill(color(0, 0, 24 - 8*lx.tempo.rampf()));
444 pg.rect(0, 0, width, height);
452 class UIMapping extends UIWindow {
454 private static final String MAP_MODE_ALL = "ALL";
455 private static final String MAP_MODE_CHANNEL = "CHNL";
456 private static final String MAP_MODE_CUBE = "CUBE";
458 private static final String CUBE_MODE_ALL = "ALL";
459 private static final String CUBE_MODE_STRIP = "SNGL";
460 private static final String CUBE_MODE_PATTERN = "PTRN";
462 private final MappingTool mappingTool;
464 private final UIIntegerBox channelBox;
465 private final UIIntegerBox cubeBox;
466 private final UIIntegerBox stripBox;
468 UIMapping(MappingTool tool, float x, float y, float w, float h) {
469 super(lx.ui, "MAPPING", x, y, w, h);
472 int yp = UIWindow.TITLE_LABEL_HEIGHT;
473 new UIToggleSet(4, yp, w-10, 20) {
474 protected void onToggle(String value) {
475 if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL;
476 else if (value == MAP_MODE_CHANNEL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_CHANNEL;
477 else if (value == MAP_MODE_CUBE) mappingTool.mappingMode = mappingTool.MAPPING_MODE_SINGLE_CUBE;
479 }.setOptions(new String[] { MAP_MODE_ALL, MAP_MODE_CHANNEL, MAP_MODE_CUBE }).addToContainer(this);
481 new UILabel(4, yp+8, w-10, 20).setLabel("CHANNEL ID").addToContainer(this);
483 (channelBox = new UIIntegerBox(4, yp, w-10, 20) {
484 protected void onValueChange(int value) {
485 mappingTool.setChannel(value-1);
487 }).setRange(1, mappingTool.numChannels()).addToContainer(this);
490 new UILabel(4, yp+8, w-10, 20).setLabel("CUBE ID").addToContainer(this);
492 (cubeBox = new UIIntegerBox(4, yp, w-10, 20) {
493 protected void onValueChange(int value) {
494 mappingTool.setCube(value-1);
496 }).setRange(1, model.cubes.size()).addToContainer(this);
501 new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new UIScrollList.Item[] {
502 new ColorScrollItem(ColorScrollItem.COLOR_RED),
503 new ColorScrollItem(ColorScrollItem.COLOR_GREEN),
504 new ColorScrollItem(ColorScrollItem.COLOR_BLUE),
505 })).addToContainer(this);
508 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP MODE").addToContainer(this);
511 new UIToggleSet(4, yp, w-10, 20) {
512 protected void onToggle(String value) {
513 if (value == CUBE_MODE_ALL) mappingTool.cubeMode = mappingTool.CUBE_MODE_ALL;
514 else if (value == CUBE_MODE_STRIP) mappingTool.cubeMode = mappingTool.CUBE_MODE_SINGLE_STRIP;
515 else if (value == CUBE_MODE_PATTERN) mappingTool.cubeMode = mappingTool.CUBE_MODE_STRIP_PATTERN;
517 }.setOptions(new String[] { CUBE_MODE_ALL, CUBE_MODE_STRIP, CUBE_MODE_PATTERN }).addToContainer(this);
520 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP ID").addToContainer(this);
523 (stripBox = new UIIntegerBox(4, yp, w-10, 20) {
524 protected void onValueChange(int value) {
525 mappingTool.setStrip(value-1);
527 }).setRange(1, Cube.STRIPS_PER_CUBE).addToContainer(this);
531 public void setChannelID(int value) {
532 channelBox.setValue(value);
535 public void setCubeID(int value) {
536 cubeBox.setValue(value);
539 public void setStripID(int value) {
540 stripBox.setValue(value);
543 class ColorScrollItem extends UIScrollList.AbstractItem {
545 public static final int COLOR_RED = 1;
546 public static final int COLOR_GREEN = 2;
547 public static final int COLOR_BLUE = 3;
549 private final int colorChannel;
551 ColorScrollItem(int colorChannel) {
552 this.colorChannel = colorChannel;
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";
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;
573 public void onMousePressed() {
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;
583 class UIDebugText extends UIContext {
585 private String line1 = "";
586 private String line2 = "";
588 UIDebugText(float x, float y, float w, float h) {
589 super(lx.ui, x, y, w, h);
592 public UIDebugText setText(String line1) {
593 return setText(line1, "");
596 public UIDebugText setText(String line1, String line2) {
597 if (!line1.equals(this.line1) || !line2.equals(this.line2)) {
600 setVisible(line1.length() + line2.length() > 0);
606 protected void onDraw(UI ui, PGraphics pg) {
607 super.onDraw(ui, pg);
608 if (line1.length() + line2.length() > 0) {
611 pg.rect(0, 0, width, height);
612 pg.textFont(ui.getItemFont());
614 pg.textAlign(LEFT, TOP);
616 pg.text(line1, 4, 4);
617 pg.text(line2, 4, 24);
622 class UISpeed extends UIWindow {
624 final BasicParameter speed;
626 UISpeed(float x, float y, float w, float h) {
627 super(lx.ui, "SPEED", x, y, w, h);
628 speed = new BasicParameter("SPEED", 0.5);
629 speed.addListener(new LXParameterListener() {
630 public void onParameterChanged(LXParameter parameter) {
631 lx.setSpeed(parameter.getValuef() * 2);
634 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20).setParameter(speed).addToContainer(this);
638 class UIMidi extends UIWindow {
640 private final UIToggleSet deckMode;
641 private final UIButton logMode;
643 UIMidi(final MidiEngine midiEngine, float x, float y, float w, float h) {
644 super(lx.ui, "MIDI", x, y, w, h);
646 // Processing compiler doesn't seem to get that list of class objects also conform to interface
647 List<UIScrollList.Item> scrollItems = new ArrayList<UIScrollList.Item>();
648 for (SCMidiInput mc : midiEngine.getControllers()) {
651 final UIScrollList scrollList;
652 (scrollList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 100)).setItems(scrollItems).addToContainer(this);
653 (deckMode = new UIToggleSet(4, 130, 90, 20) {
654 protected void onToggle(String value) {
655 midiEngine.setFocusedDeck(value == "A" ? 0 : 1);
657 }).setOptions(new String[] { "A", "B" }).addToContainer(this);
658 (logMode = new UIButton(98, 130, w-103, 20)).setLabel("LOG").addToContainer(this);
660 SCMidiInputListener listener = new SCMidiInputListener() {
661 public void onEnabled(SCMidiInput controller, boolean enabled) {
665 for (SCMidiInput mc : midiEngine.getControllers()) {
666 mc.addListener(listener);
669 midiEngine.addListener(new MidiEngineListener() {
670 public void onFocusedDeck(int deckIndex) {
671 deckMode.setValue(deckIndex == 0 ? "A" : "B");
677 public boolean logMidi() {
678 return logMode.isActive();
681 public LXDeck getFocusedDeck() {
682 return lx.engine.getDeck(deckMode.getValue() == "A" ? LEFT_DECK : RIGHT_DECK);
686 String className(Object p, String suffix) {
687 String s = p.getClass().getName();
689 if ((li = s.lastIndexOf(".")) > 0) {
690 s = s.substring(li + 1);
692 if (s.indexOf("SugarCubes$") == 0) {
693 s = s.substring("SugarCubes$".length());
695 if ((suffix != null) && ((li = s.indexOf(suffix)) != -1)) {
696 s = s.substring(0, li);