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