diff --git a/build.gradle.kts b/build.gradle.kts index 6bdc908..915b67e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -84,7 +84,7 @@ if(currentOS.isMacOsX) { } // If you need to set the sketchbook location manually, uncomment out the following // line and set sketchbookLocation to the correct location -sketchbookLocation = "C:/Users/danie/OneDrive/Documentos/Processing" +// sketchbookLocation = "$userHome/Documents/Processing" // Repositories where dependencies will be fetched from. diff --git a/src/main/java/paletai/mapping/Project.java b/src/main/java/paletai/mapping/Project.java index 59e84e2..2213e70 100644 --- a/src/main/java/paletai/mapping/Project.java +++ b/src/main/java/paletai/mapping/Project.java @@ -107,6 +107,14 @@ public class Project { private int transitionDuration = 2000; // 2 second transition private float transitionProgress = 0; + /** Whether spacebar loops back from the last scene to the first */ + private boolean loopScenes = false; + + /** Autoplay state and configuration */ + private boolean autoPlay = false; + private float autoPlayDelay = 5.0f; // seconds between scene advances + private int autoPlayLastTime = 0; // millis() timestamp of last advance + /** Available content generators discovered through reflection */ private ArrayList availableGenerators; @@ -920,6 +928,82 @@ public void controlEvent(CallbackEvent event) { } }); + // ---- Loop toggle button ---- + Toggle loopToggle = cp5.addToggle("Loop Scenes") + .setPosition(r + 120, r) + .setSize(40, screenButtonsArea) + .setCaptionLabel("Loop") + .setValue(loopScenes) + .setGroup(sceneList); + + loopToggle.getCaptionLabel() + .setFont(myFont) + .align(ControlP5.CENTER, ControlP5.CENTER); + loopToggle.setColorBackground(mainApplet.color(60, 60, 120)); + loopToggle.setColorForeground(mainApplet.color(90, 90, 160)); + loopToggle.setColorActive(mainApplet.color(100, 100, 220)); + loopToggle.setColorLabel(mainApplet.color(255)); + + loopToggle.addCallback(new CallbackListener() { + public void controlEvent(CallbackEvent event) { + if (event.getAction() == ControlP5.ACTION_RELEASE) { + loopScenes = loopToggle.getState(); + } + } + }); + + // ---- Autoplay toggle ---- + Toggle autoPlayToggle = cp5.addToggle("Autoplay") + .setPosition(r + 180, r) + .setSize(40, screenButtonsArea) + .setCaptionLabel("Auto") + .setValue(autoPlay) + .setGroup(sceneList); + + autoPlayToggle.getCaptionLabel() + .setFont(myFont) + .align(ControlP5.CENTER, ControlP5.CENTER); + autoPlayToggle.setColorBackground(mainApplet.color(80, 60, 120)); + autoPlayToggle.setColorForeground(mainApplet.color(110, 90, 160)); + autoPlayToggle.setColorActive(mainApplet.color(150, 100, 220)); + autoPlayToggle.setColorLabel(mainApplet.color(255)); + + autoPlayToggle.addCallback(new CallbackListener() { + public void controlEvent(CallbackEvent event) { + if (event.getAction() == ControlP5.ACTION_RELEASE) { + autoPlay = autoPlayToggle.getState(); + autoPlayLastTime = mainApplet.millis(); // reset timer on toggle + } + } + }); + + // ---- Autoplay delay numberbox ---- + Numberbox delayBox = cp5.addNumberbox("Delay (s)") + .setPosition(r + 230, r) + .setSize(50, screenButtonsArea) + .setValue(autoPlayDelay) + .setMin(1) + .setMax(60) + .setScrollSensitivity(0.1f) + .setGroup(sceneList); + + delayBox.getCaptionLabel().hide(); + delayBox.getValueLabel() + .setFont(myFont) + .align(ControlP5.CENTER, ControlP5.CENTER); + delayBox.setColorBackground(mainApplet.color(50)); + delayBox.setColorForeground(mainApplet.color(80)); + delayBox.setColorActive(mainApplet.color(110)); + delayBox.setColorLabel(mainApplet.color(255)); + + delayBox.addCallback(new CallbackListener() { + public void controlEvent(CallbackEvent event) { + if (event.getAction() == ControlP5.ACTION_BROADCAST) { + autoPlayDelay = delayBox.getValue(); + } + } + }); + // ---- Scene selector (radio button) ---- if (sceneRadio != null) sceneRadio.remove(); @@ -1183,6 +1267,17 @@ public void render(int mousex, int mousey) { scenes.get(currentScene).render(); } + // Autoplay: advance scene when delay has elapsed + if (autoPlay && !isTransitioning) { + if (mainApplet.millis() - autoPlayLastTime >= autoPlayDelay * 1000) { + int target = currentScene + 1; + if (target >= scenes.size() && loopScenes) { + target = 0; + } + startTransition(target); + } + } + // Update screens with appropriate media list based on transition state if (isTransitioning) { // During transition, screens need access to both scenes' media @@ -1361,12 +1456,11 @@ public void moveHoverPoint(float mousex, float mousey) { public void keyreleased(char k, int kc) { saveToFile(); if (k == ' ' && !isTransitioning) { -// sceneRadio.deactivate(currentScene); -// currentScene = PApplet.constrain(currentScene+1,0,scenes.size()-1); -// sceneRadio.activate(currentScene); -// selectScene(currentScene); - startTransition(currentScene + 1); - //PApplet.println("Next scene : currentScene + 1"); + int target = currentScene + 1; + if (target >= scenes.size() && loopScenes) { + target = 0; + } + startTransition(target); } } @@ -1410,6 +1504,7 @@ private void completeTransition() { nextScene = -1; isTransitioning = false; transitionProgress = 0; + autoPlayLastTime = mainApplet.millis(); // reset autoplay timer from end of transition sceneRadio.activate(currentScene); }