2 * DOUBLE BLACK DIAMOND DOUBLE BLACK DIAMOND
5 * ///\\\ ///\\\ ///\\\ ///\\\
6 * \\\/// \\\/// \\\/// \\\///
9 * EXPERTS ONLY!! EXPERTS ONLY!!
11 * Custom UI components using the framework.
14 class UIBlendMode extends UIWindow {
15 public UIBlendMode(float x, float y, float w, float h) {
16 super(lx.ui, "BLEND MODE", x, y, w, h);
17 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
18 for (LXTransition t : transitions) {
19 items.add(new TransitionScrollItem(t));
21 final UIScrollList tList;
22 (tList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 60)).setItems(items).addToContainer(this);
24 lx.engine.getDeck(RIGHT_DECK).addListener(new LXDeck.AbstractListener() {
25 public void faderTransitionDidChange(LXDeck deck, LXTransition transition) {
31 class TransitionScrollItem extends UIScrollList.AbstractItem {
32 private final LXTransition transition;
33 private final String label;
35 TransitionScrollItem(LXTransition transition) {
36 this.transition = transition;
37 this.label = className(transition, "Transition");
40 public String getLabel() {
44 public boolean isSelected() {
45 return this.transition == lx.engine.getDeck(RIGHT_DECK).getFaderTransition();
48 public boolean isPending() {
52 public void onMousePressed() {
53 lx.engine.getDeck(RIGHT_DECK).setFaderTransition(this.transition);
59 class UICrossfader extends UIWindow {
61 private final UIToggleSet displayMode;
63 public UICrossfader(float x, float y, float w, float h) {
64 super(lx.ui, "CROSSFADER", x, y, w, h);
66 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-9, 32).setParameter(lx.engine.getDeck(RIGHT_DECK).getFader()).addToContainer(this);
67 (displayMode = new UIToggleSet(4, UIWindow.TITLE_LABEL_HEIGHT + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this);
70 public UICrossfader setDisplayMode(String value) {
71 displayMode.setValue(value);
75 public String getDisplayMode() {
76 return displayMode.getValue();
80 class UIEffects extends UIWindow {
81 UIEffects(float x, float y, float w, float h) {
82 super(lx.ui, "FX", x, y, w, h);
84 int yp = UIWindow.TITLE_LABEL_HEIGHT;
85 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
87 for (LXEffect fx : effectsArr) {
88 items.add(new FXScrollItem(fx, i++));
90 final UIScrollList effectsList = new UIScrollList(1, yp, w-2, 60).setItems(items);
91 effectsList.addToContainer(this);
92 yp += effectsList.getHeight() + 10;
94 final UIKnob[] parameterKnobs = new UIKnob[4];
95 for (int ki = 0; ki < parameterKnobs.length; ++ki) {
96 parameterKnobs[ki] = new UIKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
97 parameterKnobs[ki].addToContainer(this);
100 LXParameterListener fxListener = new LXParameterListener() {
101 public void onParameterChanged(LXParameter parameter) {
103 for (LXParameter p : getSelectedEffect().getParameters()) {
104 if (i >= parameterKnobs.length) {
107 if (p instanceof BasicParameter) {
108 parameterKnobs[i++].setParameter((BasicParameter) p);
111 while (i < parameterKnobs.length) {
112 parameterKnobs[i++].setParameter(null);
117 selectedEffect.addListener(fxListener);
118 fxListener.onParameterChanged(null);
122 class FXScrollItem extends UIScrollList.AbstractItem {
124 private final LXEffect effect;
125 private final int index;
126 private final String label;
128 FXScrollItem(LXEffect effect, int index) {
129 this.effect = effect;
131 this.label = className(effect, "Effect");
134 public String getLabel() {
138 public boolean isSelected() {
139 return !effect.isEnabled() && (effect == getSelectedEffect());
142 public boolean isPending() {
143 return effect.isEnabled();
146 public void onMousePressed() {
147 if (effect == getSelectedEffect()) {
148 if (effect.isMomentary()) {
154 selectedEffect.setValue(index);
158 public void onMouseReleased() {
159 if (effect.isMomentary()) {
168 class UIOutput extends UIWindow {
169 public UIOutput(GrizzlyOutput[] grizzlies, float x, float y, float w, float h) {
170 super(lx.ui, "OUTPUT", x, y, w, h);
171 float yp = UIWindow.TITLE_LABEL_HEIGHT;
173 final UIScrollList outputs = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 80);
175 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
176 for (GrizzlyOutput grizzly : grizzlies) {
177 items.add(new GrizzlyScrollItem(grizzly));
178 grizzly.enabled.addListener(new LXParameterListener() {
179 public void onParameterChanged(LXParameter parameter) {
184 outputs.setItems(items).addToContainer(this);
187 class GrizzlyScrollItem extends UIScrollList.AbstractItem {
188 final GrizzlyOutput output;
190 GrizzlyScrollItem(GrizzlyOutput output) {
191 this.output = output;
194 public String getLabel() {
195 return output.ipAddress;
198 public boolean isSelected() {
199 return output.enabled.isOn();
202 public void onMousePressed() {
203 output.enabled.setValue(!isSelected());
208 class UITempo extends UIWindow {
210 private final UIButton tempoButton;
212 UITempo(float x, float y, float w, float h) {
213 super(lx.ui, "TEMPO", x, y, w, h);
214 tempoButton = new UIButton(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20) {
215 protected void onToggle(boolean active) {
220 }.setMomentary(true);
221 tempoButton.addToContainer(this);
222 new UITempoBlipper(8, UIWindow.TITLE_LABEL_HEIGHT + 5, 12, 12).addToContainer(this);
225 class UITempoBlipper extends UIObject {
226 UITempoBlipper(float x, float y, float w, float h) {
230 void onDraw(UI ui, PGraphics pg) {
231 tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.);
233 // Overlay tempo thing with openGL, redraw faster than button UI
234 pg.fill(color(0, 0, 24 - 8*lx.tempo.rampf()));
236 pg.rect(0, 0, width, height);
244 class UIMapping extends UIWindow {
246 private static final String MAP_MODE_ALL = "ALL";
247 private static final String MAP_MODE_CHANNEL = "CHNL";
248 private static final String MAP_MODE_CUBE = "CUBE";
250 private static final String CUBE_MODE_ALL = "ALL";
251 private static final String CUBE_MODE_STRIP = "SNGL";
252 private static final String CUBE_MODE_PATTERN = "PTRN";
254 private final MappingTool mappingTool;
256 private final UIIntegerBox channelBox;
257 private final UIIntegerBox cubeBox;
258 private final UIIntegerBox stripBox;
260 UIMapping(MappingTool tool, float x, float y, float w, float h) {
261 super(lx.ui, "MAPPING", x, y, w, h);
264 int yp = UIWindow.TITLE_LABEL_HEIGHT;
265 new UIToggleSet(4, yp, w-10, 20) {
266 protected void onToggle(String value) {
267 if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL;
268 else if (value == MAP_MODE_CHANNEL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_CHANNEL;
269 else if (value == MAP_MODE_CUBE) mappingTool.mappingMode = mappingTool.MAPPING_MODE_SINGLE_CUBE;
271 }.setOptions(new String[] { MAP_MODE_ALL, MAP_MODE_CHANNEL, MAP_MODE_CUBE }).addToContainer(this);
273 new UILabel(4, yp+8, w-10, 20).setLabel("CHANNEL ID").addToContainer(this);
275 (channelBox = new UIIntegerBox(4, yp, w-10, 20) {
276 protected void onValueChange(int value) {
277 mappingTool.setChannel(value-1);
279 }).setRange(1, mappingTool.numChannels()).addToContainer(this);
282 new UILabel(4, yp+8, w-10, 20).setLabel("CUBE ID").addToContainer(this);
284 (cubeBox = new UIIntegerBox(4, yp, w-10, 20) {
285 protected void onValueChange(int value) {
286 mappingTool.setCube(value-1);
288 }).setRange(1, model.cubes.size()).addToContainer(this);
293 new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new UIScrollList.Item[] {
294 new ColorScrollItem(ColorScrollItem.COLOR_RED),
295 new ColorScrollItem(ColorScrollItem.COLOR_GREEN),
296 new ColorScrollItem(ColorScrollItem.COLOR_BLUE),
297 })).addToContainer(this);
300 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP MODE").addToContainer(this);
303 new UIToggleSet(4, yp, w-10, 20) {
304 protected void onToggle(String value) {
305 if (value == CUBE_MODE_ALL) mappingTool.cubeMode = mappingTool.CUBE_MODE_ALL;
306 else if (value == CUBE_MODE_STRIP) mappingTool.cubeMode = mappingTool.CUBE_MODE_SINGLE_STRIP;
307 else if (value == CUBE_MODE_PATTERN) mappingTool.cubeMode = mappingTool.CUBE_MODE_STRIP_PATTERN;
309 }.setOptions(new String[] { CUBE_MODE_ALL, CUBE_MODE_STRIP, CUBE_MODE_PATTERN }).addToContainer(this);
312 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP ID").addToContainer(this);
315 (stripBox = new UIIntegerBox(4, yp, w-10, 20) {
316 protected void onValueChange(int value) {
317 mappingTool.setStrip(value-1);
319 }).setRange(1, Cube.STRIPS_PER_CUBE).addToContainer(this);
323 public void setChannelID(int value) {
324 channelBox.setValue(value);
327 public void setCubeID(int value) {
328 cubeBox.setValue(value);
331 public void setStripID(int value) {
332 stripBox.setValue(value);
335 class ColorScrollItem extends UIScrollList.AbstractItem {
337 public static final int COLOR_RED = 1;
338 public static final int COLOR_GREEN = 2;
339 public static final int COLOR_BLUE = 3;
341 private final int colorChannel;
343 ColorScrollItem(int colorChannel) {
344 this.colorChannel = colorChannel;
347 public String getLabel() {
348 switch (colorChannel) {
349 case COLOR_RED: return "Red";
350 case COLOR_GREEN: return "Green";
351 case COLOR_BLUE: return "Blue";
356 public boolean isSelected() {
357 switch (colorChannel) {
358 case COLOR_RED: return mappingTool.channelModeRed;
359 case COLOR_GREEN: return mappingTool.channelModeGreen;
360 case COLOR_BLUE: return mappingTool.channelModeBlue;
365 public void onMousePressed() {
366 switch (colorChannel) {
367 case COLOR_RED: mappingTool.channelModeRed = !mappingTool.channelModeRed; break;
368 case COLOR_GREEN: mappingTool.channelModeGreen = !mappingTool.channelModeGreen; break;
369 case COLOR_BLUE: mappingTool.channelModeBlue = !mappingTool.channelModeBlue; break;
375 class UIDebugText extends UIContext {
377 private String line1 = "";
378 private String line2 = "";
380 UIDebugText(float x, float y, float w, float h) {
381 super(lx.ui, x, y, w, h);
384 public UIDebugText setText(String line1) {
385 return setText(line1, "");
388 public UIDebugText setText(String line1, String line2) {
389 if (!line1.equals(this.line1) || !line2.equals(this.line2)) {
392 setVisible(line1.length() + line2.length() > 0);
398 protected void onDraw(UI ui, PGraphics pg) {
399 super.onDraw(ui, pg);
400 if (line1.length() + line2.length() > 0) {
403 pg.rect(0, 0, width, height);
404 pg.textFont(ui.getItemFont());
406 pg.textAlign(LEFT, TOP);
408 pg.text(line1, 4, 4);
409 pg.text(line2, 4, 24);
414 class UISpeed extends UIWindow {
416 final BasicParameter speed;
418 UISpeed(float x, float y, float w, float h) {
419 super(lx.ui, "SPEED", x, y, w, h);
420 speed = new BasicParameter("SPEED", 0.5);
421 speed.addListener(new LXParameterListener() {
422 public void onParameterChanged(LXParameter parameter) {
423 lx.setSpeed(parameter.getValuef() * 2);
426 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20).setParameter(speed).addToContainer(this);
430 class UIMidi extends UIWindow {
432 private final UIToggleSet deckMode;
433 private final UIButton logMode;
435 UIMidi(final MidiEngine midiEngine, float x, float y, float w, float h) {
436 super(lx.ui, "MIDI", x, y, w, h);
438 // Processing compiler doesn't seem to get that list of class objects also conform to interface
439 List<UIScrollList.Item> scrollItems = new ArrayList<UIScrollList.Item>();
440 for (SCMidiInput mc : midiEngine.getControllers()) {
443 final UIScrollList scrollList;
444 (scrollList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 100)).setItems(scrollItems).addToContainer(this);
445 (deckMode = new UIToggleSet(4, 130, 90, 20) {
446 protected void onToggle(String value) {
447 midiEngine.setFocusedDeck(value == "A" ? 0 : 1);
449 }).setOptions(new String[] { "A", "B" }).addToContainer(this);
450 (logMode = new UIButton(98, 130, w-103, 20)).setLabel("LOG").addToContainer(this);
452 SCMidiInputListener listener = new SCMidiInputListener() {
453 public void onEnabled(SCMidiInput controller, boolean enabled) {
457 for (SCMidiInput mc : midiEngine.getControllers()) {
458 mc.addListener(listener);
461 midiEngine.addListener(new MidiEngineListener() {
462 public void onFocusedDeck(int deckIndex) {
463 deckMode.setValue(deckIndex == 0 ? "A" : "B");
469 public boolean logMidi() {
470 return logMode.isActive();
473 public LXDeck getFocusedDeck() {
474 return lx.engine.getDeck(deckMode.getValue() == "A" ? LEFT_DECK : RIGHT_DECK);
478 String className(Object p, String suffix) {
479 String s = p.getClass().getName();
481 if ((li = s.lastIndexOf(".")) > 0) {
482 s = s.substring(li + 1);
484 if (s.indexOf("SugarCubes$") == 0) {
485 s = s.substring("SugarCubes$".length());
487 if ((suffix != null) && ((li = s.indexOf(suffix)) != -1)) {
488 s = s.substring(0, li);