Remove select() from UIScrollList, just mouse events
[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 */
13
14class UIPatternDeck extends UIWindow {
15
16 Engine.Deck deck;
17
18 public UIPatternDeck(Engine.Deck deck, String label, float x, float y, float w, float h) {
19 super(label, x, y, w, h);
20 this.deck = deck;
21 int yp = titleHeight;
22
23 List<ScrollItem> items = new ArrayList<ScrollItem>();
24 for (LXPattern p : deck.getPatterns()) {
25 items.add(new PatternScrollItem(p));
26 }
27 final UIScrollList patternList = new UIScrollList(1, yp, w-2, 160).setItems(items);
28 patternList.addToContainer(this);
29 yp += patternList.h + 10;
30
31 final UIParameterKnob[] parameterKnobs = new UIParameterKnob[12];
32 for (int ki = 0; ki < parameterKnobs.length; ++ki) {
33 parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
34 parameterKnobs[ki].addToContainer(this);
35 }
36
37 Engine.Listener lxListener = new Engine.Listener() {
38 public void patternWillChange(Engine.Deck deck, LXPattern pattern, LXPattern nextPattern) {
39 patternList.redraw();
40 }
41 public void patternDidChange(Engine.Deck deck, LXPattern pattern) {
42 patternList.redraw();
43 int pi = 0;
44 for (LXParameter parameter : pattern.getParameters()) {
45 if (pi >= parameterKnobs.length) {
46 break;
47 }
48 parameterKnobs[pi++].setParameter(parameter);
49 }
50 while (pi < parameterKnobs.length) {
51 parameterKnobs[pi++].setParameter(null);
52 }
53 }
54 };
55
56 deck.addListener(lxListener);
57 lxListener.patternDidChange(deck, deck.getActivePattern());
58
59 }
60
61 class PatternScrollItem extends AbstractScrollItem {
62
63 private LXPattern pattern;
64 private String label;
65
66 PatternScrollItem(LXPattern pattern) {
67 this.pattern = pattern;
68 label = className(pattern, "Pattern");
69 }
70
71 public String getLabel() {
72 return label;
73 }
74
75 public boolean isSelected() {
76 return deck.getActivePattern() == pattern;
77 }
78
79 public boolean isPending() {
80 return deck.getNextPattern() == pattern;
81 }
82
8f7f055d 83 public void onMousePressed() {
d626bc9b
MS
84 deck.goPattern(pattern);
85 }
86 }
87}
88
89class UICrossfader extends UIWindow {
90
91 public UICrossfader(float x, float y, float w, float h) {
92 super("CROSSFADER", x, y, w, h);
93
94 List<ScrollItem> items = new ArrayList<ScrollItem>();
95 for (LXTransition t : transitions) {
96 items.add(new TransitionScrollItem(t));
97 }
fe30b226
MS
98 new UIScrollList(1, titleHeight, w-2, 120).setItems(items).addToContainer(this);
99 new UIParameterSlider(4, titleHeight + 126, w-10, 24).setParameter(lx.engine.getDeck(1).getCrossfader()).addToContainer(this);
100 new UIToggleSet(4, 182, w-10, 20) {
d626bc9b
MS
101 protected void onToggle(String value) {
102 displayMode = value;
103 }
104 }.setOptions(new String[] { "A", "COMP", "B" }).setValue(displayMode = "COMP").addToContainer(this);
105 }
106}
107
108class TransitionScrollItem extends AbstractScrollItem {
109 private final LXTransition transition;
110 private String label;
111
112 TransitionScrollItem(LXTransition transition) {
113 this.transition = transition;
114 label = className(transition, "Transition");
115 }
116
117 public String getLabel() {
118 return label;
119 }
120
121 public boolean isSelected() {
122 return transition == lx.engine.getDeck(1).getBlendTransition();
123 }
124
125 public boolean isPending() {
126 return false;
127 }
128
8f7f055d 129 public void onMousePressed() {
d626bc9b
MS
130 lx.engine.getDeck(1).setBlendTransition(transition);
131 }
132}
133
134class UIEffects extends UIWindow {
135 UIEffects(float x, float y, float w, float h) {
136 super("FX", x, y, w, h);
137
138 int yp = titleHeight;
139 List<ScrollItem> items = new ArrayList<ScrollItem>();
140 for (LXEffect fx : glucose.lx.getEffects()) {
141 items.add(new FXScrollItem(fx));
142 }
143 final UIScrollList effectsList = new UIScrollList(1, yp, w-2, 60).setItems(items);
144 effectsList.addToContainer(this);
145 yp += effectsList.h + 10;
146
147 final UIParameterKnob[] parameterKnobs = new UIParameterKnob[4];
148 for (int ki = 0; ki < parameterKnobs.length; ++ki) {
149 parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
150 parameterKnobs[ki].addToContainer(this);
151 }
152
153 GLucose.EffectListener fxListener = new GLucose.EffectListener() {
154 public void effectSelected(LXEffect effect) {
155 int i = 0;
156 for (LXParameter p : effect.getParameters()) {
157 if (i >= parameterKnobs.length) {
158 break;
159 }
160 parameterKnobs[i++].setParameter(p);
161 }
162 while (i < parameterKnobs.length) {
163 parameterKnobs[i++].setParameter(null);
164 }
165 }
166 };
167
168 glucose.addEffectListener(fxListener);
169 fxListener.effectSelected(glucose.getSelectedEffect());
170
171 }
172
173 class FXScrollItem extends AbstractScrollItem {
174
175 private LXEffect effect;
176 private String label;
177
178 FXScrollItem(LXEffect effect) {
179 this.effect = effect;
180 label = className(effect, "Effect");
181 }
182
183 public String getLabel() {
184 return label;
185 }
186
187 public boolean isSelected() {
188 return !effect.isEnabled() && (glucose.getSelectedEffect() == effect);
189 }
190
191 public boolean isPending() {
192 return effect.isEnabled();
193 }
194
d626bc9b
MS
195 public void onMousePressed() {
196 if (glucose.getSelectedEffect() == effect) {
197 if (effect.isMomentary()) {
198 effect.enable();
199 } else {
200 effect.toggle();
201 }
8f7f055d
MS
202 } else {
203 glucose.setSelectedEffect(effect);
d626bc9b
MS
204 }
205 }
206
207 public void onMouseReleased() {
208 if (effect.isMomentary()) {
209 effect.disable();
210 }
211 }
212
213 }
214
215}
216
217class UIOutput extends UIWindow {
218 public UIOutput(float x, float y, float w, float h) {
219 super("OUTPUT", x, y, w, h);
220 float yp = titleHeight;
1f42cce7
MS
221
222 final UIScrollList outputs = new UIScrollList(1, titleHeight, w-2, 80);
223
224 List<ScrollItem> items = new ArrayList<ScrollItem>();
d626bc9b 225 for (final PandaDriver panda : pandaBoards) {
1f42cce7 226 items.add(new PandaScrollItem(panda));
d626bc9b
MS
227 panda.setListener(new PandaDriver.Listener() {
228 public void onToggle(boolean active) {
1f42cce7 229 outputs.redraw();
d626bc9b
MS
230 }
231 });
d626bc9b 232 }
1f42cce7
MS
233 outputs.setItems(items).addToContainer(this);
234 }
235
236 class PandaScrollItem extends AbstractScrollItem {
237 final PandaDriver panda;
238 PandaScrollItem(PandaDriver panda) {
239 this.panda = panda;
240 }
241
242 public String getLabel() {
243 return panda.ip;
244 }
245
246 public boolean isSelected() {
247 return panda.isEnabled();
248 }
249
8f7f055d 250 public void onMousePressed() {
1f42cce7
MS
251 panda.toggle();
252 }
253 }
d626bc9b
MS
254}
255
256class UITempo extends UIWindow {
257
258 private final UIButton tempoButton;
259
260 UITempo(float x, float y, float w, float h) {
261 super("TEMPO", x, y, w, h);
78a44a1b 262 tempoButton = new UIButton(4, titleHeight, w-10, 20) {
d626bc9b
MS
263 protected void onToggle(boolean active) {
264 if (active) {
265 lx.tempo.tap();
266 }
267 }
268 }.setMomentary(true);
269 tempoButton.addToContainer(this);
270 }
271
272 public void draw() {
273 tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.);
274 super.draw();
275
276 // Overlay tempo thing with openGL, redraw faster than button UI
277 fill(color(0, 0, 24 - 8*lx.tempo.rampf()));
278 noStroke();
279 rect(x + 8, y + titleHeight + 5, 12, 12);
280 }
281}
282
283class UIMapping extends UIWindow {
284
285 private static final String MAP_MODE_ALL = "ALL";
286 private static final String MAP_MODE_CHANNEL = "CHNL";
287 private static final String MAP_MODE_CUBE = "CUBE";
288
289 private static final String CUBE_MODE_ALL = "ALL";
290 private static final String CUBE_MODE_STRIP = "SNGL";
291 private static final String CUBE_MODE_PATTERN = "PTRN";
292
293 private final MappingTool mappingTool;
294
295 private final UIIntegerBox channelBox;
296 private final UIIntegerBox cubeBox;
297 private final UIIntegerBox stripBox;
298
299 UIMapping(MappingTool tool, float x, float y, float w, float h) {
300 super("MAPPING", x, y, w, h);
301 mappingTool = tool;
302
303 int yp = titleHeight;
78a44a1b 304 new UIToggleSet(4, yp, w-10, 20) {
d626bc9b
MS
305 protected void onToggle(String value) {
306 if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL;
307 else if (value == MAP_MODE_CHANNEL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_CHANNEL;
308 else if (value == MAP_MODE_CUBE) mappingTool.mappingMode = mappingTool.MAPPING_MODE_SINGLE_CUBE;
309 }
310 }.setOptions(new String[] { MAP_MODE_ALL, MAP_MODE_CHANNEL, MAP_MODE_CUBE }).addToContainer(this);
311 yp += 24;
78a44a1b 312 new UILabel(4, yp+8, w-10, 20).setLabel("CHANNEL ID").addToContainer(this);
d626bc9b 313 yp += 24;
78a44a1b 314 (channelBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
315 protected void onValueChange(int value) {
316 mappingTool.setChannel(value-1);
317 }
318 }).setRange(1, mappingTool.numChannels()).addToContainer(this);
319 yp += 24;
320
78a44a1b 321 new UILabel(4, yp+8, w-10, 20).setLabel("CUBE ID").addToContainer(this);
d626bc9b 322 yp += 24;
78a44a1b 323 (cubeBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
324 protected void onValueChange(int value) {
325 mappingTool.setCube(value-1);
326 }
327 }).setRange(1, glucose.model.cubes.size()).addToContainer(this);
328 yp += 24;
329
78a44a1b 330 new UILabel(4, yp+8, w-10, 20).setLabel("COLORS").addToContainer(this);
d626bc9b
MS
331 yp += 24;
332
333 new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new ScrollItem[] {
334 new ColorScrollItem(ColorScrollItem.COLOR_RED),
335 new ColorScrollItem(ColorScrollItem.COLOR_GREEN),
336 new ColorScrollItem(ColorScrollItem.COLOR_BLUE),
337 })).addToContainer(this);
338 yp += 64;
339
78a44a1b 340 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP MODE").addToContainer(this);
d626bc9b
MS
341 yp += 24;
342
78a44a1b 343 new UIToggleSet(4, yp, w-10, 20) {
d626bc9b
MS
344 protected void onToggle(String value) {
345 if (value == CUBE_MODE_ALL) mappingTool.cubeMode = mappingTool.CUBE_MODE_ALL;
346 else if (value == CUBE_MODE_STRIP) mappingTool.cubeMode = mappingTool.CUBE_MODE_SINGLE_STRIP;
347 else if (value == CUBE_MODE_PATTERN) mappingTool.cubeMode = mappingTool.CUBE_MODE_STRIP_PATTERN;
348 }
349 }.setOptions(new String[] { CUBE_MODE_ALL, CUBE_MODE_STRIP, CUBE_MODE_PATTERN }).addToContainer(this);
350
351 yp += 24;
78a44a1b 352 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP ID").addToContainer(this);
d626bc9b
MS
353
354 yp += 24;
78a44a1b 355 (stripBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
356 protected void onValueChange(int value) {
357 mappingTool.setStrip(value-1);
358 }
359 }).setRange(1, Cube.STRIPS_PER_CUBE).addToContainer(this);
360
361 }
362
363 public void setChannelID(int value) {
364 channelBox.setValue(value);
365 }
366
367 public void setCubeID(int value) {
368 cubeBox.setValue(value);
369 }
370
371 public void setStripID(int value) {
372 stripBox.setValue(value);
373 }
374
375 class ColorScrollItem extends AbstractScrollItem {
376
377 public static final int COLOR_RED = 1;
378 public static final int COLOR_GREEN = 2;
379 public static final int COLOR_BLUE = 3;
380
381 private final int colorChannel;
382
383 ColorScrollItem(int colorChannel) {
384 this.colorChannel = colorChannel;
385 }
386
387 public String getLabel() {
388 switch (colorChannel) {
389 case COLOR_RED: return "Red";
390 case COLOR_GREEN: return "Green";
391 case COLOR_BLUE: return "Blue";
392 }
393 return "";
394 }
395
396 public boolean isSelected() {
397 switch (colorChannel) {
398 case COLOR_RED: return mappingTool.channelModeRed;
399 case COLOR_GREEN: return mappingTool.channelModeGreen;
400 case COLOR_BLUE: return mappingTool.channelModeBlue;
401 }
402 return false;
403 }
404
405 public void select() {
406 switch (colorChannel) {
407 case COLOR_RED: mappingTool.channelModeRed = !mappingTool.channelModeRed; break;
408 case COLOR_GREEN: mappingTool.channelModeGreen = !mappingTool.channelModeGreen; break;
409 case COLOR_BLUE: mappingTool.channelModeBlue = !mappingTool.channelModeBlue; break;
410 }
411 }
412 }
413}
414
415class UIDebugText extends UIContext {
416
417 private String line1 = "";
418 private String line2 = "";
419
420 UIDebugText(float x, float y, float w, float h) {
421 super(x, y, w, h);
422 }
423
424 public UIDebugText setText(String line1) {
425 return setText(line1, "");
426 }
427
428 public UIDebugText setText(String line1, String line2) {
429 if (!line1.equals(this.line1) || !line2.equals(this.line2)) {
430 this.line1 = line1;
431 this.line2 = line2;
432 setVisible(line1.length() + line2.length() > 0);
433 redraw();
434 }
435 return this;
436 }
437
438 protected void onDraw(PGraphics pg) {
439 super.onDraw(pg);
440 if (line1.length() + line2.length() > 0) {
441 pg.noStroke();
442 pg.fill(#444444);
443 pg.rect(0, 0, w, h);
444 pg.textFont(defaultItemFont);
445 pg.textAlign(LEFT, TOP);
446 pg.fill(#cccccc);
447 pg.text(line1, 4, 4);
448 pg.text(line2, 4, 24);
449 }
450 }
451}
452
453String className(Object p, String suffix) {
454 String s = p.getClass().getName();
455 int li;
456 if ((li = s.lastIndexOf(".")) > 0) {
457 s = s.substring(li + 1);
458 }
459 if (s.indexOf("SugarCubes$") == 0) {
460 s = s.substring("SugarCubes$".length());
461 }
462 if ((suffix != null) && ((li = s.indexOf(suffix)) != -1)) {
463 s = s.substring(0, li);
464 }
465 return s;
466}