├── docs ├── package-list ├── script.js ├── allclasses-noframe.html ├── allclasses-frame.html ├── com │ └── krab │ │ └── lazy │ │ ├── package-frame.html │ │ └── package-tree.html ├── index.html ├── deprecated-list.html ├── constant-values.html ├── index-files │ ├── index-1.html │ └── index-2.html └── overview-tree.html ├── data ├── JetBrainsMono-Regular.ttf └── shaders │ ├── testShader.glsl │ ├── checkerboard.glsl │ ├── guideGridPoints.glsl │ ├── sliderBackground.glsl │ └── sliderBackgroundColor.glsl ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── git_delete_latest_tag.sh ├── src └── main │ ├── java │ └── com │ │ └── krab │ │ └── lazy │ │ ├── nodes │ │ ├── NodeType.java │ │ ├── GradientColorStopPositionSlider.java │ │ ├── RadioItemNode.java │ │ ├── SliderIntNode.java │ │ ├── ColorPickerHexNode.java │ │ ├── SaveItemNode.java │ │ ├── GradientColorStopNode.java │ │ ├── GradientBlendType.java │ │ ├── ColorPreviewNode.java │ │ ├── ToggleNode.java │ │ ├── ButtonNode.java │ │ ├── ImageFolderNode.java │ │ ├── ImagePreviewNode.java │ │ ├── PlotFolderNode.java │ │ └── ColorSliderNode.java │ │ ├── examples │ │ ├── TexturePreview │ │ │ ├── data │ │ │ │ ├── picsum_dog.jpg │ │ │ │ └── hueShift.glsl │ │ │ └── TexturePreview.pde │ │ ├── ShaderReloading │ │ │ ├── data │ │ │ │ └── template.glsl │ │ │ └── ShaderReloading.pde │ │ ├── BasicExample │ │ │ └── BasicExample.pde │ │ ├── TexturedTriangleFan │ │ │ └── TexturedTriangleFan.pde │ │ ├── PeasyCamExample │ │ │ └── PeasyCamExample.pde │ │ ├── GradientColorAt │ │ │ └── GradientColorAt.pde │ │ ├── OptionalSetup │ │ │ └── OptionalSetup.pde │ │ ├── PathHiding │ │ │ └── PathHiding.pde │ │ ├── MouseDrawing │ │ │ └── MouseDrawing.pde │ │ ├── IndexedPaths │ │ │ └── IndexedPaths.pde │ │ ├── InputWatcher │ │ │ └── InputWatcher.pde │ │ ├── UtilityMethods │ │ │ └── UtilityMethods.pde │ │ └── GeneralOverview │ │ │ └── GeneralOverview.pde │ │ ├── stores │ │ ├── WindowRestorationStrategy.java │ │ ├── GlobalReferences.java │ │ ├── ShaderStore.java │ │ ├── StringConstants.java │ │ ├── ChangeListener.java │ │ ├── DelayStore.java │ │ ├── NormColorStore.java │ │ ├── HotkeyStore.java │ │ └── UndoRedoStore.java │ │ ├── themes │ │ ├── ThemeColorType.java │ │ ├── Theme.java │ │ ├── ThemeType.java │ │ └── ThemeStore.java │ │ ├── utils │ │ ├── ArrayListBuilder.java │ │ ├── KeyCodes.java │ │ ├── ClipboardUtils.java │ │ ├── NodePaths.java │ │ ├── MouseHiding.java │ │ └── ContextLines.java │ │ ├── ColorPoint.java │ │ ├── input │ │ ├── HotkeySubscriber.java │ │ ├── LazyKeyEvent.java │ │ ├── LazyMouseEvent.java │ │ └── UserInputSubscriber.java │ │ ├── examples_intellij │ │ ├── ShaderWithoutGui.java │ │ ├── PixelDensity.java │ │ ├── ExampleSketch.java │ │ ├── GradientSimple.java │ │ ├── TexturePreviewExample.java │ │ ├── SliderSketch.java │ │ ├── SaveFromCodeTest.java │ │ ├── Gradient.java │ │ ├── SimpleShape.java │ │ ├── MouseDrawing.java │ │ ├── TextEditor.java │ │ ├── SettingsTest.java │ │ ├── InputWatcherTest.java │ │ ├── SinewaveExample.java │ │ ├── ShaderTest.java │ │ ├── ReadmeVisualsGenerator.java │ │ └── Controls.java │ │ ├── KeyState.java │ │ ├── PickerColor.java │ │ ├── windows │ │ └── WindowManager.java │ │ └── Input.java │ └── resources │ └── META-INF │ └── MANIFEST.MF ├── .gitattributes ├── settings.gradle ├── .gitignore ├── LICENSE.md ├── deploy.sh ├── README_DEPLOY.md ├── gradlew.bat └── library.properties /docs/package-list: -------------------------------------------------------------------------------- 1 | com.krab.lazy 2 | -------------------------------------------------------------------------------- /data/JetBrainsMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrabCode/LazyGui/HEAD/data/JetBrainsMono-Regular.ttf -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrabCode/LazyGui/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /git_delete_latest_tag.sh: -------------------------------------------------------------------------------- 1 | echo "this also turns an active github release into a draft, make sure to re-release it" 2 | git push --delete origin latest -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/NodeType.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | public enum NodeType { 4 | VALUE, 5 | FOLDER, 6 | TRANSIENT 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/TexturePreview/data/picsum_dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KrabCode/LazyGui/HEAD/src/main/java/com/krab/lazy/examples/TexturePreview/data/picsum_dog.jpg -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/WindowRestorationStrategy.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | public enum WindowRestorationStrategy { 4 | ONLY_ON_STARTUP, 5 | ALWAYS, 6 | NEVER 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/themes/ThemeColorType.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.themes; 2 | 3 | public enum ThemeColorType { 4 | WINDOW_BORDER, 5 | NORMAL_BACKGROUND, 6 | FOCUS_BACKGROUND, 7 | NORMAL_FOREGROUND, 8 | FOCUS_FOREGROUND, 9 | } 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /data/shaders/testShader.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | uniform vec2 resolution; 3 | uniform float time; 4 | 5 | void main(){ 6 | vec2 uv = (gl_FragCoord.xy-.5*resolution) / resolution.y; 7 | vec3 col = 0.5 + 0.5*cos(time+uv.xyx+vec3(0,2,4)); 8 | gl_FragColor = vec4(col, 1.); 9 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/ShaderReloading/data/template.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D texture; 2 | uniform vec2 resolution; 3 | uniform float time; 4 | 5 | void main(){ 6 | vec2 uv = (gl_FragCoord.xy-.5*resolution) / resolution.y; 7 | vec3 col = 0.5 + 0.5*cos(time+uv.xyx+vec3(0,2,4)); 8 | gl_FragColor = vec4(col, 1.); 9 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/8.0/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'LazyGui' 11 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/BasicExample/BasicExample.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | 5 | void setup() { 6 | size(800, 800, P2D); 7 | gui = new LazyGui(this); 8 | } 9 | 10 | void draw() { 11 | background(gui.colorPicker("background").hex); 12 | int number = gui.sliderInt("pick a number", 7); 13 | fill(255); 14 | textSize(64); 15 | text(number, 400, 500); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/ShaderReloading/ShaderReloading.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | void setup() { 4 | size(800, 800, P2D); 5 | ShaderReloader.setApplet(this); 6 | } 7 | 8 | void draw() { 9 | String shaderPath = "template.glsl"; 10 | PShader shader = ShaderReloader.getShader(shaderPath); 11 | shader.set("time", (float) 0.001 * millis()); 12 | ShaderReloader.filter(shaderPath); 13 | } -------------------------------------------------------------------------------- /data/shaders/checkerboard.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform vec2 quadPos; 3 | uniform vec2 quadSize; 4 | 5 | void main(){ 6 | vec3 checkerboard = vec3(0); 7 | vec2 rep = vec2(12); 8 | vec2 windowId = floor((gl_FragCoord.xy - quadPos * vec2(1,-1))/rep); 9 | vec2 id = windowId; 10 | // vec2 staticId = floor(gl_FragCoord.xy/rep); 11 | // id = staticId; 12 | if(mod(id.x + id.y,2.) == 0.){ 13 | checkerboard += 1.; 14 | } 15 | checkerboard *= 0.3; 16 | gl_FragColor = vec4(checkerboard, 1); 17 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/GradientColorStopPositionSlider.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | public class GradientColorStopPositionSlider extends SliderNode{ 4 | 5 | public GradientColorStopPositionSlider(String path, FolderNode parentFolder, float defaultValue, float min, float max, boolean constrained) { 6 | super(path, parentFolder, defaultValue, min, max, constrained); 7 | maximumFloatPrecisionIndex = precisionRange.indexOf(0.1f); 8 | setPrecisionIndexAndValue(precisionRange.indexOf(0.01f)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /.idea/ 3 | /out/ 4 | /saves/ 5 | /lib/ 6 | *.iml 7 | /data/JetBrainsMono-2.242 8 | /processing-3.5.4/ 9 | 10 | src/test/Camera.java 11 | /.fleet/ 12 | 13 | # save and screenshot folder, let's not clog the repo with huge png 14 | /data/gui/ 15 | /library/ 16 | /deploy/ 17 | /deploy_resources/ 18 | /deploy_resources/* 19 | /target/ 20 | .project 21 | .classpath 22 | /.settings/ 23 | /data/recording_assets/ 24 | /auto_deploy/ 25 | 26 | # Ignore Gradle project-specific cache directory 27 | .gradle 28 | 29 | # Ignore Gradle build output directory 30 | build 31 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/GlobalReferences.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | import com.jogamp.newt.opengl.GLWindow; 4 | import com.krab.lazy.LazyGui; 5 | import processing.core.PApplet; 6 | 7 | public class GlobalReferences { 8 | 9 | public static PApplet app; 10 | public static LazyGui gui; 11 | public static GLWindow appWindow; 12 | 13 | public static void init(LazyGui gui, PApplet app){ 14 | GlobalReferences.app = app; 15 | appWindow = (com.jogamp.newt.opengl.GLWindow) app.getSurface().getNative(); 16 | GlobalReferences.gui = gui; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: gson-2.8.9.jar core.jar gluegen-rt.jar gluegen-rt-natives-li 3 | nux-aarch64.jar gluegen-rt-natives-linux-amd64.jar gluegen-rt-natives-l 4 | inux-armv6hf.jar gluegen-rt-natives-linux-i586.jar gluegen-rt-natives-m 5 | acosx-universal.jar gluegen-rt-natives-windows-amd64.jar gluegen-rt-nat 6 | ives-windows-i586.jar jogl-all.jar jogl-all-natives-linux-aarch64.jar j 7 | ogl-all-natives-linux-amd64.jar jogl-all-natives-linux-armv6hf.jar jogl 8 | -all-natives-linux-i586.jar jogl-all-natives-macosx-universal.jar jogl- 9 | all-natives-windows-amd64.jar jogl-all-natives-windows-i586.jar 10 | 11 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/utils/ArrayListBuilder.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.utils; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class ArrayListBuilder { 6 | private final ArrayList list = new ArrayList<>(); 7 | 8 | public ArrayList build() { 9 | return list; 10 | } 11 | 12 | ArrayListBuilder add(T o) { 13 | list.add(o); 14 | return this; 15 | } 16 | 17 | @SafeVarargs 18 | public final ArrayListBuilder add(T... items) { 19 | for (T t : items) { 20 | add(t); 21 | } 22 | return this; 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/ShaderStore.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | import processing.opengl.PShader; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class ShaderStore { 9 | private static final Map shaders = new HashMap<>(); 10 | private static final String shaderFolder = "shaders/"; 11 | 12 | private ShaderStore() { 13 | 14 | } 15 | 16 | public static PShader getShader(String path) { 17 | String fullPath = shaderFolder + path; 18 | if(!shaders.containsKey(fullPath)) { 19 | shaders.put(fullPath, GlobalReferences.app.loadShader(fullPath)); 20 | } 21 | return shaders.get(fullPath); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/RadioItemNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | class RadioItemNode extends ToggleNode { 4 | 5 | final String valueString; 6 | 7 | RadioItemNode(String path, FolderNode folder, boolean valueBoolean, String valueString) { 8 | super(path, folder, valueBoolean); 9 | this.type = NodeType.TRANSIENT; 10 | this.valueString = valueString; 11 | } 12 | 13 | @Override 14 | public void mouseReleasedOverNode(float x, float y){ 15 | if(armed && !valueBoolean){ // can only toggle manually to true, toggle to false happens automatically 16 | valueBoolean = true; 17 | onValueChangingActionEnded(); 18 | } 19 | armed = false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/ColorPoint.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy; 2 | 3 | /** 4 | * Used as a parameter for initializing a gradient with a set of default colors at default positions. 5 | * @see LazyGui#gradient(String, ColorPoint...) gradient function where it is used 6 | */ 7 | public class ColorPoint{ 8 | int color; // 9 | float position; // 10 | 11 | /** 12 | * Constructor for ColorPoint 13 | * @param color processing hex color like 0xFF00FF00 or color(255, 0, 0) 14 | * @param position expected to be in the range [0, 1] 15 | * @see LazyGui#colorPoint(int, float) more convenient way to create a ColorPoint. 16 | */ 17 | public ColorPoint(int color, float position){ 18 | this.color = color; 19 | this.position = position; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/StringConstants.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | /** 4 | * DO NOT MODIFY ANYTHING IN THIS FILE 5 | * Assume that users' existing json saves already contain these keys. 6 | * Modifying these keys would break loading these saves. 7 | */ 8 | public class StringConstants { 9 | public static final String FOLDER_PATH_SAVES = "saves"; 10 | public static final String FOLDER_PATH_OPTIONS = "options"; 11 | public static final String FOLDER_AUTODETECT_LABEL = "label"; 12 | public static final String FOLDER_AUTODETECT_NAME = "name"; 13 | public static final String FOLDER_AUTODETECT_ACTIVE = "active"; 14 | public static final String FOLDER_AUTODETECT_ENABLED = "enabled"; 15 | public static final String FOLDER_AUTODETECT_VISIBLE = "visible"; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/input/HotkeySubscriber.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.input; 2 | 3 | import com.krab.lazy.stores.HotkeyStore; 4 | 5 | /** 6 | * Singleton class listening for global hotkeys that fall through all the potential visual controls under the mouse unconsumed. 7 | */ 8 | public class HotkeySubscriber implements UserInputSubscriber { 9 | 10 | static HotkeySubscriber singleton; 11 | 12 | private HotkeySubscriber() {} 13 | 14 | public static void initSingleton() { 15 | if(singleton == null){ 16 | singleton = new HotkeySubscriber(); 17 | } 18 | UserInputPublisher.subscribe(singleton); 19 | } 20 | 21 | @Override 22 | public void keyPressed(LazyKeyEvent keyEvent) { 23 | HotkeyStore.handleHotkeyInteraction(keyEvent); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/SliderIntNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | public class SliderIntNode extends SliderNode { 4 | 5 | public SliderIntNode(String path, FolderNode parentFolder, int defaultValue, int min, int max, boolean constrained) { 6 | super(path, parentFolder, defaultValue, min, max, constrained, false); 7 | minimumFloatPrecisionIndex = precisionRange.indexOf(0.01f); 8 | } 9 | 10 | public int getIntValue(){ 11 | return (int) Math.floor(valueFloat); 12 | } 13 | 14 | @Override 15 | public String getValueToDisplay() { 16 | // float floor as a string 17 | String floatDisplay = super.getValueToDisplay(); 18 | if(floatDisplay.contains(".")){ 19 | return floatDisplay.split("\\.")[0]; 20 | } 21 | return floatDisplay; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/ShaderWithoutGui.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.ShaderReloader; 4 | import processing.core.PApplet; 5 | import processing.opengl.PShader; 6 | 7 | public class ShaderWithoutGui extends PApplet { 8 | 9 | public static void main(String[] args) { 10 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 11 | } 12 | 13 | @Override 14 | public void settings() { 15 | size(800, 800, P2D); 16 | } 17 | 18 | @Override 19 | public void setup() { 20 | ShaderReloader.setApplet(this); 21 | } 22 | 23 | @Override 24 | public void draw() { 25 | String path = "shaders/testShader.glsl"; 26 | PShader shader = ShaderReloader.getShader(path); 27 | shader.set("time", millis() / 1000f); 28 | ShaderReloader.filter(path); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/utils/KeyCodes.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.utils; 2 | 3 | 4 | import com.jogamp.newt.event.KeyEvent; 5 | 6 | import java.util.ArrayList; 7 | 8 | public class KeyCodes { 9 | public static final int DELETE = KeyEvent.VK_DELETE; 10 | public static final int C = KeyEvent.VK_C; 11 | public static final int V = KeyEvent.VK_V; 12 | public static final int Z = KeyEvent.VK_Z; 13 | public static final int Y = KeyEvent.VK_Y; 14 | public static final int S = KeyEvent.VK_S; 15 | public static final int CTRL = KeyEvent.VK_CONTROL; 16 | public static final int ALT = KeyEvent.VK_ALT; 17 | public static final int SHIFT = KeyEvent.VK_SHIFT; 18 | public static final int SHIFT_TWO = 16; 19 | private static final ArrayList textInputIgnoredKeyCodes = new ArrayListBuilder().add(CTRL, ALT, SHIFT, SHIFT_TWO).build(); 20 | public static boolean shouldIgnoreForTextInput(int keyCode){ 21 | return textInputIgnoredKeyCodes.contains(keyCode); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/TexturedTriangleFan/TexturedTriangleFan.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | 5 | void setup() { 6 | size(800, 800, P2D); 7 | gui = new LazyGui(this); 8 | } 9 | 10 | void draw() { 11 | background(gui.colorPicker("background").hex); 12 | gui.pushFolder("shape"); 13 | translate(width/2, height/2); 14 | rotate(gui.slider("rotation")); 15 | stroke(gui.colorPicker("stroke").hex); 16 | strokeWeight(gui.slider("weight", 1.5)); 17 | beginShape(TRIANGLE_FAN); 18 | PGraphics fillTexture = gui.gradient("texture"); 19 | textureMode(NORMAL); 20 | texture(fillTexture); 21 | vertex(0, 0, 0.5, 0); 22 | int vertexCount = gui.sliderInt("vertices", 6, 3, 10000); 23 | float radius = gui.slider("radius", 250); 24 | for (int i = 0; i <= vertexCount; i++) { 25 | float theta = map(i, 0, vertexCount, 0, TAU); 26 | float x = radius * cos(theta); 27 | float y = radius * sin(theta); 28 | vertex(x, y, 0.5, 1); 29 | } 30 | endShape(); 31 | gui.popFolder(); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/utils/ClipboardUtils.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.utils; 2 | 3 | import java.awt.*; 4 | import java.awt.datatransfer.Clipboard; 5 | import java.awt.datatransfer.DataFlavor; 6 | import java.awt.datatransfer.StringSelection; 7 | import java.awt.datatransfer.UnsupportedFlavorException; 8 | import java.io.*; 9 | 10 | public class ClipboardUtils { 11 | 12 | public static void setClipboardString(String data) { 13 | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 14 | StringSelection selection = new StringSelection(data); 15 | clipboard.setContents(selection, selection); 16 | } 17 | 18 | public static String getClipboardString() { 19 | Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); 20 | try { 21 | return (String) clipboard.getData(DataFlavor.stringFlavor); 22 | } catch (UnsupportedFlavorException | IOException ex) { 23 | ex.printStackTrace(); 24 | } 25 | return ""; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/ColorPickerHexNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | 4 | 5 | import com.krab.lazy.input.LazyKeyEvent; 6 | import processing.core.PGraphics; 7 | 8 | 9 | class ColorPickerHexNode extends AbstractNode { 10 | 11 | final ColorPickerFolderNode parentColorPickerFolder; 12 | 13 | ColorPickerHexNode(String path, ColorPickerFolderNode parentFolder) { 14 | super(NodeType.VALUE, path, parentFolder); 15 | this.parentColorPickerFolder = parentFolder; 16 | } 17 | 18 | @Override 19 | protected void drawNodeBackground(PGraphics pg) { 20 | 21 | } 22 | 23 | @Override 24 | protected void drawNodeForeground(PGraphics pg, String name) { 25 | fillForegroundBasedOnMouseOver(pg); 26 | drawLeftText(pg, name); 27 | drawRightTextToNotOverflowLeftText(pg, parentColorPickerFolder.hexString, name, false); 28 | } 29 | 30 | @Override 31 | public void keyPressedOverNode(LazyKeyEvent e, float x, float y) { 32 | parentColorPickerFolder.keyPressedOverNode(e, x, y); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Jakub Rak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/SaveItemNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | import com.krab.lazy.stores.JsonSaveStore; 4 | import com.krab.lazy.windows.WindowManager; 5 | import processing.core.PGraphics; 6 | 7 | class SaveItemNode extends AbstractNode { 8 | final String fileName; 9 | final SaveFolderNode saveFolderParent; 10 | 11 | SaveItemNode(String path, SaveFolderNode parent, String fileName) { 12 | super(NodeType.TRANSIENT, path, parent); 13 | saveFolderParent = parent; 14 | this.fileName = fileName; 15 | } 16 | 17 | protected void drawNodeBackground(PGraphics pg) { 18 | fillForegroundBasedOnMouseOver(pg); 19 | } 20 | 21 | @Override 22 | protected void drawNodeForeground(PGraphics pg, String name) { 23 | drawLeftText(pg, name); 24 | drawRightTextToNotOverflowLeftText(pg, "load", name,true); 25 | } 26 | 27 | public void mousePressedOverNode(float x, float y) { 28 | JsonSaveStore.loadStateFromFilePath(fileName); 29 | WindowManager.setFocus(saveFolderParent.window); 30 | onValueChangingActionEnded(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/TexturePreview/TexturePreview.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | PGraphics pgInvert; 5 | PGraphics pgHue; 6 | PImage img; 7 | 8 | String SHADER_HUE_SHIFT_PATH = "hueShift.glsl"; 9 | PShader shaderHueShift; 10 | 11 | void setup() { 12 | size(800, 800, P2D); 13 | gui = new LazyGui(this); 14 | pgInvert = createGraphics(400, 400, P2D); 15 | pgHue = createGraphics(400, 400, P2D); 16 | img = loadImage("picsum_dog.jpg"); 17 | shaderHueShift = loadShader(SHADER_HUE_SHIFT_PATH); 18 | } 19 | 20 | public void draw() { 21 | background(gui.colorPicker("background").hex); 22 | 23 | gui.image("source image", img); 24 | 25 | pgInvert.beginDraw(); 26 | pgInvert.image(img, 0, 0); 27 | pgInvert.filter(INVERT); 28 | pgInvert.endDraw(); 29 | gui.image("inverted", pgInvert); 30 | 31 | pgHue.beginDraw(); 32 | pgHue.image(img, 0, 0); 33 | shaderHueShift.set("hueShiftAmount", frameCount * 0.01f); 34 | pgHue.filter(shaderHueShift); 35 | pgHue.endDraw(); 36 | gui.image("hue shifted", pgHue); 37 | 38 | imageMode(CENTER); 39 | image(pgHue, 400, 400); 40 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/GradientColorStopNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | import com.krab.lazy.stores.GlobalReferences; 4 | import processing.core.PGraphics; 5 | 6 | class GradientColorStopNode extends ColorPickerFolderNode { 7 | final GradientColorStopPositionSlider posSlider; 8 | 9 | GradientColorStopNode(String path, FolderNode parentFolder, int hex, float gradientPos) { 10 | super(path, parentFolder, hex); 11 | posSlider = new GradientColorStopPositionSlider(path + "/pos", this, gradientPos, 0,1,true); 12 | this.children.add(posSlider); 13 | } 14 | 15 | @Override 16 | protected void drawNodeForeground(PGraphics pg, String name) { 17 | super.drawNodeForeground(pg, name); 18 | } 19 | 20 | float getGradientPos() { 21 | return (float) posSlider.valueFloat; 22 | } 23 | 24 | public boolean isPosSliderBeingUsed() { 25 | return isMouseOverNode || posSlider.isInlineNodeDragged || 26 | (window != null 27 | && !window.closed 28 | && window.isFocused() 29 | && window.isPointInsideContent(GlobalReferences.app.mouseX, GlobalReferences.app.mouseY)); 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/ChangeListener.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | import com.krab.lazy.utils.NodePaths; 4 | 5 | import java.util.ArrayList; 6 | 7 | /** 8 | * Static class for tracking value changes in nodes. Backend for gui.hasChanged() in the main API. 9 | * Paths mentioned here are gui paths, not file paths. 10 | * 11 | */ 12 | public class ChangeListener { 13 | static ArrayList pathsThatChangedThisFrame = new ArrayList<>(); 14 | static ArrayList pathsThatChangedLastFrame = new ArrayList<>(); 15 | 16 | public static void onValueChangingActionEnded(String path) { 17 | pathsThatChangedThisFrame.add(path); 18 | } 19 | 20 | public static void onFrameFinished(){ 21 | pathsThatChangedLastFrame.clear(); 22 | if(!pathsThatChangedThisFrame.isEmpty()){ 23 | UndoRedoStore.onUndoableActionEnded(); 24 | } 25 | pathsThatChangedLastFrame.addAll(pathsThatChangedThisFrame); 26 | pathsThatChangedThisFrame.clear(); 27 | } 28 | 29 | public static boolean hasChangeFinishedLastFrame(String path){ 30 | String pathWithoutTrailingSlash = NodePaths.getPathWithoutTrailingSlash(path); 31 | return pathsThatChangedLastFrame.contains(pathWithoutTrailingSlash); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/PeasyCamExample/PeasyCamExample.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | import peasy.PeasyCam; 3 | 4 | // adapted from the HelloPeasy example to show how it can work with LazyGui 5 | // requires the PeasyCam library, tested on PeasyCam version 302 6 | 7 | PeasyCam cam; 8 | LazyGui gui; 9 | 10 | public void settings() { 11 | size(800, 600, P3D); 12 | } 13 | 14 | public void setup() { 15 | cam = new PeasyCam(this, 400); 16 | gui = new LazyGui(this); 17 | } 18 | 19 | public void draw() { 20 | rotateX(-.5f); 21 | rotateY(-.5f); 22 | lights(); 23 | scale(10); 24 | strokeWeight(gui.slider("stroke weight", 0.1f)); 25 | background(gui.colorPicker("background", color(0)).hex); 26 | 27 | fill(gui.colorPicker("big box", color(255,0,0)).hex); 28 | box(30); 29 | pushMatrix(); 30 | translate(0, 0, 20); 31 | 32 | fill(gui.colorPicker("small box", color(0,0,255)).hex); 33 | box(5); 34 | popMatrix(); 35 | 36 | 37 | cam.beginHUD(); // makes the gui visual exempt from the PeasyCam controlled 3D scene 38 | gui.draw(); // displays the gui manually here - rather than automatically when draw() ends 39 | cam.endHUD(); 40 | 41 | // PeasyCam ignores mouse input while the mouse interacts with the GUI 42 | cam.setMouseControlled(gui.isMouseOutsideGui()); 43 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/PixelDensity.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import processing.core.PApplet; 4 | import com.krab.lazy.LazyGui; 5 | 6 | public class PixelDensity extends PApplet { 7 | LazyGui gui; 8 | 9 | public static void main(String[] args) { 10 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 11 | } 12 | 13 | @Override 14 | public void settings() { 15 | size(1080, 1080, P2D); 16 | pixelDensity(2); // see issue #291: https://github.com/KrabCode/LazyGui/issues/291 17 | } 18 | 19 | @Override 20 | public void setup() { 21 | gui = new LazyGui(this); 22 | gui.sliderIntSet("options/windows/cell size", 44); 23 | gui.sliderIntSet("options/font/main font size", 32); 24 | gui.sliderIntSet("options/font/side font size", 28); 25 | gui.sliderIntSet("options/font/y offset", 25); 26 | 27 | colorMode(HSB, 1, 1, 1, 1); 28 | } 29 | 30 | @Override 31 | public void draw() { 32 | drawBackground(); 33 | } 34 | 35 | private void drawBackground() { 36 | fill(gui.colorPicker("background").hex); 37 | noStroke(); 38 | rectMode(CORNER); 39 | rect(0, 0, width, height); 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /docs/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | All Classes 7 | 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/DelayStore.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | public class DelayStore { 4 | private static int keyboardBufferDelayMillis = 500; 5 | 6 | public static int getKeyboardBufferDelayMillis() { 7 | return keyboardBufferDelayMillis; 8 | } 9 | 10 | public static void setKeyboardBufferDelayMillis(int keyboardBufferDelayMillis) { 11 | DelayStore.keyboardBufferDelayMillis = keyboardBufferDelayMillis; 12 | } 13 | 14 | public static void updateInputDelay() { 15 | GlobalReferences.gui.pushFolder("keyboard delay"); 16 | DelayStore.setKeyboardBufferDelayMillis( 17 | GlobalReferences.gui.sliderInt("delay (ms)", DelayStore.getKeyboardBufferDelayMillis(), 100, 5000)); 18 | 19 | if( GlobalReferences.gui.button("read more")){ 20 | GlobalReferences.gui.textSet("", "the buffer delay slider sets the time\n" + 21 | "that must elapse after the last keyboard input has been made\n" + 22 | "before the new value overwrites any previous content\n" + 23 | "in the currently moused over text / slider\n" + 24 | "in order to avoid jarring sketch changes with each keystroke" 25 | ); 26 | } 27 | GlobalReferences.gui.popFolder(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/TexturePreview/data/hueShift.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform sampler2D texture; 3 | uniform vec2 resolution; 4 | uniform float time; 5 | uniform float hueShiftAmount; 6 | uniform float satShiftAmount; 7 | uniform float brShiftAmount; 8 | 9 | // based on code from here 10 | // https://gist.github.com/983/e170a24ae8eba2cd174f 11 | 12 | vec3 rgb2hsv(vec3 c) 13 | { 14 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 15 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); 16 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); 17 | 18 | float d = q.x - min(q.w, q.y); 19 | float e = 1.0e-10; 20 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 21 | } 22 | 23 | vec3 hsv2rgb(vec3 c) 24 | { 25 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 26 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 27 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 28 | } 29 | 30 | void main(){ 31 | vec2 uv = gl_FragCoord.xy / resolution.xy; 32 | vec4 col = texture(texture, uv).rgba; 33 | vec3 hsv = rgb2hsv(col.rgb); 34 | hsv.x += hueShiftAmount; 35 | hsv.y += satShiftAmount; 36 | hsv.z += brShiftAmount; 37 | float d = length(uv-0.5)*2.; 38 | float t = time * 1; 39 | col.rgb = hsv2rgb(hsv); 40 | gl_FragColor = col; 41 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/ExampleSketch.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import processing.core.PApplet; 4 | import processing.core.PGraphics; 5 | import com.krab.lazy.LazyGui; 6 | 7 | public class ExampleSketch extends PApplet { 8 | LazyGui gui; 9 | PGraphics pg; 10 | 11 | public static void main(String[] args) { 12 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 13 | } 14 | 15 | @Override 16 | public void settings() { 17 | size(800, 800, P2D); 18 | } 19 | 20 | @Override 21 | public void setup() { 22 | gui = new LazyGui(this); 23 | pg = createGraphics(width, height, P2D); 24 | colorMode(HSB, 1, 1, 1, 1); 25 | // frameRate(144); 26 | } 27 | 28 | @Override 29 | public void draw() { 30 | pg.beginDraw(); 31 | drawBackground(); 32 | pg.endDraw(); 33 | image(pg, 0, 0); 34 | gui.draw(); 35 | } 36 | 37 | private void drawBackground() { 38 | if(gui.toggle("gradient", true)){ 39 | pg.image(gui.gradient("background"), 0, 0); 40 | return; 41 | } 42 | pg.fill(gui.colorPicker("solid").hex); 43 | pg.noStroke(); 44 | pg.rectMode(CORNER); 45 | pg.rect(0, 0, width, height); 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/themes/Theme.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.themes; 2 | 3 | /** 4 | * Data container for individual theme colors. 5 | */ 6 | public class Theme { 7 | int windowBorder; 8 | int normalBackground; 9 | int focusBackground; 10 | int normalForeground; 11 | int focusForeground; 12 | 13 | @SuppressWarnings("unused") 14 | private Theme(){ 15 | 16 | } 17 | 18 | /** 19 | * The only available constructor for this class. 20 | * Enforces specifying all the available values as parameters. 21 | * 22 | * @param windowBorderColor color of the border lines 23 | * @param normalBackgroundColor background of idle elements 24 | * @param focusBackgroundColor background of currently selected elements 25 | * @param normalForegroundColor foreground of idle elements 26 | * @param focusForegroundColor foreground of currently selected elements 27 | */ 28 | public Theme(int windowBorderColor, int normalBackgroundColor, int focusBackgroundColor, int normalForegroundColor, int focusForegroundColor) { 29 | this.windowBorder = windowBorderColor; 30 | this.normalBackground = normalBackgroundColor; 31 | this.focusBackground = focusBackgroundColor; 32 | this.normalForeground = normalForegroundColor; 33 | this.focusForeground = focusForegroundColor; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/GradientBlendType.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | /** 4 | * Enum for gradient blend types. 5 | * DO NOT CHANGE THE INDEXES OR NAMES OF THE ENUMS. IF YOU DO, DO THE SAME THING IN THE SHADER (data/shaders/gradient.glsl). 6 | * Changing the indexes will affect (break) the corresponding gradient.glsl shader which is doing the actual gradient blending. 7 | * Changing the names will break setting them from the constructor settings via the string parameter. 8 | * The indexes are sent to the shader as integer uniforms to determine the blend type. 9 | */ 10 | public enum GradientBlendType { 11 | MIX(0, "mix"), 12 | HSV(1, "hsv"), 13 | OKLAB(2, "oklab"); 14 | 15 | public final String name; 16 | public final int index; 17 | 18 | GradientBlendType(int index, String name) { 19 | this.index = index; 20 | this.name = name; 21 | } 22 | 23 | static String[] getNamesAsList() { 24 | return new String[]{ 25 | MIX.name, 26 | HSV.name, 27 | OKLAB.name 28 | }; 29 | } 30 | 31 | static int getIndexByName(String name) { 32 | for (GradientBlendType value : values()) { 33 | if (value.name.equals(name)) { 34 | return value.index; 35 | } 36 | } 37 | return -1; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /docs/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | All Classes 7 | 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/GradientSimple.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGui; 4 | import com.krab.lazy.LazyGuiSettings; 5 | import processing.core.PApplet; 6 | import processing.core.PGraphics; 7 | import processing.core.PImage; 8 | 9 | /** 10 | * Created by Jakub 'Krab' Rak on 2024-08-19 11 | */ 12 | public class GradientSimple extends PApplet { 13 | private LazyGui gui; 14 | PGraphics pg; 15 | private final int fullHeight = 2340; 16 | private final int fullWidth = 1080; 17 | 18 | public static void main(String[] args) { 19 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 20 | } 21 | 22 | public void settings() { 23 | float scale = 0.4f; 24 | size(floor(fullWidth * scale), floor(fullHeight * scale), P2D); 25 | } 26 | 27 | public void setup() { 28 | gui = new LazyGui(this); 29 | pg = createGraphics(fullWidth, fullHeight); 30 | noStroke(); 31 | } 32 | 33 | public void draw() { 34 | tint(gui.colorPicker("tint", color(255, 255, 255, 255)).hex); 35 | PImage gradient = 36 | gui.gradient("path", 37 | gui.colorPoint(color(255,0,0), 0), 38 | gui.colorPoint(color(0,255,0), 0.5f), 39 | gui.colorPoint(color(0,0,255), 1) 40 | ); 41 | image(gradient, 0, 0); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/com/krab/lazy/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.krab.lazy 7 | 8 | 9 | 10 | 11 | 12 |

com.krab.lazy

13 |
14 |

Classes

15 | 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /data/shaders/guideGridPoints.glsl: -------------------------------------------------------------------------------- 1 | uniform vec4 window; 2 | uniform float alpha; 3 | uniform sampler2D texture; 4 | uniform vec2 resolution; 5 | uniform bool sdfCropEnabled; 6 | uniform float sdfCropDistance; 7 | uniform float gridCellSize; 8 | uniform vec3 pointColor; 9 | uniform float pointWeight; 10 | uniform bool shouldCenterPoints; 11 | 12 | #ifdef GL_ES 13 | precision mediump float; 14 | precision mediump int; 15 | #endif 16 | 17 | 18 | float sdBox(in vec2 p, in vec2 b) 19 | { 20 | vec2 d = abs(p)-b; 21 | return length(max(d,0.0)) + min(max(d.x,d.y),0.0); 22 | } 23 | 24 | float sdPoint(){ 25 | vec2 p = vec2(gl_FragCoord.x, resolution.y-gl_FragCoord.y) - 0.5; 26 | if(!shouldCenterPoints){ 27 | p += gridCellSize / 2.; 28 | } 29 | vec2 v = fract(p / vec2(gridCellSize)) - 0.5; 30 | float w = (pointWeight / 2.) / gridCellSize; 31 | 32 | return smoothstep(w, w-(1./gridCellSize), length(v)); 33 | } 34 | 35 | void main() { 36 | float m = min(resolution.x, resolution.y); 37 | vec2 uv = (gl_FragCoord.xy / m); 38 | uv.y = 1. - uv.y; 39 | float sdfAlpha = 1.; 40 | if(sdfCropEnabled){ 41 | vec4 windowNormalized = vec4(window.xy / m, window.zw / m); 42 | float sdfResult = sdBox(windowNormalized.xy + windowNormalized.zw / 2. - uv , windowNormalized.zw / 2.); 43 | sdfAlpha = smoothstep(sdfCropDistance/m, 0., sdfResult); 44 | } 45 | sdfAlpha *= smoothstep(0., 1., sdPoint()); 46 | gl_FragColor = vec4(pointColor, min(alpha, sdfAlpha)); 47 | } -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | targetDir=build/deploy/LazyGui 2 | sourceJarName=LazyGui-with-gson.jar 3 | targetJarName=LazyGui.jar 4 | 5 | echo "Deleting data/gui/ ..." 6 | # testing saves are stored in /data/gui 7 | rm -rf ./data/gui 8 | 9 | echo "Cleaning up build/deploy/* ..." 10 | # clean deploy directory 11 | rm -rf ./build/deploy/* 12 | 13 | echo "Copying sources..." 14 | mkdir -p $targetDir/data/ && cp -r data/ $targetDir/ 15 | mkdir -p $targetDir/src/ && cp -r src $targetDir/ 16 | echo "Copying docs..." 17 | mkdir -p $targetDir/reference/ && cp -r docs/* $targetDir/reference 18 | mkdir -p $targetDir/examples/ && cp -r src/main/java/com/krab/lazy/examples $targetDir/ 19 | echo "Copying jar..." 20 | mkdir -p $targetDir/library/ && cp build/libs/$sourceJarName $targetDir/library/$targetJarName 21 | cp library.properties $targetDir/library.properties 22 | cp README.md $targetDir/README.md 23 | cp LICENSE.md $targetDir/src/LICENSE.md 24 | 25 | name=LazyGui 26 | echo "Zipping..." 27 | cd $targetDir/.. || exit 28 | rm -rf $name.zip 29 | 7z a -bb0 $name.zip $name/ > nul 30 | 31 | cp $name/library.properties $name.txt 32 | cp $name/library/$name.jar $name.jar 33 | 34 | echo 35 | echo "Deployed LazyGui successfully to:" 36 | pwd 37 | echo 38 | echo "Version in library.properties:" 39 | grep prettyVersion $name/library.properties 40 | echo 41 | echo "To publish this release upload these files" 42 | echo " - LazyGui.jar" 43 | echo " - LazyGui.txt" 44 | echo " - LazyGui.zip" 45 | echo 46 | echo "--> https://github.com/KrabCode/LazyGui/releases/tag/latest" -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/utils/NodePaths.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.utils; 2 | 3 | 4 | @SuppressWarnings("RegExpRedundantEscape") 5 | public class NodePaths { 6 | 7 | static final String REGEX_UNESCAPED_SLASH_LOOKBEHIND = "(? Manage Tools -> Libraries menu 21 | - When the number of "commits to master since this release" gets annoying it can be deleted with `git_delete_latest_tag.sh` 22 | - But that also turns the latest release on GitHub into a draft so make sure to re-release it for it to be available in Processing 23 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/utils/MouseHiding.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.utils; 2 | 3 | import com.krab.lazy.stores.GlobalReferences; 4 | 5 | public class MouseHiding { 6 | public static boolean shouldHideWhenDragging = true; 7 | public static boolean shouldConfineToWindow = false; 8 | private static int mouseHidePosX; 9 | private static int mouseHidePosY; 10 | private static boolean isMouseHidden = false; 11 | 12 | public static void updateSettings() { 13 | GlobalReferences.gui.pushFolder("mouse"); 14 | shouldHideWhenDragging = GlobalReferences.gui.toggle("hide when dragged", shouldHideWhenDragging); 15 | shouldConfineToWindow = GlobalReferences.gui.toggle("confine to window", shouldConfineToWindow); 16 | GlobalReferences.appWindow.confinePointer(shouldConfineToWindow); 17 | GlobalReferences.gui.popFolder(); 18 | if(isMouseHidden){ 19 | GlobalReferences.app.mouseX = mouseHidePosX; 20 | GlobalReferences.app.mouseY = mouseHidePosY; 21 | } 22 | } 23 | 24 | public static void tryHideMouseForDragging() { 25 | if(!shouldHideWhenDragging){ 26 | return; 27 | } 28 | GlobalReferences.app.noCursor(); 29 | if(!isMouseHidden){ 30 | mouseHidePosX = GlobalReferences.app.mouseX; 31 | mouseHidePosY = GlobalReferences.app.mouseY; 32 | } 33 | isMouseHidden = true; 34 | } 35 | 36 | public static void tryRevealMouseAfterDragging() { 37 | if(!shouldHideWhenDragging){ 38 | return; 39 | } 40 | if(isMouseHidden){ 41 | resetMousePos(); 42 | } 43 | isMouseHidden = false; 44 | GlobalReferences.app.cursor(); 45 | } 46 | 47 | private static void resetMousePos() { 48 | GlobalReferences.appWindow.warpPointer(mouseHidePosX, mouseHidePosY); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/ColorPreviewNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | 4 | import com.krab.lazy.input.LazyKeyEvent; 5 | import com.krab.lazy.stores.ShaderStore; 6 | import processing.core.PGraphics; 7 | import processing.opengl.PShader; 8 | 9 | import static processing.core.PConstants.CORNER; 10 | 11 | class ColorPreviewNode extends AbstractNode { 12 | 13 | final ColorPickerFolderNode parentColorPickerFolder; 14 | final String checkerboardShaderPath = "checkerboard.glsl"; 15 | 16 | ColorPreviewNode(String path, ColorPickerFolderNode parentColorPickerFolder) { 17 | super(NodeType.TRANSIENT, path, parentColorPickerFolder); 18 | this.parentColorPickerFolder = parentColorPickerFolder; 19 | masterInlineNodeHeightInCells = 3; 20 | ShaderStore.getShader(checkerboardShaderPath); 21 | } 22 | 23 | @Override 24 | protected void drawNodeBackground(PGraphics pg) { 25 | drawCheckerboard(pg); 26 | drawColorPreview(pg); 27 | } 28 | 29 | @Override 30 | protected void drawNodeForeground(PGraphics pg, String name) { 31 | 32 | } 33 | 34 | private void drawCheckerboard(PGraphics pg) { 35 | PShader checkerboardShader = ShaderStore.getShader(checkerboardShaderPath); 36 | checkerboardShader.set("quadPos", pos.x, pos.y); 37 | pg.shader(checkerboardShader); 38 | pg.rectMode(CORNER); 39 | pg.fill(1); 40 | pg.noStroke(); 41 | pg.rect(0,0, size.x, size.y); 42 | pg.resetShader(); 43 | } 44 | 45 | private void drawColorPreview(PGraphics pg) { 46 | pg.fill(parentColorPickerFolder.getColor().hex); 47 | pg.noStroke(); 48 | pg.rect(0, 0, size.x, size.y); 49 | } 50 | 51 | @Override 52 | public void keyPressedOverNode(LazyKeyEvent e, float x, float y) { 53 | parentColorPickerFolder.keyPressedOverNode(e, x, y); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/OptionalSetup/OptionalSetup.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | 5 | void setup() { 6 | size(800, 800, P2D); 7 | gui = new LazyGui(this, new LazyGuiSettings() 8 | // AUTOLOAD 9 | .setLoadLatestSaveOnStartup(false) // set as false to not load anything on startup 10 | .setLoadSpecificSaveOnStartup("1") // expects filenames like "1" or "auto.json", overrides 'load latest' 11 | 12 | // AUTOSAVE 13 | .setAutosaveOnExit(true) // but the shutdown hook only works on graceful exit, for example the ESC button 14 | .setAutosaveLockGuardEnabled(true) // for not autosaving settings that locked the sketch in an endless loop 15 | .setAutosaveLockGuardMillisLimit(1000) // millis the last frame must be rendered faster than for autosave to work 16 | 17 | // MOUSE 18 | .setMouseHideWhenDragging(true) // when dragging a slider for example 19 | .setMouseConfineToWindow(false) 20 | 21 | // LAYOUT 22 | .setCellSize(22) // affects the size of the whole gui 23 | .setMainFontSize(16) 24 | .setSideFontSize(15) 25 | .setStartGuiHidden(false) // uncover hidden gui with the 'h' hotkey 26 | 27 | // THEME 28 | .setThemePreset("dark") // selected preset, one of "dark", "light", "pink", "blue" 29 | .setThemeCustom( 30 | color(0, 0, 255), // window border color 31 | color(16), // normal background color 32 | color(0, 0, 0), // focused background color 33 | color(200), // normal foreground color 34 | color(255)) // focused foreground color 35 | // custom theme overrides preset when not null 36 | ); 37 | 38 | } 39 | 40 | void draw() { 41 | background(gui.colorPicker("background").hex); 42 | int number = gui.sliderInt("pick a number", 7); 43 | fill(255); 44 | textSize(64); 45 | text(number, 400, 500); 46 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/NormColorStore.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | import processing.core.PGraphics; 4 | 5 | import static processing.core.PConstants.HSB; 6 | import static processing.core.PConstants.P2D; 7 | 8 | public class NormColorStore { 9 | 10 | private static PGraphics colorStore = null; 11 | 12 | public static void init() { 13 | colorStore = GlobalReferences.app.createGraphics(256, 256, P2D); 14 | colorStore.colorMode(HSB, 1, 1, 1, 1); 15 | } 16 | 17 | public static int color(float br) { 18 | return color(0, 0, br, 1); 19 | } 20 | 21 | public static int color(float br, float alpha) { 22 | return color(0, 0, br, alpha); 23 | } 24 | 25 | public static int color(float hue, float sat, float br) { 26 | return color(hue, sat, br, 1); 27 | } 28 | 29 | public static int color(float hue, float sat, float br, float alpha) { 30 | return colorStore.color(hue, sat, br, alpha); 31 | } 32 | 33 | public static float red(int hex){ 34 | return colorStore.red(hex); 35 | } 36 | 37 | public static float green(int hex){ 38 | return colorStore.green(hex); 39 | } 40 | 41 | public static float blue(int hex){ 42 | return colorStore.blue(hex); 43 | } 44 | 45 | public static float hue(int hex){ return colorStore.hue(hex); } 46 | 47 | public static float sat(int hex){ return colorStore.saturation(hex); } 48 | 49 | public static float br(int hex){ return colorStore.brightness(hex); } 50 | 51 | public static float alpha(int hex) { 52 | return colorStore.alpha(hex); 53 | } 54 | 55 | public static PGraphics getColorStore() { 56 | return colorStore; 57 | } 58 | 59 | public static int toTransparent(int hex) { 60 | if(hex == 0x00000000){ 61 | hex = 0xFF010101; 62 | } 63 | return colorStore.color(hex, 0); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/PathHiding/PathHiding.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | 5 | public void setup() { 6 | size(1200, 800, P2D); 7 | smooth(8); 8 | gui = new LazyGui(this); 9 | 10 | // hide the gui options if you don't need to see them 11 | gui.hide("options"); 12 | 13 | textSize(64); 14 | } 15 | 16 | public void draw() { 17 | background(gui.colorPicker("background", color(50)).hex); 18 | drawText(); 19 | drawRectangles(); 20 | } 21 | 22 | private void drawText() { 23 | gui.pushFolder("text"); 24 | boolean show = gui.toggle("editable?"); 25 | String content = gui.text("content", "hello"); 26 | text(content, 200, 600); 27 | 28 | // hide any single control element by path 29 | if (show) { 30 | gui.show("content"); 31 | } else { 32 | gui.hide("content"); 33 | } 34 | 35 | gui.popFolder(); 36 | } 37 | 38 | void drawRectangles() { 39 | gui.pushFolder("rects"); 40 | int maxRectCount = 20; 41 | int rectCount = gui.sliderInt("count", 10, 0, maxRectCount); 42 | 43 | for (int i = 0; i < maxRectCount; i++) { 44 | // make a dynamic list of rects each with its own folder 45 | gui.pushFolder("#" + i); 46 | 47 | if(i < rectCount){ 48 | // show the current folder in case it was hidden 49 | gui.showCurrentFolder(); 50 | }else{ 51 | // this rect is over the rectCount limit, so hide its folder and skip drawing it 52 | gui.hideCurrentFolder(); 53 | // shouldn't forget to pop out of the folder before 'continue' or 'return' 54 | gui.popFolder(); 55 | continue; 56 | } 57 | PVector pos = gui.plotXY("pos", 600, 80 + i * 22); 58 | PVector size = gui.plotXY("size", 5); 59 | fill(gui.colorPicker("fill", color(200)).hex); 60 | noStroke(); 61 | rect(pos.x, pos.y, size.x, size.y); 62 | gui.popFolder(); 63 | } 64 | gui.popFolder(); 65 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/MouseDrawing/MouseDrawing.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | PGraphics canvas; 5 | PickerColor circleColor; 6 | PickerColor lineColor; 7 | float lineWeight, circleSize; 8 | 9 | void setup() { 10 | size(800, 800, P2D); 11 | gui = new LazyGui(this); 12 | canvas = createGraphics(width, height); 13 | colorMode(HSB, 1, 1, 1, 1); 14 | clearCanvas(); 15 | noStroke(); 16 | } 17 | 18 | void draw() { 19 | gui.pushFolder("drawing"); 20 | circleColor = gui.colorPicker("circle color", color(0)); 21 | circleSize = gui.slider("circle size", 75); 22 | lineColor = gui.colorPicker("line color", color(1, 0.5, 1)); 23 | gui.colorPickerHueAdd("line color", radians(gui.slider("line hue +", 0.5f))); 24 | lineWeight = gui.slider("line weight", 50); 25 | gui.popFolder(); 26 | if (gui.button("clear")) { 27 | clearCanvas(); 28 | } 29 | image(canvas, 0, 0); 30 | 31 | 32 | boolean mouseOutsideGui = gui.isMouseOutsideGui(); 33 | textSize(32); 34 | text(mouseOutsideGui ? "The mouse is now a brush." : "The mouse is now using the GUI.", 10, height - 12); 35 | } 36 | 37 | void mousePressed() { 38 | if (gui.isMouseOutsideGui()) { 39 | drawCircleAtMouse(); 40 | } 41 | } 42 | 43 | void mouseReleased() { 44 | if (gui.isMouseOutsideGui()) { 45 | drawCircleAtMouse(); 46 | } 47 | } 48 | 49 | void mouseDragged() { 50 | if (gui.isMouseOutsideGui()) { 51 | drawLineAtMouse(); 52 | } 53 | } 54 | 55 | void clearCanvas() { 56 | canvas.beginDraw(); 57 | canvas.background(gui.colorPicker("background", color(50)).hex); 58 | canvas.endDraw(); 59 | } 60 | 61 | void drawCircleAtMouse() { 62 | canvas.beginDraw(); 63 | canvas.noStroke(); 64 | canvas.fill(circleColor.hex); 65 | canvas.ellipse(mouseX, mouseY, circleSize, circleSize); 66 | canvas.endDraw(); 67 | } 68 | 69 | void drawLineAtMouse() { 70 | canvas.beginDraw(); 71 | canvas.stroke(lineColor.hex); 72 | canvas.strokeWeight(lineWeight); 73 | canvas.line(pmouseX, pmouseY, mouseX, mouseY); 74 | canvas.endDraw(); 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/KeyState.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy; 2 | 3 | /** 4 | * Data transfer object for representing a keyboard button state. 5 | * @see Input 6 | */ 7 | public class KeyState { 8 | /** 9 | * True during any frame the button is physically down in the active position. 10 | */ 11 | public boolean down; 12 | 13 | /** 14 | * True for one frame after the button is pushed down to its active position. 15 | * Also sets framePressed to the current frameCount when true. 16 | */ 17 | public boolean pressed; 18 | 19 | /** 20 | * True for one frame after the button is released up from its active position into the idle position. 21 | * Also sets frameReleased to the current frameCount when true. 22 | */ 23 | public boolean released; 24 | 25 | /** 26 | * What the frameCount was equal to last time released was true for this key or keyCode. 27 | * Equal to -Integer.MAX_VALUE rather than 0 by default to not display an animation on startup when using 28 | * norm(frameCount, framePressed, framePressed + animationDuration) 29 | */ 30 | public int framePressed = -Integer.MAX_VALUE; 31 | 32 | /** 33 | * What the frameCount was equal to last time pressed was true for this key or keyCode. 34 | * Equal to -Integer.MAX_VALUE rather than 0 by default to not display an animation on startup when using 35 | * norm(frameCount, frameReleased, frameReleased + animationDuration) 36 | */ 37 | @SuppressWarnings("unused") 38 | public int frameReleased = -Integer.MAX_VALUE; 39 | 40 | /** 41 | * Used internally by the InputWatcherBackend. Not meant to be user-facing. 42 | * @param down is the key currently down? 43 | * @param pressed was the key just pressed? 44 | * @param released was the key just released? 45 | */ 46 | public KeyState(boolean down, boolean pressed, boolean released) { 47 | this.down = down; 48 | this.pressed = pressed; 49 | this.released = released; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/ToggleNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.annotations.Expose; 5 | 6 | import com.krab.lazy.stores.LayoutStore; 7 | import com.krab.lazy.input.LazyMouseEvent; 8 | import com.krab.lazy.stores.JsonSaveStore; 9 | import processing.core.PGraphics; 10 | 11 | public class ToggleNode extends AbstractNode { 12 | 13 | @Expose 14 | public 15 | boolean valueBoolean; 16 | protected boolean armed = false; 17 | 18 | public ToggleNode(String path, FolderNode folder, boolean defaultValue) { 19 | super(NodeType.VALUE, path, folder); 20 | valueBoolean = defaultValue; 21 | isInlineNodeDraggable = false; 22 | JsonSaveStore.overwriteWithLoadedStateIfAny(this); 23 | } 24 | 25 | @Override 26 | protected void drawNodeBackground(PGraphics pg) { 27 | 28 | } 29 | 30 | @Override 31 | protected void drawNodeForeground(PGraphics pg, String name) { 32 | drawLeftText(pg, name); 33 | drawRightBackdrop(pg, LayoutStore.cell); 34 | drawRightToggleHandle(pg, valueBoolean); 35 | } 36 | 37 | @Override 38 | public void mousePressedOverNode(float x, float y) { 39 | super.mousePressedOverNode(x, y); 40 | armed = true; 41 | } 42 | 43 | @Override 44 | public void mouseReleasedOverNode(float x, float y){ 45 | super.mouseReleasedOverNode(x,y); 46 | if(armed){ 47 | valueBoolean = !valueBoolean; 48 | onValueChangingActionEnded(); 49 | } 50 | armed = false; 51 | } 52 | 53 | @Override 54 | public void mouseDragNodeContinue(LazyMouseEvent e) { 55 | super.mouseDragNodeContinue(e); 56 | e.setConsumed(true); 57 | } 58 | 59 | public void overwriteState(JsonElement loadedNode) { 60 | JsonElement booleanElement = loadedNode.getAsJsonObject().get("valueBoolean"); 61 | if(booleanElement != null){ 62 | valueBoolean = booleanElement.getAsBoolean(); 63 | } 64 | } 65 | 66 | @Override 67 | public String getValueAsString() { 68 | return String.valueOf(valueBoolean); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/IndexedPaths/IndexedPaths.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | 5 | void setup() { 6 | size(1200, 800, P2D); 7 | smooth(8); 8 | rectMode(CENTER); 9 | textAlign(CENTER, CENTER); 10 | textSize(32); 11 | gui = new LazyGui(this); 12 | } 13 | 14 | void draw() { 15 | background(gui.colorPicker("background", color(0xFF252525)).hex); 16 | drawForeground(); 17 | } 18 | 19 | void drawForeground() { 20 | gui.pushFolder("foreground"); 21 | int rectCount = gui.sliderInt("rect count", 6, 2, 12); 22 | translate(width/2, height/2); 23 | for (int i = 0; i < rectCount; i++) { 24 | pushMatrix(); 25 | gui.pushFolder("global settings"); 26 | 27 | // you can ask for the same control element inside loops 28 | // like in "rect fill" here, which applies the same color to all rectangles 29 | fill(gui.colorPicker("rect fill", color(0xFFB2B0B0)).hex); 30 | float groupWidth = gui.slider("total width", 900, 20, 2400); 31 | float rectSize = gui.slider("rect size", 100); 32 | float x = map(i, 0, rectCount-1, -groupWidth/2, groupWidth/2); 33 | translate(x, 0); 34 | rect(0, 0, rectSize, rectSize); 35 | PVector globalTextPos = gui.plotXY("global offset"); 36 | translate(globalTextPos.x, globalTextPos.y); 37 | gui.popFolder(); 38 | 39 | // or you can put 'i' inside the path to make a new folder for each of them 40 | // with new folders growing automatically as you increase the i limit 41 | gui.pushFolder("#" + i); 42 | float rotation = gui.slider("rotation"); 43 | rotate(rotation); 44 | PVector localTextPos = gui.plotXY("local offset"); 45 | 46 | // when a toggle starts with 'active' it also lights up the folder icon 47 | if(gui.toggle("active shake")){ 48 | localTextPos.add(PVector.random2D().mult(3)); 49 | } 50 | translate(localTextPos.x, localTextPos.y); 51 | int defaultLabel = floor(pow(2, i+1)); 52 | 53 | // when the text path starts with 'label' this also sets a display name for the folder 54 | String label = gui.text("label text", "" + defaultLabel); 55 | fill(gui.colorPicker("text color", color(24)).hex); 56 | text(label, 0, 0); 57 | 58 | popMatrix(); 59 | gui.popFolder(); 60 | } 61 | gui.popFolder(); 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/SliderSketch.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGui; 4 | import processing.core.PApplet; 5 | import processing.core.PGraphics; 6 | 7 | public class SliderSketch extends PApplet { 8 | LazyGui gui; 9 | PGraphics pg; 10 | 11 | public static void main(String[] args) { 12 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 13 | } 14 | 15 | @Override 16 | public void settings() { 17 | size(800, 800, P2D); 18 | } 19 | 20 | @Override 21 | public void setup() { 22 | gui = new LazyGui(this); 23 | pg = createGraphics(width, height, P2D); 24 | colorMode(HSB, 1, 1, 1, 1); 25 | frameRate(144); 26 | } 27 | 28 | @Override 29 | public void draw() { 30 | pg.beginDraw(); 31 | drawBackground(); 32 | drawArc(); 33 | drawText(); 34 | pg.endDraw(); 35 | image(pg, 0, 0); 36 | gui.draw(); 37 | } 38 | 39 | private void drawText() { 40 | pg.pushMatrix(); 41 | pg.fill(gui.colorPicker("text fill", color(1)).hex); 42 | pg.textSize(gui.slider("text size", 32)); 43 | pg.textAlign(CENTER, CENTER); 44 | pg.translate(width/2f, height/2f); 45 | pg.translate(gui.plotXY("pos").x, gui.plotXY("pos").y); 46 | pg.text(nf(gui.slider("value"), 0, 8), 0, 0); 47 | pg.popMatrix(); 48 | } 49 | 50 | private void drawArc() { 51 | pg.pushMatrix(); 52 | float maxAngleNorm = gui.slider("max angle", 1, 0, 1); 53 | pg.translate(width/2f, height/2f); 54 | pg.fill(gui.colorPicker("fill", color(0.2f)).hex); 55 | pg.stroke(gui.colorPicker("stroke", color(0.8f)).hex); 56 | pg.strokeWeight(gui.slider("stroke weight", 4)); 57 | float diameter = gui.slider("diameter", 400); 58 | pg.arc(0, 0, diameter, diameter, 0, maxAngleNorm * TWO_PI); 59 | pg.popMatrix(); 60 | } 61 | 62 | private void drawBackground() { 63 | if(gui.toggle("gradient", true)){ 64 | pg.image(gui.gradient("background"), 0, 0); 65 | return; 66 | } 67 | pg.fill(gui.colorPicker("solid").hex); 68 | pg.noStroke(); 69 | pg.rectMode(CORNER); 70 | pg.rect(0, 0, width, height); 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/InputWatcher/InputWatcher.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | import java.util.List; 3 | 4 | LazyGui gui; 5 | int nextBackgroundColor = 0xFF0F0F0F; 6 | int currentBackgroundColor = 0xFF0F0F0F; 7 | 8 | @Override 9 | public void settings() { 10 | size(800, 800, P2D); 11 | } 12 | 13 | @Override 14 | public void setup() { 15 | gui = new LazyGui(this); 16 | colorMode(HSB, 1, 1, 1, 1); 17 | } 18 | 19 | @Override 20 | public void draw() { 21 | Input.debugPrintKeyEvents(gui.toggle("debug keys")); 22 | drawBackground(); 23 | fill(1); 24 | debugViewKeysDown(); 25 | detectCtrlSpacePress(); 26 | } 27 | 28 | private void debugViewKeysDown() { 29 | List downChars = Input.getAllDownChars(); 30 | List downCodes = Input.getAllDownCodes(); 31 | String textContent = "chars: " + downChars + "\ncodes: " + downCodes; 32 | fill(0, 0.5f); 33 | noStroke(); 34 | rectMode(CORNER); 35 | float bgWidth = textWidth(textContent) + 25; 36 | float bgHeight = 75; 37 | rect(0, height - bgHeight, bgWidth, bgHeight); 38 | fill(0.75f); 39 | textFont(gui.getMainFont()); 40 | textAlign(LEFT, BOTTOM); 41 | text(textContent, 10, height - 10); 42 | } 43 | 44 | private void detectCtrlSpacePress() { 45 | KeyState control = Input.getCode(CONTROL); 46 | KeyState space = Input.getChar(' '); 47 | translate(width / 2f, height / 2f); 48 | fill(1); 49 | noStroke(); 50 | rectMode(CENTER); 51 | if (control.down) { 52 | rect(-10, 8, 40, 2); 53 | } 54 | if (space.down) { 55 | rect(65, 8, 50, 2); 56 | } 57 | fill(1); 58 | if (control.down && space.pressed) { 59 | nextBackgroundColor = color(random(1), random(1), random(0.1f, 0.5f)); 60 | } 61 | if (control.down && space.framePressed > 0) { 62 | float fadeoutDuration = 60; 63 | float timeSinceCtrlSpacePressedNormalized = constrain( 64 | norm(frameCount, space.framePressed, space.framePressed + fadeoutDuration), 65 | 0, 1 66 | ); 67 | currentBackgroundColor = lerpColor( 68 | currentBackgroundColor, 69 | nextBackgroundColor, 70 | timeSinceCtrlSpacePressedNormalized 71 | ); 72 | } 73 | String guide = "Press CTRL + Space"; 74 | textAlign(CENTER); 75 | text(guide, 0, 0); 76 | } 77 | 78 | private void drawBackground() { 79 | fill(currentBackgroundColor); 80 | noStroke(); 81 | rectMode(CORNER); 82 | rect(0, 0, width, height); 83 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/SaveFromCodeTest.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGui; 4 | import processing.core.PApplet; 5 | import processing.core.PGraphics; 6 | import processing.core.PImage; 7 | 8 | public class SaveFromCodeTest extends PApplet { 9 | LazyGui gui; 10 | PGraphics pg; 11 | 12 | public static void main(String[] args) { 13 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 14 | } 15 | 16 | @Override 17 | public void settings() { 18 | size(800, 800, P2D); 19 | } 20 | 21 | @Override 22 | public void setup() { 23 | gui = new LazyGui(this); 24 | pg = createGraphics(width, height, P2D); 25 | pg.beginDraw(); 26 | pg.colorMode(HSB, 1, 1, 1, 1); 27 | pg.endDraw(); 28 | loadRandomImage(); 29 | colorMode(HSB, 1, 1, 1, 1); 30 | frameRate(144); 31 | } 32 | 33 | private void loadRandomImage() { 34 | drawImageOnCanvas(loadImage("https://picsum.photos/800/800.jpg")); 35 | } 36 | 37 | private void drawImageOnCanvas(PImage img) { 38 | pg.beginDraw(); 39 | pg.colorMode(HSB, 1, 1, 1, 1); 40 | pg.background(1); 41 | pg.image(img, 0, 0); 42 | pg.endDraw(); 43 | } 44 | 45 | @Override 46 | public void mousePressed(){ 47 | pg.beginDraw(); 48 | pg.noStroke(); 49 | pg.fill(0.1f); 50 | pg.ellipse(mouseX, mouseY, 10, 10); 51 | pg.endDraw(); 52 | } 53 | 54 | @Override 55 | public void mouseDragged(){ 56 | pg.beginDraw(); 57 | float t = (frameCount * 0.01f) % 1; 58 | pg.stroke(t, 1, 1); 59 | pg.noFill(); 60 | pg.strokeWeight(10); 61 | pg.line(mouseX, mouseY, pmouseX, pmouseY); 62 | pg.endDraw(); 63 | } 64 | 65 | @Override 66 | public void draw() { 67 | if(gui.button("random image")){ 68 | loadRandomImage(); 69 | } 70 | String savePath = gui.text("save name\\/path"); 71 | String imagePath = savePath + ".jpg"; 72 | if(gui.button("create save")) { 73 | gui.createSave(savePath); 74 | pg.save(imagePath); 75 | println("Saved img at: " + imagePath); 76 | } 77 | if(gui.button("load save")){ 78 | gui.loadSave(savePath); 79 | drawImageOnCanvas(loadImage(imagePath)); 80 | println("Loaded img from: " + imagePath); 81 | } 82 | image(pg, 0, 0); 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/Gradient.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGui; 4 | import com.krab.lazy.PickerColor; 5 | import processing.core.PApplet; 6 | 7 | public class Gradient extends PApplet { 8 | 9 | int defaultBackgroundColor = 0xFF0F0F0F; 10 | LazyGui gui; 11 | 12 | public static void main(String[] args) { 13 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 14 | } 15 | 16 | public void settings() { 17 | size(1144, 880, P2D); 18 | smooth(8); 19 | } 20 | 21 | public void setup() { 22 | colorMode(HSB, 1, 1, 1, 1); 23 | background(defaultBackgroundColor); 24 | gui = new LazyGui(this); 25 | } 26 | 27 | public void draw() { 28 | fadeToBlack(); 29 | drawNewCircles(); 30 | } 31 | 32 | void drawNewCircles() { 33 | gui.pushFolder("circles"); 34 | if(gui.hasChanged()){ 35 | background(defaultBackgroundColor); 36 | } 37 | gui.gradient("fill", new int[]{ 38 | //specify default colors for this gradient 39 | unhex("FFF6E1C3"), 40 | unhex("FFE9A178"), 41 | unhex("FFA84448"), 42 | unhex("FF7A3E65") 43 | }); 44 | float circleSize = 10; 45 | for (int i = 0; i < gui.sliderInt("new per frame", 50); i++) { 46 | float size = abs(randomGaussian()) * circleSize; 47 | float xPosition = random(width); 48 | float yPosition = random(height); 49 | float yPositionNormalized = norm(yPosition, 0, height); 50 | // get the color at this position between 0 and 1 51 | PickerColor gradientColor = gui.gradientColorAt("fill", yPositionNormalized); 52 | fill(gradientColor.hex); 53 | ellipse(xPosition, yPosition, size, size); 54 | } 55 | gui.popFolder(); 56 | } 57 | 58 | void fadeToBlack() { 59 | // fadeToBlack by subtracting white at low alpha 60 | blendMode(SUBTRACT); 61 | float fadeAlpha = gui.sliderInt("fade to background", 1, 0, 255) / (float) 255; 62 | fill(1, fadeAlpha); 63 | noStroke(); 64 | rect(0, 0, width, height); 65 | 66 | // enforce a minimum brightness 67 | blendMode(LIGHTEST); 68 | fill(gui.colorPicker("background", defaultBackgroundColor).hex); 69 | rect(0, 0, width, height); 70 | 71 | // reset blend mode to default 72 | blendMode(BLEND); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/ButtonNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | 4 | import com.krab.lazy.input.LazyMouseEvent; 5 | import com.krab.lazy.themes.ThemeColorType; 6 | import com.krab.lazy.themes.ThemeStore; 7 | import processing.core.PGraphics; 8 | 9 | import static com.krab.lazy.stores.GlobalReferences.app; 10 | import static com.krab.lazy.stores.LayoutStore.cell; 11 | import static processing.core.PConstants.CENTER; 12 | 13 | public class ButtonNode extends AbstractNode { 14 | public ButtonNode(String path, FolderNode folder) { 15 | super(NodeType.TRANSIENT, path, folder); 16 | isInlineNodeDraggable = false; 17 | } 18 | 19 | boolean valueBoolean = false; 20 | private boolean mousePressedLastFrame = false; 21 | 22 | @Override 23 | protected void drawNodeBackground(PGraphics pg) { 24 | boolean mousePressed = app.mousePressed; 25 | valueBoolean = isMouseOverNode && mousePressedLastFrame && !mousePressed; 26 | mousePressedLastFrame = mousePressed; 27 | } 28 | 29 | @Override 30 | protected void drawNodeForeground(PGraphics pg, String name) { 31 | drawLeftText(pg, name); 32 | drawRightBackdrop(pg, cell); 33 | drawRightButton(pg); 34 | } 35 | 36 | void drawRightButton(PGraphics pg) { 37 | pg.noFill(); 38 | pg.translate(size.x - cell *0.5f, cell * 0.5f); 39 | fillBackgroundBasedOnMouseOver(pg); 40 | pg.stroke(ThemeStore.getColor(ThemeColorType.NORMAL_FOREGROUND)); 41 | pg.rectMode(CENTER); 42 | float outerButtonSize = cell * 0.6f; 43 | pg.rect(0,0, outerButtonSize, outerButtonSize); 44 | pg.stroke(ThemeStore.getColor(isInlineNodeDragged ? ThemeColorType.FOCUS_FOREGROUND : ThemeColorType.NORMAL_FOREGROUND)); 45 | if(isMouseOverNode){ 46 | if (isInlineNodeDragged){ 47 | pg.fill(ThemeStore.getColor(ThemeColorType.FOCUS_FOREGROUND)); 48 | }else{ 49 | pg.fill(ThemeStore.getColor(ThemeColorType.NORMAL_FOREGROUND)); 50 | } 51 | } 52 | float innerButtonSize = cell * 0.35f; 53 | pg.rect(0,0, innerButtonSize, innerButtonSize); 54 | } 55 | 56 | @Override 57 | public void mouseDragNodeContinue(LazyMouseEvent e) { 58 | super.mouseDragNodeContinue(e); 59 | e.setConsumed(true); 60 | } 61 | 62 | public boolean getBooleanValueAndSetItToFalse() { 63 | boolean result = valueBoolean; 64 | valueBoolean = false; 65 | if(result){ 66 | onValueChangingActionEnded(); 67 | } 68 | return result; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /data/shaders/sliderBackground.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform vec2 quadPos; 3 | uniform vec2 quadSize; 4 | //uniform vec2 windowSize; 5 | uniform float time; 6 | uniform float scrollX; 7 | uniform float precisionNormalized; 8 | uniform vec3 colorA; 9 | uniform vec3 colorB; 10 | 11 | const float PI = 3.14159; 12 | const float TAU = PI * 2.; 13 | const int colorsPerGradient = 3; 14 | 15 | 16 | // https://iquilezles.org/www/articles/palettes/palettes.htm 17 | 18 | struct colorPoint 19 | { 20 | float pos; 21 | vec3 val; 22 | }; 23 | 24 | colorPoint emptyColorPoint() 25 | { 26 | return colorPoint(1.1, vec3(1.,0.,0.)); 27 | } 28 | 29 | float map(float value, float start1, float stop1, float start2, float stop2) 30 | { 31 | return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1)); 32 | } 33 | 34 | float norm(float value, float start, float stop) 35 | { 36 | return map(value, start, stop, 0., 1.); 37 | } 38 | 39 | int findClosestLeftNeighbourIndex(float pos, colorPoint[colorsPerGradient] gradient) 40 | { 41 | for(int i = 0; i < colorsPerGradient-1; i++){ 42 | if(pos >= gradient[i].pos && pos <= gradient[i+1].pos){ 43 | return i; 44 | } 45 | } 46 | return 0; 47 | } 48 | 49 | vec3 gradientColorAt(float normalizedPos, colorPoint[colorsPerGradient] gradient) 50 | { 51 | float pos = clamp(normalizedPos, 0., 1.); 52 | int leftIndex = findClosestLeftNeighbourIndex(pos, gradient); 53 | int rightIndex = leftIndex + 1; 54 | colorPoint A = gradient[leftIndex]; 55 | colorPoint B = gradient[rightIndex]; 56 | float normalizedPosBetweenNeighbours = norm(pos, A.pos, B.pos); 57 | return mix(A.val, B.val, normalizedPosBetweenNeighbours); 58 | } 59 | 60 | vec3 hexToRgb(int color) 61 | { 62 | float rValue = float(color / 256 / 256); 63 | float gValue = float(color / 256 - int(rValue * 256.0)); 64 | float bValue = float(color - int(rValue * 256.0 * 256.0) - int(gValue * 256.0)); 65 | return vec3(rValue / 255.0, gValue / 255.0, bValue / 255.0); 66 | } 67 | 68 | mat2 rotate2D(float angle){ 69 | return mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); 70 | } 71 | 72 | void main(){ 73 | vec2 uv = gl_FragCoord.xy; 74 | uv *= rotate2D(PI * 0.25); 75 | float freq = pow(50.,precisionNormalized); 76 | float x = (uv.x - scrollX) * freq * PI * 0.01; 77 | x = 0.5+0.5*clamp(sin(x)*30., 0., 1.); 78 | colorPoint[colorsPerGradient] gradient = colorPoint[]( 79 | colorPoint(0., colorA), 80 | colorPoint(0.5, colorB), 81 | colorPoint(1., colorA) 82 | ); 83 | vec3 color = gradientColorAt(x, gradient); 84 | gl_FragColor = vec4(color, 1.); 85 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/SimpleShape.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGui; 4 | import com.krab.lazy.LazyGuiSettings; 5 | import processing.core.PApplet; 6 | import processing.core.PGraphics; 7 | import processing.core.PVector; 8 | 9 | public class SimpleShape extends PApplet { 10 | LazyGui gui; 11 | 12 | public static void main(String[] args) { 13 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 14 | } 15 | 16 | public void settings() { 17 | size(22*41, 22*20, P2D); 18 | smooth(4); 19 | } 20 | 21 | public void setup() { 22 | gui = new LazyGui(this, new LazyGuiSettings().setWindowRestoreAlways()); 23 | } 24 | 25 | public void draw() { 26 | gui.pushFolder("scene"); 27 | drawBackground(); 28 | drawForegroundShape(); 29 | gui.popFolder(); 30 | } 31 | 32 | private void drawForegroundShape() { 33 | gui.pushFolder("shape"); 34 | String[] shapeTypeOptions = new String[]{"square", "circle", "triangle"}; 35 | String selectedShape = gui.radio("shape type", shapeTypeOptions, "ellipse"); 36 | PVector pos = gui.plotXY("position"); 37 | PVector size = gui.plotXY("size", 250); 38 | translate(width/2f, height/2f); 39 | float rotationAngle = gui.slider("rotation"); 40 | float rotationAngleDelta = gui.slider("rotation ++", 0.1f); 41 | gui.sliderSet("rotation", rotationAngle + rotationAngleDelta); 42 | fill(gui.colorPicker("fill", color(0xFF689FC8)).hex); 43 | gui.colorPickerHueAdd("fill", radians(gui.slider("fill hue ++", 0.1f))); 44 | stroke(gui.colorPicker("stroke").hex); 45 | strokeWeight(gui.slider("stroke weight", 10)); 46 | if(gui.toggle("no stroke")){ 47 | noStroke(); 48 | } 49 | rectMode(CENTER); 50 | translate(pos.x, pos.y); 51 | rotate(radians(rotationAngle)); 52 | // println("shape selected: " + selectedShape); 53 | if("circle".equals(selectedShape)){ 54 | ellipse(0, 0, size.x, size.y); 55 | }else if("square".equals(selectedShape)){ 56 | rect(0, 0, size.x, size.y); 57 | }else if("triangle".equals(selectedShape)){ 58 | triangle(-size.x/2, size.y/2, size.x/2, size.y/2, 0, -size.y/2); 59 | } 60 | gui.popFolder(); 61 | } 62 | 63 | private void drawBackground() { 64 | gui.pushFolder("background"); 65 | boolean useGradient = gui.toggle("solid\\/gradient", false); 66 | int solidBackgroundColor = gui.colorPicker("solid", color(0xFF252525)).hex; 67 | PGraphics gradient = gui.gradient("gradient"); 68 | if(useGradient){ 69 | image(gradient, 0, 0); 70 | }else{ 71 | background(solidBackgroundColor); 72 | } 73 | gui.popFolder(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/MouseDrawing.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGui; 4 | import com.krab.lazy.LazyGuiSettings; 5 | import com.krab.lazy.PickerColor; 6 | import processing.core.PApplet; 7 | import processing.core.PGraphics; 8 | 9 | public class MouseDrawing extends PApplet { 10 | LazyGui gui; 11 | PGraphics canvas; 12 | PickerColor circleColor; 13 | PickerColor lineColor; 14 | private float lineWeight = 15; 15 | private float circleSize = 50; 16 | 17 | 18 | public static void main(String[] args) { 19 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 20 | } 21 | 22 | @Override 23 | public void settings() { 24 | size(800, 800, P2D); 25 | } 26 | 27 | @Override 28 | public void setup() { 29 | gui = new LazyGui(this, new LazyGuiSettings().setLoadLatestSaveOnStartup(false)); 30 | canvas = createGraphics(width, height); 31 | canvas.beginDraw(); 32 | canvas.background(50); 33 | canvas.endDraw(); 34 | noStroke(); 35 | } 36 | 37 | @Override 38 | public void draw() { 39 | gui.pushFolder("drawing"); 40 | circleColor = gui.colorPicker("circle color", color(0)); 41 | circleSize = gui.slider("circle size", circleSize); 42 | lineColor = gui.colorPicker("line color", color(150, 255, 100)); 43 | gui.colorPickerHueAdd("line color", radians(gui.slider("line hue +", 0.5f))); 44 | lineWeight = gui.slider("line weight", lineWeight); 45 | gui.popFolder(); 46 | clear(); 47 | if(gui.button("clear canvas")){ 48 | canvas.beginDraw(); 49 | canvas.background(50); 50 | canvas.endDraw(); 51 | } 52 | image(canvas, 0, 0); 53 | 54 | boolean mouseOutsideGui = gui.isMouseOutsideGui(); 55 | textSize(32); 56 | text(mouseOutsideGui ? "The mouse is now a brush." : "The mouse is now using the GUI.", 10, height - 12); 57 | } 58 | 59 | public void mousePressed() { 60 | if (gui.isMouseOutsideGui()) { 61 | drawCircleAtMouse(); 62 | } 63 | } 64 | 65 | public void mouseReleased() { 66 | if (gui.isMouseOutsideGui()) { 67 | drawCircleAtMouse(); 68 | } 69 | } 70 | 71 | public void mouseDragged() { 72 | if (gui.isMouseOutsideGui()) { 73 | drawLineAtMouse(); 74 | } 75 | } 76 | 77 | private void drawCircleAtMouse() { 78 | canvas.beginDraw(); 79 | canvas.noStroke(); 80 | canvas.fill(circleColor.hex); 81 | canvas.ellipse(mouseX, mouseY, circleSize, circleSize); 82 | canvas.endDraw(); 83 | } 84 | 85 | private void drawLineAtMouse() { 86 | canvas.beginDraw(); 87 | canvas.stroke(lineColor.hex); 88 | canvas.strokeWeight(lineWeight); 89 | canvas.line(pmouseX, pmouseY, mouseX, mouseY); 90 | canvas.endDraw(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/TextEditor.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.Input; 4 | import com.krab.lazy.LazyGui; 5 | import com.krab.lazy.LazyGuiSettings; 6 | import processing.core.PApplet; 7 | import processing.core.PFont; 8 | import processing.core.PVector; 9 | 10 | import java.util.HashMap; 11 | 12 | public class TextEditor extends PApplet { 13 | LazyGui gui; 14 | 15 | public static void main(String[] args) { 16 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 17 | } 18 | 19 | public void settings(){ 20 | size(800,600,P2D); 21 | } 22 | 23 | public void setup() { 24 | gui = new LazyGui(this, new LazyGuiSettings() 25 | .setLoadLatestSaveOnStartup(false) 26 | ); 27 | } 28 | 29 | public void draw() { 30 | background(gui.colorPicker("background", color(10)).hex); 31 | gui.pushFolder("text"); 32 | String textValue = gui.text("hello", "lorem\nipsum\ndolor\nsit\namet"); 33 | PVector pos = gui.plotXY("text pos", 400, 300); 34 | translate(pos.x, pos.y); 35 | font(); 36 | text(textValue, 0, 0); 37 | gui.popFolder(); 38 | } 39 | 40 | // font() related fields 41 | PFont selectedFont; 42 | HashMap xAligns; 43 | HashMap yAligns; 44 | 45 | // Select from lazily created, cached fonts. 46 | void font() { 47 | gui.pushFolder("font"); 48 | fill(gui.colorPicker("fill", color(255)).hex); 49 | int size = gui.sliderInt("size", 64, 1, 256); 50 | float leading = gui.slider("leading", 64); 51 | if (xAligns == null || yAligns == null) { 52 | xAligns = new HashMap(); 53 | xAligns.put("left", LEFT); 54 | xAligns.put("center", CENTER); 55 | xAligns.put("right", RIGHT); 56 | yAligns = new HashMap(); 57 | yAligns.put("top", TOP); 58 | yAligns.put("center", CENTER); 59 | yAligns.put("bottom", BOTTOM); 60 | } 61 | String xAlignSelection = gui.radio("align x", xAligns.keySet().toArray(new String[0]), "center"); 62 | String yAlignSelection = gui.radio("align y", yAligns.keySet().toArray(new String[0]), "center"); 63 | textAlign(xAligns.get(xAlignSelection), yAligns.get(yAlignSelection)); 64 | String fontName = gui.text("font name", "Arial").trim(); 65 | if (gui.button("list fonts")) { 66 | String[] fonts = PFont.list(); 67 | for (String font : fonts) { 68 | println(font + " "); // some spaces to avoid copying newlines from the console 69 | } 70 | } 71 | if (selectedFont == null || gui.hasChanged("font name") || gui.hasChanged("size")) { 72 | selectedFont = createFont(fontName, size); 73 | } 74 | textFont(selectedFont); 75 | textLeading(leading); 76 | gui.popFolder(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/SettingsTest.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGuiSettings; 4 | import processing.core.PApplet; 5 | import com.krab.lazy.LazyGui; 6 | 7 | public class SettingsTest extends PApplet { 8 | LazyGui gui; 9 | 10 | public static void main(String[] args) { 11 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 12 | } 13 | 14 | @Override 15 | public void settings() { 16 | size(600,600, P2D); 17 | noSmooth(); 18 | } 19 | 20 | public void setup() { 21 | gui = new LazyGui(this, new LazyGuiSettings() 22 | // AUTOLOAD 23 | 24 | .setLoadLatestSaveOnStartup(false) // set as false to not load anything on startup 25 | 26 | // .setLoadSpecificSaveOnStartup("auto.json") // expects filenames like "1" or "auto.json" or an absolute path 27 | // .setLoadSpecificSaveOnStartupOnce("C:\\Users\\Krab\\Desktop\\auto.json") // loads save only when the save folder is found empty 28 | 29 | // AUTOSAVE 30 | .setAutosaveOnExit(false) // the shutdown hook only works on graceful exit, for example the ESC button 31 | .setAutosaveLockGuardEnabled(true) // for not autosaving settings that locked the sketch in an endless loop 32 | .setAutosaveLockGuardMillisLimit(1000) // millis the last frame must be rendered faster than for autosave to work 33 | 34 | // MOUSE 35 | .setMouseHideWhenDragging(true) // when dragging a slider for example 36 | .setMouseConfineToWindow(false) 37 | 38 | // LAYOUT 39 | .setCellSize(22) // affects the size of the whole gui 40 | .setMainFontSize(16) 41 | .setSideFontSize(15) 42 | .setStartGuiHidden(false) // uncover hidden gui with the 'h' hotkey 43 | 44 | // THEME 45 | .setThemePreset("dark") // selected preset, one of "dark", "light", "pink", "blue" 46 | .setThemeCustom( 47 | color(0, 0, 255), // window border color 48 | color(16), // normal background color 49 | color(0, 0, 0), // focused background color 50 | color(200), // normal foreground color 51 | color(255)) // focused foreground color 52 | // custom theme overrides preset when not null 53 | 54 | .setAutosuggestWindowWidth(true) 55 | .setSketchNameOverride("GUI Root") 56 | .setSmooth(0) 57 | .setHideBuiltInFolders(false) 58 | .setHideRadioValue(true) 59 | 60 | .setShowSquigglyEqualsInsideSliders(true) 61 | .setHotkeyMouseWheelActive(false) 62 | ); 63 | 64 | 65 | textSize(64); 66 | } 67 | 68 | public void draw() { 69 | image(gui.gradient("background"), 0, 0); 70 | gui.plotXY("hello plot"); 71 | gui.slider("test slider", 7.12f); 72 | gui.draw(); 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Generated Documentation (Untitled) 7 | 60 | 61 | 62 | 63 | 64 | 65 | <noscript> 66 | <div>JavaScript is disabled on your browser.</div> 67 | </noscript> 68 | <h2>Frame Alert</h2> 69 | <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="com/krab/lazy/package-summary.html">Non-frame version</a>.</p> 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/themes/ThemeType.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.themes; 2 | 3 | /** 4 | * Shorthands for some pre-defined themes with a custom option. 5 | */ 6 | public enum ThemeType { 7 | DARK, 8 | LIGHT, 9 | PINK, 10 | BLUE, 11 | CUSTOM; 12 | 13 | static String[] getAllNames() { 14 | return new String[]{"dark", "light", "pink", "blue", "custom"}; 15 | } 16 | 17 | static ThemeType[] getAllValues() { 18 | return new ThemeType[]{DARK, LIGHT, PINK, BLUE, CUSTOM}; 19 | } 20 | 21 | public static ThemeType getValue(String name) { 22 | switch (name) { 23 | case "dark": { 24 | return DARK; 25 | } 26 | case "light": { 27 | return LIGHT; 28 | } 29 | case "pink": { 30 | return PINK; 31 | } 32 | case "blue": { 33 | return BLUE; 34 | } 35 | case "custom": { 36 | return CUSTOM; 37 | } 38 | } 39 | return null; 40 | } 41 | 42 | static String getName(ThemeType query) { 43 | switch (query) { 44 | case DARK: { 45 | return "dark"; 46 | } 47 | case LIGHT: { 48 | return "light"; 49 | } 50 | case PINK: { 51 | return "pink"; 52 | } 53 | case BLUE: { 54 | return "blue"; 55 | } 56 | case CUSTOM: { 57 | return "custom"; 58 | } 59 | } 60 | return null; 61 | } 62 | 63 | static Theme getPalette(ThemeType query) { 64 | switch (query) { 65 | case DARK: 66 | case CUSTOM: { 67 | return new Theme(0xFF787878, 68 | 0xFF0B0B0B, 69 | 0xFF2F2F2F, 70 | 0xFFB0B0B0, 71 | 0xFFFFFFFF); 72 | } 73 | case LIGHT: { 74 | return new Theme(0xFF000000, 75 | 0xFFD9D9D9, 76 | 0xFFAFAFAF, 77 | 0xFF000000, 78 | 0xFF000000 79 | ); 80 | } 81 | case PINK: { 82 | return new Theme( 83 | 0xFFfcd3e7, 84 | 0xFF916b99, 85 | 0xFF532e6a, 86 | 0xFFFFFFFF, 87 | 0xFFFFFFFF 88 | ); 89 | } 90 | case BLUE: { 91 | return new Theme( 92 | 0xFF000000, 93 | 0xFFc9d1ef, 94 | 0xFF6271c4, 95 | 0xFF000000, 96 | 0xFFFFFFFF 97 | ); 98 | } 99 | } 100 | return null; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/PickerColor.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy; 2 | 3 | import com.krab.lazy.nodes.ColorPickerFolderNode; 4 | import com.krab.lazy.stores.NormColorStore; 5 | import processing.core.PApplet; 6 | 7 | /** 8 | * Data transfer object for ColorPicker value. 9 | * Hue, saturation, brightness and alpha are normalized to a range of [0,1]. 10 | * The hex value can be used in any processing colorMode, it will always show the correct color. 11 | * This object's fields are final, if you want to change the ColorPicker from code, use LazyGui.colorPickerSet instead. 12 | * Please note that ColorPicker tries to avoid hex values of exactly 0 because 13 | * they are not transparent in processing even though the alpha is 0, which is probably a bug. 14 | * It returns 0x00010101 instead which looks perfectly transparent in processing. 15 | * @see ColorPickerFolderNode 16 | */ 17 | public class PickerColor { 18 | /** 19 | * Integer representation of a processing hex color. Can be passed to fill(), stroke() directly in any colorMode. 20 | * See: Processing color datatype 21 | */ 22 | public final int hex; 23 | 24 | /** 25 | * Hue in range of [0,1] 26 | */ 27 | public final float hue; 28 | 29 | /** 30 | * Saturation in range of [0,1] 31 | */ 32 | public final float saturation; 33 | 34 | /** 35 | * Brightness in range of [0,1] 36 | */ 37 | public final float brightness; 38 | 39 | /** 40 | * Alpha in range of [0,1] 41 | */ 42 | public final float alpha; 43 | 44 | /** 45 | * Simple constructor that just assigns the parameters into the corresponding fields. 46 | * @param hex processing int color 47 | * @param hue hue in range of [0,1] 48 | * @param sat saturation in range of [0,1] 49 | * @param br brightness in range of [0,1] 50 | * @param alpha alpha in range of [0,1] 51 | */ 52 | public PickerColor(int hex, float hue, float sat, float br, float alpha){ 53 | this.hex = hex; 54 | this.hue = hue; 55 | this.saturation = sat; 56 | this.brightness = br; 57 | this.alpha = alpha; 58 | } 59 | 60 | /** 61 | * Utility constructor that gets all the other HSB color data from the hex int color, 62 | * but this can be CPU intensive when done too much. 63 | * 64 | * @param hex processing integer color to parse as HSBA 65 | */ 66 | public PickerColor(int hex) { 67 | this.hex = hex; 68 | this.hue = NormColorStore.hue(hex); 69 | this.saturation = NormColorStore.sat(hex); 70 | this.brightness = NormColorStore.br(hex); 71 | this.alpha = NormColorStore.alpha(hex); 72 | } 73 | 74 | public String toString() { 75 | return "PickerColor{" + 76 | "hexInt=" + hex + 77 | ", hexString=" + PApplet.hex(hex) + 78 | ", hue=" + hue + 79 | ", saturation=" + saturation + 80 | ", brightness=" + brightness + 81 | ", alpha=" + alpha + 82 | '}'; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/InputWatcherTest.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.*; 4 | import processing.core.PApplet; 5 | 6 | import java.util.List; 7 | 8 | public class InputWatcherTest extends PApplet { 9 | LazyGui gui; 10 | int nextBackgroundColor = 0xFF0F0F0F; 11 | int currentBackgroundColor = 0xFF0F0F0F; 12 | 13 | public static void main(String[] args) { 14 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 15 | } 16 | 17 | @Override 18 | public void settings() { 19 | size(800, 800, P2D); 20 | } 21 | 22 | @Override 23 | public void setup() { 24 | gui = new LazyGui(this); 25 | colorMode(HSB, 1, 1, 1, 1); 26 | } 27 | 28 | @Override 29 | public void draw() { 30 | Input.debugPrintKeyEvents(gui.toggle("debug keys")); 31 | drawBackground(); 32 | fill(1); 33 | debugViewKeysDown(); 34 | detectCtrlSpacePress(); 35 | } 36 | 37 | private void debugViewKeysDown() { 38 | List downChars = Input.getAllDownChars(); 39 | List downCodes = Input.getAllDownCodes(); 40 | String textContent = "chars: " + downChars + "\ncodes: " + downCodes; 41 | fill(0, 0.5f); 42 | noStroke(); 43 | rectMode(CORNER); 44 | float bgWidth = textWidth(textContent) + 25; 45 | float bgHeight = 75; 46 | rect(0, height - bgHeight, bgWidth, bgHeight); 47 | fill(0.75f); 48 | textFont(gui.getMainFont()); 49 | textAlign(LEFT, BOTTOM); 50 | text(textContent, 10, height - 10); 51 | } 52 | 53 | private void detectCtrlSpacePress() { 54 | KeyState control = Input.getCode(CONTROL); 55 | KeyState space = Input.getChar(' '); 56 | translate(width / 2f, height / 2f); 57 | fill(1); 58 | noStroke(); 59 | rectMode(CENTER); 60 | if (control.down) { 61 | rect(-10, 8, 40, 2); 62 | } 63 | if (space.down) { 64 | rect(65, 8, 50, 2); 65 | } 66 | fill(1); 67 | if (control.down && space.pressed) { 68 | nextBackgroundColor = color(random(1), random(1), random(0.1f, 0.5f)); 69 | } 70 | if (control.down && space.framePressed > 0) { 71 | float fadeoutDuration = 60; 72 | float timeSinceCtrlSpacePressedNormalized = constrain( 73 | norm(frameCount, space.framePressed, space.framePressed + fadeoutDuration), 74 | 0, 1 75 | ); 76 | currentBackgroundColor = lerpColor( 77 | currentBackgroundColor, 78 | nextBackgroundColor, 79 | timeSinceCtrlSpacePressedNormalized 80 | ); 81 | } 82 | String guide = "Press CTRL + Space"; 83 | textAlign(CENTER); 84 | text(guide, 0, 0); 85 | } 86 | 87 | private void drawBackground() { 88 | fill(currentBackgroundColor); 89 | noStroke(); 90 | rectMode(CORNER); 91 | rect(0, 0, width, height); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/HotkeyStore.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | import com.krab.lazy.utils.KeyCodes; 4 | import com.krab.lazy.windows.WindowManager; 5 | import com.krab.lazy.input.LazyKeyEvent; 6 | 7 | public class HotkeyStore { 8 | 9 | private static boolean hotkeyHideActive, hotkeyUndoActive, hotkeyRedoActive, hotkeyScreenshotActive, 10 | hotkeyCloseAllWindowsActive, hotkeySaveActive, hotkeyMouseWheelActive; 11 | private static boolean isScreenshotRequestedOnMainThread = false; 12 | 13 | public static void updateHotkeyToggles() { 14 | GlobalReferences.gui.pushFolder("hotkeys"); 15 | hotkeyHideActive = GlobalReferences.gui.toggle("h: hide\\/show gui", true); 16 | hotkeyCloseAllWindowsActive = GlobalReferences.gui.toggle("d: close windows", true); 17 | hotkeyScreenshotActive = GlobalReferences.gui.toggle("i: screenshot", true); 18 | hotkeyUndoActive = GlobalReferences.gui.toggle("ctrl + z: undo", true); 19 | hotkeyRedoActive = GlobalReferences.gui.toggle("ctrl + y: redo", true); 20 | hotkeySaveActive = GlobalReferences.gui.toggle("ctrl + s: new save", true); 21 | hotkeyMouseWheelActive = GlobalReferences.gui.toggle("mouse wheel", hotkeyMouseWheelActive); 22 | GlobalReferences.gui.textSet("mouseover specific hotkeys", 23 | "r: reset control element to default value\n" + 24 | "ctrl + c: copy from (single value or folder)\n" + 25 | "ctrl + v: paste to (single value or folder)\n" + 26 | "these hotkeys cannot be turned off for now" 27 | ); 28 | GlobalReferences.gui.popFolder(); 29 | } 30 | 31 | public static void handleHotkeyInteraction(LazyKeyEvent keyEvent) { 32 | char key = keyEvent.getKey(); 33 | int keyCode = keyEvent.getKeyCode(); 34 | if (key == 'h' && hotkeyHideActive) { 35 | LayoutStore.hideGuiToggle(); 36 | } 37 | isScreenshotRequestedOnMainThread = (key == 'i' && hotkeyScreenshotActive); 38 | if(key == 'd' && hotkeyCloseAllWindowsActive){ 39 | WindowManager.closeAllWindows(); 40 | } 41 | if(keyEvent.isControlDown() && keyCode == KeyCodes.Z && hotkeyUndoActive){ 42 | UndoRedoStore.undo(); 43 | } 44 | if(keyEvent.isControlDown() && keyCode == KeyCodes.Y && hotkeyRedoActive){ 45 | UndoRedoStore.redo(); 46 | } 47 | if(keyEvent.isControlDown() && keyCode == KeyCodes.S && hotkeySaveActive){ 48 | JsonSaveStore.createNextSaveInGuiFolder(); 49 | } 50 | } 51 | 52 | public static boolean isScreenshotRequestedOnMainThread(){ 53 | return isScreenshotRequestedOnMainThread; 54 | } 55 | 56 | public static void setScreenshotRequestedOnMainThread(boolean val){ 57 | isScreenshotRequestedOnMainThread = val; 58 | } 59 | 60 | public static void setHotkeyMouseWheelActive(boolean val){ 61 | hotkeyMouseWheelActive = val; 62 | } 63 | 64 | public static boolean isHotkeyMouseWheelActive(){ 65 | return hotkeyMouseWheelActive; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/utils/ContextLines.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.utils; 2 | 3 | import com.krab.lazy.nodes.FolderNode; 4 | import com.krab.lazy.nodes.NodeType; 5 | import com.krab.lazy.stores.GlobalReferences; 6 | import com.krab.lazy.stores.NodeTree; 7 | import com.krab.lazy.stores.NormColorStore; 8 | import com.krab.lazy.nodes.AbstractNode; 9 | import processing.core.PConstants; 10 | import processing.core.PGraphics; 11 | 12 | import java.util.List; 13 | 14 | public class ContextLines { 15 | public static final String NEVER = "never"; 16 | public static final String ON_HOVER = "on hover"; 17 | public static final String ALWAYS = "always"; 18 | public static final int SHOW_CONTEXT_LINES_MODE_NEVER = 0; 19 | public static final int SHOW_CONTEXT_LINES_MODE_ON_HOVER = 1; 20 | public static final int SHOW_CONTEXT_LINES_ALWAYS = 2; 21 | public static final List contextLinesOptions = new ArrayListBuilder() 22 | .add(NEVER, ON_HOVER, ALWAYS).build(); 23 | private static int showContextLinesMode; 24 | private static boolean shouldPickShortestLine; 25 | private static int lineStroke; 26 | private static float weight; 27 | private static float endpointRectSize; 28 | 29 | public static void updateSettings() { 30 | GlobalReferences.gui.pushFolder("context lines"); 31 | showContextLinesMode = contextLinesOptions.indexOf( 32 | GlobalReferences.gui.radio("visibility", contextLinesOptions, ON_HOVER)); 33 | shouldPickShortestLine = GlobalReferences.gui.toggle("shortest line"); 34 | lineStroke = GlobalReferences.gui.colorPicker("color", NormColorStore.color(0.5f)).hex; 35 | weight = GlobalReferences.gui.slider("weight", 1.2f); 36 | endpointRectSize = GlobalReferences.gui.slider("end size", 3.5f); 37 | GlobalReferences.gui.popFolder(); 38 | } 39 | 40 | public static void drawLines(PGraphics pg){ 41 | pg.pushStyle(); 42 | pg.stroke(lineStroke); 43 | pg.fill(lineStroke); 44 | pg.strokeCap(PConstants.SQUARE); 45 | pg.strokeWeight(weight); 46 | List allNodes = NodeTree.getAllNodesAsList(); 47 | if (showContextLinesMode == SHOW_CONTEXT_LINES_MODE_NEVER) { 48 | pg.popStyle(); 49 | return; 50 | } 51 | for (AbstractNode node : allNodes) { 52 | if (node.type != NodeType.FOLDER) { 53 | continue; 54 | } 55 | FolderNode folderNode = (FolderNode) node; 56 | if (folderNode.window == null || folderNode.window.closed || !folderNode.isInlineNodeVisible()) { 57 | continue; 58 | } 59 | boolean shouldShowLineFromTitleTowardsInlineNode = showContextLinesMode == SHOW_CONTEXT_LINES_ALWAYS || 60 | (folderNode.window.isTitleHighlighted() && showContextLinesMode == SHOW_CONTEXT_LINES_MODE_ON_HOVER); 61 | if (shouldShowLineFromTitleTowardsInlineNode) { 62 | folderNode.window.drawContextLineFromTitleBarToInlineNode(pg, endpointRectSize, shouldPickShortestLine); 63 | } 64 | } 65 | pg.popStyle(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/UtilityMethods/UtilityMethods.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | 5 | void setup() { 6 | size(800, 800, P2D); 7 | gui = new LazyGui(this); 8 | } 9 | 10 | void draw() { 11 | background(gui.colorPicker("background", color(36)).hex); 12 | translate(width/2, height/2); 13 | 14 | gui.pushFolder("rect"); 15 | pushMatrix(); 16 | transform(); 17 | PVector size = gui.plotXY("size", 300, 100); 18 | style(); 19 | rect(0, 0, size.x, size.y); 20 | popMatrix(); 21 | gui.popFolder(); 22 | 23 | gui.pushFolder("text"); 24 | pushMatrix(); 25 | transform(); 26 | font(); 27 | text(gui.text("text", "hello"), 0, 0); 28 | popMatrix(); 29 | gui.popFolder(); 30 | } 31 | 32 | // Change position and rotation without creating a new gui folder. 33 | void transform() { 34 | gui.pushFolder("transform"); 35 | PVector pos = gui.plotXY("pos"); 36 | translate(pos.x, pos.y); 37 | rotate(gui.slider("rotate")); 38 | PVector scale = gui.plotXY("scale", 1.00); 39 | scale(scale.x, scale.y); 40 | gui.popFolder(); 41 | } 42 | 43 | // Change drawing style 44 | void style() { 45 | gui.pushFolder("style"); 46 | strokeWeight(gui.slider("weight", 4)); 47 | stroke(gui.colorPicker("stroke", color(0)).hex); 48 | fill(gui.colorPicker("fill", color(200)).hex); 49 | String rectMode = gui.radio("rect mode", new String[]{"center", "corner"}); 50 | if ("center".equals(rectMode)) { 51 | rectMode(CENTER); 52 | } else { 53 | rectMode(CORNER); 54 | } 55 | gui.popFolder(); 56 | } 57 | 58 | 59 | // font() related fields 60 | HashMap selectedFontsByFolder = new HashMap(); 61 | HashMap xAligns; 62 | HashMap yAligns; 63 | 64 | void font() { 65 | gui.pushFolder("font"); 66 | fill(gui.colorPicker("fill", color(150,0,0)).hex); 67 | int size = gui.sliderInt("size", 64, 1, 256); 68 | float leading = gui.slider("leading", 64); 69 | if (xAligns == null || yAligns == null) { 70 | xAligns = new HashMap(); 71 | xAligns.put("left", LEFT); 72 | xAligns.put("center", CENTER); 73 | xAligns.put("right", RIGHT); 74 | yAligns = new HashMap(); 75 | yAligns.put("top", TOP); 76 | yAligns.put("center", CENTER); 77 | yAligns.put("bottom", BOTTOM); 78 | } 79 | String xAlignSelection = gui.radio("align x", xAligns.keySet().toArray(new String[0]), "center"); 80 | String yAlignSelection = gui.radio("align y", yAligns.keySet().toArray(new String[0]), "center"); 81 | textAlign(xAligns.get(xAlignSelection), yAligns.get(yAlignSelection)); 82 | String fontName = gui.text("font name", "Arial").trim(); 83 | if (gui.button("list fonts")) { 84 | String[] fonts = PFont.list(); 85 | for (String font : fonts) { 86 | println(font + " "); // some spaces to avoid copying newlines from the console 87 | } 88 | } 89 | String mapKey = gui.getFolder(); // the map separates different font() calls from different folders which allows using multiple fonts at a time 90 | if (!selectedFontsByFolder.containsKey(mapKey) || gui.hasChanged("font name") || gui.hasChanged("size")) { 91 | selectedFontsByFolder.put(mapKey, createFont(fontName, size)); 92 | } 93 | textFont(selectedFontsByFolder.get(mapKey)); 94 | textLeading(leading); 95 | gui.popFolder(); 96 | } -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/SinewaveExample.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.PickerColor; 4 | import processing.core.PApplet; 5 | import processing.core.PGraphics; 6 | import com.krab.lazy.LazyGui; 7 | import processing.core.PVector; 8 | 9 | public class SinewaveExample extends PApplet { 10 | LazyGui gui; 11 | PGraphics pg; 12 | float time; 13 | 14 | public static void main(String[] args) { 15 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 16 | } 17 | 18 | @Override 19 | public void settings() { 20 | size(1000,1000, P2D); 21 | smooth(4); 22 | } 23 | 24 | @Override 25 | public void setup() { 26 | gui = new LazyGui(this); 27 | pg = createGraphics(width, height, P2D); 28 | pg.smooth(4); 29 | } 30 | 31 | @Override 32 | public void draw() { 33 | pg.beginDraw(); 34 | gui.pushFolder("scene"); 35 | // drawBackground(); 36 | drawBackgroundGradient(); 37 | pg.translate(width / 2f, height / 2f); 38 | drawRectangle(); 39 | drawSinewave(); 40 | gui.popFolder(); 41 | pg.endDraw(); 42 | image(pg, 0, 0); 43 | } 44 | 45 | private void drawRectangle() { 46 | pg.pushMatrix(); 47 | gui.pushFolder("rect"); 48 | pg.fill(gui.colorPicker("fill", 0xFF000000).hex); 49 | pg.stroke(gui.colorPicker("stroke", 0xFFA0A0A0).hex); 50 | pg.strokeWeight(gui.slider("weight", 6)); 51 | pg.rectMode(CENTER); 52 | PVector pos = gui.plotXY("pos"); 53 | PVector size = gui.plotXY("size", 500, 280); 54 | pg.rect(pos.x, pos.y, size.x, size.y); 55 | gui.popFolder(); 56 | pg.popMatrix(); 57 | } 58 | 59 | private void drawSinewave() { 60 | pg.pushMatrix(); 61 | gui.pushFolder("sinewave"); 62 | int detail = gui.sliderInt("detail", 100); 63 | int waveCount = gui.sliderInt("wave count", 4); 64 | float freq = gui.slider("freq", 1); 65 | time += radians(gui.slider("time", 1)); 66 | PVector pos = gui.plotXY("pos"); 67 | PVector size = gui.plotXY("size", 400, 200); 68 | pg.translate(pos.x, pos.y); 69 | pg.noFill(); 70 | pg.stroke(gui.colorPicker("stroke", color(255)).hex); 71 | pg.strokeWeight(gui.slider("weight", 4)); 72 | for (int j = 0; j < waveCount; j++) { 73 | float jNorm = norm(j, 0, waveCount); 74 | pg.beginShape(); 75 | for (int i = 0; i < detail; i++) { 76 | float norm = norm(i, 0, detail - 1); 77 | float x = -size.x / 2f + size.x * norm; 78 | float y = size.y * 0.5f * sin(norm * freq * TAU + time + jNorm * TAU); 79 | pg.vertex(x, y); 80 | } 81 | pg.endShape(); 82 | } 83 | gui.popFolder(); 84 | pg.popMatrix(); 85 | } 86 | 87 | private void drawBackground() { 88 | PickerColor clr = gui.colorPicker("background", color(255 * 0.15f)); 89 | pg.fill(clr.hex); 90 | pg.noStroke(); 91 | pg.rectMode(CORNER); 92 | pg.rect(0, 0, width, height); 93 | } 94 | 95 | private void drawBackgroundGradient() { 96 | pg.image(gui.gradient("gradient"), 0, 0); 97 | } 98 | } 99 | 100 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples/GeneralOverview/GeneralOverview.pde: -------------------------------------------------------------------------------- 1 | import com.krab.lazy.*; 2 | 3 | LazyGui gui; 4 | 5 | void setup() { 6 | size(1200, 800, P2D); 7 | smooth(8); 8 | gui = new LazyGui(this); 9 | } 10 | 11 | void draw() { 12 | // change the current GUI folder to go into the "scene" folder 13 | gui.pushFolder("scene"); 14 | 15 | drawBackground(); 16 | drawForegroundShape(); 17 | drawForegroundText(); 18 | 19 | // go one level up from the current folder 20 | gui.popFolder(); 21 | } 22 | 23 | void drawForegroundShape() { 24 | // go into a new "shape" folder nested inside the current folder 25 | gui.pushFolder("shape"); 26 | 27 | // get various values from the GUI using a unique path and an optional default value parameter 28 | PVector pos = gui.plotXY("position"); 29 | PVector size = gui.plotXY("size", 250); 30 | float rotationAngle = gui.slider("rotation"); 31 | 32 | // enforce a minimum and maximum value on sliders with the min/max parameters (-10, 10) here 33 | float rotateDelta = gui.slider("rotation ++", 0.1, -10, 10); 34 | 35 | // change GUI values from code 36 | gui.sliderSet("rotation", rotationAngle + rotateDelta); 37 | fill(gui.colorPicker("fill", color(0xFF689FC8)).hex); 38 | gui.colorPickerHueAdd("fill", radians(gui.slider("fill hue ++", 0.1f))); 39 | if (gui.button("fill = black")) { 40 | gui.colorPickerSet("fill", color(0)); 41 | } 42 | 43 | // plug GUI values directly into where they get consumed 44 | stroke(gui.colorPicker("stroke", 0xFF666666).hex); 45 | strokeWeight(gui.slider("stroke weight", 10)); 46 | if (gui.toggle("no stroke")) { 47 | noStroke(); 48 | } 49 | 50 | rectMode(CENTER); 51 | pushMatrix(); 52 | translate(width/2f, height/2f); 53 | translate(pos.x, pos.y); 54 | rotate(radians(rotationAngle)); 55 | 56 | // pick one string from an array using gui.radio() 57 | String selectedShape = gui.radio("shape type", new String[]{"rectangle", "ellipse"}); 58 | boolean shouldDrawEllipse = selectedShape.equals("ellipse"); 59 | if (shouldDrawEllipse) { 60 | ellipse(0, 0, size.x, size.y); 61 | } else { 62 | rect(0, 0, size.x, size.y); 63 | } 64 | popMatrix(); 65 | 66 | // go up one level back into the "scene" folder 67 | gui.popFolder(); 68 | } 69 | 70 | void drawForegroundText() { 71 | // pushFolder() and popFolder() is not the only way to control folder placement 72 | // we can use forward slash separators '/' to achieve the same effect 73 | String labelText = gui.text("text/content", "editable text"); 74 | int textSize = gui.sliderInt("text/size", 64); 75 | PVector pos = gui.plotXY("text/pos", width*0.1, height*0.9); 76 | fill(gui.colorPicker("text/fill", color(255)).hex); 77 | textSize(textSize); 78 | text(labelText, pos.x, pos.y); 79 | } 80 | 81 | void drawBackground() { 82 | gui.pushFolder("background"); 83 | // the controls are ordered on screen by which gets called first 84 | // so it can be better to ask for all the values before any if-statement branching 85 | // because this way you can enforce any given ordering of them in the GUI 86 | // and avoid control elements appearing suddenly at runtime at unexpected places 87 | int solidBackgroundColor = gui.colorPicker("solid", color(0xFF252525)).hex; 88 | PGraphics gradient = gui.gradient("gradient"); 89 | boolean useGradient = gui.toggle("solid\\/gradient"); // here '\\' escapes the '/' path separator 90 | if (useGradient) { 91 | image(gradient, 0, 0); 92 | } else { 93 | background(solidBackgroundColor); 94 | } 95 | gui.popFolder(); 96 | } 97 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | # suppress inspection "UnusedProperty" for whole file 2 | 3 | # More on this file here: https://github.com/processing/processing/wiki/Library-Basics 4 | # UTF-8 supported. 5 | 6 | # The name of your library as you want it formatted. 7 | name=LazyGui 8 | 9 | # A web page for your library, NOT a direct link to where to download it. 10 | url=https://github.com/KrabCode/LazyGui 11 | 12 | # The category of your library, must be one (or many) of the following: 13 | # "3D" "Animation" "Compilations" "Data" 14 | # "Fabrication" "Geometry" "GUI" "Hardware" 15 | # "I/O" "Language" "Math" "Simulation" 16 | # "Sound" "Utilities" "Typography" "Video & Vision" 17 | # 18 | # If a value other than those listed is used, your library will be listed as 19 | # "Other". 20 | category=GUI 21 | 22 | # List of authors. Links can be provided using the syntax [author name](url). 23 | authors=[Jakub 'Krab' Rak](https://github.com/KrabCode) 24 | 25 | # A short sentence (or fragment) to summarize the library's function. This will 26 | # be shown from inside the PDE when the library is being installed. Avoid 27 | # repeating the name of your library here. Also, avoid saying anything redundant 28 | # like mentioning that it's a library. This should start with a capitalized 29 | # letter, and end with a period. 30 | sentence=Feature rich, visually minimalist GUI for a smooth tinkering experience. 31 | 32 | # Additional information suitable for the Processing website. The value of 33 | # 'sentence' will always be prepended, so you should start by writing the 34 | # second sentence here. If your library only works on certain operating systems, 35 | # mention it here. 36 | paragraph=Make more complex scenes and animations faster by not mentioning any control elements or folders in setup(). Only ask for their values in draw() at unique string paths and let the GUI take care of the windows and control elements. Features a json save system with autosave on program exit, copy/paste, undo/redo, these control elements: [slider, 2D plot, color picker, gradient picker, button, toggle, text input, radio], and much more... Works on Windows, Mac and Linux. 37 | 38 | # A version number that increments once with each release. This is used to 39 | # compare different versions of the same library, and check if an update is 40 | # available. You should think of it as a counter, counting the total number of 41 | # releases you've had. 42 | 43 | # This must be parsable as an int 44 | version=54 45 | 46 | # The version as the user will see it. If blank, the version attribute will be 47 | # used here. 48 | prettyVersion=v1.12.2 49 | 50 | # The min and max revision of Processing compatible with your library. 51 | # Note that these fields use the revision and not the version of Processing, 52 | # parsable as an int. For example, the revision number for 2.2.1 is 227. 53 | # You can find the revision numbers in the change log: https://raw.githubusercontent.com/processing/processing/master/build/shared/revisions.txt 54 | # Only use maxRevision (or minRevision), when your library is known to 55 | # break in a later (or earlier) release. Otherwise, use the default value 0. 56 | minRevision = 0 57 | maxRevision = 0 58 | 59 | # The list of imports specified by the author. 60 | # This will be the list of entries added as imports when a user 61 | # selects an item from the "Import Library" menu. 62 | # Only used by library authors that want to override the default 63 | # behavior of importing all packages in their library. 64 | imports=com.krab.lazy -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/stores/UndoRedoStore.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.stores; 2 | 3 | import java.util.ArrayList; 4 | 5 | import static processing.core.PApplet.println; 6 | 7 | /** 8 | * For internal use by LazyGui, it's fed new states by the ChangeListener and also triggered manually by the undo/redo hotkeys. 9 | * The stateStack is an ordered list of full json saves of the GUI state, which combines undo and redo into one stack 10 | * and the stateIndex keeps track of the where we currently are inside the combined stack. 11 | * Indexes in the stack larger than stateIndex are for undo, indexes before it are redo. 12 | * undo() increments the index by 1 and tries to apply the state it found there. 13 | * redo() decrements the index by 1 and tries to apply the state it found there. 14 | * onUndoableActionEnded() clears the redo by removing all elements before the stateIndex, 15 | * sets stateIndex to 0 and then inserts the new action at index 0. 16 | */ 17 | public class UndoRedoStore { 18 | private static final boolean debugPrint = false; 19 | 20 | static final ArrayList stateStack = new ArrayList<>(); 21 | static int stateIndex = 0; 22 | 23 | public static void init(){ 24 | onUndoableActionEnded(); 25 | } 26 | 27 | public static void onUndoableActionEnded(){ 28 | String newState = JsonSaveStore.getTreeAsJsonString(); 29 | trimStack(stateIndex); 30 | stateStack.add(0, newState); 31 | stateIndex = 0; 32 | if(debugPrint){ 33 | println("undo/redo frame " + GlobalReferences.app.frameCount + " new action current list size:" + stateStack.size()); 34 | printStack(); 35 | } 36 | } 37 | 38 | private static void trimStack(int stateIndex) { 39 | if(stateStack.isEmpty()){ 40 | return; 41 | } 42 | stateStack.removeAll(stateStack.subList(0, stateIndex)); 43 | } 44 | 45 | public static void undo(){ 46 | tryLoadStateAtIndex(stateIndex + 1); 47 | if(debugPrint) { 48 | println("undo (+1)", stateIndex, "/", stateStack.size() - 1); 49 | printStack(); 50 | } 51 | } 52 | 53 | public static void redo(){ 54 | tryLoadStateAtIndex(stateIndex - 1); 55 | if(debugPrint) { 56 | println("redo (-1)", stateIndex, "/", stateStack.size() - 1); 57 | printStack(); 58 | } 59 | } 60 | 61 | private static void tryLoadStateAtIndex(int newIndex) { 62 | if(!validateNewIndex(newIndex)){ 63 | return; 64 | } 65 | String newState = stateStack.get(newIndex); 66 | JsonSaveStore.loadStateFromJsonString(newState); 67 | stateIndex = newIndex; 68 | } 69 | 70 | private static boolean validateNewIndex(int newIndex) { 71 | if(newIndex == stateIndex){ 72 | if(debugPrint){ 73 | println("validation failed: can't apply the same index as is already selected (" + newIndex + ")"); 74 | } 75 | return false; 76 | } 77 | if(newIndex < 0 || newIndex > stateStack.size() - 1){ 78 | if(debugPrint) { 79 | println("validation failed: new index out of bounds (" + newIndex + ")"); 80 | } 81 | return false; 82 | } 83 | return true; 84 | } 85 | 86 | private static void printStack() { 87 | for(int i = 0; i < stateStack.size(); i++){ 88 | println(i == stateIndex ? "(" + i + ")" : " " + i + " "); 89 | } 90 | println("---\n"); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/ShaderTest.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGui; 4 | import com.krab.lazy.ShaderReloader; 5 | import processing.core.PApplet; 6 | import processing.core.PGraphics; 7 | import processing.opengl.PShader; 8 | 9 | public class ShaderTest extends PApplet { 10 | LazyGui gui; 11 | PGraphics pg; 12 | 13 | public static void main(String[] args) { 14 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 15 | } 16 | 17 | @Override 18 | public void settings() { 19 | size(800, 800, P2D); 20 | } 21 | 22 | @Override 23 | public void setup() { 24 | gui = new LazyGui(this); 25 | pg = createGraphics(width, height, P2D); 26 | colorMode(HSB,1,1,1,1); 27 | } 28 | 29 | @Override 30 | public void draw() { 31 | pg.beginDraw(); 32 | drawBackground(); 33 | drawShader(); 34 | pg.endDraw(); 35 | image(pg, 0, 0); 36 | } 37 | 38 | private void drawBackground() { 39 | pg.fill(gui.colorPicker("background").hex); 40 | pg.noStroke(); 41 | pg.rectMode(CORNER); 42 | pg.rect(0, 0, width, height); 43 | } 44 | 45 | private void drawShader() { 46 | gui.pushFolder("shader uniforms"); 47 | String shaderPath = gui.text("shader path", "shaders/testShader.glsl"); 48 | PShader shader = ShaderReloader.getShader(shaderPath); 49 | shader.set("time", radians(frameCount)); 50 | setUniforms(shader, UNIFORM_TYPE.INTEGER); 51 | setUniforms(shader, UNIFORM_TYPE.FLOAT); 52 | setUniforms(shader, UNIFORM_TYPE.VECTOR); 53 | setUniforms(shader, UNIFORM_TYPE.COLOR); 54 | setUniforms(shader, UNIFORM_TYPE.SAMPLER); 55 | ShaderReloader.filter(shaderPath, pg); 56 | gui.popFolder(); 57 | } 58 | 59 | enum UNIFORM_TYPE{ 60 | INTEGER, 61 | FLOAT, 62 | VECTOR, 63 | COLOR, 64 | SAMPLER 65 | } 66 | 67 | private void setUniforms(PShader shader, UNIFORM_TYPE type) { 68 | gui.pushFolder(type.name().toLowerCase() + "s"); 69 | int maxSliderCount = 20; 70 | boolean addNew = gui.button("add new"); 71 | int sliderCount = gui.sliderInt("count"); 72 | if(addNew){ 73 | gui.sliderSet("count", sliderCount + 1); 74 | } 75 | for (int i = 0; i < maxSliderCount; i++) { 76 | gui.pushFolder(type.name().toLowerCase() + " " + i); 77 | if(i < sliderCount){ 78 | gui.showCurrentFolder(); 79 | }else{ 80 | gui.hideCurrentFolder(); 81 | gui.popFolder(); 82 | continue; 83 | } 84 | String name = gui.text("name"); 85 | switch(type){ 86 | case INTEGER: 87 | shader.set(name, gui.sliderInt("value")); 88 | break; 89 | case FLOAT: 90 | shader.set(name, gui.slider("value")); 91 | break; 92 | case VECTOR: 93 | shader.set(name, gui.plotXYZ("value")); 94 | break; 95 | case COLOR: 96 | int hex = gui.colorPicker("value").hex; 97 | shader.set(name, red(hex), green(hex), blue(hex), alpha(hex)); 98 | break; 99 | case SAMPLER: 100 | shader.set(name, gui.gradient("value")); 101 | break; 102 | } 103 | gui.popFolder(); 104 | } 105 | gui.popFolder(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /data/shaders/sliderBackgroundColor.glsl: -------------------------------------------------------------------------------- 1 | 2 | uniform vec2 quadPos; 3 | uniform vec2 quadSize; 4 | uniform float time; 5 | uniform float precisionNormalized; 6 | 7 | uniform float hueValue; 8 | uniform float saturationValue; 9 | uniform float brightnessValue; 10 | uniform float alphaValue; 11 | 12 | uniform int mode; 13 | // 0 = hue 14 | // 1 = sat 15 | // 2 = brightness 16 | // 3 = alpha 17 | 18 | const float PI = 3.14159; 19 | const float TAU = PI * 2.; 20 | 21 | 22 | // https://iquilezles.org/www/articles/palettes/palettes.htm 23 | 24 | struct colorPoint 25 | { 26 | float pos; 27 | vec3 val; 28 | }; 29 | 30 | colorPoint emptyColorPoint() 31 | { 32 | return colorPoint(1.1, vec3(1.,0.,0.)); 33 | } 34 | 35 | float map(float value, float start1, float stop1, float start2, float stop2) 36 | { 37 | return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1)); 38 | } 39 | 40 | float norm(float value, float start, float stop) 41 | { 42 | return map(value, start, stop, 0., 1.); 43 | } 44 | 45 | mat2 rotate2D(float angle){ 46 | return mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); 47 | } 48 | 49 | vec3 rgb2hsv(vec3 c) 50 | { 51 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 52 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); 53 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); 54 | 55 | float d = q.x - min(q.w, q.y); 56 | float e = 1.0e-10; 57 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 58 | } 59 | 60 | vec3 hsv2rgb(vec3 c) 61 | { 62 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 63 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 64 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 65 | } 66 | 67 | void main(){ 68 | vec2 uv = (gl_FragCoord.xy - quadPos.xy) / quadSize.xy; 69 | vec4 clr; 70 | if(mode == 0){ // hue 71 | float hueRangeMin = hueValue - precisionNormalized; 72 | float hueRangeMax = hueValue + precisionNormalized; 73 | float hueVarying = mod(map(uv.x, 0, 1, hueRangeMin, hueRangeMax), 1.); // hue repeats so mod() instead of clamp() 74 | clr = vec4(hsv2rgb(vec3(hueVarying, max(0.5, saturationValue), max(0.5, brightnessValue))), 1.); 75 | } 76 | if(mode == 1){ // sat 77 | float satRangeMin = saturationValue - precisionNormalized; 78 | float satRangeMax = saturationValue + precisionNormalized; 79 | float satVarying = clamp(map(uv.x, 0, 1, satRangeMin, satRangeMax), 0., 1.); 80 | clr = vec4(hsv2rgb(vec3(hueValue, satVarying, brightnessValue)), 1.); 81 | } 82 | if(mode == 2){ // brightness 83 | float brRangeMin = brightnessValue - precisionNormalized; 84 | float brRangeMax = brightnessValue + precisionNormalized; 85 | float brVarying = clamp(map(uv.x, 0, 1, brRangeMin, brRangeMax), 0., 1.); 86 | clr = vec4(hsv2rgb(vec3(hueValue, saturationValue, brVarying)), 1.);; 87 | } 88 | if(mode == 3){ // alpha 89 | float aRangeMin = alphaValue - precisionNormalized; 90 | float aRangeMax = alphaValue + precisionNormalized; 91 | float aVarying = clamp(map(uv.x, 0, 1, aRangeMin, aRangeMax), 0., 1.); 92 | clr = vec4(hsv2rgb(vec3(hueValue, saturationValue, brightnessValue)), aVarying); 93 | } 94 | float checkerboardColumns = 20.; 95 | float checkerboardRows = 4.001; 96 | vec3 checkerboard = vec3(0); 97 | vec2 rep = vec2(10.); 98 | vec2 id = floor(gl_FragCoord.xy/rep); 99 | if(mod(id.x + id.y,2.) < 0.001){ 100 | checkerboard += 1.; 101 | } 102 | checkerboard *= 0.3; 103 | gl_FragColor = vec4(mix(checkerboard, clr.rgb, clr.w), 1); 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/ReadmeVisualsGenerator.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGuiSettings; 4 | import processing.core.PApplet; 5 | import processing.core.PGraphics; 6 | import com.krab.lazy.LazyGui; 7 | import processing.core.PVector; 8 | 9 | public class ReadmeVisualsGenerator extends PApplet { 10 | LazyGui gui; 11 | PGraphics pg; 12 | 13 | public static void main(String[] args) { 14 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 15 | } 16 | 17 | @Override 18 | public void settings() { 19 | size(22 * 30, 22 * 8, P2D); 20 | } 21 | 22 | @Override 23 | public void setup() { 24 | gui = new LazyGui(this, new LazyGuiSettings().setLoadLatestSaveOnStartup(false).setAutosaveOnExit(false)); 25 | gui.toggleSet("options/windows/keep in bounds", false); 26 | pg = createGraphics(width, height, P2D); 27 | colorMode(HSB, 1, 1, 1, 1); 28 | frameRate(144); 29 | } 30 | 31 | @Override 32 | public void draw() { 33 | pg.beginDraw(); 34 | { 35 | gui.pushFolder("background"); 36 | background(gui.colorPicker("color picker", color(0xFF0F0F0F)).hex); 37 | gui.popFolder(); 38 | } 39 | { 40 | gui.pushFolder("gradient"); 41 | if (gui.toggle("active")) { 42 | pg.image(gui.gradient("gradient picker"), 0, 0, width, height); 43 | } 44 | gui.popFolder(); 45 | } 46 | 47 | updateControls(); 48 | pg.endDraw(); 49 | image(pg, 0, 0); 50 | gui.draw(); 51 | } 52 | 53 | private void updateControls() { 54 | { 55 | gui.pushFolder("controls"); 56 | pg.fill(gui.colorPicker("fill", color(0xFF7F7F7F)).hex); 57 | pg.noStroke(); 58 | { 59 | gui.pushFolder("slider"); 60 | float x = gui.slider("x", 0); 61 | pg.rect(0, 0, x, height); 62 | gui.popFolder(); 63 | } 64 | { 65 | gui.pushFolder("plot"); 66 | PVector pos = gui.plotXY("pos", -width / 3f, height / 2f); 67 | String shape = gui.radio("shape", new String[]{ 68 | "rectangle", "circle", "triangle" 69 | }); 70 | pg.pushMatrix(); 71 | pg.translate(pos.x, pos.y); 72 | if (shape.equals("rectangle")) { 73 | pg.rectMode(CENTER); 74 | pg.rect(0, 0, 50, 50); 75 | } else if (shape.equals("circle")) { 76 | pg.ellipse(0, 0, 50, 50); 77 | } else { 78 | pg.beginShape(); 79 | float r = 25; 80 | for (int i = 0; i < 3; i++) { 81 | float theta = map(i, 0, 3, 0, TAU); 82 | pg.vertex(r * cos(theta), r * sin(theta)); 83 | } 84 | pg.endShape(); 85 | } 86 | pg.popMatrix(); 87 | gui.popFolder(); 88 | } 89 | { 90 | if (gui.toggle("toggle/move")) { 91 | gui.sliderAdd("slider/x", 1); 92 | } 93 | } 94 | { 95 | gui.pushFolder("text input"); 96 | String text = gui.text("content", "hello"); 97 | pg.textAlign(LEFT, TOP); 98 | pg.textSize(50); 99 | pg.text(text, 20, 10); 100 | gui.popFolder(); 101 | } 102 | gui.popFolder(); 103 | } 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /docs/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Deprecated List 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 |
42 | 69 | 70 |
71 |

Deprecated API

72 |

Contents

73 |
74 | 75 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | 90 |
91 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/constant-values.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Constant Field Values 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 |
42 | 69 | 70 |
71 |

Constant Field Values

72 |

Contents

73 |
74 | 75 |
76 | 77 | 78 | 79 | 80 | 81 | 82 | 90 |
91 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/windows/WindowManager.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.windows; 2 | 3 | import com.krab.lazy.nodes.FolderNode; 4 | import com.krab.lazy.stores.LayoutStore; 5 | import com.krab.lazy.stores.NodeTree; 6 | import com.krab.lazy.utils.SnapToGrid; 7 | import processing.core.PGraphics; 8 | import processing.core.PVector; 9 | 10 | import java.util.ArrayList; 11 | import java.util.concurrent.CopyOnWriteArrayList; 12 | 13 | public class WindowManager { 14 | private static final CopyOnWriteArrayList windows = new CopyOnWriteArrayList<>(); 15 | private static final ArrayList windowsToSetFocusOn = new ArrayList<>(); 16 | 17 | public static void addRootWindow() { 18 | addWindow(new Window(NodeTree.getRoot(), LayoutStore.cell, LayoutStore.cell, LayoutStore.cell * LayoutStore.defaultWindowWidthInCells)); 19 | } 20 | 21 | public static void addWindow(Window window) { 22 | windows.add(window); 23 | } 24 | 25 | public static void uncoverOrCreateWindow(FolderNode folderNode){ 26 | uncoverOrCreateWindow(folderNode, true, null, null, null); 27 | } 28 | 29 | public static void uncoverOrCreateWindow(FolderNode folderNode, boolean setFocus, Float nullablePosX, Float nullablePosY, Float nullableSizeX) { 30 | PVector pos = new PVector(LayoutStore.cell, LayoutStore.cell); 31 | if(folderNode.parent != null){ 32 | Window parentWindow = folderNode.parent.window; 33 | if(parentWindow != null){ 34 | pos = new PVector(parentWindow.posX + parentWindow.windowSizeX + LayoutStore.cell, parentWindow.posY); 35 | } 36 | } 37 | if(nullablePosX != null){ 38 | pos.x = nullablePosX; 39 | } 40 | if(nullablePosY != null){ 41 | pos.y = nullablePosY; 42 | } 43 | boolean windowFound = false; 44 | for (Window w : windows) { 45 | if(w.folder.path.equals(folderNode.path)){ 46 | w.posX = pos.x; 47 | w.posY = pos.y; 48 | if(LayoutStore.doesFolderRowClickCloseWindowIfOpen() && !w.closed){ 49 | w.close(); 50 | }else{ 51 | w.open(setFocus); 52 | } 53 | windowFound = true; 54 | break; 55 | } 56 | } 57 | if(!windowFound){ 58 | Window window = new Window(folderNode, pos.x, pos.y, nullableSizeX); 59 | windows.add(window); 60 | window.open(setFocus); 61 | } 62 | if(windowFound && folderNode.parent == null){ 63 | folderNode.window.posX = pos.x; 64 | folderNode.window.posY = pos.y; 65 | if(nullableSizeX != null){ 66 | folderNode.window.windowSizeX = nullableSizeX; 67 | } 68 | } 69 | } 70 | 71 | public static void updateAndDrawWindows(PGraphics pg) { 72 | if(!windowsToSetFocusOn.isEmpty()){ 73 | for (Window w : windowsToSetFocusOn){ 74 | windows.remove(w); 75 | windows.add(w); 76 | } 77 | windowsToSetFocusOn.clear(); 78 | } 79 | for (Window win : windows) { 80 | win.drawWindow(pg); 81 | } 82 | } 83 | 84 | static boolean isFocused(Window window) { 85 | return windows.get(windows.size()-1).equals(window); 86 | } 87 | 88 | public static void setFocus(Window window) { 89 | windowsToSetFocusOn.add(window); 90 | } 91 | 92 | public static void closeAllWindows() { 93 | for(Window win : windows){ 94 | if(!win.isRoot()){ 95 | win.close(); 96 | } 97 | } 98 | } 99 | 100 | public static void snapAllStaticWindowsToGrid() { 101 | for (Window w : windows) { 102 | if(w.closed || w.isBeingDraggedAround){ 103 | continue; 104 | } 105 | PVector newPos = SnapToGrid.trySnapToGrid(w.posX, w.posY); 106 | w.posX = newPos.x; 107 | w.posY = newPos.y; 108 | w.windowSizeX = SnapToGrid.trySnapToGrid(w.windowSizeX, 0).x; 109 | } 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/ImageFolderNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.krab.lazy.input.LazyKeyEvent; 5 | import com.krab.lazy.stores.GlobalReferences; 6 | import com.krab.lazy.stores.JsonSaveStore; 7 | import com.krab.lazy.stores.LayoutStore; 8 | import com.krab.lazy.themes.ThemeColorType; 9 | import com.krab.lazy.themes.ThemeStore; 10 | import processing.core.PGraphics; 11 | import processing.core.PImage; 12 | 13 | /** 14 | * Folder node that holds a transient PImage (not serialized) and exposes setter/getter. 15 | * Contains a single inline ImagePreviewNode child to render the image inside the folder's window. 16 | */ 17 | public class ImageFolderNode extends FolderNode { 18 | 19 | private transient PImage image; 20 | boolean mainCanvasWorkaroundApplied = false; 21 | 22 | public ImageFolderNode(String path, FolderNode parent) { 23 | super(path, parent); 24 | idealWindowWidthInCells = 8; 25 | // add the preview child 26 | children.add(new ImagePreviewNode(path + "/preview", this)); 27 | // don't serialize image - ensure other folder state (like window) can be loaded normally 28 | JsonSaveStore.overwriteWithLoadedStateIfAny(this); 29 | } 30 | 31 | public void setImage(PImage img) { 32 | if(!mainCanvasWorkaroundApplied && img == GlobalReferences.app.g) { 33 | // there's a bug when using the main canvas and calling background() on it and trying to display it before draw() ends 34 | // it says "OpenOpenGL error 1282 at bot endDraw(): invalid operation" and doesn't display it 35 | // workaround: call endDraw() and beginDraw() on it once to force some internal state update 36 | ((PGraphics) img).endDraw(); 37 | ((PGraphics) img).beginDraw(); 38 | mainCanvasWorkaroundApplied = true; 39 | } 40 | this.image = img; 41 | } 42 | 43 | public PImage getImage() { 44 | return image; 45 | } 46 | 47 | @Override 48 | public void overwriteState(JsonElement loadedNode) { 49 | // use default FolderNode behavior to restore window positions, etc. 50 | super.overwriteState(loadedNode); 51 | } 52 | 53 | @Override 54 | public void keyPressedOverNode(LazyKeyEvent e, float x, float y) { 55 | super.keyPressedOverNode(e, x, y); 56 | } 57 | 58 | @Override 59 | protected void drawNodeForeground(PGraphics pg, String name) { 60 | // draw the standard left text 61 | drawLeftText(pg, name); 62 | 63 | // if there is no image, show the eye with a slash 64 | boolean showSlash = (image == null); 65 | drawInlineEye(pg, showSlash); 66 | } 67 | 68 | private void drawInlineEye(PGraphics pg, boolean showSlash) { 69 | // draw a small eye icon at the same place/size as other preview icons 70 | float previewRectSize = LayoutStore.cell * 0.6f; 71 | float iconX = size.x - LayoutStore.cell * 0.5f; 72 | float iconY = size.y * 0.5f; 73 | 74 | pg.pushMatrix(); 75 | pg.translate(iconX, iconY); 76 | 77 | float w = previewRectSize; 78 | float h = previewRectSize * 0.6f; 79 | 80 | // outline color depends on hover 81 | int stroke = isMouseOverNode ? ThemeStore.getColor(ThemeColorType.FOCUS_FOREGROUND) : ThemeStore.getColor(ThemeColorType.NORMAL_FOREGROUND); 82 | 83 | // eye outline 84 | pg.pushStyle(); 85 | pg.stroke(stroke); 86 | pg.strokeWeight(1.2f); 87 | pg.noFill(); 88 | pg.ellipse(0, 0, w, h); 89 | 90 | // pupil 91 | pg.noStroke(); 92 | pg.fill(stroke); 93 | float pupilSize = h * 0.45f; 94 | pg.ellipse(0, 0, pupilSize, pupilSize); 95 | 96 | if (showSlash) { 97 | // optional slash when showing null state 98 | pg.stroke(stroke); 99 | pg.strokeWeight(2f); 100 | float slashHalfW = w * 0.45f; 101 | float slashHalfH = h * 0.45f; 102 | pg.line(-slashHalfW, -slashHalfH, slashHalfW, slashHalfH); 103 | } 104 | pg.popStyle(); 105 | pg.popMatrix(); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/examples_intellij/Controls.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.examples_intellij; 2 | 3 | import com.krab.lazy.LazyGuiSettings; 4 | import com.krab.lazy.stores.FontStore; 5 | import processing.core.PApplet; 6 | import processing.core.PFont; 7 | import processing.core.PGraphics; 8 | import com.krab.lazy.LazyGui; 9 | import processing.core.PVector; 10 | 11 | public class Controls extends PApplet { 12 | LazyGui gui; 13 | PGraphics pg; 14 | PFont segoeUIBlack; 15 | 16 | public static void main(String[] args) { 17 | PApplet.main(java.lang.invoke.MethodHandles.lookup().lookupClass()); 18 | } 19 | 20 | @Override 21 | public void settings() { 22 | size(ceil(1200/22f)*22,ceil(500/22f)*22, P2D); 23 | } 24 | 25 | @Override 26 | public void setup() { 27 | gui = new LazyGui(this, new LazyGuiSettings() 28 | .setLoadLatestSaveOnStartup(false) 29 | // .setLoadSpecificSaveOnStartup("1") 30 | ); 31 | pg = createGraphics(width, height, P2D); 32 | colorMode(HSB, 1, 1, 1, 1); 33 | } 34 | 35 | @Override 36 | public void draw() { 37 | pg.beginDraw(); 38 | pg.clear(); 39 | pg.image(gui.gradient("background"), 0, 0); 40 | drawNoiseRectangle(); 41 | pg.endDraw(); 42 | image(pg, 0, 0); 43 | } 44 | 45 | private void drawNoiseRectangle() { 46 | gui.pushFolder("sketch"); 47 | pg.translate(gui.plotXY("translate", width / 2f, height / 2f).x, gui.plotXY("translate").y); 48 | 49 | pg.pushMatrix(); 50 | gui.pushFolder("rect"); 51 | { 52 | PVector rectPos = gui.plotXY("pos"); 53 | PVector rectSize = gui.plotXY("size", 450, 300); 54 | pg.fill(gui.colorPicker("fill", color(0.65f)).hex); 55 | pg.stroke(gui.colorPicker("stroke").hex); 56 | pg.strokeWeight(gui.slider("weight", 5)); 57 | pg.translate(rectPos.x, rectPos.y); 58 | pg.rectMode(CORNER); 59 | pg.rect(0, 0, rectSize.x, rectSize.y); 60 | } 61 | gui.popFolder(); 62 | pg.popMatrix(); 63 | 64 | gui.pushFolder("graph"); 65 | pg.pushMatrix(); 66 | { 67 | PVector graphPos = gui.plotXY("pos"); 68 | PVector graphSize = gui.plotXY("graph size", 400,200); 69 | float sinHeight = gui.slider("sin height", 100); 70 | float barWidth = gui.slider("bar width", 1); 71 | pg.translate(graphPos.x, graphPos.y); 72 | int count = gui.sliderInt("count", 6, 2, width); 73 | float freq = gui.slider("freq", 1); 74 | float time = gui.slider("time"); 75 | gui.sliderSet("time", time + radians(gui.slider("time speed", 1))); 76 | pg.stroke(gui.colorPicker("stroke").hex); 77 | pg.strokeWeight(gui.slider("weight", 5)); 78 | pg.rectMode(CENTER); 79 | gui.gradient("fill gradient", new int[]{unhex("FF86A3B8"), unhex("FFE8D2A6"), unhex("FFF48484"), unhex("FFF55050")}); 80 | for (int i = 0; i < count; i++) { 81 | float iNorm = norm(i, 0, count - 1); 82 | float x = iNorm * graphSize.x; 83 | float sinX = sin(iNorm * TAU * freq + time); 84 | float w = graphSize.x / (count-1) * barWidth; 85 | pg.fill(gui.gradientColorAt("fill gradient", 0.5f + 0.5f * sinX).hex); 86 | float h = -sinX * sinHeight - graphSize.y; 87 | pg.rect(x+w/2, -h/2, w, h); 88 | } 89 | } 90 | pg.popMatrix(); 91 | gui.popFolder(); 92 | 93 | pg.pushMatrix(); 94 | gui.pushFolder("text"); 95 | { 96 | if (gui.button("reset font") || segoeUIBlack == null) { 97 | segoeUIBlack = createFont(FontStore.mainFontPathDefault, gui.slider("size", 64)); 98 | } 99 | pg.textFont(segoeUIBlack, gui.slider("size", 64)); 100 | pg.fill(gui.colorPicker("fill").hex); 101 | pg.text(gui.text("title", "example sketch"), 102 | gui.plotXY("pos", 0, -50).x, 103 | gui.plotXY("pos").y); 104 | } 105 | gui.popFolder(); 106 | pg.popMatrix(); 107 | 108 | gui.popFolder(); 109 | } 110 | } 111 | 112 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/ImagePreviewNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | import com.krab.lazy.stores.LayoutStore; 4 | import com.krab.lazy.stores.FontStore; 5 | import com.krab.lazy.themes.ThemeColorType; 6 | import com.krab.lazy.themes.ThemeStore; 7 | import processing.core.PGraphics; 8 | import processing.core.PImage; 9 | 10 | import static processing.core.PConstants.CORNER; 11 | 12 | /** 13 | * A transient preview node that draws a PImage centered and uniformly scaled to fit the node bounds. 14 | * It does not own or serialize the image; the parent `ImageFolderNode` stores the transient image. 15 | */ 16 | class ImagePreviewNode extends AbstractNode { 17 | 18 | private final ImageFolderNode parentFolder; 19 | 20 | ImagePreviewNode(String path, ImageFolderNode parent) { 21 | super(NodeType.TRANSIENT, path, parent); 22 | this.parentFolder = parent; 23 | isInlineNodeDraggable = false; 24 | } 25 | 26 | @Override 27 | public void updateValuesRegardlessOfParentWindowOpenness() { 28 | // adjust height (in cells) based on the parent window width to preserve image aspect ratio 29 | PImage img = parentFolder.getImage(); 30 | if (img == null || parent == null || parent.window == null) { 31 | return; 32 | } 33 | float availableW = parent.window.windowSizeX - 2; // match drawing padding 34 | if (availableW <= 0 || img.width <= 0) { 35 | return; 36 | } 37 | // desired draw width is the available width for the node 38 | // compute scale to make image match available width 39 | float scaleForWidth = parent.window.windowSizeX / (float) img.width; 40 | // clamp to 1.0 to avoid upscaling 41 | scaleForWidth = Math.min(scaleForWidth, 1.0f); 42 | // compute desired height in pixels 43 | float desiredDrawH = img.height * scaleForWidth; 44 | // convert to cells, apply immediately (no smoothing) 45 | masterInlineNodeHeightInCells = Math.max(1f, desiredDrawH / LayoutStore.cell); 46 | } 47 | 48 | @Override 49 | protected void drawNodeBackground(PGraphics pg) { 50 | PImage img = parentFolder.getImage(); 51 | if (img == null) { 52 | // draw a neutral background and a short message 53 | pg.pushStyle(); 54 | pg.noStroke(); 55 | pg.fill(ThemeStore.getColor(ThemeColorType.NORMAL_BACKGROUND)); 56 | pg.rect(0, 0, size.x, size.y); 57 | // set text style and draw message centered vertically, left padded 58 | fillForegroundBasedOnMouseOver(pg); 59 | pg.textFont(FontStore.getSideFont()); 60 | pg.textAlign(processing.core.PConstants.LEFT, processing.core.PConstants.CENTER); 61 | String msg = "null image"; 62 | String trimmed = FontStore.getSubstringFromStartToFit(pg, msg, size.x - FontStore.textMarginX * 2); 63 | float x = FontStore.textMarginX; 64 | float y = FontStore.textMarginY; 65 | pg.text(trimmed, x, y); 66 | pg.popStyle(); 67 | return; 68 | } 69 | 70 | float availableW = size.x; 71 | float availableH = size.y; 72 | float imgW = img.width; 73 | float imgH = img.height; 74 | if (imgW <= 0 || imgH <= 0) { 75 | return; 76 | } 77 | float scale = Math.min(availableW / imgW, availableH / imgH); 78 | // clamp scale to 1.0 to avoid upscaling 79 | scale = Math.min(scale, 1.0f); 80 | // allow upscaling so image grows as window is resized while preserving aspect ratio 81 | float drawW = imgW * scale; 82 | float drawH = imgH * scale; 83 | // align image to top-left with a small padding instead of centering 84 | float offsetX = 1f; 85 | float offsetY = 1f; 86 | 87 | pg.pushStyle(); 88 | pg.imageMode(CORNER); 89 | pg.noStroke(); 90 | pg.fill(ThemeStore.getColor(ThemeColorType.NORMAL_BACKGROUND)); 91 | pg.rect(0, 0, size.x, size.y); 92 | pg.tint(0xFFFFFFFF); 93 | if(scale > 0.99f){ 94 | // draw pixel-perfect if not scaled 95 | pg.image(img, offsetX, offsetY); 96 | }else{ 97 | pg.image(img, offsetX, offsetY, drawW, drawH); 98 | } 99 | pg.popStyle(); 100 | } 101 | 102 | @Override 103 | protected void drawNodeForeground(PGraphics pg, String name) { 104 | // no foreground for preview 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/Input.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy; 2 | 3 | import com.krab.lazy.input.InputWatcherBackend; 4 | import processing.core.PVector; 5 | import java.util.List; 6 | 7 | /** 8 | * Static wrapper for a utility class that keeps track of all currently pressed keys to simplify the code for complex keyboard interaction, because Processing doesn't offer that. 9 | * Ask it for individual key states using chars or keyCodes and see if the key was pressed this frame, whether it is now down or whether it was just released. 10 | * Also includes two simple mouse position functions. 11 | * Mouse events are considered well-supported by Processing so there is no alternative offered here. 12 | */ 13 | @SuppressWarnings("unused") 14 | public class Input { 15 | /** 16 | * Get the current keyboard button state by using its char value. 17 | * Meant to be used like getChar('n').down 18 | * 19 | * @param key char representation of the key 20 | * @return current state of the keyboard button 21 | */ 22 | public static KeyState getChar(Character key){ 23 | return InputWatcherBackend.getKeyStateByChar(key); 24 | } 25 | 26 | /** 27 | * Get the current keyboard button state by using its keyCode value. 28 | * Meant to be used like getCode(LEFT).down 29 | * 30 | * @param keyCode keyCode representation of the key 31 | * @return current state of the keyboard button 32 | */ 33 | public static KeyState getCode(int keyCode){ 34 | return InputWatcherBackend.getKeyStateByCode(keyCode); 35 | } 36 | 37 | /** 38 | * Gets all currently pressed chars as lowercase strings in a list. 39 | * Does not include special keys for which key == CODED is true like CTRL and DELETE. 40 | * The list is sorted in alphabetical order. 41 | * @return list of all currently pressed chars as lowercase strings in a list 42 | * @see processing key reference page 43 | * @see Processing keyCode reference 44 | */ 45 | public static List getAllDownChars(){ 46 | return InputWatcherBackend.getAllDownChars(); 47 | } 48 | 49 | /** 50 | * Gets all currently pressed keys as integer keyCodes in a list. Includes all standard chars as well as special keys like CTRL and DELETE, 51 | * which you can compare with processing constants or com.jogamp.newt.event.KeyEvent int constants. 52 | * The list is sorted in natural ascending order. 53 | * @see processing keyCode reference page 54 | * @return list of all currently pressed keys as integer keyCodes 55 | */ 56 | public static List getAllDownCodes(){ 57 | return InputWatcherBackend.getAllDownCodes(); 58 | } 59 | 60 | /** 61 | * Prints all newly received key events to console when this is set to true until manually set to false. 62 | * False by default to not clutter the console. 63 | * 64 | * @param shouldDebugKeys should the InputWatcher print all the key events it receives to console? 65 | */ 66 | public static void debugPrintKeyEvents(boolean shouldDebugKeys) { 67 | InputWatcherBackend.setDebugKeys(shouldDebugKeys); 68 | } 69 | 70 | /** 71 | * Get the current mouseX and mouseY as a PVector. 72 | * 73 | * @return a PVector with the current mouse position 74 | */ 75 | public static PVector mousePos(){ 76 | return InputWatcherBackend.mousePos(); 77 | } 78 | 79 | /** 80 | * Get pmouseX and pmouseY as a PVector describing the last frame's mouse position. 81 | * This vector plus mouseDelta() should equal the current mousePos() 82 | * 83 | * @return a PVector with the previous frame's mouse position 84 | */ 85 | public static PVector mousePosLastFrame(){ 86 | return InputWatcherBackend.mousePosLastFrame(); 87 | } 88 | 89 | /** 90 | * Gets the difference between current frame mouse position and previous frame mouse position as a PVector. 91 | * This is equivalent to new PVector(app.mouseX - app.pmouseX, app.mouseY - app.pmouseY); 92 | * 93 | * @return a PVector with the difference between the last known mouse position and the current one 94 | */ 95 | public static PVector mouseDelta(){ 96 | return InputWatcherBackend.mouseDelta(); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/PlotFolderNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | import com.krab.lazy.input.LazyKeyEvent; 4 | import com.krab.lazy.utils.KeyCodes; 5 | import processing.core.PGraphics; 6 | import processing.core.PVector; 7 | 8 | import static com.krab.lazy.stores.LayoutStore.cell; 9 | 10 | public class PlotFolderNode extends FolderNode { 11 | static final String PLOT_DISPLAY_NAME = "_"; 12 | static final String SLIDER_X_NAME = "x"; 13 | static final String SLIDER_Y_NAME = "y"; 14 | static final String SLIDER_Z_NAME = "z"; 15 | 16 | private final SliderNode sliderX; 17 | private final SliderNode sliderY; 18 | private SliderNode sliderZ; 19 | int syncedPrecisionIndex = -1; 20 | 21 | public PlotFolderNode(String path, FolderNode parent, PVector defaultXY, boolean useZ) { 22 | super(path, parent); 23 | idealWindowWidthInCells = 7; 24 | PVector defaultPos = new PVector(); 25 | if (defaultXY != null) { 26 | defaultPos = defaultXY.copy(); 27 | } 28 | sliderX = new SliderNode(path + "/" + SLIDER_X_NAME, this, defaultPos.x, -Float.MAX_VALUE, Float.MAX_VALUE, false, false); 29 | sliderY = new SliderNode(path + "/" + SLIDER_Y_NAME, this, defaultPos.y, -Float.MAX_VALUE, Float.MAX_VALUE, false, false); 30 | children.add(new PlotDisplayNode(path + "/" + PLOT_DISPLAY_NAME, this, sliderX, sliderY)); 31 | children.add(sliderX); 32 | children.add(sliderY); 33 | if (useZ) { 34 | sliderZ = new SliderNode(path + "/" + SLIDER_Z_NAME, this, defaultPos.z, -Float.MAX_VALUE, Float.MAX_VALUE, false, false); 35 | children.add(sliderZ); 36 | } 37 | } 38 | 39 | @Override 40 | protected void drawNodeForeground(PGraphics pg, String name) { 41 | drawLeftText(pg, name); 42 | drawRightBackdrop(pg, cell); 43 | String vectorToDisplay = getValueAsString(); 44 | drawRightTextToNotOverflowLeftText(pg, vectorToDisplay, name, true); 45 | } 46 | 47 | @Override 48 | public void updateValuesRegardlessOfParentWindowOpenness() { 49 | syncPrecision(); 50 | } 51 | 52 | private void syncPrecision() { 53 | if (syncedPrecisionIndex == -1) { 54 | syncedPrecisionIndex = sliderX.currentPrecisionIndex; 55 | } 56 | boolean changeDetected = sliderX.currentPrecisionIndex != syncedPrecisionIndex || 57 | sliderY.currentPrecisionIndex != syncedPrecisionIndex || 58 | (sliderZ != null && sliderZ.currentPrecisionIndex != syncedPrecisionIndex); 59 | if (changeDetected) { 60 | if (sliderX.currentPrecisionIndex != syncedPrecisionIndex) { 61 | syncedPrecisionIndex = sliderX.currentPrecisionIndex; 62 | } else if (sliderY.currentPrecisionIndex != syncedPrecisionIndex) { 63 | syncedPrecisionIndex = sliderY.currentPrecisionIndex; 64 | } else { 65 | syncedPrecisionIndex = sliderZ.currentPrecisionIndex; 66 | } 67 | sliderX.setPrecisionIndexAndValue(syncedPrecisionIndex); 68 | sliderY.setPrecisionIndexAndValue(syncedPrecisionIndex); 69 | if (sliderZ != null) { 70 | sliderZ.setPrecisionIndexAndValue(syncedPrecisionIndex); 71 | } 72 | } 73 | } 74 | 75 | public PVector getVectorValue() { 76 | return new PVector( 77 | (float) sliderX.valueFloat, 78 | (float) sliderY.valueFloat, 79 | sliderZ == null ? 0 : (float) sliderZ.valueFloat 80 | ); 81 | } 82 | 83 | public void setVectorValue(float x, float y, float z) { 84 | sliderX.valueFloat = x; 85 | sliderY.valueFloat = y; 86 | if (sliderZ != null) { 87 | sliderZ.valueFloat = z; 88 | } 89 | } 90 | 91 | public void keyPressedOverNode(LazyKeyEvent e, float x, float y) { 92 | if ((e.isControlDown() && e.getKeyCode() == KeyCodes.C) || (e.isControlDown() && e.getKeyCode() == KeyCodes.V)) { 93 | super.keyPressedOverNode(e, x, y); 94 | onValueChangingActionEnded(); 95 | } else { 96 | sliderX.keyPressedOverNode(e, x, y); 97 | sliderY.keyPressedOverNode(e, x, y); 98 | if (sliderZ != null) { 99 | sliderZ.keyPressedOverNode(e, x, y); 100 | } 101 | } 102 | } 103 | 104 | @Override 105 | public String getValueAsString() { 106 | return sliderX.getValueToDisplay() + "|" + sliderY.getValueToDisplay() + 107 | (sliderZ == null ? "" : "|" + sliderZ.getValueToDisplay()); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /docs/index-files/index-1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | A-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 |
42 | 69 | 70 |
A B C D F G H I K L M P R S T  71 | 72 | 73 |

A

74 |
75 |
alpha - Variable in class com.krab.lazy.PickerColor
76 |
77 |
Alpha in range of [0,1]
78 |
79 |
80 | A B C D F G H I K L M P R S T 
81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 97 |
98 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /docs/overview-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 |
42 | 69 | 70 |
71 |

Hierarchy For All Packages

72 | Package Hierarchies: 73 | 76 |
77 |
78 |

Class Hierarchy

79 | 92 |
93 | 94 |
95 | 96 | 97 | 98 | 99 | 100 | 101 | 109 |
110 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /docs/com/krab/lazy/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.krab.lazy Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 |
42 | 69 | 70 |
71 |

Hierarchy For Package com.krab.lazy

72 |
73 |
74 |

Class Hierarchy

75 | 88 |
89 | 90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | 105 |
106 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/nodes/ColorSliderNode.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.nodes; 2 | 3 | 4 | 5 | import com.krab.lazy.utils.KeyCodes; 6 | import com.krab.lazy.input.LazyKeyEvent; 7 | import com.krab.lazy.input.LazyMouseEvent; 8 | import com.krab.lazy.stores.NormColorStore; 9 | import com.krab.lazy.stores.ShaderStore; 10 | import com.krab.lazy.themes.ThemeColorType; 11 | import com.krab.lazy.themes.ThemeStore; 12 | import processing.core.PGraphics; 13 | import processing.opengl.PShader; 14 | 15 | import static processing.core.PApplet.norm; 16 | 17 | abstract class ColorSliderNode extends SliderNode { 18 | 19 | final ColorPickerFolderNode parentColorPickerFolder; 20 | private final String colorShaderPath = "sliderBackgroundColor.glsl"; 21 | protected int shaderColorMode = -1; 22 | 23 | ColorSliderNode(String path, ColorPickerFolderNode parentFolder) { 24 | super(path, parentFolder, 0, 0, 1, true); 25 | this.parentColorPickerFolder = parentFolder; 26 | showPercentIndicatorWhenConstrained = false; 27 | setPrecisionIndexAndValue(precisionRange.indexOf(0.01f)); 28 | maximumFloatPrecisionIndex = precisionRange.indexOf(0.01f); 29 | initSliderBackgroundShader(); 30 | ShaderStore.getShader(colorShaderPath); 31 | } 32 | 33 | @Override 34 | public void mouseDragNodeContinue(LazyMouseEvent e) { 35 | super.mouseDragNodeContinue(e); 36 | updateColorInParentFolder(); 37 | e.setConsumed(true); 38 | } 39 | 40 | @Override 41 | public void mouseReleasedOverNode(float x, float y) { 42 | super.mouseReleasedOverNode(x, y); 43 | updateColorInParentFolder(); 44 | } 45 | 46 | @Override 47 | protected void onValueFloatChanged() { 48 | super.onValueFloatChanged(); 49 | updateColorInParentFolder(); 50 | } 51 | 52 | protected void updateColorInParentFolder() { 53 | if(parentColorPickerFolder == null) { 54 | return; 55 | } 56 | parentColorPickerFolder.loadValuesFromHSBA(); 57 | } 58 | 59 | @Override 60 | protected void drawNodeBackground(PGraphics pg) { 61 | super.drawNodeBackground(pg); 62 | if(isInlineNodeDragged){ 63 | pg.stroke(foregroundMouseOverBrightnessAwareColor()); 64 | pg.strokeWeight(1); 65 | pg.line(size.x / 2f, 0f, size.x / 2f, size.y-1f); 66 | } 67 | } 68 | 69 | @Override 70 | protected void updateBackgroundShader(PGraphics pg) { 71 | PShader bgShader = ShaderStore.getShader(colorShaderPath); 72 | bgShader.set("quadPos", pos.x, pos.y); 73 | bgShader.set("quadSize", size.x, size.y); 74 | bgShader.set("hueValue", parentColorPickerFolder.hue()); 75 | bgShader.set("brightnessValue", parentColorPickerFolder.brightness()); 76 | bgShader.set("saturationValue", parentColorPickerFolder.saturation()); 77 | bgShader.set("alphaValue", parentColorPickerFolder.alpha()); 78 | bgShader.set("mode", shaderColorMode); 79 | bgShader.set("precisionNormalized", norm(currentPrecisionIndex, 0, precisionRange.size())); 80 | pg.shader(bgShader); 81 | } 82 | 83 | @Override 84 | protected void drawNodeForeground(PGraphics pg, String name) { 85 | pg.fill(foregroundMouseOverBrightnessAwareColor()); 86 | drawLeftText(pg, name); 87 | drawRightText(pg, getValueToDisplay(), false); 88 | } 89 | 90 | protected int foregroundMouseOverBrightnessAwareColor(){ 91 | if(isMouseOverNode){ 92 | if(parentColorPickerFolder.brightness() > 0.7f){ 93 | return NormColorStore.color(0); 94 | }else{ 95 | return NormColorStore.color(1); 96 | } 97 | }else{ 98 | return ThemeStore.getColor(ThemeColorType.NORMAL_FOREGROUND); 99 | } 100 | } 101 | 102 | 103 | @Override 104 | public void keyPressedOverNode(LazyKeyEvent e, float x, float y) { 105 | super.keyPressedOverNode(e, x, y); // handle the value change inside SliderNode 106 | if (e.isControlDown() && e.getKeyCode() == KeyCodes.V) { 107 | // reflect the value change in the resulting color 108 | updateColorInParentFolder(); 109 | } 110 | } 111 | 112 | static class HueNode extends ColorSliderNode { 113 | 114 | HueNode(String path, ColorPickerFolderNode parentFolder) { 115 | super(path, parentFolder); 116 | shaderColorMode = 0; 117 | } 118 | 119 | @Override 120 | protected boolean tryConstrainValue() { 121 | while (valueFloat < 0) { 122 | valueFloat += 1; 123 | } 124 | valueFloat %= 1; 125 | return false; 126 | } 127 | } 128 | 129 | static class SaturationNode extends ColorSliderNode { 130 | SaturationNode(String path, ColorPickerFolderNode parentFolder) { 131 | super(path, parentFolder); 132 | shaderColorMode = 1; 133 | } 134 | } 135 | 136 | static class BrightnessNode extends ColorSliderNode { 137 | BrightnessNode(String path, ColorPickerFolderNode parentFolder) { 138 | super(path, parentFolder); 139 | shaderColorMode = 2; 140 | } 141 | } 142 | 143 | static class AlphaNode extends ColorSliderNode { 144 | AlphaNode(String path, ColorPickerFolderNode parentFolder) { 145 | super(path, parentFolder); 146 | shaderColorMode = 3; 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/com/krab/lazy/themes/ThemeStore.java: -------------------------------------------------------------------------------- 1 | package com.krab.lazy.themes; 2 | 3 | import com.krab.lazy.stores.GlobalReferences; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | 9 | public class ThemeStore { 10 | private static final Map paletteMap = new HashMap<>(); 11 | public static ThemeType currentSelection = ThemeType.DARK; 12 | private static String defaultThemeType = currentSelection.name(); 13 | 14 | public static void setCustomPaletteAndMakeDefaultBeforeInit(Theme theme) { 15 | defaultThemeType = ThemeType.getName(ThemeType.CUSTOM); 16 | paletteMap.put(ThemeType.CUSTOM, theme); 17 | } 18 | public static void selectThemeByTypeBeforeInit(ThemeType typeToSelect){ 19 | defaultThemeType = ThemeType.getName(typeToSelect); 20 | } 21 | 22 | public static void init() { 23 | ThemeType[] allTypes = ThemeType.getAllValues(); 24 | for (ThemeType type : allTypes) { 25 | if(!paletteMap.containsKey(type)){ 26 | paletteMap.put(type, ThemeType.getPalette(type)); 27 | } 28 | } 29 | } 30 | 31 | public static int getColor(ThemeColorType type) { 32 | switch (type) { 33 | case WINDOW_BORDER: 34 | return paletteMap.get(ThemeType.CUSTOM).windowBorder; 35 | case NORMAL_BACKGROUND: 36 | return paletteMap.get(ThemeType.CUSTOM).normalBackground; 37 | case FOCUS_BACKGROUND: 38 | return paletteMap.get(ThemeType.CUSTOM).focusBackground; 39 | case NORMAL_FOREGROUND: 40 | return paletteMap.get(ThemeType.CUSTOM).normalForeground; 41 | case FOCUS_FOREGROUND: 42 | return paletteMap.get(ThemeType.CUSTOM).focusForeground; 43 | } 44 | return 0xFFFF0000; 45 | } 46 | 47 | static int getColor(ThemeColorType colorType, ThemeType paletteType) { 48 | switch (colorType) { 49 | case WINDOW_BORDER: 50 | return paletteMap.get(paletteType).windowBorder; 51 | case NORMAL_BACKGROUND: 52 | return paletteMap.get(paletteType).normalBackground; 53 | case FOCUS_BACKGROUND: 54 | return paletteMap.get(paletteType).focusBackground; 55 | case NORMAL_FOREGROUND: 56 | return paletteMap.get(paletteType).normalForeground; 57 | case FOCUS_FOREGROUND: 58 | return paletteMap.get(paletteType).focusForeground; 59 | } 60 | return 0xFFFF0000; 61 | } 62 | 63 | static void setCustomColor(ThemeColorType type, int val) { 64 | switch (type) { 65 | case WINDOW_BORDER: 66 | paletteMap.get(ThemeType.CUSTOM).windowBorder = val; 67 | break; 68 | case NORMAL_BACKGROUND: 69 | paletteMap.get(ThemeType.CUSTOM).normalBackground = val; 70 | break; 71 | case FOCUS_BACKGROUND: 72 | paletteMap.get(ThemeType.CUSTOM).focusBackground = val; 73 | break; 74 | case NORMAL_FOREGROUND: 75 | paletteMap.get(ThemeType.CUSTOM).normalForeground = val; 76 | break; 77 | case FOCUS_FOREGROUND: 78 | paletteMap.get(ThemeType.CUSTOM).focusForeground = val; 79 | break; 80 | } 81 | } 82 | 83 | public static void updateThemePicker() { 84 | GlobalReferences.gui.pushFolder("themes"); 85 | String userSelection = GlobalReferences.gui.radio("preset", ThemeType.getAllNames(), defaultThemeType); 86 | 87 | if (!userSelection.equals(ThemeType.getName(ThemeStore.currentSelection))) { 88 | ThemeType newSelectionToCopy = ThemeType.getValue(userSelection); 89 | GlobalReferences.gui.colorPickerSet("focus foreground", ThemeStore.getColor(ThemeColorType.FOCUS_FOREGROUND, newSelectionToCopy)); 90 | GlobalReferences.gui.colorPickerSet("focus background", ThemeStore.getColor(ThemeColorType.FOCUS_BACKGROUND, newSelectionToCopy)); 91 | GlobalReferences.gui.colorPickerSet("normal foreground", ThemeStore.getColor(ThemeColorType.NORMAL_FOREGROUND, newSelectionToCopy)); 92 | GlobalReferences.gui.colorPickerSet("normal background", ThemeStore.getColor(ThemeColorType.NORMAL_BACKGROUND, newSelectionToCopy)); 93 | GlobalReferences.gui.colorPickerSet("window border", ThemeStore.getColor(ThemeColorType.WINDOW_BORDER, newSelectionToCopy)); 94 | ThemeStore.currentSelection = newSelectionToCopy; 95 | } 96 | assert currentSelection != null; 97 | Theme defaultTheme = ThemeType.getPalette(currentSelection); 98 | assert defaultTheme != null; 99 | ThemeStore.setCustomColor(ThemeColorType.FOCUS_FOREGROUND, 100 | GlobalReferences.gui.colorPicker("focus foreground", defaultTheme.focusForeground).hex); 101 | ThemeStore.setCustomColor(ThemeColorType.FOCUS_BACKGROUND, 102 | GlobalReferences.gui.colorPicker("focus background", defaultTheme.focusBackground).hex); 103 | ThemeStore.setCustomColor(ThemeColorType.NORMAL_FOREGROUND, 104 | GlobalReferences.gui.colorPicker("normal foreground", defaultTheme.normalForeground).hex); 105 | ThemeStore.setCustomColor(ThemeColorType.NORMAL_BACKGROUND, 106 | GlobalReferences.gui.colorPicker("normal background", defaultTheme.normalBackground).hex); 107 | ThemeStore.setCustomColor(ThemeColorType.WINDOW_BORDER, 108 | GlobalReferences.gui.colorPicker("window border", defaultTheme.windowBorder).hex); 109 | GlobalReferences.gui.popFolder(); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /docs/index-files/index-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | B-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 |
42 | 69 | 70 |
A B C D F G H I K L M P R S T  71 | 72 | 73 |

B

74 |
75 |
brightness - Variable in class com.krab.lazy.PickerColor
76 |
77 |
Brightness in range of [0,1]
78 |
79 |
button(String) - Method in class com.krab.lazy.LazyGui
80 |
81 |
Gets the value of a button control element and sets it to false.
82 |
83 |
84 | A B C D F G H I K L M P R S T 
85 | 86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 101 |
102 | 129 | 130 | 131 | 132 | --------------------------------------------------------------------------------