From: Mark Slee Date: Sun, 23 Feb 2014 05:19:56 +0000 (-0800) Subject: Port to newest HeronLX, use new UI libraries X-Git-Url: https://git.piment-noir.org/?p=SugarCubes.git;a=commitdiff_plain;h=4e6626a95f23831319a73d3702789621b2248bb9 Port to newest HeronLX, use new UI libraries --- diff --git a/MarkSlee.pde b/MarkSlee.pde index 62a474d..7ccf8aa 100644 --- a/MarkSlee.pde +++ b/MarkSlee.pde @@ -14,7 +14,7 @@ class Cathedrals extends SCPattern { addParameter(sat); } - protected void onActive() { + void onActive() { if (eq == null) { eq = new GraphicEQ(lx, 16); eq.slope.setValue(0.7); @@ -809,7 +809,7 @@ class BassPod extends SCPattern { addParameter(clr); } - protected void onActive() { + void onActive() { if (eq == null) { eq = new GraphicEQ(lx, 16); eq.range.setValue(0.4); @@ -861,7 +861,7 @@ class CubeEQ extends SCPattern { super(glucose); } - protected void onActive() { + void onActive() { if (eq == null) { eq = new GraphicEQ(lx, 16); addParameter(eq.level); diff --git a/TobySegaran.pde b/TobySegaran.pde index 8aaacb1..a54658f 100644 --- a/TobySegaran.pde +++ b/TobySegaran.pde @@ -154,7 +154,7 @@ class SoundRain extends SCPattern { gain = 50*parameter.getValuef(); } } - protected void onActive() { + void onActive() { if (this.fft == null) { this.fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate()); this.fft.window(FFT.HAMMING); @@ -255,7 +255,7 @@ class SoundSpikes extends SCPattern { gain = 50*parameter.getValuef(); } } - protected void onActive() { + void onActive() { if (this.fft == null) { this.fft = new FFT(lx.audioInput().bufferSize(), lx.audioInput().sampleRate()); this.fft.window(FFT.HAMMING); diff --git a/_Internals.pde b/_Internals.pde index 425ea0e..326f6e3 100644 --- a/_Internals.pde +++ b/_Internals.pde @@ -22,6 +22,9 @@ import heronarts.lx.parameter.*; import heronarts.lx.pattern.*; import heronarts.lx.transform.*; import heronarts.lx.transition.*; +import heronarts.lx.ui.*; +import heronarts.lx.ui.component.*; +import heronarts.lx.ui.control.*; import ddf.minim.*; import ddf.minim.analysis.*; import processing.opengl.*; @@ -61,7 +64,6 @@ PImage logo; float[] hsb = new float[3]; // Handles to UI objects -UIContext[] overlays; UIPatternDeck uiPatternA; UICrossfader uiCrossfader; UIMidi uiMidi; @@ -69,9 +71,6 @@ UIMapping uiMapping; UIDebugText uiDebugText; UISpeed uiSpeed; -// Camera variables -float eyeR, eyeA, eyeX, eyeY, eyeZ, midX, midY, midZ; - /** * Engine construction and initialization. */ @@ -164,44 +163,32 @@ void setup() { // Build overlay UI debugUI = new DebugUI(pandaMappings); - overlays = new UIContext[] { - uiPatternA = new UIPatternDeck(lx.engine.getDeck(GLucose.LEFT_DECK), "PATTERN A", 4, 4, 140, 324), + UIContext[] contexts = new UIContext[] { + uiPatternA = new UIPatternDeck(lx.ui, lx.engine.getDeck(GLucose.LEFT_DECK), "PATTERN A", 4, 4, 140, 324), new UIBlendMode(4, 332, 140, 86), new UIEffects(4, 422, 140, 144), new UITempo(4, 570, 140, 50), uiSpeed = new UISpeed(4, 624, 140, 50), - new UIPatternDeck(lx.engine.getDeck(GLucose.RIGHT_DECK), "PATTERN B", width-144, 4, 140, 324), + new UIPatternDeck(lx.ui, lx.engine.getDeck(GLucose.RIGHT_DECK), "PATTERN B", width-144, 4, 140, 324), uiMidi = new UIMidi(midiEngine, width-144, 332, 140, 158), new UIOutput(width-144, 494, 140, 106), uiCrossfader = new UICrossfader(width/2-90, height-90, 180, 86), uiDebugText = new UIDebugText(148, height-138, width-304, 44), - uiMapping = new UIMapping(mappingTool, 4, 4, 140, 324), + uiMapping = new UIMapping(mappingTool, 4, 4, 140, 324) }; uiMapping.setVisible(false); + lx.ui.addLayer(new UICameraLayer(lx.ui).setCenter(TRAILER_WIDTH/2., glucose.model.yMax/2, TRAILER_DEPTH/2.).setRadius(290).addComponent(new UICubesLayer())); + for (UIContext context : contexts) { + lx.ui.addLayer(context); + } logTime("Built overlay UI"); // Load logo image logo = loadImage("data/logo.png"); - - // Setup camera - midX = TRAILER_WIDTH/2.; - midY = glucose.model.yMax/2; - midZ = TRAILER_DEPTH/2.; - eyeR = -290; - eyeA = .15; - eyeY = midY + 70; - eyeX = midX + eyeR*sin(eyeA); - eyeZ = midZ + eyeR*cos(eyeA); - - // Add mouse scrolling event support - addMouseWheelListener(new java.awt.event.MouseWheelListener() { - public void mouseWheelMoved(java.awt.event.MouseWheelEvent mwe) { - mouseWheel(mwe.getWheelRotation()); - }}); - + println("Total setup: " + (millis() - startMillis) + "ms"); println("Hit the 'p' key to toggle Panda Board output"); } @@ -212,33 +199,14 @@ void setup() { void draw() { long drawStart = System.nanoTime(); - // Draws the simulation and the 2D UI overlay + // Set background background(40); - - color[] simulationColors; - color[] sendColors; - simulationColors = sendColors = glucose.getColors(); - String displayMode = uiCrossfader.getDisplayMode(); - if (displayMode == "A") { - simulationColors = lx.engine.getDeck(GLucose.LEFT_DECK).getColors(); - } else if (displayMode == "B") { - simulationColors = lx.engine.getDeck(GLucose.RIGHT_DECK).getColors(); - } + + // Send colors + color[] sendColors = glucose.getColors(); if (debugMode) { - debugUI.maskColors(simulationColors); debugUI.maskColors(sendColors); } - - long simulationStart = System.nanoTime(); - if (simulationOn) { - drawSimulation(simulationColors); - } - long simulationNanos = System.nanoTime() - simulationStart; - - // 2D Overlay UI - long uiStart = System.nanoTime(); - drawUI(); - long uiNanos = System.nanoTime() - uiStart; long gammaStart = System.nanoTime(); // Gamma correction here. Apply a cubic to the brightness @@ -249,18 +217,52 @@ void draw() { sendColors[i] = lx.hsb(360.*hsb[0], 100.*hsb[1], 100.*(b*b*b)); } long gammaNanos = System.nanoTime() - gammaStart; - + long sendStart = System.nanoTime(); for (PandaDriver p : pandaBoards) { p.send(sendColors); } long sendNanos = System.nanoTime() - sendStart; - + + drawFPS(); + if (debugMode) { + debugUI.draw(); + } + + // TODO(mcslee): fix long drawNanos = System.nanoTime() - drawStart; + long simulationNanos = 0, uiNanos = 0; if (diagnosticsOn) { drawDiagnostics(drawNanos, simulationNanos, uiNanos, gammaNanos, sendNanos); - } + } +} + +class UICubesLayer extends UICameraComponent { + void onDraw(UI ui) { + color[] simulationColors = glucose.getColors(); + String displayMode = uiCrossfader.getDisplayMode(); + if (displayMode == "A") { + simulationColors = lx.engine.getDeck(GLucose.LEFT_DECK).getColors(); + } else if (displayMode == "B") { + simulationColors = lx.engine.getDeck(GLucose.RIGHT_DECK).getColors(); + } + if (debugMode) { + debugUI.maskColors(simulationColors); + } + + long simulationStart = System.nanoTime(); + if (simulationOn) { + drawSimulation(simulationColors); + } + long simulationNanos = System.nanoTime() - simulationStart; + + camera(); + javax.media.opengl.GL gl = ((PGraphicsOpenGL)g).beginGL(); + gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT); + ((PGraphicsOpenGL)g).endGL(); + strokeWeight(1); + } } void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long gammaNanos, long sendNanos) { @@ -321,12 +323,6 @@ void drawDiagnostics(long drawNanos, long simulationNanos, long uiNanos, long ga } void drawSimulation(color[] simulationColors) { - camera( - eyeX, eyeY, eyeZ, - midX, midY, midZ, - 0, -1, 0 - ); - translate(0, 40, 0); noStroke(); @@ -479,28 +475,12 @@ void drawBox(float x, float y, float z, float rx, float ry, float rz, float xd, popMatrix(); } -void drawUI() { - camera(); - javax.media.opengl.GL gl = ((PGraphicsOpenGL)g).beginGL(); - gl.glClear(javax.media.opengl.GL.GL_DEPTH_BUFFER_BIT); - ((PGraphicsOpenGL)g).endGL(); - strokeWeight(1); - - if (uiOn) { - for (UIContext context : overlays) { - context.draw(); - } - } - +void drawFPS() { // Always draw FPS meter fill(#555555); textSize(9); textAlign(LEFT, BASELINE); text("FPS: " + ((int) (frameRate*10)) / 10. + " / " + targetFramerate + " (-/+)", 4, height-4); - - if (debugMode) { - debugUI.draw(); - } } @@ -615,53 +595,9 @@ void keyPressed() { /** * Top-level mouse event handling */ -int mx, my; void mousePressed() { - boolean debugged = false; if (debugMode) { - debugged = debugUI.mousePressed(); - } - if (!debugged) { - for (UIContext context : overlays) { - context.mousePressed(mouseX, mouseY); - } - } - mx = mouseX; - my = mouseY; -} - -void mouseDragged() { - boolean dragged = false; - for (UIContext context : overlays) { - dragged |= context.mouseDragged(mouseX, mouseY); - } - if (!dragged) { - int dx = mouseX - mx; - int dy = mouseY - my; - mx = mouseX; - my = mouseY; - eyeA += dx*.003; - eyeX = midX + eyeR*sin(eyeA); - eyeZ = midZ + eyeR*cos(eyeA); - eyeY += dy; - } -} - -void mouseReleased() { - for (UIContext context : overlays) { - context.mouseReleased(mouseX, mouseY); + debugUI.mousePressed(); } } -void mouseWheel(int delta) { - boolean wheeled = false; - for (UIContext context : overlays) { - wheeled |= context.mouseWheel(mouseX, mouseY, delta); - } - - if (!wheeled) { - eyeR = constrain(eyeR - delta, -500, -80); - eyeX = midX + eyeR*sin(eyeA); - eyeZ = midZ + eyeR*cos(eyeA); - } -} diff --git a/_MIDI.pde b/_MIDI.pde index 4e1f20a..18fa5a3 100644 --- a/_MIDI.pde +++ b/_MIDI.pde @@ -115,7 +115,7 @@ public interface SCMidiInputListener { public void onEnabled(SCMidiInput controller, boolean enabled); } -public abstract class SCMidiInput extends AbstractScrollItem { +public abstract class SCMidiInput extends UIScrollList.AbstractItem { protected boolean enabled = false; private final String name; diff --git a/_UIImplementation.pde b/_UIImplementation.pde index 0ea8073..9fbc876 100644 --- a/_UIImplementation.pde +++ b/_UIImplementation.pde @@ -10,91 +10,16 @@ * * Custom UI components using the framework. */ - -class UIPatternDeck extends UIWindow { - - LXDeck deck; - - public UIPatternDeck(LXDeck deck, String label, float x, float y, float w, float h) { - super(label, x, y, w, h); - this.deck = deck; - int yp = titleHeight; - - List items = new ArrayList(); - for (LXPattern p : deck.getPatterns()) { - items.add(new PatternScrollItem(p)); - } - final UIScrollList patternList = new UIScrollList(1, yp, w-2, 140).setItems(items); - patternList.addToContainer(this); - yp += patternList.h + 10; - - final UIParameterKnob[] parameterKnobs = new UIParameterKnob[12]; - for (int ki = 0; ki < parameterKnobs.length; ++ki) { - parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48); - parameterKnobs[ki].addToContainer(this); - } - - LXDeck.Listener lxListener = new LXDeck.AbstractListener() { - public void patternWillChange(LXDeck deck, LXPattern pattern, LXPattern nextPattern) { - patternList.redraw(); - } - public void patternDidChange(LXDeck deck, LXPattern pattern) { - patternList.redraw(); - int pi = 0; - for (LXParameter parameter : pattern.getParameters()) { - if (pi >= parameterKnobs.length) { - break; - } - parameterKnobs[pi++].setParameter(parameter); - } - while (pi < parameterKnobs.length) { - parameterKnobs[pi++].setParameter(null); - } - } - }; - - deck.addListener(lxListener); - lxListener.patternDidChange(deck, deck.getActivePattern()); - - } - - class PatternScrollItem extends AbstractScrollItem { - - private LXPattern pattern; - private String label; - - PatternScrollItem(LXPattern pattern) { - this.pattern = pattern; - label = className(pattern, "Pattern"); - } - - public String getLabel() { - return label; - } - - public boolean isSelected() { - return deck.getActivePattern() == pattern; - } - - public boolean isPending() { - return deck.getNextPattern() == pattern; - } - - public void onMousePressed() { - deck.goPattern(pattern); - } - } -} class UIBlendMode extends UIWindow { public UIBlendMode(float x, float y, float w, float h) { - super("BLEND MODE", x, y, w, h); - List items = new ArrayList(); + super(lx.ui, "BLEND MODE", x, y, w, h); + List items = new ArrayList(); for (LXTransition t : glucose.getTransitions()) { items.add(new TransitionScrollItem(t)); } final UIScrollList tList; - (tList = new UIScrollList(1, titleHeight, w-2, 60)).setItems(items).addToContainer(this); + (tList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 60)).setItems(items).addToContainer(this); lx.engine.getDeck(GLucose.RIGHT_DECK).addListener(new LXDeck.AbstractListener() { public void faderTransitionDidChange(LXDeck deck, LXTransition transition) { @@ -103,7 +28,7 @@ class UIBlendMode extends UIWindow { }); } - class TransitionScrollItem extends AbstractScrollItem { + class TransitionScrollItem extends UIScrollList.AbstractItem { private final LXTransition transition; private String label; @@ -136,10 +61,10 @@ class UICrossfader extends UIWindow { private final UIToggleSet displayMode; public UICrossfader(float x, float y, float w, float h) { - super("CROSSFADER", x, y, w, h); + super(lx.ui, "CROSSFADER", x, y, w, h); - new UIParameterSlider(4, titleHeight, w-9, 32).setParameter(lx.engine.getDeck(GLucose.RIGHT_DECK).getFader()).addToContainer(this); - (displayMode = new UIToggleSet(4, titleHeight + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this); + new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-9, 32).setParameter(lx.engine.getDeck(GLucose.RIGHT_DECK).getFader()).addToContainer(this); + (displayMode = new UIToggleSet(4, UIWindow.TITLE_LABEL_HEIGHT + 36, w-9, 20)).setOptions(new String[] { "A", "COMP", "B" }).setValue("COMP").addToContainer(this); } public UICrossfader setDisplayMode(String value) { @@ -154,20 +79,20 @@ class UICrossfader extends UIWindow { class UIEffects extends UIWindow { UIEffects(float x, float y, float w, float h) { - super("FX", x, y, w, h); + super(lx.ui, "FX", x, y, w, h); - int yp = titleHeight; - List items = new ArrayList(); + int yp = UIWindow.TITLE_LABEL_HEIGHT; + List items = new ArrayList(); for (LXEffect fx : glucose.lx.getEffects()) { items.add(new FXScrollItem(fx)); } final UIScrollList effectsList = new UIScrollList(1, yp, w-2, 60).setItems(items); effectsList.addToContainer(this); - yp += effectsList.h + 10; + yp += effectsList.getHeight() + 10; - final UIParameterKnob[] parameterKnobs = new UIParameterKnob[4]; + final UIKnob[] parameterKnobs = new UIKnob[4]; for (int ki = 0; ki < parameterKnobs.length; ++ki) { - parameterKnobs[ki] = new UIParameterKnob(5 + 34*(ki % 4), yp + (ki/4) * 48); + parameterKnobs[ki] = new UIKnob(5 + 34*(ki % 4), yp + (ki/4) * 48); parameterKnobs[ki].addToContainer(this); } @@ -178,7 +103,9 @@ class UIEffects extends UIWindow { if (i >= parameterKnobs.length) { break; } - parameterKnobs[i++].setParameter(p); + if (p instanceof BasicParameter) { + parameterKnobs[i++].setParameter((BasicParameter) p); + } } while (i < parameterKnobs.length) { parameterKnobs[i++].setParameter(null); @@ -191,7 +118,7 @@ class UIEffects extends UIWindow { } - class FXScrollItem extends AbstractScrollItem { + class FXScrollItem extends UIScrollList.AbstractItem { private LXEffect effect; private String label; @@ -237,12 +164,12 @@ class UIEffects extends UIWindow { class UIOutput extends UIWindow { public UIOutput(float x, float y, float w, float h) { - super("OUTPUT", x, y, w, h); - float yp = titleHeight; + super(lx.ui, "OUTPUT", x, y, w, h); + float yp = UIWindow.TITLE_LABEL_HEIGHT; - final UIScrollList outputs = new UIScrollList(1, titleHeight, w-2, 80); + final UIScrollList outputs = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 80); - List items = new ArrayList(); + List items = new ArrayList(); for (final PandaDriver panda : pandaBoards) { items.add(new PandaScrollItem(panda)); panda.setListener(new PandaDriver.Listener() { @@ -254,7 +181,7 @@ class UIOutput extends UIWindow { outputs.setItems(items).addToContainer(this); } - class PandaScrollItem extends AbstractScrollItem { + class PandaScrollItem extends UIScrollList.AbstractItem { final PandaDriver panda; PandaScrollItem(PandaDriver panda) { this.panda = panda; @@ -279,8 +206,8 @@ class UITempo extends UIWindow { private final UIButton tempoButton; UITempo(float x, float y, float w, float h) { - super("TEMPO", x, y, w, h); - tempoButton = new UIButton(4, titleHeight, w-10, 20) { + super(lx.ui, "TEMPO", x, y, w, h); + tempoButton = new UIButton(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20) { protected void onToggle(boolean active) { if (active) { lx.tempo.tap(); @@ -288,17 +215,26 @@ class UITempo extends UIWindow { } }.setMomentary(true); tempoButton.addToContainer(this); + new UITempoBlipper(8, UIWindow.TITLE_LABEL_HEIGHT + 5, 12, 12).addToContainer(this); } - public void draw() { - tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.); - super.draw(); - - // Overlay tempo thing with openGL, redraw faster than button UI - fill(color(0, 0, 24 - 8*lx.tempo.rampf())); - noStroke(); - rect(x + 8, y + titleHeight + 5, 12, 12); + class UITempoBlipper extends UIObject { + UITempoBlipper(float x, float y, float w, float h) { + super(x, y, w, h); + } + + void onDraw(UI ui, PGraphics pg) { + tempoButton.setLabel("" + ((int)(lx.tempo.bpm() * 10)) / 10.); + + // Overlay tempo thing with openGL, redraw faster than button UI + pg.fill(color(0, 0, 24 - 8*lx.tempo.rampf())); + pg.noStroke(); + pg.rect(0, 0, width, height); + + redraw(); + } } + } class UIMapping extends UIWindow { @@ -318,10 +254,10 @@ class UIMapping extends UIWindow { private final UIIntegerBox stripBox; UIMapping(MappingTool tool, float x, float y, float w, float h) { - super("MAPPING", x, y, w, h); + super(lx.ui, "MAPPING", x, y, w, h); mappingTool = tool; - int yp = titleHeight; + int yp = UIWindow.TITLE_LABEL_HEIGHT; new UIToggleSet(4, yp, w-10, 20) { protected void onToggle(String value) { if (value == MAP_MODE_ALL) mappingTool.mappingMode = mappingTool.MAPPING_MODE_ALL; @@ -350,7 +286,7 @@ class UIMapping extends UIWindow { yp += 10; - new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new ScrollItem[] { + new UIScrollList(1, yp, w-2, 60).setItems(Arrays.asList(new UIScrollList.Item[] { new ColorScrollItem(ColorScrollItem.COLOR_RED), new ColorScrollItem(ColorScrollItem.COLOR_GREEN), new ColorScrollItem(ColorScrollItem.COLOR_BLUE), @@ -392,7 +328,7 @@ class UIMapping extends UIWindow { stripBox.setValue(value); } - class ColorScrollItem extends AbstractScrollItem { + class ColorScrollItem extends UIScrollList.AbstractItem { public static final int COLOR_RED = 1; public static final int COLOR_GREEN = 2; @@ -438,7 +374,7 @@ class UIDebugText extends UIContext { private String line2 = ""; UIDebugText(float x, float y, float w, float h) { - super(x, y, w, h); + super(lx.ui, x, y, w, h); } public UIDebugText setText(String line1) { @@ -455,13 +391,13 @@ class UIDebugText extends UIContext { return this; } - protected void onDraw(PGraphics pg) { - super.onDraw(pg); + protected void onDraw(UI ui, PGraphics pg) { + super.onDraw(ui, pg); if (line1.length() + line2.length() > 0) { pg.noStroke(); pg.fill(#444444); - pg.rect(0, 0, w, h); - pg.textFont(defaultItemFont); + pg.rect(0, 0, width, height); + pg.textFont(ui.getItemFont()); pg.textSize(10); pg.textAlign(LEFT, TOP); pg.fill(#cccccc); @@ -476,14 +412,14 @@ class UISpeed extends UIWindow { final BasicParameter speed; UISpeed(float x, float y, float w, float h) { - super("SPEED", x, y, w, h); + super(lx.ui, "SPEED", x, y, w, h); speed = new BasicParameter("SPEED", 0.5); - new UIParameterSlider(4, titleHeight, w-10, 20) - .setParameter(speed.addListener(new LXParameterListener() { + speed.addListener(new LXParameterListener() { public void onParameterChanged(LXParameter parameter) { lx.setSpeed(parameter.getValuef() * 2); } - })).addToContainer(this); + }); + new UISlider(4, UIWindow.TITLE_LABEL_HEIGHT, w-10, 20).setParameter(speed).addToContainer(this); } } @@ -493,15 +429,15 @@ class UIMidi extends UIWindow { private final UIButton logMode; UIMidi(final MidiEngine midiEngine, float x, float y, float w, float h) { - super("MIDI", x, y, w, h); + super(lx.ui, "MIDI", x, y, w, h); // Processing compiler doesn't seem to get that list of class objects also conform to interface - List scrollItems = new ArrayList(); + List scrollItems = new ArrayList(); for (SCMidiInput mc : midiEngine.getControllers()) { scrollItems.add(mc); } final UIScrollList scrollList; - (scrollList = new UIScrollList(1, titleHeight, w-2, 100)).setItems(scrollItems).addToContainer(this); + (scrollList = new UIScrollList(1, UIWindow.TITLE_LABEL_HEIGHT, w-2, 100)).setItems(scrollItems).addToContainer(this); (deckMode = new UIToggleSet(4, 130, 90, 20) { protected void onToggle(String value) { midiEngine.setFocusedDeck(value == "A" ? 0 : 1); diff --git a/code/HeronLX.jar b/code/HeronLX.jar index 23d5bf8..277c571 100755 Binary files a/code/HeronLX.jar and b/code/HeronLX.jar differ