redo with new anti-GLucose
[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 */
7d60f6f6 13import java.util.Arrays;
36e19b7b
MS
14class UICubesLayer extends UICameraComponent {
15 void onDraw(UI ui) {
16 color[] simulationColors = lx.getColors();
17 String displayMode = uiCrossfader.getDisplayMode();
18 if (displayMode == "A") {
19 simulationColors = lx.engine.getDeck(LEFT_DECK).getColors();
20 } else if (displayMode == "B") {
21 simulationColors = lx.engine.getDeck(RIGHT_DECK).getColors();
d626bc9b 22 }
36e19b7b
MS
23
24 long simulationStart = System.nanoTime();
25 if (simulationOn) {
26 drawSimulation(simulationColors);
27 }
28 simulationNanos = System.nanoTime() - simulationStart;
d626bc9b 29
36e19b7b 30 camera();
7d60f6f6 31 PGraphicsOpenGL gl = (PGraphicsOpenGL) g;
36e19b7b 32 strokeWeight(1);
d626bc9b
MS
33 }
34
36e19b7b
MS
35 void drawSimulation(color[] simulationColors) {
36 translate(0, 30, 0);
37
38 noStroke();
39 fill(#141414);
40 drawBox(0, -TRAILER_HEIGHT, 0, 0, 0, 0, TRAILER_WIDTH, TRAILER_HEIGHT, TRAILER_DEPTH, TRAILER_HEIGHT/2.);
41 fill(#070707);
42 stroke(#222222);
43 beginShape();
44 vertex(0, 0, 0);
45 vertex(TRAILER_WIDTH, 0, 0);
46 vertex(TRAILER_WIDTH, 0, TRAILER_DEPTH);
47 vertex(0, 0, TRAILER_DEPTH);
48 endShape();
49
50 // Draw the logo on the front of platform
51 pushMatrix();
52 translate(0, 0, -1);
53 float s = .07;
54 scale(s, -s, s);
55 image(logo, TRAILER_WIDTH/2/s-logo.width/2, TRAILER_HEIGHT/2/s-logo.height/2-2/s);
56 popMatrix();
d626bc9b 57
36e19b7b
MS
58 noStroke();
59 for (Cube c : model.cubes) {
60 drawCube(c);
d626bc9b 61 }
36e19b7b
MS
62
63 noFill();
64 strokeWeight(2);
65 beginShape(POINTS);
66 for (LXPoint p : model.points) {
67 stroke(simulationColors[p.index]);
68 vertex(p.x, p.y, p.z);
69 }
70 endShape();
71 }
72
73 void drawCube(Cube c) {
74 float in = .15;
75 noStroke();
76 fill(#393939);
77 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);
78 }
79
80 void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, float yd, float zd, float sw) {
81 pushMatrix();
82 translate(x, y, z);
83 rotate(rx / 180. * PI, -1, 0, 0);
84 rotate(ry / 180. * PI, 0, -1, 0);
85 rotate(rz / 180. * PI, 0, 0, -1);
86 for (int i = 0; i < 4; ++i) {
87 float wid = (i % 2 == 0) ? xd : zd;
88
89 beginShape();
90 vertex(0, 0);
91 vertex(wid, 0);
92 vertex(wid, yd);
93 vertex(wid - sw, yd);
94 vertex(wid - sw, sw);
95 vertex(0, sw);
96 endShape();
97 beginShape();
98 vertex(0, sw);
99 vertex(0, yd);
100 vertex(wid - sw, yd);
101 vertex(wid - sw, yd - sw);
102 vertex(sw, yd - sw);
103 vertex(sw, sw);
104 endShape();
105
106 translate(wid, 0, 0);
107 rotate(HALF_PI, 0, -1, 0);
d626bc9b 108 }
36e19b7b 109 popMatrix();
d626bc9b
MS
110 }
111}
112
a8d55ade
MS
113class UIBlendMode extends UIWindow {
114 public UIBlendMode(float x, float y, float w, float h) {
4e6626a9
MS
115 super(lx.ui, "BLEND MODE", x, y, w, h);
116 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
3f16fd02 117 for (LXTransition t : transitions) {
d626bc9b 118 items.add(new TransitionScrollItem(t));
a898d79b
MS
119 }
120 final UIScrollList tList;
4e6626a9 121 (tList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 60)).setItems(items).addToContainer(this);
a8d55ade 122
0c7bfdb5 123 lx.engine.getDeck(RIGHT_DECK).addListener(new LXDeck.AbstractListener() {
42a424d7 124 public void faderTransitionDidChange(LXDeck deck, LXTransition transition) {
a898d79b 125 tList.redraw();
d626bc9b 126 }
a898d79b
MS
127 });
128 }
a8d55ade 129
4e6626a9 130 class TransitionScrollItem extends UIScrollList.AbstractItem {
a8d55ade 131 private final LXTransition transition;
3f16fd02 132 private final String label;
a8d55ade
MS
133
134 TransitionScrollItem(LXTransition transition) {
135 this.transition = transition;
3f16fd02 136 this.label = className(transition, "Transition");
a8d55ade
MS
137 }
138
139 public String getLabel() {
140 return label;
141 }
142
143 public boolean isSelected() {
0c7bfdb5 144 return this.transition == lx.engine.getDeck(RIGHT_DECK).getFaderTransition();
a8d55ade
MS
145 }
146
147 public boolean isPending() {
148 return false;
149 }
150
151 public void onMousePressed() {
0c7bfdb5 152 lx.engine.getDeck(RIGHT_DECK).setFaderTransition(this.transition);
a8d55ade 153 }
d626bc9b 154 }
a8d55ade 155
d626bc9b
MS
156}
157
a8d55ade 158class UICrossfader extends UIWindow {
d626bc9b 159
a8d55ade 160 private final UIToggleSet displayMode;
d626bc9b 161
a8d55ade 162 public UICrossfader(float x, float y, float w, float h) {
4e6626a9 163 super(lx.ui, "CROSSFADER", x, y, w, h);
a8d55ade 164
0c7bfdb5 165 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-9, 32).setParameter(lx.engine.getDeck(RIGHT_DECK).getFader()).addToContainer(this);
4e6626a9 166 (displayMode = new UIToggleSet(4, UIWindow.TITLE_LABEL_HEIGHT + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this);
d626bc9b
MS
167 }
168
88a3dd9e
MS
169 public UICrossfader setDisplayMode(String value) {
170 displayMode.setValue(value);
171 return this;
172 }
173
a8d55ade
MS
174 public String getDisplayMode() {
175 return displayMode.getValue();
d626bc9b
MS
176 }
177}
178
179class UIEffects extends UIWindow {
180 UIEffects(float x, float y, float w, float h) {
4e6626a9 181 super(lx.ui, "FX", x, y, w, h);
d626bc9b 182
4e6626a9
MS
183 int yp = UIWindow.TITLE_LABEL_HEIGHT;
184 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
0c7bfdb5
MS
185 int i = 0;
186 for (LXEffect fx : effectsArr) {
187 items.add(new FXScrollItem(fx, i++));
d626bc9b
MS
188 }
189 final UIScrollList effectsList = new UIScrollList(1, yp, w-2, 60).setItems(items);
190 effectsList.addToContainer(this);
4e6626a9 191 yp += effectsList.getHeight() + 10;
d626bc9b 192
4e6626a9 193 final UIKnob[] parameterKnobs = new UIKnob[4];
d626bc9b 194 for (int ki = 0; ki < parameterKnobs.length; ++ki) {
4e6626a9 195 parameterKnobs[ki] = new UIKnob(5 + 34*(ki % 4), yp + (ki/4) * 48);
d626bc9b
MS
196 parameterKnobs[ki].addToContainer(this);
197 }
198
0c7bfdb5
MS
199 LXParameterListener fxListener = new LXParameterListener() {
200 public void onParameterChanged(LXParameter parameter) {
d626bc9b 201 int i = 0;
0c7bfdb5 202 for (LXParameter p : getSelectedEffect().getParameters()) {
d626bc9b
MS
203 if (i >= parameterKnobs.length) {
204 break;
205 }
4e6626a9
MS
206 if (p instanceof BasicParameter) {
207 parameterKnobs[i++].setParameter((BasicParameter) p);
208 }
d626bc9b
MS
209 }
210 while (i < parameterKnobs.length) {
211 parameterKnobs[i++].setParameter(null);
212 }
213 }
214 };
215
0c7bfdb5
MS
216 selectedEffect.addListener(fxListener);
217 fxListener.onParameterChanged(null);
d626bc9b
MS
218
219 }
220
4e6626a9 221 class FXScrollItem extends UIScrollList.AbstractItem {
d626bc9b 222
0c7bfdb5
MS
223 private final LXEffect effect;
224 private final int index;
225 private final String label;
d626bc9b 226
0c7bfdb5 227 FXScrollItem(LXEffect effect, int index) {
d626bc9b 228 this.effect = effect;
0c7bfdb5
MS
229 this.index = index;
230 this.label = className(effect, "Effect");
d626bc9b
MS
231 }
232
233 public String getLabel() {
234 return label;
235 }
236
237 public boolean isSelected() {
0c7bfdb5 238 return !effect.isEnabled() && (effect == getSelectedEffect());
d626bc9b
MS
239 }
240
241 public boolean isPending() {
242 return effect.isEnabled();
243 }
244
d626bc9b 245 public void onMousePressed() {
0c7bfdb5 246 if (effect == getSelectedEffect()) {
d626bc9b
MS
247 if (effect.isMomentary()) {
248 effect.enable();
249 } else {
250 effect.toggle();
251 }
8f7f055d 252 } else {
0c7bfdb5 253 selectedEffect.setValue(index);
d626bc9b
MS
254 }
255 }
256
257 public void onMouseReleased() {
258 if (effect.isMomentary()) {
259 effect.disable();
260 }
261 }
262
263 }
264
265}
266
267class UIOutput extends UIWindow {
e037f60f 268 public UIOutput(GrizzlyOutput[] grizzlies, float x, float y, float w, float h) {
4e6626a9
MS
269 super(lx.ui, "OUTPUT", x, y, w, h);
270 float yp = UIWindow.TITLE_LABEL_HEIGHT;
1f42cce7 271
4e6626a9 272 final UIScrollList outputs = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 80);
1f42cce7 273
4e6626a9 274 List<UIScrollList.Item> items = new ArrayList<UIScrollList.Item>();
e037f60f
MS
275 for (GrizzlyOutput grizzly : grizzlies) {
276 items.add(new GrizzlyScrollItem(grizzly));
277 grizzly.enabled.addListener(new LXParameterListener() {
278 public void onParameterChanged(LXParameter parameter) {
1f42cce7 279 outputs.redraw();
d626bc9b
MS
280 }
281 });
d626bc9b 282 }
1f42cce7
MS
283 outputs.setItems(items).addToContainer(this);
284 }
285
e037f60f
MS
286 class GrizzlyScrollItem extends UIScrollList.AbstractItem {
287 final GrizzlyOutput output;
288
289 GrizzlyScrollItem(GrizzlyOutput output) {
290 this.output = output;
1f42cce7
MS
291 }
292
293 public String getLabel() {
e037f60f 294 return output.ipAddress;
1f42cce7
MS
295 }
296
297 public boolean isSelected() {
e037f60f 298 return output.enabled.isOn();
1f42cce7
MS
299 }
300
8f7f055d 301 public void onMousePressed() {
4749563e 302 output.enabled.setValue(!isSelected());
1f42cce7
MS
303 }
304 }
d626bc9b
MS
305}
306
307class UITempo extends UIWindow {
308
309 private final UIButton tempoButton;
310
311 UITempo(float x, float y, float w, float h) {
4e6626a9
MS
312 super(lx.ui, "TEMPO", x, y, w, h);
313 tempoButton = new UIButton(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20) {
d626bc9b
MS
314 protected void onToggle(boolean active) {
315 if (active) {
316 lx.tempo.tap();
317 }
318 }
319 }.setMomentary(true);
320 tempoButton.addToContainer(this);
4e6626a9 321 new UITempoBlipper(8, UIWindow.TITLE_LABEL_HEIGHT + 5, 12, 12).addToContainer(this);
d626bc9b
MS
322 }
323
4e6626a9
MS
324 class UITempoBlipper extends UIObject {
325 UITempoBlipper(float x, float y, float w, float h) {
326 super(x, y, w, h);
327 }
d626bc9b 328
4e6626a9
MS
329 void onDraw(UI ui, PGraphics pg) {
330 tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.);
331
332 // Overlay tempo thing with openGL, redraw faster than button UI
333 pg.fill(color(0, 0, 24 - 8*lx.tempo.rampf()));
334 pg.noStroke();
335 pg.rect(0, 0, width, height);
336
337 redraw();
338 }
d626bc9b 339 }
4e6626a9 340
d626bc9b
MS
341}
342
343class UIMapping extends UIWindow {
344
345 private static final String MAP_MODE_ALL = "ALL";
346 private static final String MAP_MODE_CHANNEL = "CHNL";
347 private static final String MAP_MODE_CUBE = "CUBE";
348
349 private static final String CUBE_MODE_ALL = "ALL";
350 private static final String CUBE_MODE_STRIP = "SNGL";
351 private static final String CUBE_MODE_PATTERN = "PTRN";
352
353 private final MappingTool mappingTool;
354
355 private final UIIntegerBox channelBox;
356 private final UIIntegerBox cubeBox;
357 private final UIIntegerBox stripBox;
358
359 UIMapping(MappingTool tool, float x, float y, float w, float h) {
4e6626a9 360 super(lx.ui, "MAPPING", x, y, w, h);
d626bc9b
MS
361 mappingTool = tool;
362
4e6626a9 363 int yp = UIWindow.TITLE_LABEL_HEIGHT;
78a44a1b 364 new UIToggleSet(4, yp, w-10, 20) {
d626bc9b
MS
365 protected void onToggle(String value) {
366 if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL;
367 else if (value == MAP_MODE_CHANNEL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_CHANNEL;
368 else if (value == MAP_MODE_CUBE) mappingTool.mappingMode = mappingTool.MAPPING_MODE_SINGLE_CUBE;
369 }
370 }.setOptions(new String[] { MAP_MODE_ALL, MAP_MODE_CHANNEL, MAP_MODE_CUBE }).addToContainer(this);
371 yp += 24;
78a44a1b 372 new UILabel(4, yp+8, w-10, 20).setLabel("CHANNEL ID").addToContainer(this);
d626bc9b 373 yp += 24;
78a44a1b 374 (channelBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
375 protected void onValueChange(int value) {
376 mappingTool.setChannel(value-1);
377 }
378 }).setRange(1, mappingTool.numChannels()).addToContainer(this);
379 yp += 24;
380
78a44a1b 381 new UILabel(4, yp+8, w-10, 20).setLabel("CUBE ID").addToContainer(this);
d626bc9b 382 yp += 24;
78a44a1b 383 (cubeBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
384 protected void onValueChange(int value) {
385 mappingTool.setCube(value-1);
386 }
b9b7b3d4 387 }).setRange(1, model.cubes.size()).addToContainer(this);
d626bc9b
MS
388 yp += 24;
389
a8d55ade
MS
390 yp += 10;
391
4e6626a9 392 new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new UIScrollList.Item[] {
d626bc9b
MS
393 new ColorScrollItem(ColorScrollItem.COLOR_RED),
394 new ColorScrollItem(ColorScrollItem.COLOR_GREEN),
395 new ColorScrollItem(ColorScrollItem.COLOR_BLUE),
396 })).addToContainer(this);
397 yp += 64;
398
78a44a1b 399 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP MODE").addToContainer(this);
d626bc9b
MS
400 yp += 24;
401
78a44a1b 402 new UIToggleSet(4, yp, w-10, 20) {
d626bc9b
MS
403 protected void onToggle(String value) {
404 if (value == CUBE_MODE_ALL) mappingTool.cubeMode = mappingTool.CUBE_MODE_ALL;
405 else if (value == CUBE_MODE_STRIP) mappingTool.cubeMode = mappingTool.CUBE_MODE_SINGLE_STRIP;
406 else if (value == CUBE_MODE_PATTERN) mappingTool.cubeMode = mappingTool.CUBE_MODE_STRIP_PATTERN;
407 }
408 }.setOptions(new String[] { CUBE_MODE_ALL, CUBE_MODE_STRIP, CUBE_MODE_PATTERN }).addToContainer(this);
409
410 yp += 24;
78a44a1b 411 new UILabel(4, yp+8, w-10, 20).setLabel("STRIP ID").addToContainer(this);
d626bc9b
MS
412
413 yp += 24;
78a44a1b 414 (stripBox = new UIIntegerBox(4, yp, w-10, 20) {
d626bc9b
MS
415 protected void onValueChange(int value) {
416 mappingTool.setStrip(value-1);
417 }
418 }).setRange(1, Cube.STRIPS_PER_CUBE).addToContainer(this);
419
420 }
421
422 public void setChannelID(int value) {
423 channelBox.setValue(value);
424 }
425
426 public void setCubeID(int value) {
427 cubeBox.setValue(value);
428 }
429
430 public void setStripID(int value) {
431 stripBox.setValue(value);
432 }
433
4e6626a9 434 class ColorScrollItem extends UIScrollList.AbstractItem {
d626bc9b
MS
435
436 public static final int COLOR_RED = 1;
437 public static final int COLOR_GREEN = 2;
438 public static final int COLOR_BLUE = 3;
439
440 private final int colorChannel;
441
442 ColorScrollItem(int colorChannel) {
443 this.colorChannel = colorChannel;
444 }
445
446 public String getLabel() {
447 switch (colorChannel) {
448 case COLOR_RED: return "Red";
449 case COLOR_GREEN: return "Green";
450 case COLOR_BLUE: return "Blue";
451 }
452 return "";
453 }
454
455 public boolean isSelected() {
456 switch (colorChannel) {
457 case COLOR_RED: return mappingTool.channelModeRed;
458 case COLOR_GREEN: return mappingTool.channelModeGreen;
459 case COLOR_BLUE: return mappingTool.channelModeBlue;
460 }
461 return false;
462 }
463
a8d55ade 464 public void onMousePressed() {
d626bc9b
MS
465 switch (colorChannel) {
466 case COLOR_RED: mappingTool.channelModeRed = !mappingTool.channelModeRed; break;
467 case COLOR_GREEN: mappingTool.channelModeGreen = !mappingTool.channelModeGreen; break;
468 case COLOR_BLUE: mappingTool.channelModeBlue = !mappingTool.channelModeBlue; break;
469 }
470 }
471 }
472}
473
474class UIDebugText extends UIContext {
475
476 private String line1 = "";
477 private String line2 = "";
478
479 UIDebugText(float x, float y, float w, float h) {
4e6626a9 480 super(lx.ui, x, y, w, h);
d626bc9b
MS
481 }
482
483 public UIDebugText setText(String line1) {
484 return setText(line1, "");
485 }
486
487 public UIDebugText setText(String line1, String line2) {
488 if (!line1.equals(this.line1) || !line2.equals(this.line2)) {
489 this.line1 = line1;
490 this.line2 = line2;
491 setVisible(line1.length() + line2.length() > 0);
492 redraw();
493 }
494 return this;
495 }
496
4e6626a9
MS
497 protected void onDraw(UI ui, PGraphics pg) {
498 super.onDraw(ui, pg);
d626bc9b
MS
499 if (line1.length() + line2.length() > 0) {
500 pg.noStroke();
501 pg.fill(#444444);
4e6626a9
MS
502 pg.rect(0, 0, width, height);
503 pg.textFont(ui.getItemFont());
a8d55ade 504 pg.textSize(10);
d626bc9b
MS
505 pg.textAlign(LEFT, TOP);
506 pg.fill(#cccccc);
507 pg.text(line1, 4, 4);
508 pg.text(line2, 4, 24);
509 }
510 }
511}
512
34327c96 513class UISpeed extends UIWindow {
fa4f822d
MS
514
515 final BasicParameter speed;
516
34327c96 517 UISpeed(float x, float y, float w, float h) {
4e6626a9 518 super(lx.ui, "SPEED", x, y, w, h);
fa4f822d 519 speed = new BasicParameter("SPEED", 0.5);
4e6626a9 520 speed.addListener(new LXParameterListener() {
34327c96
MS
521 public void onParameterChanged(LXParameter parameter) {
522 lx.setSpeed(parameter.getValuef() * 2);
523 }
4e6626a9
MS
524 });
525 new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20).setParameter(speed).addToContainer(this);
34327c96
MS
526 }
527}
528
a8d55ade
MS
529class UIMidi extends UIWindow {
530
9692dc7b
MS
531 private final UIToggleSet deckMode;
532 private final UIButton logMode;
a8d55ade 533
d6ac1ee8 534 UIMidi(final MidiEngine midiEngine, float x, float y, float w, float h) {
4e6626a9 535 super(lx.ui, "MIDI", x, y, w, h);
d6ac1ee8 536
a8d55ade 537 // Processing compiler doesn't seem to get that list of class objects also conform to interface
4e6626a9 538 List<UIScrollList.Item> scrollItems = new ArrayList<UIScrollList.Item>();
d6ac1ee8 539 for (SCMidiInput mc : midiEngine.getControllers()) {
30bf6510 540 scrollItems.add(mc);
a8d55ade 541 }
30bf6510 542 final UIScrollList scrollList;
4e6626a9 543 (scrollList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 100)).setItems(scrollItems).addToContainer(this);
d6ac1ee8
MS
544 (deckMode = new UIToggleSet(4, 130, 90, 20) {
545 protected void onToggle(String value) {
546 midiEngine.setFocusedDeck(value == "A" ? 0 : 1);
547 }
548 }).setOptions(new String[] { "A", "B" }).addToContainer(this);
4df91daf 549 (logMode = new UIButton(98, 130, w-103, 20)).setLabel("LOG").addToContainer(this);
30bf6510
MS
550
551 SCMidiInputListener listener = new SCMidiInputListener() {
552 public void onEnabled(SCMidiInput controller, boolean enabled) {
553 scrollList.redraw();
554 }
555 };
d6ac1ee8 556 for (SCMidiInput mc : midiEngine.getControllers()) {
30bf6510
MS
557 mc.addListener(listener);
558 }
d6ac1ee8
MS
559
560 midiEngine.addListener(new MidiEngineListener() {
561 public void onFocusedDeck(int deckIndex) {
562 deckMode.setValue(deckIndex == 0 ? "A" : "B");
563 }
564 });
30bf6510 565
9692dc7b
MS
566 }
567
568 public boolean logMidi() {
569 return logMode.isActive();
a8d55ade
MS
570 }
571
42a424d7 572 public LXDeck getFocusedDeck() {
0c7bfdb5 573 return lx.engine.getDeck(deckMode.getValue() == "A" ? LEFT_DECK : RIGHT_DECK);
a8d55ade
MS
574 }
575}
576
d626bc9b
MS
577String className(Object p, String suffix) {
578 String s = p.getClass().getName();
579 int li;
580 if ((li = s.lastIndexOf(".")) > 0) {
581 s = s.substring(li + 1);
582 }
583 if (s.indexOf("SugarCubes$") == 0) {
584 s = s.substring("SugarCubes$".length());
585 }
586 if ((suffix != null) && ((li = s.indexOf(suffix)) != -1)) {
587 s = s.substring(0, li);
588 }
589 return s;
590}