diff --git a/assets/Shaders/font/bitmapchar/bitmapchar.vs b/assets/Shaders/font/bitmapchar/bitmapchar.vs index 439f8516..9246ac38 100644 --- a/assets/Shaders/font/bitmapchar/bitmapchar.vs +++ b/assets/Shaders/font/bitmapchar/bitmapchar.vs @@ -14,18 +14,15 @@ void main(){ vec2 finalPos = vec2( - ((aPos.x + 1)/2 * mDimension.x + mPosition.x) * 2 - 1, - ((((aPos.y + 1)/2) * mDimension.y + mPosition.y) * 2 - 1) - // (aPos.y * mDimension.y + mPosition.y) - // -((((aPos.y + 1)/2) * mDimension.y + mPosition.y) * 2 - 1) - // aPos.y * mDimension.y + (mPosition.y) + (1 - mDimension.y) - ); + ((aPos.x + 1)/2 * mDimension.x + mPosition.x) * 2 - 1, + ((aPos.y + 1)/2 * -mDimension.y + mPosition.y) * 2 - 1 + ); gl_Position = vec4(finalPos.x, finalPos.y, 0.0, 1.0); vec2 finalTex = vec2( - aTexCoords.x * tDimension.x + tPosition.x, - (1-aTexCoords.y) * tDimension.y + tPosition.y - ); + aTexCoords.x * tDimension.x + tPosition.x, + (1 - aTexCoords.y) * tDimension.y + tPosition.y + ); TexCoords = finalTex; } \ No newline at end of file diff --git a/assets/Shaders/plane/plane.fs b/assets/Shaders/plane/plane.fs index 21c738d3..d1039d55 100644 --- a/assets/Shaders/plane/plane.fs +++ b/assets/Shaders/plane/plane.fs @@ -1,4 +1,4 @@ -#version 330 core +#version 430 core out vec4 FragColor; in vec2 TexCoords; diff --git a/assets/Shaders/plane/plane.vs b/assets/Shaders/plane/plane.vs index 6b421834..12c85cb8 100644 --- a/assets/Shaders/plane/plane.vs +++ b/assets/Shaders/plane/plane.vs @@ -1,4 +1,4 @@ -#version 330 core +#version 430 core layout (location = 0) in vec3 aPos; layout (location = 4) in vec2 aTexCoords; @@ -10,17 +10,19 @@ uniform vec3 tPosition; uniform vec3 tDimension; void main(){ + vec2 finalPos = vec2( - ((aPos.x + 1)/2 * mDimension.x + mPosition.x) * 2 - 1, - ((((aPos.y + 1)/2) * mDimension.y + (1 - mDimension.y) - mPosition.y) * 2 - 1) - // ((((aPos.y + 1)/2) * mDimension.y + mPosition.y) * 2 - 1) - // aPos.y * mDimension.y + (mPosition.y) + (1 - mDimension.y) - ); + ((aPos.x + 1)/2 * mDimension.x + mPosition.x) * 2 - 1, + ((aPos.y + 1)/2 * mDimension.y + (1 - mDimension.y) - mPosition.y) * 2 - 1 + + // ((((aPos.y + 1)/2) * mDimension.y + mPosition.y) * 2 - 1) + // aPos.y * mDimension.y + (mPosition.y) + (1 - mDimension.y) + ); gl_Position = vec4(finalPos.x, finalPos.y, 0.0, 1.0); vec2 finalTex = vec2( aTexCoords.x * tDimension.x + tPosition.x, - 1 - (aTexCoords.y * tDimension.y + tPosition.y) + aTexCoords.y * tDimension.y + tPosition.y ); // vec2 finalTex = aTexCoords; // vec2 finalTex = vec2( diff --git a/assets/Textures/ui/uiFrame1.png b/assets/Textures/ui/uiFrame1.png new file mode 100644 index 00000000..731ae74a Binary files /dev/null and b/assets/Textures/ui/uiFrame1.png differ diff --git a/assets/Textures/ui/uiFrame2.png b/assets/Textures/ui/uiFrame2.png new file mode 100644 index 00000000..6437b467 Binary files /dev/null and b/assets/Textures/ui/uiFrame2.png differ diff --git a/buildNumber.properties b/buildNumber.properties index afe971cc..914e4669 100644 --- a/buildNumber.properties +++ b/buildNumber.properties @@ -1,3 +1,3 @@ #maven.buildNumber.plugin properties file -#Sun Mar 24 15:51:37 EDT 2024 -buildNumber=83 +#Thu Apr 04 18:08:22 EDT 2024 +buildNumber=94 diff --git a/docs/src/highlevel-design/creatures/creatureideas.md b/docs/src/highlevel-design/creatures/creatureideas.md new file mode 100644 index 00000000..5dfc2456 --- /dev/null +++ b/docs/src/highlevel-design/creatures/creatureideas.md @@ -0,0 +1,4 @@ +@page creatureideas Creature Ideas + +Leaf Sheep +Jellyfish \ No newline at end of file diff --git a/docs/src/highlevel-design/creatures/creaturesindex.md b/docs/src/highlevel-design/creatures/creaturesindex.md index 45808428..bd58ac6e 100644 --- a/docs/src/highlevel-design/creatures/creaturesindex.md +++ b/docs/src/highlevel-design/creatures/creaturesindex.md @@ -1,4 +1,5 @@ @page creaturesindex Creatures [TOC] + - @subpage creatureideas - @subpage creaturemechanicsideas \ No newline at end of file diff --git a/docs/src/highlevel-design/creatures/mechanicsideas.md b/docs/src/highlevel-design/creatures/mechanicsideas.md index 9d8efded..27ecc63d 100644 --- a/docs/src/highlevel-design/creatures/mechanicsideas.md +++ b/docs/src/highlevel-design/creatures/mechanicsideas.md @@ -3,4 +3,6 @@ If/when fluidsim is a part of the engine, have a creature that constantly keeps a bubble of water around itself (drawing from nearby sources as it approaches them). When it runs up to regular creatures to try to attack them, it will force them into swimming state or outright kill them. Ocean-faring monsters that create voids that push away liquid (thus making them challenging to fight on a boat) -Scary creatures that, when entering a chunk, gradually reduce environment volume to zero (ie crickets stop chirping because it's so scary) Like a demon scarecrow or devil \ No newline at end of file +Scary creatures that, when entering a chunk, gradually reduce environment volume to zero (ie crickets stop chirping because it's so scary) Like a demon scarecrow or devil + +Custom cursors per playable race (ie gauntlet for humans, claw for demons, etc) \ No newline at end of file diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 7cdbd82d..21f42288 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -203,6 +203,12 @@ Level loading/saving + Basic Editor # TODO +UI Work + - Make ui feel more responsive, whatever that means (answer is make hover-over styling work lol) + - Frames for windows (WIP) + - Need to figure out style-wise what we want to do here (generally minimalist) + - Fix scrollable handling + Level loading/saving + Basic Editor - Basic editor functionality - Menu of types of entities to spawn diff --git a/pom.xml b/pom.xml index 745867cb..226c20eb 100644 --- a/pom.xml +++ b/pom.xml @@ -256,6 +256,20 @@ runtime + + + + org.lwjgl + lwjgl-yoga + ${lwjgl.version} + + + org.lwjgl + lwjgl-yoga + ${lwjgl.version} + ${lwjgl.natives} + + diff --git a/src/main/java/electrosphere/controls/CameraHandler.java b/src/main/java/electrosphere/controls/CameraHandler.java index 3a637ac1..1969444c 100644 --- a/src/main/java/electrosphere/controls/CameraHandler.java +++ b/src/main/java/electrosphere/controls/CameraHandler.java @@ -6,7 +6,6 @@ import org.joml.Vector3f; import electrosphere.client.targeting.crosshair.Crosshair; import electrosphere.engine.Globals; -import electrosphere.engine.Main; import electrosphere.entity.EntityUtils; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.renderer.ui.events.MouseEvent; diff --git a/src/main/java/electrosphere/controls/Control.java b/src/main/java/electrosphere/controls/Control.java index 7d190ec6..9115bbe7 100644 --- a/src/main/java/electrosphere/controls/Control.java +++ b/src/main/java/electrosphere/controls/Control.java @@ -1,13 +1,18 @@ package electrosphere.controls; import electrosphere.renderer.ui.events.MouseEvent; +import electrosphere.renderer.ui.events.ScrollEvent; +/** + * A low level control inside the engine + */ public class Control { public static enum ControlType { KEY, MOUSE_BUTTON, MOUSE_MOVEMENT, + MOUSE_SCROLL, } ControlType type; @@ -18,6 +23,7 @@ public class Control { ControlMethod onRepeat; ControlMethod onClick; MouseCallback onMove; + ScrollCallback onScroll; float pressFrame = 0; float repeatTimeout = 0; @@ -72,6 +78,10 @@ public class Control { onClick = method; } + public void setOnScroll(ScrollCallback callback){ + onScroll = callback; + } + public void onPress(){ if(onPress != null){ onPress.execute(); @@ -102,6 +112,12 @@ public class Control { } } + public void onScroll(ScrollEvent event){ + if(onScroll != null){ + onScroll.execute(event); + } + } + public float getPressFrame(){ return this.pressFrame; } @@ -126,5 +142,9 @@ public class Control { public interface MouseCallback { public void execute(MouseEvent event); } + + public interface ScrollCallback { + public void execute(ScrollEvent event); + } } diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index 8377c795..01e52599 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -58,8 +58,6 @@ import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_2; import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_LEFT; import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_RIGHT; import static org.lwjgl.glfw.GLFW.glfwGetCursorPos; -import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; -import static org.lwjgl.glfw.GLFW.glfwMaximizeWindow; import static org.lwjgl.glfw.GLFW.glfwSetInputMode; import java.util.HashMap; @@ -69,9 +67,7 @@ import java.util.List; import org.joml.Vector2f; import org.joml.Vector3d; import org.joml.Vector3f; -import org.lwjgl.glfw.GLFW; -import electrosphere.audio.AudioUtils; import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; import electrosphere.client.targeting.crosshair.Crosshair; import electrosphere.client.terrain.editing.TerrainEditing; @@ -96,7 +92,6 @@ import electrosphere.entity.state.movement.groundmove.GroundMovementTree.Movemen import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.logger.LoggerInterface; -import electrosphere.menu.MenuGenerators; import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowUtils; import electrosphere.menu.ingame.MenuGeneratorsInGame; @@ -108,6 +103,7 @@ import electrosphere.renderer.ui.events.KeyboardEvent; import electrosphere.renderer.ui.events.MenuEvent; import electrosphere.renderer.ui.events.MenuEvent.MenuEventType; import electrosphere.renderer.ui.events.MouseEvent; +import electrosphere.renderer.ui.events.ScrollEvent; /** * @@ -145,6 +141,7 @@ public class ControlHandler { public static final String INPUT_CODE_MENU_MOUSE_PRIMARY = "menuMousePrimary"; public static final String DATA_STRING_INPUT_CODE_MENU_BACKOUT = "menuBackout"; public static final String MENU_MOUSE_MOVE = "menuMouseMove"; + public static final String MENU_SCROLL = "menuScroll"; @@ -288,6 +285,7 @@ public class ControlHandler { handler.addControl(DATA_STRING_INPUT_CODE_MENU_BACKOUT, new Control(ControlType.KEY,GLFW_KEY_ESCAPE)); handler.addControl(MENU_MOUSE_MOVE, new Control(ControlType.MOUSE_MOVEMENT,0)); handler.addControl(INPUT_CODE_MENU_MOUSE_PRIMARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_LEFT)); + handler.addControl(MENU_SCROLL, new Control(ControlType.MOUSE_SCROLL,0)); /* Map the typing controls @@ -437,6 +435,7 @@ public class ControlHandler { break; } + Globals.scrollCallback.clear(); } @@ -1099,6 +1098,12 @@ public class ControlHandler { Globals.elementManager.updateHover(mouseEvent.getCurrentX(), mouseEvent.getCurrentY()); }}); + //scrolling the mouse + menuNavigationControlList.add(controls.get(MENU_SCROLL)); + controls.get(MENU_SCROLL).setOnScroll(new Control.ScrollCallback() {public void execute(ScrollEvent scrollEvent){ + Globals.elementManager.fireEvent(scrollEvent, GLFW_KEY_X, GLFW_KEY_Z); + }}); + //Decrementing a menu element @@ -1125,8 +1130,8 @@ public class ControlHandler { menuNavigationControlList.add(controls.get(DATA_STRING_INPUT_CODE_MENU_SELECT)); controls.get(DATA_STRING_INPUT_CODE_MENU_SELECT).setOnPress(new ControlMethod(){public void execute(){ Globals.elementManager.click(new ClickEvent( - Globals.elementManager.getFocusedElement().getPositionX(), - Globals.elementManager.getFocusedElement().getPositionY(), + Globals.elementManager.getFocusedElement().getInternalX() + 1, + Globals.elementManager.getFocusedElement().getInternalY() + 1, true, Globals.mouseCallback.getButton(GLFW_MOUSE_BUTTON_2) )); @@ -1249,8 +1254,8 @@ public class ControlHandler { controls.get(currentKey).setOnPress(new ControlMethod(){public void execute(){ Globals.elementManager.fireEvent( new KeyboardEvent(convertKeycodeToName(controls.get(currentKey).keyValue)), - Globals.elementManager.getFocusedElement().getPositionX(), - Globals.elementManager.getFocusedElement().getPositionY() + Globals.elementManager.getFocusedElement().getInternalX() + 1, + Globals.elementManager.getFocusedElement().getInternalY() + 1 ); // MenuCallbacks.menuHandleKeypress(Globals.currentMenu,currentKey); }}); @@ -1329,60 +1334,67 @@ public class ControlHandler { for(Control control : controls){ switch(control.getType()){ - case KEY: - if(Globals.controlCallback.getKey(control.getKeyValue())){ - if(!control.isState()){ - //on press - control.onPress(); - control.setPressFrame((float)Globals.timekeeper.getMostRecentRawFrametime()); + case KEY: { + if(Globals.controlCallback.getKey(control.getKeyValue())){ + if(!control.isState()){ + //on press + control.onPress(); + control.setPressFrame((float)Globals.timekeeper.getMostRecentRawFrametime()); + } else { + //on repeat + if((float)Globals.timekeeper.getMostRecentRawFrametime() - control.getPressFrame() > control.getRepeatTimeout()){ + control.onRepeat(); + } + } + control.setState(true); } else { - //on repeat - if((float)Globals.timekeeper.getMostRecentRawFrametime() - control.getPressFrame() > control.getRepeatTimeout()){ + if(control.isState()){ + //on release + control.onRelease(); + //on click + if((float)Globals.timekeeper.getMostRecentRawFrametime() - control.getPressFrame() < control.getRepeatTimeout()){ + control.onClick(); + } + } else { + } + control.setState(false); + } + } break; + case MOUSE_BUTTON: { + if(Globals.mouseCallback.getButton(control.getKeyValue())){ + if(!control.isState()){ + //on press + control.onPress(); + control.setPressFrame((float)Globals.timekeeper.getMostRecentRawFrametime()); + } else { + //on repeat control.onRepeat(); } - } - control.setState(true); - } else { - if(control.isState()){ - //on release - control.onRelease(); - //on click - if((float)Globals.timekeeper.getMostRecentRawFrametime() - control.getPressFrame() < control.getRepeatTimeout()){ - control.onClick(); + control.setState(true); + } else { + if(control.isState()){ + //on release + control.onRelease(); + if((float)Globals.timekeeper.getMostRecentRawFrametime() - control.getPressFrame() < control.getRepeatTimeout()){ + control.onClick(); + } + } else { } - } else { + control.setState(false); } - control.setState(false); - } - break; - case MOUSE_BUTTON: - if(Globals.mouseCallback.getButton(control.getKeyValue())){ - if(!control.isState()){ - //on press - control.onPress(); - control.setPressFrame((float)Globals.timekeeper.getMostRecentRawFrametime()); - } else { - //on repeat - control.onRepeat(); + } break; + case MOUSE_MOVEMENT: { + if(mouseMoveEvent){ + control.onMove(currentMouseEvent); } - control.setState(true); - } else { - if(control.isState()){ - //on release - control.onRelease(); - if((float)Globals.timekeeper.getMostRecentRawFrametime() - control.getPressFrame() < control.getRepeatTimeout()){ - control.onClick(); - } - } else { + } break; + case MOUSE_SCROLL: { + double yScroll = Globals.scrollCallback.getOffsetY(); + if(yScroll != 0){ + ScrollEvent event = new ScrollEvent(xpos,ypos,yScroll); + control.onScroll(event); } - control.setState(false); - } - break; - case MOUSE_MOVEMENT: - if(mouseMoveEvent){ - control.onMove(currentMouseEvent); - } - break; + } break; } } } diff --git a/src/main/java/electrosphere/controls/MouseCallback.java b/src/main/java/electrosphere/controls/MouseCallback.java index 536b2c2e..1ec4f787 100644 --- a/src/main/java/electrosphere/controls/MouseCallback.java +++ b/src/main/java/electrosphere/controls/MouseCallback.java @@ -5,10 +5,15 @@ import org.lwjgl.glfw.GLFWMouseButtonCallback; import electrosphere.logger.LoggerInterface; +/** + * A callback for mouse functions + */ public class MouseCallback extends GLFWMouseButtonCallback { + //the number of buttons available static final short KEY_VALUE_ARRAY_SIZE = 512; + //current value of all buttons pressed boolean[] buttonValues = new boolean[KEY_VALUE_ARRAY_SIZE]; @Override @@ -23,9 +28,9 @@ public class MouseCallback extends GLFWMouseButtonCallback { } /** - * !!!WARNING!!!, will silently fail if opengl elementsn ot defined or keycode is outside of key value array size or is not in main rendering thread - * @param keycode - * @return + * !!!WARNING!!!, will silently fail if opengl elements not defined or keycode is outside of key value array size or is not in main rendering thread + * @param keycode The keycode + * @return The button's pressed state */ public boolean getButton(int keycode){ if(keycode >= 0 && keycode < KEY_VALUE_ARRAY_SIZE){ diff --git a/src/main/java/electrosphere/controls/ScrollCallback.java b/src/main/java/electrosphere/controls/ScrollCallback.java new file mode 100644 index 00000000..85d387e3 --- /dev/null +++ b/src/main/java/electrosphere/controls/ScrollCallback.java @@ -0,0 +1,44 @@ +package electrosphere.controls; + +import org.lwjgl.glfw.GLFWScrollCallback; + +/** + * A callback for scroll events from the mouse + */ +public class ScrollCallback extends GLFWScrollCallback { + + //the offsets from the most recent scroll event + double offsetX = 0; + double offsetY = 0; + + @Override + public void invoke(long window, double xoffset, double yoffset) { + offsetX = xoffset; + offsetY = yoffset; + } + + /** + * The x offset from the scroll, !!setting the stored value to 0 in the process!! + * @return The x scroll offset + */ + public double getOffsetX(){ + return offsetX; + } + + /** + * The y offset from the scroll, !!setting the stored value to 0 in the process!! + * @return The y scroll offset + */ + public double getOffsetY(){ + return offsetY; + } + + /** + * Clears the data cached in the callback + */ + public void clear(){ + offsetX = 0; + offsetY = 0; + } + +} diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index 5cac0faa..cb99b5e5 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -27,6 +27,7 @@ import electrosphere.controls.CameraHandler; import electrosphere.controls.ControlCallback; import electrosphere.controls.ControlHandler; import electrosphere.controls.MouseCallback; +import electrosphere.controls.ScrollCallback; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.engine.assetmanager.AssetManager; import electrosphere.engine.loadingthreads.LoadingThread; @@ -121,7 +122,9 @@ public class Globals { // //Garbage Collection // - public static boolean EXPLICIT_GC = true; + //set to true to trigger full GC every frame + //a full GC includes collecting old generations as well -- likely very laggy!! + public static boolean EXPLICIT_GC = false; // @@ -151,6 +154,7 @@ public class Globals { public static boolean updateCamera = true; public static ControlCallback controlCallback = new ControlCallback(); public static MouseCallback mouseCallback = new MouseCallback(); + public static ScrollCallback scrollCallback = new ScrollCallback(); // @@ -513,10 +517,12 @@ public class Globals { solidPlaneModelID = assetManager.registerModel(RenderUtils.createInWindowPanel("Shaders/ui/plainBox/plainBox.vs", "Shaders/ui/plainBox/plainBox.fs")); //image panel - ImagePanel.imagePanelModelPath = assetManager.registerModel(RenderUtils.createPlaneModel("Shaders/font/bitmapchar/bitmapchar.vs", "Shaders/font/bitmapchar/bitmapchar.fs")); + ImagePanel.imagePanelModelPath = assetManager.registerModel(RenderUtils.createPlaneModel("Shaders/plane/plane.vs", "Shaders/plane/plane.fs")); //init ui images assetManager.addTexturePathtoQueue("Textures/ui/WindowBorder.png"); + assetManager.addTexturePathtoQueue("Textures/ui/uiFrame1.png"); + assetManager.addTexturePathtoQueue("Textures/ui/uiFrame2.png"); testingTexture = "Textures/Testing1.png"; Globals.assetManager.addTexturePathtoQueue(testingTexture); diff --git a/src/main/java/electrosphere/logger/LoggerInterface.java b/src/main/java/electrosphere/logger/LoggerInterface.java index ffe3f69d..c97c0da4 100644 --- a/src/main/java/electrosphere/logger/LoggerInterface.java +++ b/src/main/java/electrosphere/logger/LoggerInterface.java @@ -19,6 +19,7 @@ public class LoggerInterface { public static Logger loggerAuth; public static Logger loggerDB; public static Logger loggerAudio; + public static Logger loggerUI; public static void initLoggers(){ loggerStartup = new Logger(LogLevel.WARNING); @@ -30,6 +31,7 @@ public class LoggerInterface { loggerAuth = new Logger(LogLevel.WARNING); loggerDB = new Logger(LogLevel.WARNING); loggerAudio = new Logger(LogLevel.WARNING); + loggerUI = new Logger(LogLevel.INFO); loggerStartup.INFO("Initialized loggers"); } } diff --git a/src/main/java/electrosphere/menu/MenuGenerators.java b/src/main/java/electrosphere/menu/MenuGenerators.java index 084ddfb3..f3a38ec4 100644 --- a/src/main/java/electrosphere/menu/MenuGenerators.java +++ b/src/main/java/electrosphere/menu/MenuGenerators.java @@ -27,6 +27,7 @@ import electrosphere.renderer.ui.Window; import electrosphere.renderer.ui.elements.ActorPanel; import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.Div; +import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.ImagePanel; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.ScrollableContainer; @@ -39,7 +40,6 @@ import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallb import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.NavigationEvent; import electrosphere.renderer.ui.events.ValueChangeEvent; -import electrosphere.renderer.ui.form.FormElement; import electrosphere.server.saves.SaveUtils; import electrosphere.server.terrain.generation.OverworldChunkGenerator; import electrosphere.server.terrain.manager.ServerTerrainManager; @@ -66,7 +66,7 @@ public class MenuGenerators { //button (select save) Button selectButton = new Button(); - Label selectLabel = new Label(100,125 + verticalPosition,1.0f); + Label selectLabel = new Label(1.0f); selectLabel.setText(saveName.toUpperCase()); selectButton.addChild(selectLabel); rVal.addChild(selectButton); @@ -97,7 +97,7 @@ public class MenuGenerators { //button (create) Button createButton = new Button(); - Label createLabel = new Label(100,125 + verticalPosition + 200,1.0f); + Label createLabel = new Label(1.0f); createLabel.setText("Create World"); createButton.addChild(createLabel); rVal.addChild(createButton); @@ -123,7 +123,7 @@ public class MenuGenerators { //button (create) Button createButton = new Button(); - Label createLabel = new Label(100,screenTop + verticalPosition,1.0f); + Label createLabel = new Label(1.0f); createLabel.setText("Create"); createButton.addChild(createLabel); rVal.addChild(createButton); @@ -148,7 +148,7 @@ public class MenuGenerators { //button (save) Button saveButton = new Button(); - Label saveLabel = new Label(100,screenTop + 125,1.0f); + Label saveLabel = new Label(1.0f); saveLabel.setText("Save"); saveButton.addChild(saveLabel); rVal.addChild(saveButton); @@ -160,7 +160,7 @@ public class MenuGenerators { //button (cancel) Button cancelButton = new Button(); - Label cancelLabel = new Label(100,screenTop + 200,1.0f); + Label cancelLabel = new Label(1.0f); cancelLabel.setText("Cancel"); cancelButton.addChild(cancelLabel); rVal.addChild(cancelButton); @@ -182,7 +182,7 @@ public class MenuGenerators { //button (create) Button createButton = new Button(); - Label createLabel = new Label(100,screenTop + verticalPosition,1.0f); + Label createLabel = new Label(1.0f); createLabel.setText("Create World"); createButton.addChild(createLabel); rVal.addChild(createButton); @@ -201,7 +201,7 @@ public class MenuGenerators { //button (create) Button createButton = new Button(); - Label createLabel = new Label(100,screenTop + verticalPosition,1.0f); + Label createLabel = new Label(1.0f); createLabel.setText("Create World"); createButton.addChild(createLabel); rVal.addChild(createButton); @@ -215,7 +215,7 @@ public class MenuGenerators { //button (host) Button hostButton = new Button(); - Label hostLabel = new Label(100,screenTop + 125,1.0f); + Label hostLabel = new Label(1.0f); hostLabel.setText("Host"); hostButton.addChild(hostLabel); rVal.addChild(hostButton); @@ -233,7 +233,7 @@ public class MenuGenerators { //button (join) Button joinButton = new Button(); - Label joinLabel = new Label(100,screenTop + 200,1.0f); + Label joinLabel = new Label(1.0f); joinLabel.setText("Join"); joinButton.addChild(joinLabel); rVal.addChild(joinButton); @@ -245,7 +245,7 @@ public class MenuGenerators { //button (back) Button connectButton = new Button(); - Label connectLabel = new Label(100,screenTop + 275,1.0f); + Label connectLabel = new Label(1.0f); connectLabel.setText("Back"); connectButton.addChild(connectLabel); rVal.addChild(connectButton); @@ -262,7 +262,7 @@ public class MenuGenerators { int screenTop = 150; //label (address) - Label addressLabel = new Label(100,screenTop + 50,1.0f); + Label addressLabel = new Label(1.0f); addressLabel.setText("IP Address"); rVal.addChild(addressLabel); @@ -272,7 +272,7 @@ public class MenuGenerators { rVal.addChild(addressInput); //label (port) - Label portLabel = new Label(100,screenTop + 200,1.0f); + Label portLabel = new Label(1.0f); portLabel.setText("Port"); rVal.addChild(portLabel); @@ -282,7 +282,7 @@ public class MenuGenerators { rVal.addChild(portInput); //label (address) - Label usernameLabel = new Label(100,screenTop + 350,1.0f); + Label usernameLabel = new Label(1.0f); usernameLabel.setText("Username"); rVal.addChild(usernameLabel); @@ -292,7 +292,7 @@ public class MenuGenerators { rVal.addChild(usernameInput); //label (port) - Label passwordLabel = new Label(100,screenTop + 500,1.0f); + Label passwordLabel = new Label(1.0f); passwordLabel.setText("Password"); rVal.addChild(passwordLabel); @@ -303,7 +303,7 @@ public class MenuGenerators { //button (connect) Button connectButton = new Button(); - Label connectLabel = new Label(100,screenTop + 650,1.0f); + Label connectLabel = new Label(1.0f); connectLabel.setText("Connect"); connectButton.addChild(connectLabel); rVal.addChild(connectButton); @@ -322,7 +322,7 @@ public class MenuGenerators { //button (back) Button backButton = new Button(); - Label backLabel = new Label(100,screenTop + 725,1.0f); + Label backLabel = new Label(1.0f); backLabel.setText("Back"); backButton.addChild(backLabel); rVal.addChild(backButton); @@ -336,16 +336,15 @@ public class MenuGenerators { public static Element createOptionsMainMenu(){ FormElement rVal = new FormElement(); - int screenTop = 150; //label (options) - Label optionsLabel = new Label(100,screenTop + 50,1.0f); + Label optionsLabel = new Label(1.0f); optionsLabel.setText("Options"); rVal.addChild(optionsLabel); //button (back) Button backButton = new Button(); - Label backLabel = new Label(100,screenTop + 275,1.0f); + Label backLabel = new Label(1.0f); backLabel.setText("Back"); backButton.addChild(backLabel); rVal.addChild(backButton); @@ -357,61 +356,6 @@ public class MenuGenerators { return rVal; } - public static Element createUITestMenu(){ - FormElement rVal = new FormElement(); - int screenTop = 150; - - //button (back) - Button backButton = new Button(); - Label backLabel = new Label(100,screenTop + 275,1.0f); - backLabel.setText("Back"); - backButton.addChild(backLabel); - rVal.addChild(backButton); - backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); - return false; - }}); - - //slider test - Slider slider = new Slider(0, 0, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - rVal.addChild(slider); - - ActorPanel actorPanel = new ActorPanel(500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx")); - if(Globals.playerCamera == null){ - Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(-1,0,0)); - } - rVal.addChild(actorPanel); - - // slider = new Slider(0, 100, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 200, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 300, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 400, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 500, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 600, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 700, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 800, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - // slider = new Slider(0, 900, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); - // rVal.addChild(slider); - - return rVal; - } - } diff --git a/src/main/java/electrosphere/menu/WindowUtils.java b/src/main/java/electrosphere/menu/WindowUtils.java index 5f06104f..8752f8ed 100644 --- a/src/main/java/electrosphere/menu/WindowUtils.java +++ b/src/main/java/electrosphere/menu/WindowUtils.java @@ -19,8 +19,9 @@ public class WindowUtils { if(mainMenuEl != null && mainMenuEl instanceof Window){ Window mainMenu = (Window) mainMenuEl; //todo: destroy elements as well - mainMenu.getChildren().clear(); + mainMenu.clear(); mainMenu.addChild(newMenu); + mainMenu.applyYoga(); Globals.elementManager.focusFirstElement(); } } @@ -107,16 +108,17 @@ public class WindowUtils { } static void initLoadingWindow(){ - Window loadingWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); - Label loadingLabel = new Label(100,50,1.0f); + Window loadingWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT,false); + Label loadingLabel = new Label(1.0f); loadingLabel.setText("LOADING"); loadingWindow.addChild(loadingLabel); + loadingWindow.applyYoga(); Globals.elementManager.registerWindow(WindowStrings.WINDOW_LOADING, loadingWindow); WindowUtils.recursiveSetVisible(loadingWindow, true); } static void initMainMenuWindow(){ - Window mainMenuWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + Window mainMenuWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT,false); Globals.elementManager.registerWindow(WindowStrings.WINDOW_MENU_MAIN, mainMenuWindow); WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); } @@ -126,7 +128,7 @@ public class WindowUtils { } static void initItemDragContainerWindow(){ - Window itemDragContainerWindow = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT); + Window itemDragContainerWindow = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); Globals.elementManager.registerWindow(WindowStrings.WINDOW_ITEM_DRAG_CONTAINER, itemDragContainerWindow); } diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java index be5406b7..90f66400 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java @@ -1,6 +1,7 @@ package electrosphere.menu.ingame; import org.joml.Vector3f; +import org.lwjgl.util.yoga.Yoga; import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; @@ -25,6 +26,7 @@ import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.ScrollableContainer; import electrosphere.renderer.ui.elements.Slider; import electrosphere.renderer.ui.elements.TextInput; +import electrosphere.renderer.ui.elements.VirtualScrollable; import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback; import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback; @@ -42,7 +44,7 @@ public class MenuGeneratorsInGame { // int screenTop = Globals.WINDOW_HEIGHT - 150; int width = 500; int height = 500; - Window rVal = new Window(0,0,width,height); + Window rVal = new Window(0,0,width,height,true); // int screenLeft = (Globals.WINDOW_WIDTH - width)/2; Div div = new Div(); rVal.addChild(div); @@ -59,15 +61,15 @@ public class MenuGeneratorsInGame { }}); //black texture background - ImagePanel imagePanel = new ImagePanel(0,0,width,height,Globals.blackTexture); + // ImagePanel imagePanel = new ImagePanel(0,0,width,height,Globals.blackTexture); // imagePanel.setWidth(width); // imagePanel.setHeight(height); // imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); - div.addChild(imagePanel); + // div.addChild(imagePanel); //label 1 (back) Button backButton = new Button(); - Label backLabel = new Label(100,50,1.0f); + Label backLabel = new Label(1.0f); backLabel.setText("Back"); backButton.addChild(backLabel); div.addChild(backButton); @@ -86,7 +88,7 @@ public class MenuGeneratorsInGame { //label 2 (quit) Button saveButton = new Button(); - Label saveLabel = new Label(100,150,1.0f); + Label saveLabel = new Label(1.0f); saveLabel.setText("Save"); saveButton.addChild(saveLabel); div.addChild(saveButton); @@ -99,7 +101,7 @@ public class MenuGeneratorsInGame { //label 3 (quit) Button quitButton = new Button(); - Label quitLabel = new Label(100,250,1.0f); + Label quitLabel = new Label(1.0f); quitLabel.setText("Quit"); quitButton.addChild(quitLabel); div.addChild(quitButton); @@ -112,7 +114,7 @@ public class MenuGeneratorsInGame { // if(Globals.server != null && Globals.macroData == null){ //label 4 (debug) Button debugButton = new Button(); - Label debugLabel = new Label(100,350,1.0f); + Label debugLabel = new Label(1.0f); debugLabel.setText("Debug"); debugButton.addChild(debugLabel); div.addChild(debugButton); @@ -122,6 +124,8 @@ public class MenuGeneratorsInGame { }}); // } + rVal.applyYoga(); + return rVal; } @@ -136,15 +140,15 @@ public class MenuGeneratorsInGame { // int screenTop = Globals.WINDOW_HEIGHT - 150; int width = 500; int height = 500; - float fontSize = 0.4f; - Window rVal = new Window(0,0,width,height); + float fontSize = 1.0f; + Window rVal = new Window(0,0,width,height,true); // int screenLeft = (Globals.WINDOW_WIDTH - width)/2; // Div div = new Div(); // div.setPositionX(0); // div.setPositionY(0); // div.setWidth(500); // div.setHeight(500); - ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height); + VirtualScrollable scrollable = new VirtualScrollable(width, height); rVal.addChild(scrollable); // scrollable.addChild(div); rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ @@ -153,15 +157,15 @@ public class MenuGeneratorsInGame { }}); //black texture background - ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture); + // ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture); // imagePanel.setWidth(width); // imagePanel.setHeight(height); // imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); - scrollable.addChild(imagePanel); + // scrollable.addChild(imagePanel); //label 1 (back) Button backButton = new Button(); - Label backLabel = new Label(100,50,fontSize); + Label backLabel = new Label(fontSize); backLabel.setText("Back"); backButton.addChild(backLabel); scrollable.addChild(backButton); @@ -178,7 +182,7 @@ public class MenuGeneratorsInGame { //label 3 (load model and debug) Button debugModelButton = new Button(); - Label debugModelLabel = new Label(100,250,fontSize); + Label debugModelLabel = new Label(fontSize); debugModelLabel.setText("Print Model Debug Info"); debugModelButton.addChild(debugModelLabel); scrollable.addChild(debugModelButton); @@ -199,7 +203,7 @@ public class MenuGeneratorsInGame { //label 4 (reload all shaders) Button reloadShaderButton = new Button(); - Label reloadShaderLabel = new Label(100,350,fontSize); + Label reloadShaderLabel = new Label(fontSize); reloadShaderLabel.setText("Reload all shaders"); reloadShaderButton.addChild(reloadShaderLabel); scrollable.addChild(reloadShaderButton); @@ -211,7 +215,7 @@ public class MenuGeneratorsInGame { //reload all models Button reloadModelButton = new Button(); - Label reloadModelLabel = new Label(100,450,fontSize); + Label reloadModelLabel = new Label(fontSize); reloadModelLabel.setText("Reload all models"); reloadModelButton.addChild(reloadModelLabel); scrollable.addChild(reloadModelButton); @@ -223,7 +227,7 @@ public class MenuGeneratorsInGame { //disable drawing player character Button toggleDrawPlayerButton = new Button(); - Label toggleDrawPlayerLabel = new Label(100,550,fontSize); + Label toggleDrawPlayerLabel = new Label(fontSize); toggleDrawPlayerLabel.setText("Toggle draw character"); toggleDrawPlayerButton.addChild(toggleDrawPlayerLabel); scrollable.addChild(toggleDrawPlayerButton); @@ -244,7 +248,7 @@ public class MenuGeneratorsInGame { //pull up character editor Button characterSliderMenuButton = new Button(); - Label characterSliderMenuLabel = new Label(100,650,fontSize); + Label characterSliderMenuLabel = new Label(fontSize); characterSliderMenuLabel.setText("Character slider menu"); characterSliderMenuButton.addChild(characterSliderMenuLabel); scrollable.addChild(characterSliderMenuButton); @@ -253,21 +257,9 @@ public class MenuGeneratorsInGame { return false; }}); - for(int i = 0; i < 5; i++){ - Button someButton = new Button(); - Label someLabel = new Label(100,750 + i * 100,fontSize); - someLabel.setText("aaaaaa" + i); - someButton.addChild(someLabel); - scrollable.addChild(someButton); - someButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - // Main.running = false; - return false; - }}); - } - //label (switch framebuffer) Button switchFramebufferButton = new Button(); - Label switchFramebufferLabel = new Label(100,1250,fontSize); + Label switchFramebufferLabel = new Label(fontSize); switchFramebufferLabel.setText("Switch Active Framebuffer"); switchFramebufferButton.addChild(switchFramebufferLabel); scrollable.addChild(switchFramebufferButton); @@ -279,7 +271,7 @@ public class MenuGeneratorsInGame { //label (toggle draw collision spheres) Button toggleCollisionSpheresButton = new Button(); - Label toggleCollisionSpheresLabel = new Label(100,1350,fontSize); + Label toggleCollisionSpheresLabel = new Label(fontSize); toggleCollisionSpheresLabel.setText("Toggle draw collision spheres"); toggleCollisionSpheresButton.addChild(toggleCollisionSpheresLabel); scrollable.addChild(toggleCollisionSpheresButton); @@ -291,7 +283,7 @@ public class MenuGeneratorsInGame { //label (toggle draw physics objects) Button togglePhysicsObjectsButton = new Button(); - Label togglePhysicsObjectsLabel = new Label(100,1450,fontSize); + Label togglePhysicsObjectsLabel = new Label(fontSize); togglePhysicsObjectsLabel.setText("Toggle draw physics objects"); togglePhysicsObjectsButton.addChild(togglePhysicsObjectsLabel); scrollable.addChild(togglePhysicsObjectsButton); @@ -303,7 +295,7 @@ public class MenuGeneratorsInGame { //label (toggle draw movement vectors) Button toggleMovementVectorsButton = new Button(); - Label toggleMovementVectorsLabel = new Label(100,1550,fontSize); + Label toggleMovementVectorsLabel = new Label(fontSize); toggleMovementVectorsLabel.setText("Toggle draw movement vectors"); toggleMovementVectorsButton.addChild(toggleMovementVectorsLabel); scrollable.addChild(toggleMovementVectorsButton); @@ -315,7 +307,7 @@ public class MenuGeneratorsInGame { //label (toggle draw navmesh) Button toggleNavmeshButton = new Button(); - Label toggleNavmeshLabel = new Label(100,1650,fontSize); + Label toggleNavmeshLabel = new Label(fontSize); toggleNavmeshLabel.setText("Toggle draw navmesh"); toggleNavmeshButton.addChild(toggleNavmeshLabel); scrollable.addChild(toggleNavmeshButton); @@ -325,6 +317,8 @@ public class MenuGeneratorsInGame { return false; }}); + rVal.applyYoga(); + return rVal; } @@ -332,7 +326,7 @@ public class MenuGeneratorsInGame { int width = 500; int height = 500; float fontSize = 0.4f; - Window rVal = new Window(0,0,width,height); + Window rVal = new Window(0,0,width,height,true); // int screenLeft = (Globals.WINDOW_WIDTH - width)/2; // Div div = new Div(); // div.setPositionX(0); @@ -356,7 +350,7 @@ public class MenuGeneratorsInGame { //label 1 (back) Button backButton = new Button(); - Label backLabel = new Label(200,50,fontSize); + Label backLabel = new Label(fontSize); backLabel.setText("Back"); backButton.addChild(backLabel); scrollable.addChild(backButton); @@ -388,6 +382,8 @@ public class MenuGeneratorsInGame { } } + rVal.applyYoga(); + return rVal; } diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java index 256614e6..dc4b366a 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java @@ -36,7 +36,7 @@ public class MenuGeneratorsInventory { int width = 500; int height = 500; - Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT); + Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); Div div = new Div(); rVal.addChild(div); @@ -200,7 +200,7 @@ public class MenuGeneratorsInventory { int width = 500; int height = 500; // int screenLeft = (Globals.WINDOW_WIDTH - width)/2; - Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT); + Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); Div div = new Div(); div.setPositionX(1000); @@ -367,7 +367,7 @@ public class MenuGeneratorsInventory { } public static Element worldItemDropCaptureWindow(){ - Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT); + Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); Div div = new Div(); div.setOnDragRelease(new DragEventCallback() {public boolean execute(DragEvent event){ if(Globals.draggedItem != null){ diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsArena.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsArena.java index 2798b304..29260805 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsArena.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsArena.java @@ -3,14 +3,13 @@ package electrosphere.menu.mainmenu; import electrosphere.auth.AuthenticationManager; import electrosphere.engine.Globals; import electrosphere.engine.loadingthreads.LoadingThread; -import electrosphere.net.NetUtils; import electrosphere.renderer.ui.elements.Button; +import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.TextInput; import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.ClickEvent; -import electrosphere.renderer.ui.form.FormElement; public class MenuGeneratorsArena { @@ -19,28 +18,32 @@ public class MenuGeneratorsArena { int screenTop = 150; //label (address) - Label usernameLabel = new Label(100,screenTop + 50,1.0f); + Label usernameLabel = new Label(1.0f); usernameLabel.setText("Username"); rVal.addChild(usernameLabel); //text entry (address) TextInput usernameInput = new TextInput(100,screenTop + 125,1.0f); usernameInput.setText(""); + usernameInput.setMinWidth(200); + usernameInput.setMaxWidth(200); rVal.addChild(usernameInput); //label (port) - Label passwordLabel = new Label(100,screenTop + 200,1.0f); + Label passwordLabel = new Label(1.0f); passwordLabel.setText("Password"); rVal.addChild(passwordLabel); //text entry (port) TextInput passwordInput = new TextInput(100,screenTop + 275,1.0f); passwordInput.setText(""); + passwordInput.setMinWidth(200); + passwordInput.setMaxWidth(200); rVal.addChild(passwordInput); //button (connect) Button connectButton = new Button(); - Label connectLabel = new Label(100,screenTop + 350,1.0f); + Label connectLabel = new Label(1.0f); connectLabel.setText("Login"); connectButton.addChild(connectLabel); rVal.addChild(connectButton); diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDebug.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDebug.java index 6c2dab08..8a021138 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDebug.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsDebug.java @@ -25,10 +25,10 @@ public class MenuGeneratorsDebug { static final int X_OFFSET = 1000; public static Window createTopLevelDebugMenu(){ - Window rVal = new Window(X_OFFSET,100,800,800); + Window rVal = new Window(X_OFFSET,100,800,800,true); //label (title) - Label titleLabel = new Label(100,50,1.0f); + Label titleLabel = new Label(1.0f); titleLabel.setText("DEBUG"); rVal.addChild(titleLabel); @@ -73,7 +73,7 @@ public class MenuGeneratorsDebug { } static int recursivelyAppendElementTree(List toAddList, int verticalOffset, int horizontalOffset, Element child){ - Label currentWindowLabel = new Label(100 + horizontalOffset * 25,100 + verticalOffset * 50,0.5f); + Label currentWindowLabel = new Label(0.5f); currentWindowLabel.setText(child.toString()); toAddList.add(currentWindowLabel); if(child instanceof ContainerElement){ diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java index d82f47ac..4fe66f20 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsLevelEditor.java @@ -2,17 +2,19 @@ package electrosphere.menu.mainmenu; import java.util.List; +import org.lwjgl.util.yoga.Yoga; + import electrosphere.engine.Globals; import electrosphere.engine.loadingthreads.LoadingThread; -import electrosphere.menu.MenuGenerators; import electrosphere.menu.WindowUtils; import electrosphere.renderer.ui.elements.Button; +import electrosphere.renderer.ui.elements.Div; +import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.TextInput; import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.ClickEvent; -import electrosphere.renderer.ui.form.FormElement; import electrosphere.server.saves.SaveUtils; /** @@ -26,17 +28,16 @@ public class MenuGeneratorsLevelEditor { */ public static Element createLevelEditorTopMenu(){ FormElement rVal = new FormElement(); - int screenTop = 150; //label (address) - Label usernameLabel = new Label(100,screenTop + 50,1.0f); + Label usernameLabel = new Label(1.0f); usernameLabel.setText("Select Level"); rVal.addChild(usernameLabel); //button (back) { Button backButton = new Button(); - Label backLabel = new Label(100,screenTop + 150,1.0f); + Label backLabel = new Label(1.0f); backLabel.setText("Back"); backButton.addChild(backLabel); rVal.addChild(backButton); @@ -49,7 +50,7 @@ public class MenuGeneratorsLevelEditor { //button (create level) { Button createLevelButton = new Button(); - Label createLevelLabel = new Label(100,screenTop + 225,1.0f); + Label createLevelLabel = new Label(1.0f); createLevelLabel.setText("Create Level"); createLevelButton.addChild(createLevelLabel); rVal.addChild(createLevelButton); @@ -62,29 +63,31 @@ public class MenuGeneratorsLevelEditor { //the buttons to load existing levels List saveNames = SaveUtils.getSaves(); - int i = 0; for(String saveName : saveNames){ - i++; + //containing div + Div div = new Div(); + div.setFlexDirection(Yoga.YGFlexDirectionRow); + div.setMaxHeight(30); //delete level button Button deleteButton = new Button(); - Label deleteLabel = new Label(100,screenTop + 225 + 75 * i,1.0f); - deleteLabel.setText("[X]"); + Label deleteLabel = new Label(1.0f); + deleteLabel.setText(" X "); deleteButton.addChild(deleteLabel); - rVal.addChild(deleteButton); + deleteButton.setMarginRight(10); deleteButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ SaveUtils.deleteSave(saveName); WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorTopMenu()); return false; }}); + div.addChild(deleteButton); //button (launch level) Button launchButton = new Button(); - Label launchLabel = new Label(200,screenTop + 225 + 75 * i,1.0f); + Label launchLabel = new Label(1.0f); launchLabel.setText(saveName); launchButton.addChild(launchLabel); - rVal.addChild(launchButton); launchButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ //launch level Globals.currentSaveName = saveName; @@ -95,6 +98,9 @@ public class MenuGeneratorsLevelEditor { loadingThread.start(); return false; }}); + div.addChild(launchButton); + + rVal.addChild(div); } return rVal; @@ -110,14 +116,14 @@ public class MenuGeneratorsLevelEditor { int screenTop = 150; //label (address) - Label usernameLabel = new Label(100,screenTop + 50,1.0f); + Label usernameLabel = new Label(1.0f); usernameLabel.setText("Create Level"); rVal.addChild(usernameLabel); //button (back) { Button backButton = new Button(); - Label backLabel = new Label(100,screenTop + 150,1.0f); + Label backLabel = new Label(1.0f); backLabel.setText("Back"); backButton.addChild(backLabel); rVal.addChild(backButton); @@ -129,7 +135,7 @@ public class MenuGeneratorsLevelEditor { //label for text input for level name { - Label levelNameLabel = new Label(100,screenTop + 225,1.0f); + Label levelNameLabel = new Label(1.0f); levelNameLabel.setText("Level Name:"); rVal.addChild(levelNameLabel); } @@ -140,6 +146,7 @@ public class MenuGeneratorsLevelEditor { String defaultSaveName = "defaultLevel_" + i; while(saveNames.contains(defaultSaveName)){ i++; + defaultSaveName = "defaultLevel_" + i; } //get level name @@ -150,7 +157,7 @@ public class MenuGeneratorsLevelEditor { //button (create level) { Button createLevelButton = new Button(); - Label createLevelLabel = new Label(100,screenTop + 375,1.0f); + Label createLevelLabel = new Label(1.0f); createLevelLabel.setText("Create Level"); createLevelButton.addChild(createLevelLabel); rVal.addChild(createLevelButton); diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java index 582cd3c5..87c57098 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsMultiplayer.java @@ -3,8 +3,8 @@ package electrosphere.menu.mainmenu; import java.util.LinkedList; import java.util.List; -import org.joml.Quaternionf; import org.joml.Vector3f; +import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.entity.types.camera.CameraEntityUtils; @@ -15,16 +15,14 @@ import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.menu.MenuGenerators; import electrosphere.menu.WindowUtils; import electrosphere.net.parser.net.message.CharacterMessage; -import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorUtils; -import electrosphere.renderer.actor.ActorStaticMorph.StaticMorphTransforms; import electrosphere.renderer.anim.Animation; -import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elements.ActorPanel; import electrosphere.renderer.ui.elements.Button; -import electrosphere.renderer.ui.elements.ImagePanel; +import electrosphere.renderer.ui.elements.Div; +import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.ScrollableContainer; import electrosphere.renderer.ui.elements.Slider; @@ -34,19 +32,16 @@ import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback; import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.ValueChangeEvent; -import electrosphere.renderer.ui.form.FormElement; import electrosphere.util.Utilities; public class MenuGeneratorsMultiplayer { public static Element createMultiplayerCharacterSelectionWindow(){ FormElement rVal = new FormElement(); - // int screenTop = Globals.WINDOW_HEIGHT - 150; - int verticalPosition = 125; //button (create) Button createButton = new Button(); - Label createLabel = new Label(100,125 + verticalPosition + 200,1.0f); + Label createLabel = new Label(1.0f); createLabel.setText("Create Character"); createButton.addChild(createLabel); rVal.addChild(createButton); @@ -61,8 +56,6 @@ public class MenuGeneratorsMultiplayer { static String selectedRace = ""; public static Element createMultiplayerCharacterCreationWindow(){ FormElement rVal = new FormElement(); - // int screenTop = Globals.WINDOW_HEIGHT - 150; - int verticalPosition = 125; //select race StringCarousel raceCarousel = new StringCarousel(100, 125, 1.0f); @@ -76,7 +69,7 @@ public class MenuGeneratorsMultiplayer { //button (create) Button createButton = new Button(); - Label createLabel = new Label(100,275,1.0f); + Label createLabel = new Label(1.0f); createLabel.setText("Select Race"); createButton.addChild(createLabel); rVal.addChild(createButton); @@ -121,7 +114,7 @@ public class MenuGeneratorsMultiplayer { for(VisualAttribute attribute : selectedRaceType.getVisualAttributes()){ if(attribute.getType().equals(VisualAttribute.TYPE_BONE)){ //add label for slider - Label sliderName = new Label(20, verticalPosition, 0.6f); + Label sliderName = new Label(0.6f); sliderName.setText(attribute.getAttributeId()); controlsToAdd.add(sliderName); //add a slider @@ -155,7 +148,7 @@ public class MenuGeneratorsMultiplayer { }}); } else if(attribute.getType().equals(VisualAttribute.TYPE_REMESH)){ //add label for carousel - Label sliderName = new Label(20, verticalPosition, 0.6f); + Label sliderName = new Label(0.6f); sliderName.setText(attribute.getAttributeId()); controlsToAdd.add(sliderName); //for adding the value to the creature template @@ -198,7 +191,7 @@ public class MenuGeneratorsMultiplayer { //add button to actually create the character Button createCharacterButton = new Button(); - Label createCharacterLabel = new Label(horizontalPosition,verticalPosition,1.0f); + Label createCharacterLabel = new Label(1.0f); createCharacterLabel.setText("Create"); createCharacterButton.addChild(createCharacterLabel); controlsToAdd.add(createCharacterButton); @@ -210,13 +203,18 @@ public class MenuGeneratorsMultiplayer { int width = 1800; int height = verticalPosition + 300; + Div rVal = new Div(); + rVal.setFlexDirection(Yoga.YGFlexDirectionRow); + ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height); for(Element newControl : controlsToAdd){ scrollable.addChild(newControl); } - scrollable.addChild(actorPanel); + + rVal.addChild(scrollable); + rVal.addChild(actorPanel); // rVal.addChild(scrollable); // Label testLabel = new Label(100,215,1.0f); @@ -227,7 +225,7 @@ public class MenuGeneratorsMultiplayer { // ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture); // scrollable.addChild(imagePanel); - return scrollable; + return rVal; } diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java index a63a9e29..6109922c 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java @@ -1,28 +1,35 @@ package electrosphere.menu.mainmenu; +import org.lwjgl.util.yoga.Yoga; + import electrosphere.engine.Globals; import electrosphere.engine.loadingthreads.LoadingThread; import electrosphere.menu.MenuGenerators; import electrosphere.menu.WindowUtils; import electrosphere.renderer.ui.elements.Button; +import electrosphere.renderer.ui.elements.FormElement; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.ClickEvent; -import electrosphere.renderer.ui.form.FormElement; public class MenuGeneratorsTitleMenu { public static Element createTitleMenu(){ FormElement rVal = new FormElement(); + //top-bottom + rVal.setJustifyContent(Yoga.YGJustifyCenter); + //left-right + rVal.setAlignItems(Yoga.YGAlignCenter); + rVal.setAlignContent(Yoga.YGAlignFlexStart); //label (title) - Label titleLabel = new Label(100,150,1.0f); + Label titleLabel = new Label(1.0f); titleLabel.setText("ORPG"); rVal.addChild(titleLabel); //button (multiplayer) Button singleplayerButton = new Button(); - Label singleplayerLabel = new Label(100,275,1.0f); + Label singleplayerLabel = new Label(1.0f); singleplayerLabel.setText("Singleplayer"); singleplayerButton.addChild(singleplayerLabel); rVal.addChild(singleplayerButton); @@ -38,7 +45,7 @@ public class MenuGeneratorsTitleMenu { //button (multiplayer) Button multiplayerButton = new Button(); - Label multiplayerLabel = new Label(100,350,1.0f); + Label multiplayerLabel = new Label(1.0f); multiplayerLabel.setText("Multiplayer"); multiplayerButton.addChild(multiplayerLabel); rVal.addChild(multiplayerButton); @@ -49,7 +56,7 @@ public class MenuGeneratorsTitleMenu { //button (arena) Button arenaButton = new Button(); - Label arenaLabel = new Label(100,425,1.0f); + Label arenaLabel = new Label(1.0f); arenaLabel.setText("Arena"); arenaButton.addChild(arenaLabel); rVal.addChild(arenaButton); @@ -65,7 +72,7 @@ public class MenuGeneratorsTitleMenu { //button (static level) Button staticLevelButton = new Button(); - Label staticLevelLabel = new Label(100,500,1.0f); + Label staticLevelLabel = new Label(1.0f); staticLevelLabel.setText("Level Editor"); staticLevelButton.addChild(staticLevelLabel); rVal.addChild(staticLevelButton); @@ -76,7 +83,7 @@ public class MenuGeneratorsTitleMenu { //button (options) Button optionsButton = new Button(); - Label optionsLabel = new Label(100,575,1.0f); + Label optionsLabel = new Label(1.0f); optionsLabel.setText("Options"); optionsButton.addChild(optionsLabel); rVal.addChild(optionsButton); @@ -87,7 +94,7 @@ public class MenuGeneratorsTitleMenu { //button (sp debug) Button uiDebugSPQuickstartButton = new Button(); - Label uiDebugSPQuickstartLabel = new Label(100,650,1.0f); + Label uiDebugSPQuickstartLabel = new Label(1.0f); uiDebugSPQuickstartLabel.setText("Debug SP Quickstart"); uiDebugSPQuickstartButton.addChild(uiDebugSPQuickstartLabel); rVal.addChild(uiDebugSPQuickstartButton); @@ -102,12 +109,12 @@ public class MenuGeneratorsTitleMenu { //button (ui testing) Button uiTestingButton = new Button(); - Label uiTestingLabel = new Label(100,725,1.0f); + Label uiTestingLabel = new Label(1.0f); uiTestingLabel.setText("UI Testing"); uiTestingButton.addChild(uiTestingLabel); rVal.addChild(uiTestingButton); uiTestingButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ - WindowUtils.replaceMainMenuContents(MenuGenerators.createUITestMenu()); + WindowUtils.replaceMainMenuContents(MenuGeneratorsUITesting.createUITestMenu()); return false; }}); diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java new file mode 100644 index 00000000..35144ad7 --- /dev/null +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java @@ -0,0 +1,68 @@ +package electrosphere.menu.mainmenu; + +import org.joml.Vector3f; + +import electrosphere.engine.Globals; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.menu.WindowUtils; +import electrosphere.renderer.actor.ActorUtils; +import electrosphere.renderer.ui.elements.ActorPanel; +import electrosphere.renderer.ui.elements.Button; +import electrosphere.renderer.ui.elements.FormElement; +import electrosphere.renderer.ui.elements.Label; +import electrosphere.renderer.ui.elements.Slider; +import electrosphere.renderer.ui.elements.VirtualScrollable; +import electrosphere.renderer.ui.elementtypes.ClickableElement; +import electrosphere.renderer.ui.elementtypes.Element; +import electrosphere.renderer.ui.events.ClickEvent; + +/** + * Menu generators for creating test visualizations for ui elements + */ +public class MenuGeneratorsUITesting { + + /** + * Title menu ui testing window + * @return + */ + public static Element createUITestMenu(){ + FormElement rVal = new FormElement(); + + //button (back) + Button backButton = new Button(); + Label backLabel = new Label(1.0f); + backLabel.setText("Back"); + backButton.addChild(backLabel); + rVal.addChild(backButton); + backButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu()); + return false; + }}); + + //slider test + Slider slider = new Slider(0, 0, 500, 100, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,0,0)); + rVal.addChild(slider); + + ActorPanel actorPanel = new ActorPanel(500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx")); + if(Globals.playerCamera == null){ + Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(-1,0,0)); + } + rVal.addChild(actorPanel); + + // + //Virtual scrollable test + VirtualScrollable virtualScrollable = new VirtualScrollable(300, 75); + //add a ton of children + for(int i = 0; i < 10; i++){ + Button testButton = new Button(); + Label testLabel = new Label(1.0f); + testLabel.setText("Test button " + i); + testButton.addChild(testLabel); + virtualScrollable.addChild(testButton); + } + rVal.addChild(virtualScrollable); + + return rVal; + } + +} diff --git a/src/main/java/electrosphere/net/server/Server.java b/src/main/java/electrosphere/net/server/Server.java index 3f556991..3c5fc8e0 100644 --- a/src/main/java/electrosphere/net/server/Server.java +++ b/src/main/java/electrosphere/net/server/Server.java @@ -69,6 +69,8 @@ public class Server implements Runnable{ ServerConnectionHandler newClient = new ServerConnectionHandler(newSocket); clientMap.put(newSocket.getInetAddress().getHostAddress(), newClient); new Thread(newClient).start(); + } catch (SocketException ex){ + LoggerInterface.loggerNetworking.ERROR("Socket closed!",ex); } catch (IOException ex) { LoggerInterface.loggerNetworking.ERROR("Socket error on client socket!",ex); } diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 9c73cb2a..ddf14ce0 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -306,13 +306,12 @@ public class RenderingEngine { Globals.WINDOW_HEIGHT = bufferHeight; // - // Attack controls callbacks + // Attach controls callbacks // //set key callback GLFW.glfwSetKeyCallback(Globals.window, Globals.controlCallback); - - //set mouse callback GLFW.glfwSetMouseButtonCallback(Globals.window, Globals.mouseCallback); + GLFW.glfwSetScrollCallback(Globals.window, Globals.scrollCallback); //get title bar dimensions // setTitleBarDimensions(); diff --git a/src/main/java/electrosphere/renderer/debug/DebugRendering.java b/src/main/java/electrosphere/renderer/debug/DebugRendering.java index 069e195b..71cd0303 100644 --- a/src/main/java/electrosphere/renderer/debug/DebugRendering.java +++ b/src/main/java/electrosphere/renderer/debug/DebugRendering.java @@ -34,11 +34,22 @@ public class DebugRendering { public static void drawUIBoundsWireframe(){ glDisable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + int parentPosX = 0; + int parentPosY = 0; for(Element currentElement : Globals.elementManager.getWindowList()){ if(currentElement instanceof DrawableElement){ DrawableElement drawable = (DrawableElement) currentElement; if(drawable.getVisible()){ - drawable.draw(Globals.renderingEngine.getRenderPipelineState(),Globals.renderingEngine.getOpenGLState(),RenderingEngine.GL_DEFAULT_FRAMEBUFFER, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + drawable.draw( + Globals.renderingEngine.getRenderPipelineState(), + Globals.renderingEngine.getOpenGLState(), + RenderingEngine.GL_DEFAULT_FRAMEBUFFER, + parentPosX, + parentPosY, + Globals.WINDOW_WIDTH, + Globals.WINDOW_HEIGHT + ); } } } diff --git a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java index 91169195..85aef5a7 100644 --- a/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/UIPipeline.java @@ -7,6 +7,7 @@ import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.texture.Texture; +import electrosphere.renderer.ui.Window; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; @@ -63,12 +64,16 @@ public class UIPipeline implements RenderPipeline { renderPipelineState.setUseBones(false); renderPipelineState.setUseLight(false); + //the initial parent position values + int parentPosX = 0; + int parentPosY = 0; + openGLState.glDepthTest(false); for(Element currentElement : Globals.elementManager.getWindowList()){ if(currentElement instanceof DrawableElement){ DrawableElement drawable = (DrawableElement) currentElement; if(drawable.getVisible()){ - drawable.draw(renderPipelineState, openGLState, RenderingEngine.GL_DEFAULT_FRAMEBUFFER, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + drawable.draw(renderPipelineState, openGLState, RenderingEngine.GL_DEFAULT_FRAMEBUFFER, parentPosX, parentPosY, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); } } } diff --git a/src/main/java/electrosphere/renderer/ui/ElementManager.java b/src/main/java/electrosphere/renderer/ui/ElementManager.java index 083177eb..e7a3de2c 100644 --- a/src/main/java/electrosphere/renderer/ui/ElementManager.java +++ b/src/main/java/electrosphere/renderer/ui/ElementManager.java @@ -1,6 +1,5 @@ package electrosphere.renderer.ui; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; @@ -19,7 +18,6 @@ import electrosphere.renderer.ui.events.DragEvent; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.HoverEvent; -import electrosphere.renderer.ui.events.MouseEvent; import electrosphere.renderer.ui.events.NavigationEvent; import electrosphere.renderer.ui.events.DragEvent.DragEventType; import electrosphere.renderer.ui.events.NavigationEvent.NavigationEventType; @@ -52,6 +50,10 @@ public class ElementManager { return elementMap.get(name); } + /** + * Gets the list of all registered windows + * @return The list of all registered windows + */ public List getWindowList(){ return elementList; } @@ -137,6 +139,24 @@ public class ElementManager { } } + /** + * Sets a specific element to be focused + * @param focusableElement The focusable element + */ + public void focusElement(FocusableElement focusableElement){ + if(currentFocusedElement != null){ + currentFocusedElement.handleEvent(new FocusEvent(false)); + } + this.currentFocusedElement = focusableElement; + focusableElement.handleEvent(new FocusEvent(true)); + } + + /** + * Fires an event at a given position + * @param event The event + * @param x the x coordinate of the position + * @param y the y coordinate of the position + */ public void fireEvent(Event event, int x, int y){ boolean propagate = true; ListIterator windowIterator = elementList.listIterator(elementList.size()); @@ -149,18 +169,32 @@ public class ElementManager { propagate = currentElement.handleEvent(event); } if(!propagate){ + currentWindow.applyYoga(); break; } } } + /** + * Recursively uilds a stack of elements at a given position based on their depth into the tree + * @param inputStack The empty stack to fill + * @param current The current element + * @param x the x position to query + * @param y the y position to query + * @param offsetX the x offset accumulated + * @param offsetY the y offset accumulated + * @return the stack, filled with all relevant elements + */ Stack buildElementPositionalStack(Stack inputStack, Element current, int x, int y, int offsetX, int offsetY){ inputStack.push(current); if(current instanceof ContainerElement){ + ContainerElement container = (ContainerElement)current; + int xLoc = x - container.getInternalX() - container.getChildOffsetX(); + int yLoc = y - container.getInternalY() - container.getChildOffsetY(); for(Element el : ((ContainerElement)current).getChildren()){ //if contains x,y, call function on el - if(elementContainsPoint(el,x,y)){ - buildElementPositionalStack(inputStack, el, x, y, offsetX + el.getPositionX(), offsetY + el.getPositionY()); + if(elementContainsPoint(el,xLoc,yLoc,offsetX,offsetY)){ + buildElementPositionalStack(inputStack, el, xLoc, yLoc, offsetX, offsetY); } } } @@ -212,12 +246,12 @@ public class ElementManager { * @param y the y component of the coordinate * @return True if it contains that point, false otherwise */ - boolean elementContainsPoint(Element el, int x, int y){ + boolean elementContainsPoint(Element el, int x, int y, int offsetX, int offsetY){ return - x >= el.getPositionX() && - x <= el.getPositionX() + el.getWidth() && - y >= el.getPositionY() && - y <= el.getPositionY() + el.getHeight(); + x >= el.getInternalX() + offsetX && + x <= el.getInternalX() + offsetX + el.getInternalWidth() && + y >= el.getInternalY() + offsetY && + y <= el.getInternalY() + offsetY + el.getInternalHeight(); } // public void click(MouseEvent event){ diff --git a/src/main/java/electrosphere/renderer/ui/WidgetUtils.java b/src/main/java/electrosphere/renderer/ui/WidgetUtils.java index 587ac85d..bd964811 100644 --- a/src/main/java/electrosphere/renderer/ui/WidgetUtils.java +++ b/src/main/java/electrosphere/renderer/ui/WidgetUtils.java @@ -124,7 +124,7 @@ public class WidgetUtils { int x = Globals.WINDOW_WIDTH - width; int y = Globals.WINDOW_HEIGHT - height; // Window rVal = new Window(x, 10, 100, 20); - Window rVal = new Window(x,y,width,height); + Window rVal = new Window(x,y,width,height,true); // Window rVal = new Window(100,100,100,100); // System.out.println(x + " " + y + " " + width + " " + height); // LayoutSchemeListScrollable rVal = new LayoutSchemeListScrollable(x, y, width, height, true); @@ -133,13 +133,13 @@ public class WidgetUtils { // Widget rVal = WidgetUtils.createTextBox(x, y, width, height, 4, 1, "MENU", true); //the actual "menu" label - Label menuLabel = new Label(0,0,0.3f); + Label menuLabel = new Label(0.3f); menuLabel.setText("Menu"); menuLabel.setVisible(true); rVal.addChild(menuLabel); //label telling player what key they have their menu bound to - Label keyCodeLabel = new Label(0,10,0.3f); + Label keyCodeLabel = new Label(0.3f); keyCodeLabel.setText(ControlHandler.convertKeycodeToName(Globals.controlHandler.getControl(ControlHandler.DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU).getKeyValue())); keyCodeLabel.setVisible(true); rVal.addChild(keyCodeLabel); @@ -152,7 +152,9 @@ public class WidgetUtils { public static Button createLabelButton(String label, int posX, int posY, float fontSize, ClickableElement.ClickEventCallback callback){ Button rVal = new Button(); - Label buttonLabel = new Label(posX,posY,fontSize); + Label buttonLabel = new Label(fontSize); + rVal.setPositionX(posX); + rVal.setPositionY(posY); buttonLabel.setText(label); rVal.addChild(buttonLabel); rVal.setOnClick(callback); diff --git a/src/main/java/electrosphere/renderer/ui/Window.java b/src/main/java/electrosphere/renderer/ui/Window.java index f78537ba..48f5168d 100644 --- a/src/main/java/electrosphere/renderer/ui/Window.java +++ b/src/main/java/electrosphere/renderer/ui/Window.java @@ -11,6 +11,9 @@ import java.util.LinkedList; import java.util.List; import org.joml.Vector3f; +import org.lwjgl.util.yoga.YGLayout; +import org.lwjgl.util.yoga.YGNode; +import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.logger.LoggerInterface; @@ -21,6 +24,7 @@ import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; +import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; @@ -29,8 +33,7 @@ import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.NavigationEvent; /** - * - * @author amaterasu + * A window */ public class Window implements DrawableElement, ContainerElement, NavigableElement { List childList = new LinkedList(); @@ -45,53 +48,91 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme NavigationEventCallback navCallback; static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,0.0f,0.0f); + + //controls whether to show window decorations (ie the frame) + boolean showDecorations = true; - public Window(int positionX, int positionY, int width, int height){ - //TODO: figure out why this has to be 1920x1080 + /** + * Constructor + * @param showDecorations + * @param positionX + * @param positionY + * @param width + * @param height + */ + public Window(int positionX, int positionY, int width, int height, boolean showDecorations){ widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); -// widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer(); customMat.setTexturePointer(widgetBuffer.getTexturePointer()); -// customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer()); float ndcWidth = (float)width/Globals.WINDOW_WIDTH; float ndcHeight = (float)height/Globals.WINDOW_HEIGHT; float ndcX = (float)positionX/Globals.WINDOW_WIDTH; float ndcY = (float)positionY/Globals.WINDOW_HEIGHT; - this.width = width; - this.height = height; boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); + this.showDecorations = showDecorations; + this.yogaNode = Yoga.YGNodeNew(); + this.layout = YGNode.create(this.yogaNode).layout(); + this.setWidth(width); + this.setHeight(height); } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { widgetBuffer.bind(); openGLState.glViewport(width, height); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //grab assets required to render window + Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); + Texture windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png"); for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),width,height); + drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),parentPosX,parentPosY,width,height); } } //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer); openGLState.glViewport(parentWidth, parentHeight); + + //error if assets are null + if(planeModel == null || windowFrame == null){ + LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model or window frame!!", new Exception()); + } + + //render background of window + if(planeModel != null && windowFrame != null && showDecorations){ + planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); + planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); + planeModel.pushUniformToMesh("plane", "tPosition", texPosition); + planeModel.pushUniformToMesh("plane", "tDimension", texScale); + customMat.setTexturePointer(windowFrame.getTexturePointer()); + planeModel.getMeshes().get(0).setMaterial(customMat); + planeModel.drawUI(); + } - Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); + //render content of window if(planeModel != null){ planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); + customMat.setTexturePointer(widgetBuffer.getTexturePointer()); planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); - } else { - LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model!!", new Exception()); } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_WINDOW){ @@ -99,13 +140,30 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme } } - public void pack() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + /** + * Destroys the element + */ + public void destroy(){ + for(Element el : getChildren()){ + el.destroy(); + } } - + + /** + * clears all children + */ + public void clear(){ + for(Element el : getChildren()){ + Yoga.YGNodeRemoveChild(this.yogaNode,el.getYogaNode()); + el.destroy(); + } + getChildren().clear(); + } + @Override public void setWidth(int width){ this.width = width; + Yoga.YGNodeStyleSetWidth(this.yogaNode, width); for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; @@ -118,6 +176,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme @Override public void setHeight(int height){ this.height = height; + Yoga.YGNodeStyleSetHeight(this.yogaNode, height); for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; @@ -126,6 +185,26 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme } } } + + @Override + public void setMaxWidth(int width) { + Yoga.YGNodeStyleSetMaxWidth(yogaNode, width); + } + + @Override + public void setMaxHeight(int height) { + Yoga.YGNodeStyleSetMaxHeight(yogaNode, height); + } + + @Override + public void setMinWidth(int width) { + Yoga.YGNodeStyleSetMinWidth(yogaNode, width); + } + + @Override + public void setMinHeight(int height) { + Yoga.YGNodeStyleSetMinHeight(yogaNode, height); + } // public void setTextureCoord(int x, int y){ // float ndcX = (float)x/Globals.WINDOW_WIDTH; @@ -147,6 +226,11 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme public int parentWidth = 1; public int parentHeight = 1; + + int marginTop = 0; + int marginRight = 0; + int marginBottom = 0; + int marginLeft = 0; public boolean visible = false; @@ -184,6 +268,38 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.positionY = positionY; } + public int getMarginTop(){ + return marginTop; + } + + public int getMarginRight(){ + return marginRight; + } + + public int getMarginBottom(){ + return marginBottom; + } + + public int getMarginLeft(){ + return marginLeft; + } + + public void setMarginTop(int marginTop){ + this.marginTop = marginTop; + } + + public void setMarginRight(int marginRight){ + this.marginRight = marginRight; + } + + public void setMarginBottom(int marginBottom){ + this.marginBottom = marginBottom; + } + + public void setMarginLeft(int marginLeft){ + this.marginLeft = marginLeft; + } + @Override public void setParentWidth(int width) { this.width = width; @@ -194,6 +310,62 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.height = height; } + //the yoga node id + long yogaNode = -1; + //the layout object + YGLayout layout; + + @Override + public long getYogaNode() { + return yogaNode; + } + + @Override + public void applyYoga() { + //calculate yoga layout + Yoga.YGNodeCalculateLayout(yogaNode, width, height, Yoga.YGFlexDirectionColumn); + //apply yoga values to all children + LoggerInterface.loggerUI.INFO("==Apply yoga to windoow=="); + for(Element child : this.getChildren()){ + child.applyYoga(); + } + // //get the values from yoga + // float leftRaw = layout.positions(Yoga.YGEdgeLeft); + // float topRaw = layout.positions(Yoga.YGEdgeTop); + // float widthRaw = layout.dimensions(Yoga.YGDimensionWidth); + // float heightRaw = layout.dimensions(Yoga.YGDimensionHeight); + // //apply the values to this component + // this.setPositionX((int)leftRaw + this.getMarginLeft()); + // this.setPositionY((int)topRaw + this.getMarginTop()); + // this.setWidth((int)widthRaw - this.getMarginLeft() - this.getMarginRight()); + // this.setHeight((int)heightRaw - this.getMarginTop() - this.getMarginBottom()); + } + + @Override + public void setDirection(int layout) { + Yoga.YGNodeStyleSetDirection(yogaNode, Yoga.YGFlexDirectionColumn); + } + + @Override + public void setFlexDirection(int layout){ + Yoga.YGNodeStyleSetFlexDirection(yogaNode, layout); + } + + @Override + public void setJustifyContent(int justification){ + Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justification); + } + + @Override + public void setAlignItems(int alignment){ + Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignment); + } + + @Override + public void setAlignContent(int alignment){ + Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignment); + } + @Override public void addChild(Element child) { childList.add(child); @@ -202,6 +374,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme drawableChild.setParentWidth(width); drawableChild.setParentHeight(height); drawableChild.setVisible(false); + Yoga.YGNodeInsertChild(yogaNode, drawableChild.getYogaNode(), childList.size() - 1); } } @@ -213,6 +386,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme @Override public void removeChild(Element child) { childList.remove(child); + Yoga.YGNodeRemoveChild(yogaNode, child.getYogaNode()); } public boolean handleEvent(Event event){ @@ -230,4 +404,44 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme navCallback = callback; } + @Override + public int getInternalX() { + return positionX; + } + + @Override + public int getInternalY() { + return positionY; + } + + @Override + public int getInternalWidth() { + return width; + } + + @Override + public int getInternalHeight() { + return height; + } + + @Override + public int getChildOffsetX(){ + return 0; + } + + @Override + public int getChildOffsetY(){ + return 0; + } + + @Override + public float getChildScaleX(){ + return 1; + } + + @Override + public float getChildScaleY(){ + return 1; + } + } diff --git a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java index 015482e6..e4a92857 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java @@ -2,20 +2,14 @@ package electrosphere.renderer.ui.elements; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; -import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_LESS; import static org.lwjgl.opengl.GL11.glClear; import static org.lwjgl.opengl.GL11.glClearColor; -import static org.lwjgl.opengl.GL11.glDepthFunc; import static org.lwjgl.opengl.GL11.glDepthMask; -import static org.lwjgl.opengl.GL11.glDisable; -import static org.lwjgl.opengl.GL11.glEnable; -import static org.lwjgl.opengl.GL11.glViewport; import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; import static org.lwjgl.opengl.GL30.glBindFramebuffer; import org.joml.Matrix4d; -import org.joml.Matrix4f; import org.joml.Quaterniond; import org.joml.Vector3d; import org.joml.Vector3f; @@ -37,7 +31,7 @@ import electrosphere.renderer.ui.events.DragEvent; import electrosphere.renderer.ui.events.DragEvent.DragEventType; import electrosphere.renderer.ui.events.Event; -public class ActorPanel implements DrawableElement, DraggableElement { +public class ActorPanel extends StandardElement implements DrawableElement, DraggableElement { Material customMat = new Material(); Framebuffer elementBuffer; @@ -62,6 +56,7 @@ public class ActorPanel implements DrawableElement, DraggableElement { static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,0.0f,1.0f); public ActorPanel(int x, int y, int width, int height, Actor actor){ + super(); elementBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); customMat.setTexturePointer(elementBuffer.getTexturePointer()); this.actor = actor; @@ -76,7 +71,15 @@ public class ActorPanel implements DrawableElement, DraggableElement { @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { elementBuffer.bind(); // Globals.renderingEngine.setViewportSize(width, height); @@ -144,10 +147,6 @@ public class ActorPanel implements DrawableElement, DraggableElement { Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - openGLState.setActiveShader( - renderPipelineState, - Globals.assetManager.fetchShader("Shaders/ui/windowContent/windowContent.vs", null, "Shaders/ui/windowContent/windowContent.fs") - ); @@ -156,7 +155,7 @@ public class ActorPanel implements DrawableElement, DraggableElement { // // Set rendering engine state // - renderPipelineState.setUseMeshShader(false); + renderPipelineState.setUseMeshShader(true); renderPipelineState.setBufferStandardUniforms(false); renderPipelineState.setBufferNonStandardUniforms(true); renderPipelineState.setUseMaterial(true); @@ -185,65 +184,18 @@ public class ActorPanel implements DrawableElement, DraggableElement { } } - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; public boolean visible = false; - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getPositionX() { - return positionX; - } - - public int getPositionY() { - return positionY; - } - - public boolean getVisible() { - return visible; - } - - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - public void setPositionY(int positionY) { - this.positionY = positionY; - } public void setVisible(boolean draw) { this.visible = draw; } - - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } + public boolean getVisible(){ + return this.visible; + } + public void setAnimation(String animation){ currentAnim = animation; } diff --git a/src/main/java/electrosphere/renderer/ui/font/bitmapchar/BitmapCharacter.java b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java similarity index 62% rename from src/main/java/electrosphere/renderer/ui/font/bitmapchar/BitmapCharacter.java rename to src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java index d66520b9..b40ff860 100644 --- a/src/main/java/electrosphere/renderer/ui/font/bitmapchar/BitmapCharacter.java +++ b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java @@ -1,4 +1,4 @@ -package electrosphere.renderer.ui.font.bitmapchar; +package electrosphere.renderer.ui.elements; import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; @@ -11,12 +11,12 @@ import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.font.Font; // import electrosphere.renderer.ui.font.FontUtils; import org.joml.Vector3f; +import org.lwjgl.util.yoga.Yoga; /** - * - * @author satellite + * A single character */ -public class BitmapCharacter implements DrawableElement { +public class BitmapCharacter extends StandardElement implements DrawableElement { String text; @@ -25,12 +25,19 @@ public class BitmapCharacter implements DrawableElement { Font font; - - public BitmapCharacter(Font font, int posX, int posY, int width, int height, char toDraw){ - this.positionX = posX; - this.positionY = posY; - this.width = width; - this.height = height; + /** + * Constructor + * @param font + * @param posX + * @param posY + * @param width + * @param height + * @param toDraw + */ + public BitmapCharacter(Font font, int width, int height, char toDraw){ + super(); + setWidth(width); + setHeight(height); this.text = "" + toDraw; this.font = font; } @@ -51,13 +58,21 @@ public class BitmapCharacter implements DrawableElement { @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight){ + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ){ Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); openGLState.glViewport(parentWidth, parentHeight); - float ndcX = (float)positionX/parentWidth; - float ndcY = (float)positionY/parentHeight;// + (float)Globals.WINDOW_TITLE_BAR_HEIGHT/parentHeight; - float ndcWidth = (float)width/parentWidth; - float ndcHeight = (float)height/parentHeight; + float ndcX = (float)(internalPositionX + parentPosX)/parentWidth; + float ndcY = (float)(parentHeight - (internalPositionY + parentPosY))/parentHeight; + float ndcWidth = (float)internalWidth/parentWidth; + float ndcHeight = (float)internalHeight/parentHeight; // float charWidth = ndcWidth/cols; // float charHeight = ndcHeight/rows; char toDraw = text.charAt(0); @@ -82,68 +97,29 @@ public class BitmapCharacter implements DrawableElement { charModel.drawUI(); } } - - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; public boolean visible = false; - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getPositionX() { - return positionX; - } - - public int getPositionY() { - return positionY; - } - public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - public void setPositionY(int positionY) { - this.positionY = positionY; - } - public void setVisible(boolean draw) { this.visible = draw; } - - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } public boolean handleEvent(Event event){ return true; } + + @Override + public void applyYoga() { + //get the values from yoga + float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); + float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); + //apply the values to this component + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Button.java b/src/main/java/electrosphere/renderer/ui/elements/Button.java index 13c0eb3f..66f6d349 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Button.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Button.java @@ -1,16 +1,17 @@ package electrosphere.renderer.ui.elements; -import java.util.LinkedList; -import java.util.List; - import org.joml.Vector3f; +import org.lwjgl.opengl.GL30; import electrosphere.engine.Globals; +import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.debug.DebugRendering; +import electrosphere.renderer.model.Material; +import electrosphere.renderer.model.Model; +import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.elementtypes.ClickableElement; -import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.FocusableElement; @@ -21,19 +22,14 @@ import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.HoverEvent; import electrosphere.renderer.ui.events.MouseEvent; -public class Button implements DrawableElement, FocusableElement, ContainerElement, ClickableElement, HoverableElement { +public class Button extends StandardContainerElement implements DrawableElement, FocusableElement, ClickableElement, HoverableElement { - List childList = new LinkedList(); + Vector3f boxPosition = new Vector3f(); + Vector3f boxDimensions = new Vector3f(); + Vector3f texPosition = new Vector3f(0,0,0); + Vector3f texScale = new Vector3f(1,1,0); + Material customMat = new Material(); - int width = -1; - int height = -1; - - int positionX = -1; - int positionY = -1; - - int parentWidth = 1; - int parentHeight = 1; - boolean visible = false; boolean focused = false; @@ -44,140 +40,18 @@ public class Button implements DrawableElement, FocusableElement, ContainerEleme static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f); - public int getWidth() { - if(width == -1){ - int minX = -1; - int maxX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - if(maxX == -1){ - maxX = child.getPositionX() + child.getWidth(); - } else if(child.getPositionX() + child.getWidth() > maxX){ - maxX = child.getPositionX() + child.getWidth(); - } - } - if(minX == -1){ - minX = 0; - } - if(maxX == -1){ - maxX = 0; - } - return maxX - minX; - } else { - return width; - } - } - - public int getHeight() { - if(height == -1){ - int minY = -1; - int maxY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - if(maxY == -1){ - maxY = child.getPositionY() + child.getHeight(); - } else if(child.getPositionY() + child.getHeight() > maxY){ - maxY = child.getPositionY() + child.getHeight(); - } - } - if(minY == -1){ - minY = 0; - } - if(maxY == -1){ - maxY = 0; - } - return maxY - minY; - } else { - return height; - } - } - - public int getPositionX() { - if(positionX == -1){ - int minX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - } - if(minX == -1){ - minX = 0; - } - return minX; - } else { - return positionX; - } - } - - public int getPositionY() { - if(positionY == -1){ - int minY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - } - if(minY == -1){ - minY = 0; - } - return minY; - } else { - return positionY; - } + public Button(){ + super(); } public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int posX) { - int deltaX = posX - getPositionX(); - this.positionX = posX; - for(Element child : childList){ - child.setPositionX(child.getPositionX() + deltaX); - } - } - - public void setPositionY(int posY) { - int deltaY = posY - getPositionY(); - this.positionY = posY; - for(Element child : childList){ - child.setPositionY(child.getPositionY() + deltaY); - } - } - public void setVisible(boolean draw) { this.visible = draw; } - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - @Override public boolean isFocused() { return focused; @@ -231,46 +105,81 @@ public class Button implements DrawableElement, FocusableElement, ContainerEleme } } - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { + + // + //Draw decorations + + float ndcWidth = (float)getWidth()/parentWidth; + float ndcHeight = (float)getHeight()/parentHeight; + float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; + float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + boxPosition = new Vector3f(ndcX,ndcY,0); + boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); + + Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); + Texture windowFrame = null; + if(this.isFocused()){ + windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame2.png"); + } else { + windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png"); + } + + //this call binds the screen as the "texture" we're rendering to + //have to call before actually rendering + GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer); + openGLState.glViewport(parentWidth, parentHeight); + + //error if assets are null + if(planeModel == null || windowFrame == null){ + LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model or window frame!!", new Exception()); + } + + //render background of window + if(planeModel != null && windowFrame != null){ + planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); + planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); + planeModel.pushUniformToMesh("plane", "tPosition", texPosition); + planeModel.pushUniformToMesh("plane", "tDimension", texScale); + customMat.setTexturePointer(windowFrame.getTexturePointer()); + planeModel.getMeshes().get(0).setMaterial(customMat); + planeModel.drawUI(); + } + + + // + //Draw children elements + for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,parentFramebufferPointer,parentWidth,parentHeight); + child.setPositionX(this.internalPositionX); + child.setPositionY(this.internalPositionY); + drawableChild.draw( + renderPipelineState, + openGLState, + parentFramebufferPointer, + parentPosX + this.internalPositionX, + parentPosY + this.internalPositionY, + parentWidth, + parentHeight + ); } } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_BUTTON){ - float ndcX = (float)positionX/parentWidth; - float ndcY = (float)positionY/parentHeight; - float ndcWidth = (float)getWidth()/parentWidth; - float ndcHeight = (float)getHeight()/parentHeight; - Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); - Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); } } - @Override - public void addChild(Element child) { - childList.add(child); - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); - drawableChild.setVisible(false); - } - } - - @Override - public List getChildren() { - return childList; - } - - @Override - public void removeChild(Element child) { - childList.remove(child); - } - @Override public void setOnFocus(FocusEventCallback callback) { onFocusCallback = callback; diff --git a/src/main/java/electrosphere/renderer/ui/elements/Div.java b/src/main/java/electrosphere/renderer/ui/elements/Div.java index d52ef00e..c159c440 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Div.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Div.java @@ -1,256 +1,47 @@ package electrosphere.renderer.ui.elements; -import java.util.LinkedList; -import java.util.List; - import org.joml.Vector3f; +import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.debug.DebugRendering; import electrosphere.renderer.ui.elementtypes.ClickableElement; -import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DraggableElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; -import electrosphere.renderer.ui.elementtypes.FocusableElement; import electrosphere.renderer.ui.elementtypes.NavigableElement; import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.DragEvent; import electrosphere.renderer.ui.events.DragEvent.DragEventType; import electrosphere.renderer.ui.events.Event; -import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.NavigationEvent; -public class Div implements ClickableElement,ContainerElement,DraggableElement,FocusableElement,DrawableElement,NavigableElement { +public class Div extends StandardContainerElement implements ClickableElement,DraggableElement,DrawableElement,NavigableElement { ClickEventCallback onClick; - FocusEventCallback onFocus; - FocusEventCallback onLoseFocus; DragEventCallback onDragStart; DragEventCallback onDrag; DragEventCallback onDragRelease; NavigationEventCallback onNavigate; boolean focused = false; - List childList = new LinkedList(); - - public int width = -1; - public int height = -1; - - public int positionX = -1; - public int positionY = -1; - - public int parentWidth = 1; - public int parentHeight = 1; public boolean visible = false; static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f); - @Override - public int getWidth() { - if(width == -1){ - if(childList.size() > 0){ - int minX = -1; - int maxX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - if(maxX == -1){ - maxX = child.getPositionX() + child.getWidth(); - } else if(child.getPositionX() + child.getWidth() > maxX){ - maxX = child.getPositionX() + child.getWidth(); - } - } - if(minX == -1){ - minX = 0; - } - if(maxX == -1){ - maxX = 0; - } - return maxX - minX; - } else { - return 1; - } - } else { - return width; - } + public Div(){ + super(); + Yoga.YGNodeStyleSetFlex(yogaNode, 1.0f); } - @Override - public int getHeight() { - if(height == -1){ - if(childList.size() > 0){ - int minY = -1; - int maxY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - if(maxY == -1){ - maxY = child.getPositionY() + child.getHeight(); - } else if(child.getPositionY() + child.getHeight() > maxY){ - maxY = child.getPositionY() + child.getHeight(); - } - } - if(minY == -1){ - minY = 0; - } - if(maxY == -1){ - maxY = 0; - } - return maxY - minY; - } else { - return 1; - } - } else { - return height; - } - } - - @Override - public int getPositionX() { - if(positionX == -1){ - if(childList.size() > 0){ - int minX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - } - if(minX == -1){ - minX = 0; - } - return minX; - } else { - return 0; - } - } else { - return positionX; - } - } - - @Override - public int getPositionY() { - if(positionY == -1){ - if(childList.size() > 0){ - int minY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - } - if(minY == -1){ - minY = 0; - } - return minY; - } else { - return 0; - } - } else { - return positionY; - } - } - - @Override - public void setWidth(int width) { - this.width = width; - } - - @Override - public void setHeight(int height) { - this.height = height; - } - - @Override - public void setPositionX(int posX) { - int deltaX = posX - getPositionX(); - this.positionX = posX; - for(Element child : childList){ - child.setPositionX(child.getPositionX() + deltaX); - } - } - @Override - - public void setPositionY(int posY) { - int deltaY = posY - getPositionY(); - this.positionY = posY; - for(Element child : childList){ - child.setPositionY(child.getPositionY() + deltaY); - } - } - - @Override - public void setParentWidth(int width) { - this.parentWidth = width; - } - - @Override - public void setParentHeight(int height) { - this.parentHeight = height; - } - - - - - - @Override - public void addChild(Element child) { - childList.add(child); - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); - drawableChild.setVisible(false); - } - } - - @Override - public List getChildren() { - return childList; - } - - @Override - public void removeChild(Element child) { - childList.remove(child); - } - - - - - - public void setFocus(boolean focus){ this.focused = focus; } - @Override - public boolean isFocused() { - return focused; - } - - @Override - public void setOnFocus(FocusEventCallback callback) { - this.onFocus = callback; - } - - @Override - public void setOnLoseFocus(FocusEventCallback callback) { - this.onLoseFocus = callback; - } - @Override public void setOnDragStart(DragEventCallback callback) { this.onDragStart = callback; @@ -284,20 +75,6 @@ public class Div implements ClickableElement,ContainerElement,DraggableElement,F } } } - if(onFocus != null){ - if(event instanceof FocusEvent){ - if(!onFocus.execute((FocusEvent)event)){ - propagate = false; - } - } - } - if(onLoseFocus != null){ - if(event instanceof FocusEvent){ - if(!onLoseFocus.execute((FocusEvent)event)){ - propagate = false; - } - } - } if(event instanceof DragEvent){ if(onDragStart != null && ((DragEvent)event).getType() == DragEventType.START){ if(!onDragStart.execute((DragEvent)event)){ @@ -336,11 +113,19 @@ public class Div implements ClickableElement,ContainerElement,DraggableElement,F } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,parentFramebufferPointer,parentWidth,parentHeight); + drawableChild.draw(renderPipelineState,openGLState,parentFramebufferPointer,parentPosX + this.internalPositionX,parentPosY + this.internalPositionY,parentWidth,parentHeight); } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/FormElement.java b/src/main/java/electrosphere/renderer/ui/elements/FormElement.java new file mode 100644 index 00000000..ed6f4557 --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/elements/FormElement.java @@ -0,0 +1,68 @@ +package electrosphere.renderer.ui.elements; + +import org.lwjgl.util.yoga.Yoga; + +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.ui.elementtypes.DrawableElement; +import electrosphere.renderer.ui.elementtypes.Element; +import electrosphere.renderer.ui.events.Event; + +public class FormElement extends StandardContainerElement implements DrawableElement { + + public boolean visible = false; + + public boolean focused = false; + + public FormElement(){ + super(); + Yoga.YGNodeStyleSetFlex(yogaNode, 1.0f); + } + + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { + for(Element child : childList){ + if(child instanceof DrawableElement){ + DrawableElement drawableChild = (DrawableElement) child; + drawableChild.draw(renderPipelineState,openGLState,parentFramebufferPointer,parentPosX + this.internalPositionX,parentPosY + this.internalPositionY,parentWidth,parentHeight); + } + } + } + + public void onFocus(){ + } + + public boolean getVisible() { + return visible; + } + + public boolean isFocused(){ + return focused; + } + + public void setVisible(boolean draw) { + this.visible = draw; + for(Element child : childList){ + if(child instanceof DrawableElement){ + DrawableElement drawableChild = (DrawableElement) child; + drawableChild.setVisible(draw); + } + } + } + + public void setFocused(boolean focused){ + this.focused = focused; + } + + public boolean handleEvent(Event event){ + return true; + } + +} diff --git a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java index ce04f7a4..59358862 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java @@ -23,7 +23,7 @@ import electrosphere.renderer.ui.events.Event; * * @author amaterasu */ -public class ImagePanel implements DrawableElement, DraggableElement { +public class ImagePanel extends StandardElement implements DrawableElement, DraggableElement { public static String imagePanelModelPath; @@ -43,6 +43,7 @@ public class ImagePanel implements DrawableElement, DraggableElement { static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,0.5f,1.0f); public ImagePanel(int x, int y, int width, int height, String texturePath){ + super(); this.texturePath = texturePath; texture = Globals.assetManager.fetchTexture(this.texturePath); if(texture != null){ @@ -68,7 +69,15 @@ public class ImagePanel implements DrawableElement, DraggableElement { @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { if(!hasLoadedTexture){ texture = Globals.assetManager.fetchTexture(this.texturePath); if(texture != null){ @@ -105,65 +114,16 @@ public class ImagePanel implements DrawableElement, DraggableElement { } } - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; - public boolean visible = false; - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getPositionX() { - return positionX; - } - - public int getPositionY() { - return positionY; - } - public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - public void setPositionY(int positionY) { - this.positionY = positionY; - } - public void setVisible(boolean draw) { this.visible = draw; } - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - public boolean handleEvent(Event event){ boolean propagate = true; if(event instanceof DragEvent){ diff --git a/src/main/java/electrosphere/renderer/ui/elements/Label.java b/src/main/java/electrosphere/renderer/ui/elements/Label.java index a762b814..aaf285d6 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Label.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Label.java @@ -1,9 +1,7 @@ package electrosphere.renderer.ui.elements; -import java.util.LinkedList; -import java.util.List; - import org.joml.Vector3f; +import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.renderer.OpenGLState; @@ -13,23 +11,12 @@ import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.font.Font; -import electrosphere.renderer.ui.font.FontUtils; -import electrosphere.renderer.ui.font.bitmapchar.BitmapCharacter; /** * * @author amaterasu */ -public class Label implements DrawableElement { - - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; +public class Label extends StandardContainerElement implements DrawableElement { public boolean visible = false; @@ -39,31 +26,44 @@ public class Label implements DrawableElement { float fontSize = 1.0f; - List childrenElements = new LinkedList(); - static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,1.0f,1.0f); Font font; + + public Label(float fontSize){ + super(); + this.font = Globals.fontManager.getFont("default"); + setHeight((int)(font.getFontHeight() * fontSize)); + this.fontSize = fontSize; + Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow); + } public Label(int x, int y, float fontSize){ - this.positionX = x; - this.positionY = y; - this.width = 0; + super(); + this.setPositionX(x); + this.setPositionY(y); this.font = Globals.fontManager.getFont("default"); - this.height = (int)(font.getFontHeight() * fontSize); + setHeight((int)(font.getFontHeight() * fontSize)); this.fontSize = fontSize; + Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow); } void generateLetters(){ - childrenElements.clear(); - int rollingOffset = 0; + //free children + for(Element child : childList){ + Yoga.YGNodeFree(child.getYogaNode()); + } + childList.clear(); + int accumulatingWidth = 0; for(int i = 0; i < text.length(); i++){ char toDraw = text.charAt(i); Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw); - BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(rollingOffset * fontSize) + positionX, positionY, (int)(bitMapDimension.x * fontSize), this.height, toDraw); - rollingOffset += (int)bitMapDimension.x; - childrenElements.add(newLetter); + BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.height, toDraw); + accumulatingWidth += bitMapDimension.x * fontSize; + childList.add(newLetter); + Yoga.YGNodeInsertChild(yogaNode, newLetter.getYogaNode(), childList.size() - 1); } + Yoga.YGNodeStyleSetWidth(yogaNode, accumulatingWidth); } public void setText(String text){ @@ -77,8 +77,8 @@ public class Label implements DrawableElement { } public void setColor(Vector3f color){ - for(BitmapCharacter character : childrenElements){ - character.setColor(color); + for(Element character : childList){ + ((BitmapCharacter)character).setColor(color); } } @@ -87,140 +87,46 @@ public class Label implements DrawableElement { } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { - for(DrawableElement child : childrenElements){ - child.draw(renderPipelineState,openGLState,parentFramebufferPointer, parentWidth, parentHeight); + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { + for(Element child : childList){ + ((DrawableElement)child).draw( + renderPipelineState, + openGLState, + parentFramebufferPointer, + parentPosX + this.internalPositionX, + parentPosY + this.internalPositionY, + parentWidth, + parentHeight + ); } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_LABEL){ - float ndcX = (float)positionX/parentWidth; - float ndcY = (float)positionY/parentHeight; - float ndcWidth = (float)getWidth()/parentWidth; - float ndcHeight = (float)getHeight()/parentHeight; + float ndcX = (float)(positionX)/parentWidth; + float ndcY = (float)(positionY)/parentHeight; + float ndcWidth = (float)internalWidth/parentWidth; + float ndcHeight = (float)internalHeight/parentHeight; Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); } } - public int getWidth() { - int minX = -1; - int maxX = -1; - for(BitmapCharacter child : childrenElements){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - if(maxX == -1){ - maxX = child.getPositionX() + child.getWidth(); - } else if(child.getPositionX() + child.getWidth() > maxX){ - maxX = child.getPositionX() + child.getWidth(); - } - } - if(minX == -1){ - minX = 0; - } - if(maxX == -1){ - maxX = 0; - } - return maxX - minX; - } - - public int getHeight() { - int minY = -1; - int maxY = -1; - for(BitmapCharacter child : childrenElements){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - if(maxY == -1){ - maxY = child.getPositionY() + child.getHeight(); - } else if(child.getPositionY() + child.getHeight() > maxY){ - maxY = child.getPositionY() + child.getHeight(); - } - } - if(minY == -1){ - minY = 0; - } - if(maxY == -1){ - maxY = 0; - } - return maxY - minY; - } - - public int getPositionX() { - int minX = -1; - for(BitmapCharacter child : childrenElements){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - } - if(minX == -1){ - minX = 0; - } - return minX; - } - - public int getPositionY() { - int minY = -1; - for(BitmapCharacter child : childrenElements){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - } - if(minY == -1){ - minY = 0; - } - return minY; - } - public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int posX) { - int deltaX = posX - this.positionX; - this.positionX = posX; - for(Element child : childrenElements){ - child.setPositionX(child.getPositionX() + deltaX); - } - } - - public void setPositionY(int posY) { - int deltaY = posY - this.positionY; - this.positionY = posY; - for(Element child : childrenElements){ - child.setPositionY(child.getPositionY() + deltaY); - } - } - public void setVisible(boolean draw) { this.visible = draw; } - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - public boolean handleEvent(Event event){ return true; } diff --git a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java index 706c701d..b17befb8 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java @@ -1,9 +1,5 @@ package electrosphere.renderer.ui.elements; -import java.util.LinkedList; -import java.util.List; - -import org.joml.Vector2f; import org.joml.Vector3f; import electrosphere.engine.Globals; @@ -14,6 +10,7 @@ import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; +import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; @@ -22,31 +19,22 @@ import electrosphere.renderer.ui.events.Event; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL30.*; -public class ScrollableContainer implements DrawableElement, ContainerElement { +public class ScrollableContainer extends StandardContainerElement implements DrawableElement { boolean focused = false; - List childList = new LinkedList(); - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; - public boolean visible = false; Framebuffer widgetBuffer; Material customMat = new Material(); Vector3f boxPosition = new Vector3f(); Vector3f boxDimensions = new Vector3f(); - Vector3f texPosition = new Vector3f(0,1,0); - Vector3f texScale = new Vector3f(1,-1,0); + Vector3f texPosition = new Vector3f(0,0,0); + Vector3f texScale = new Vector3f(1,1,0); public ScrollableContainer(int positionX, int positionY, int width, int height){ + super(); widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); // widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer(); customMat.setTexturePointer(widgetBuffer.getTexturePointer()); @@ -55,108 +43,14 @@ public class ScrollableContainer implements DrawableElement, ContainerElement { float ndcY = (float)positionY/Globals.WINDOW_HEIGHT; float ndcWidth = (float)width/Globals.WINDOW_WIDTH; float ndcHeight = (float)height/Globals.WINDOW_HEIGHT; - this.width = width; - this.height = height; + setWidth(width); + setHeight(height); boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); } - @Override - public int getWidth() { - return width; - } - - @Override - public int getHeight() { - return height; - } - - @Override - public int getPositionX() { - return positionX; - } - - @Override - public int getPositionY() { - return positionY; - } - - @Override - public void setWidth(int width) { - this.width = width; - } - - @Override - public void setHeight(int height) { - this.height = height; - } - - @Override - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - @Override - public void setPositionY(int positionY) { - this.positionY = positionY; - } - - @Override - public void setParentWidth(int width) { - parentWidth = width; - float ndcX = (float)positionX/parentWidth; - float ndcY = (float)positionY/parentHeight; - float ndcWidth = (float)width/parentWidth; - float ndcHeight = (float)height/parentHeight; - boxPosition = new Vector3f(ndcX,ndcY,0); - boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - } - - @Override - public void setParentHeight(int height) { - parentHeight = height; - float ndcX = (float)positionX/parentWidth; - float ndcY = (float)positionY/parentHeight; - float ndcWidth = (float)width/parentWidth; - float ndcHeight = (float)height/parentHeight; - boxPosition = new Vector3f(ndcX,ndcY,0); - boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - } - - - - - - @Override - public void addChild(Element child) { - childList.add(child); - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); - drawableChild.setVisible(false); - } - } - - @Override - public List getChildren() { - return childList; - } - - @Override - public void removeChild(Element child) { - childList.remove(child); - } - - - - - - - - @Override public boolean handleEvent(Event event) { return false; @@ -189,7 +83,15 @@ public class ScrollableContainer implements DrawableElement, ContainerElement { } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { //figure out if currently focused element is a child or subchild of this container if(containsFocusedElement(this)){ //if it is, if it is offscreen, calculate offset to put it onscreen @@ -235,9 +137,20 @@ public class ScrollableContainer implements DrawableElement, ContainerElement { } } + float ndcX = (float)internalPositionX/parentWidth; + float ndcY = (float)internalPositionY/parentHeight; + float ndcWidth = (float)internalWidth/parentWidth; + float ndcHeight = (float)internalHeight/parentHeight; + boxPosition = new Vector3f(ndcX,ndcY,0); + boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); + + //grab assets required to render window + Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); + Texture windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png"); + widgetBuffer.bind(); -// Globals.renderingEngine.setViewportSize(width, height); + openGLState.glViewport(width, height); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -245,20 +158,31 @@ public class ScrollableContainer implements DrawableElement, ContainerElement { for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),width,height); + drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),0,0,width,height); } } //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer); openGLState.glViewport(parentWidth, parentHeight); + + //render background of window + if(planeModel != null && windowFrame != null){ + planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); + planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); + planeModel.pushUniformToMesh("plane", "tPosition", texPosition); + planeModel.pushUniformToMesh("plane", "tDimension", texScale); + customMat.setTexturePointer(windowFrame.getTexturePointer()); + planeModel.getMeshes().get(0).setMaterial(customMat); + planeModel.drawUI(); + } - Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); if(planeModel != null){ planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tDimension", texScale); + customMat.setTexturePointer(widgetBuffer.getTexturePointer()); planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.drawUI(); } else { diff --git a/src/main/java/electrosphere/renderer/ui/elements/Slider.java b/src/main/java/electrosphere/renderer/ui/elements/Slider.java index 6a228cde..b3f99d04 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Slider.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Slider.java @@ -22,17 +22,8 @@ import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.MenuEvent; import electrosphere.renderer.ui.events.ValueChangeEvent; -public class Slider implements ClickableElement, DraggableElement, FocusableElement, DrawableElement, MenuEventElement, ValueElement { +public class Slider extends StandardElement implements ClickableElement, DraggableElement, FocusableElement, DrawableElement, MenuEventElement, ValueElement { - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; - public boolean visible = false; boolean focused = false; @@ -61,6 +52,7 @@ public class Slider implements ClickableElement, DraggableElement, FocusableElem public Slider(int positionX, int positionY, int width, int height, Vector3f colorBackground, Vector3f colorForeground){ + super(); this.positionX = positionX; this.positionY = positionY; this.width = width; @@ -72,7 +64,15 @@ public class Slider implements ClickableElement, DraggableElement, FocusableElem @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { Globals.renderingEngine.bindFramebuffer(parentFramebufferPointer); openGLState.glViewport(parentWidth, parentHeight); @@ -153,58 +153,18 @@ public class Slider implements ClickableElement, DraggableElement, FocusableElem this.value = value; } - public int getWidth() { - return width; - } - float getValueAsPercentage(){ return (value - min) / (max - min); } - public int getHeight() { - return height; - } - - public int getPositionX() { - return positionX; - } - - public int getPositionY() { - return positionY; - } - public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int posX) { - this.positionX = posX; - } - - public void setPositionY(int posY) { - this.positionY = posY; - } - public void setVisible(boolean draw) { this.visible = draw; } - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - @Override public boolean isFocused() { return focused; diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java new file mode 100644 index 00000000..b0add0c0 --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java @@ -0,0 +1,260 @@ +package electrosphere.renderer.ui.elements; + +import java.util.LinkedList; +import java.util.List; + +import org.lwjgl.util.yoga.Yoga; + +import electrosphere.logger.LoggerInterface; +import electrosphere.renderer.ui.elementtypes.ContainerElement; +import electrosphere.renderer.ui.elementtypes.DrawableElement; +import electrosphere.renderer.ui.elementtypes.Element; + +/** + * An element that contains other elements + */ +public class StandardContainerElement extends StandardElement implements ContainerElement { + + List childList = new LinkedList(); + + @Override + public int getWidth() { + if(width == -1){ + if(childList.size() > 0){ + int minX = -1; + int maxX = -1; + for(Element child : childList){ + if(minX == -1){ + minX = child.getPositionX(); + } else if(child.getPositionX() < minX){ + minX = child.getPositionX(); + } + if(maxX == -1){ + maxX = child.getPositionX() + child.getWidth(); + } else if(child.getPositionX() + child.getWidth() > maxX){ + maxX = child.getPositionX() + child.getWidth(); + } + } + if(minX == -1){ + minX = 0; + } + if(maxX == -1){ + maxX = 0; + } + return maxX - minX; + } else { + return 1; + } + } else { + return width; + } + } + + @Override + public int getHeight() { + if(height == -1){ + if(childList.size() > 0){ + int minY = -1; + int maxY = -1; + for(Element child : childList){ + if(minY == -1){ + minY = child.getPositionY(); + } else if(child.getPositionY() < minY){ + minY = child.getPositionY(); + } + if(maxY == -1){ + maxY = child.getPositionY() + child.getHeight(); + } else if(child.getPositionY() + child.getHeight() > maxY){ + maxY = child.getPositionY() + child.getHeight(); + } + } + if(minY == -1){ + minY = 0; + } + if(maxY == -1){ + maxY = 0; + } + return maxY - minY; + } else { + return 1; + } + } else { + return height; + } + } + + @Override + public int getPositionX() { + if(positionX == -1){ + if(childList.size() > 0){ + int minX = -1; + for(Element child : childList){ + if(minX == -1){ + minX = child.getPositionX(); + } else if(child.getPositionX() < minX){ + minX = child.getPositionX(); + } + } + if(minX == -1){ + minX = 0; + } + return minX; + } else { + return internalPositionX; + } + } else { + return internalPositionX; + } + } + + @Override + public int getPositionY() { + if(positionY == -1){ + if(childList.size() > 0){ + int minY = -1; + for(Element child : childList){ + if(minY == -1){ + minY = child.getPositionY(); + } else if(child.getPositionY() < minY){ + minY = child.getPositionY(); + } + } + if(minY == -1){ + minY = 0; + } + return minY; + } else { + return internalPositionY; + } + } else { + return internalPositionY; + } + } + + @Override + public void setWidth(int width) { + this.width = width; + } + + @Override + public void setHeight(int height) { + this.height = height; + } + + @Override + public void setPositionX(int posX) { + int deltaX = posX - getPositionX(); + this.positionX = posX; + for(Element child : childList){ + child.setPositionX(child.getPositionX() + deltaX); + } + } + @Override + + public void setPositionY(int posY) { + int deltaY = posY - getPositionY(); + this.positionY = posY; + for(Element child : childList){ + child.setPositionY(child.getPositionY() + deltaY); + } + } + + @Override + public void setDirection(int layout) { + Yoga.YGNodeStyleSetDirection(yogaNode, layout); + } + + @Override + public void setFlexDirection(int layout){ + Yoga.YGNodeStyleSetFlexDirection(yogaNode, layout); + } + + @Override + public void addChild(Element child) { + childList.add(child); + if(child instanceof DrawableElement){ + DrawableElement drawableChild = (DrawableElement) child; + drawableChild.setParentWidth(width); + drawableChild.setParentHeight(height); + drawableChild.setVisible(true); + Yoga.YGNodeInsertChild(yogaNode, drawableChild.getYogaNode(), childList.size() - 1); + } + } + + @Override + public List getChildren() { + return childList; + } + + @Override + public void removeChild(Element child) { + childList.remove(child); + } + + @Override + public int getChildOffsetX(){ + return 0; + } + + @Override + public int getChildOffsetY(){ + return 0; + } + + @Override + public float getChildScaleX(){ + return 1; + } + + @Override + public float getChildScaleY(){ + return 1; + } + + @Override + public void destroy(){ + for(Element child : childList){ + child.destroy(); + } + Yoga.YGNodeFree(this.yogaNode); + } + + @Override + public void applyYoga() { + //apply yoga values to all children + for(Element child : this.getChildren()){ + child.applyYoga(); + } + //get the values from yoga + float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); + float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); + float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); + float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); + LoggerInterface.loggerUI.INFO("" + this); + LoggerInterface.loggerUI.INFO(topRaw + " " + leftRaw + " " + heightRaw + " " + widthRaw); + //apply the values to this component + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + this.internalWidth = (int)widthRaw; + this.internalHeight = (int)heightRaw; + } + + @Override + public void setJustifyContent(int justification){ + Yoga.YGNodeStyleSetJustifyContent(this.yogaNode, justification); + } + + @Override + public void setAlignItems(int alignment){ + Yoga.YGNodeStyleSetAlignItems(this.yogaNode, alignment); + } + + @Override + public void setAlignContent(int alignment){ + Yoga.YGNodeStyleSetAlignContent(this.yogaNode, alignment); + } + + + + +} diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java new file mode 100644 index 00000000..c98f736d --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java @@ -0,0 +1,180 @@ +package electrosphere.renderer.ui.elements; + +import org.lwjgl.util.yoga.Yoga; + +import electrosphere.renderer.ui.elementtypes.Element; +import electrosphere.renderer.ui.events.Event; + +/** + * An implementation of element + */ +public class StandardElement implements Element { + + //these are set by the + public int width = -1; + public int height = -1; + public int positionX = -1; + public int positionY = -1; + + public int parentWidth = 1; + public int parentHeight = 1; + + int internalWidth; + int internalHeight; + int internalPositionX; + int internalPositionY; + + public boolean visible = false; + + //the yoga node id + long yogaNode = -1; + + /** + * Constructor + */ + protected StandardElement(){ + this.yogaNode = Yoga.YGNodeNew(); + } + + @Override + public int getWidth() { + return width; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public int getPositionX() { + return internalPositionX; + } + + @Override + public int getPositionY() { + return internalPositionY; + } + + @Override + public void setWidth(int width) { + this.internalWidth = width; + this.width = width; + Yoga.YGNodeStyleSetWidth(this.yogaNode, width); + } + + @Override + public void setHeight(int height) { + this.internalHeight = height; + this.height = height; + Yoga.YGNodeStyleSetHeight(this.yogaNode, height); + } + + @Override + public void setPositionX(int posX) { + this.positionX = posX; + } + @Override + + public void setPositionY(int posY) { + this.positionY = posY; + } + + @Override + public void setParentWidth(int width) { + this.parentWidth = width; + } + + @Override + public void setParentHeight(int height) { + this.parentHeight = height; + } + + public void setMarginTop(int marginTop){ + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeTop, marginTop); + } + + public void setMarginRight(int marginRight){ + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeRight, marginRight); + } + + public void setMarginBottom(int marginBottom){ + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeBottom, marginBottom); + } + + public void setMarginLeft(int marginLeft){ + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeLeft, marginLeft); + } + + public int getInternalX(){ + return internalPositionX; + } + + public int getInternalY(){ + return internalPositionY; + } + + public int getInternalWidth(){ + return internalWidth; + } + + + public int getInternalHeight(){ + return internalHeight; + } + + @Override + public void destroy(){ + Yoga.YGNodeFree(this.yogaNode); + } + + @Override + public long getYogaNode() { + return yogaNode; + } + + @Override + public void applyYoga() { + //get the values from yoga + float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); + float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); + float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); + float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); + //apply the values to this component + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + this.internalWidth = (int)widthRaw; + this.internalHeight = (int)heightRaw; + } + + + + + + @Override + public boolean handleEvent(Event event) { + boolean propagate = true; + return propagate; + } + + @Override + public void setMaxWidth(int width) { + Yoga.YGNodeStyleSetMaxWidth(yogaNode, width); + } + + @Override + public void setMaxHeight(int height) { + Yoga.YGNodeStyleSetMaxHeight(yogaNode, height); + } + + @Override + public void setMinWidth(int width) { + Yoga.YGNodeStyleSetMinWidth(yogaNode, width); + } + + @Override + public void setMinHeight(int height) { + Yoga.YGNodeStyleSetMinHeight(yogaNode, height); + } + +} diff --git a/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java b/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java index 8ec58daf..7fd03acb 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StringCarousel.java @@ -4,6 +4,7 @@ import java.util.LinkedList; import java.util.List; import org.joml.Vector3f; +import org.lwjgl.util.yoga.Yoga; import electrosphere.engine.Globals; import electrosphere.renderer.OpenGLState; @@ -19,19 +20,8 @@ import electrosphere.renderer.ui.events.MenuEvent; import electrosphere.renderer.ui.events.ValueChangeEvent; import electrosphere.renderer.ui.events.MenuEvent.MenuEventType; import electrosphere.renderer.ui.font.Font; -import electrosphere.renderer.ui.font.FontUtils; -import electrosphere.renderer.ui.font.bitmapchar.BitmapCharacter; -public class StringCarousel implements DrawableElement, MenuEventElement, FocusableElement, ValueElement { - - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; +public class StringCarousel extends StandardContainerElement implements DrawableElement, MenuEventElement, FocusableElement, ValueElement { public boolean visible = false; @@ -49,17 +39,14 @@ public class StringCarousel implements DrawableElement, MenuEventElement, Focusa float fontSize = 1.0f; - List childrenElements = new LinkedList(); - Font font; public StringCarousel(int x, int y, float fontSize){ - this.positionX = x; - this.positionY = y; - this.width = 0; + super(); this.font = Globals.fontManager.getFont("default"); - this.height = (int)(font.getFontHeight() * fontSize); this.fontSize = fontSize; + Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.imageHeight * fontSize); + Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1); } public void addOption(String option){ @@ -85,14 +72,16 @@ public class StringCarousel implements DrawableElement, MenuEventElement, Focusa } void generateLetters(){ - childrenElements.clear(); - int rollingOffset = 0; + for(Element el : getChildren()){ + Yoga.YGNodeRemoveChild(this.yogaNode,el.getYogaNode()); + el.destroy(); + } + childList.clear(); for(int i = 0; i < textCurrent.length(); i++){ char toDraw = textCurrent.charAt(i); Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw); - BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(rollingOffset * fontSize) + positionX, positionY, (int)(bitMapDimension.x * fontSize), this.height, toDraw); - rollingOffset += (int)bitMapDimension.x; - childrenElements.add(newLetter); + BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.height, toDraw); + addChild(newLetter); } } @@ -110,8 +99,8 @@ public class StringCarousel implements DrawableElement, MenuEventElement, Focusa } public void setColor(Vector3f color){ - for(BitmapCharacter character : childrenElements){ - character.setColor(color); + for(Element character : childList){ + ((BitmapCharacter)character).setColor(color); } } @@ -120,130 +109,28 @@ public class StringCarousel implements DrawableElement, MenuEventElement, Focusa } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { - for(DrawableElement child : childrenElements){ - child.draw(renderPipelineState, openGLState, parentFramebufferPointer, parentWidth, parentHeight); + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { + for(Element child : childList){ + ((DrawableElement)child).draw(renderPipelineState, openGLState, parentFramebufferPointer, parentPosX + this.internalPositionX, parentPosY + this.internalPositionY, parentWidth, parentHeight); } } - public int getWidth() { - int minX = -1; - int maxX = -1; - for(BitmapCharacter child : childrenElements){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - if(maxX == -1){ - maxX = child.getPositionX() + child.getWidth(); - } else if(child.getPositionX() + child.getWidth() > maxX){ - maxX = child.getPositionX() + child.getWidth(); - } - } - if(minX == -1){ - minX = 0; - } - if(maxX == -1){ - maxX = 0; - } - return maxX - minX; - } - - public int getHeight() { - int minY = -1; - int maxY = -1; - for(BitmapCharacter child : childrenElements){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - if(maxY == -1){ - maxY = child.getPositionY() + child.getHeight(); - } else if(child.getPositionY() + child.getHeight() > maxY){ - maxY = child.getPositionY() + child.getHeight(); - } - } - if(minY == -1){ - minY = 0; - } - if(maxY == -1){ - maxY = 0; - } - return maxY - minY; - } - - public int getPositionX() { - int minX = -1; - for(BitmapCharacter child : childrenElements){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - } - if(minX == -1){ - minX = 0; - } - return minX; - } - - public int getPositionY() { - int minY = -1; - for(BitmapCharacter child : childrenElements){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - } - if(minY == -1){ - minY = 0; - } - return minY; - } - public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int posX) { - int deltaX = posX - this.positionX; - this.positionX = posX; - for(Element child : childrenElements){ - child.setPositionX(child.getPositionX() + deltaX); - } - } - - public void setPositionY(int posY) { - int deltaY = posY - this.positionY; - this.positionY = posY; - for(Element child : childrenElements){ - child.setPositionY(child.getPositionY() + deltaY); - } - } - public void setVisible(boolean draw) { this.visible = draw; } - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - public boolean handleEvent(Event event){ boolean propagate = true; if(event instanceof MenuEvent){ diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java index 4d63fa46..01afb263 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextBox.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextBox.java @@ -1,16 +1,12 @@ package electrosphere.renderer.ui.elements; -import electrosphere.engine.Globals; -import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.events.Event; -import electrosphere.renderer.ui.font.FontUtils; import org.joml.Vector3f; -public class TextBox implements DrawableElement { +public class TextBox extends StandardContainerElement implements DrawableElement { String text; @@ -19,19 +15,13 @@ public class TextBox implements DrawableElement { Vector3f scalar; public TextBox(int positionX, int positionY, int width, int height, String text, boolean render, boolean editable) { - this.positionX = positionX; - this.positionY = positionY; - this.width = width; - this.height = height; + super(); this.text = text; scalar = new Vector3f(1,1,1); } public TextBox(int positionX, int positionY, int width, int height, String text, boolean render, boolean editable, Vector3f scalar) { - this.positionX = positionX; - this.positionY = positionY; - this.width = width; - this.height = height; + super(); this.text = text; this.scalar = scalar; } @@ -54,7 +44,15 @@ public class TextBox implements DrawableElement { @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight){ + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ){ throw new UnsupportedOperationException("Transparent Text box draw function not implemented yet oop"); // float ndcX = (float)positionX/Globals.WINDOW_WIDTH; // float ndcY = (float)positionY/Globals.WINDOW_HEIGHT; @@ -86,65 +84,14 @@ public class TextBox implements DrawableElement { // } } - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; - - public boolean visible = false; - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getPositionX() { - return positionX; - } - - public int getPositionY() { - return positionY; - } - public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - public void setPositionY(int positionY) { - this.positionY = positionY; - } - public void setVisible(boolean draw) { this.visible = draw; } - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - public boolean handleEvent(Event event){ return true; } diff --git a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java index f581881f..d309ea1e 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/TextInput.java +++ b/src/main/java/electrosphere/renderer/ui/elements/TextInput.java @@ -1,47 +1,39 @@ package electrosphere.renderer.ui.elements; import electrosphere.engine.Globals; -import electrosphere.engine.assetmanager.AssetDataStrings; +import electrosphere.logger.LoggerInterface; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.framebuffer.Framebuffer; -import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.model.Material; import electrosphere.renderer.model.Model; import electrosphere.renderer.texture.Texture; +import electrosphere.renderer.ui.elementtypes.ClickableElement; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.FocusableElement; import electrosphere.renderer.ui.elementtypes.KeyEventElement; +import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.events.FocusEvent; import electrosphere.renderer.ui.events.KeyboardEvent; import electrosphere.renderer.ui.font.Font; -import electrosphere.renderer.ui.font.FontUtils; -import electrosphere.renderer.ui.font.bitmapchar.BitmapCharacter; import org.joml.Vector3f; -import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; -import static org.lwjgl.opengl.GL30.glBindFramebuffer; +import org.lwjgl.opengl.GL30; +import org.lwjgl.util.yoga.Yoga; -import java.util.LinkedList; -import java.util.List; import java.util.regex.Pattern; /** - * - * @author amaterasu + * A Text input */ -public class TextInput implements DrawableElement, FocusableElement, KeyEventElement { - - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; +public class TextInput extends StandardContainerElement implements DrawableElement, FocusableElement, KeyEventElement, ClickableElement { + + Vector3f boxPosition = new Vector3f(); + Vector3f boxDimensions = new Vector3f(); + Vector3f texPosition = new Vector3f(0,0,0); + Vector3f texScale = new Vector3f(1,1,0); + Material customMat = new Material(); public boolean visible = false; @@ -49,6 +41,7 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle FocusEventCallback onFocusCallback; FocusEventCallback onLoseFocusCallback; KeyboardEventCallback onKeyPressCallback; + ClickEventCallback onClickCallback; Vector3f color; String text = ""; @@ -56,30 +49,38 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle float fontSize = 1.0f; - List childrenElements = new LinkedList(); Font font; + /** + * Constructor + * @param x + * @param y + * @param fontSize + */ public TextInput(int x, int y, float fontSize){ - this.positionX = x; - this.positionY = y; - this.width = 0; + super(); this.font = Globals.fontManager.getFont("default"); - this.height = (int)(this.font.getFontHeight() * fontSize); this.fontSize = fontSize; this.color = new Vector3f(1,1,1); + setHeight((int)(font.getFontHeight() * fontSize)); + Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow); + Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.imageHeight * fontSize); + Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1); } void generateLetters(){ - childrenElements.clear(); - int rollingOffset = 0; + for(Element el : getChildren()){ + Yoga.YGNodeRemoveChild(this.yogaNode,el.getYogaNode()); + el.destroy(); + } + childList.clear(); for(int i = 0; i < text.length(); i++){ char toDraw = text.charAt(i); Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw); - BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(rollingOffset * fontSize) + positionX, positionY, (int)(bitMapDimension.x * fontSize), this.height, toDraw); + BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.height, toDraw); newLetter.setColor(color); - rollingOffset += (int)bitMapDimension.x; - childrenElements.add(newLetter); + this.addChild(newLetter); } } @@ -95,8 +96,8 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle public void setColor(Vector3f color){ this.color.set(color); - for(BitmapCharacter character : childrenElements){ - character.setColor(color); + for(Element character : childList){ + ((BitmapCharacter)character).setColor(color); } } @@ -105,138 +106,70 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle } @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { - for(DrawableElement child : childrenElements){ - child.draw(renderPipelineState, openGLState, parentFramebufferPointer, parentWidth, parentHeight); - } - } + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { + // + //Draw decorations - public int getWidth() { - int minX = -1; - int maxX = -1; - for(BitmapCharacter child : childrenElements){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - if(maxX == -1){ - maxX = child.getPositionX() + child.getWidth(); - } else if(child.getPositionX() + child.getWidth() > maxX){ - maxX = child.getPositionX() + child.getWidth(); - } + float ndcWidth = (float)getInternalWidth()/parentWidth; + float ndcHeight = (float)getInternalHeight()/parentHeight; + float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; + float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + boxPosition = new Vector3f(ndcX,ndcY,0); + boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); + + Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); + Texture windowFrame = null; + if(this.isFocused()){ + windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame2.png"); + } else { + windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png"); } - if(minX == -1){ - minX = 0; - } - if(maxX == -1){ - maxX = 0; - } - return maxX - minX; - } - public int getHeight() { - int minY = -1; - int maxY = -1; - for(BitmapCharacter child : childrenElements){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - if(maxY == -1){ - maxY = child.getPositionY() + child.getHeight(); - } else if(child.getPositionY() + child.getHeight() > maxY){ - maxY = child.getPositionY() + child.getHeight(); - } - } - if(minY == -1){ - minY = 0; - } - if(maxY == -1){ - maxY = 0; - } - return maxY - minY; - } + //this call binds the screen as the "texture" we're rendering to + //have to call before actually rendering + GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer); + openGLState.glViewport(parentWidth, parentHeight); - public int getPositionX() { - int minX = -1; - for(BitmapCharacter child : childrenElements){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } + //error if assets are null + if(planeModel == null || windowFrame == null){ + LoggerInterface.loggerRenderer.ERROR("Window unable to find plane model or window frame!!", new Exception()); } - if(minX == -1){ - if(positionX == 0){ - minX = 0; - } else { - minX = positionX; - } - } - return minX; - } - public int getPositionY() { - int minY = -1; - for(BitmapCharacter child : childrenElements){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } + //render background of window + if(planeModel != null && windowFrame != null){ + planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); + planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); + planeModel.pushUniformToMesh("plane", "tPosition", texPosition); + planeModel.pushUniformToMesh("plane", "tDimension", texScale); + customMat.setTexturePointer(windowFrame.getTexturePointer()); + planeModel.getMeshes().get(0).setMaterial(customMat); + planeModel.drawUI(); } - if(minY == -1){ - if(positionY == 0){ - minY = 0; - } else { - minY = positionY; - } + + + // + //Draw children elements + for(Element child : childList){ + ((DrawableElement)child).draw(renderPipelineState, openGLState, parentFramebufferPointer, parentPosX + this.internalPositionX, parentPosY + this.internalPositionY, parentWidth, parentHeight); } - return minY; } public boolean getVisible() { return visible; } - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int posX) { - int deltaX = posX - this.positionX; - this.positionX = posX; - for(Element child : childrenElements){ - child.setPositionX(child.getPositionX() + deltaX); - } - } - - public void setPositionY(int posY) { - int deltaY = posY - this.positionY; - this.positionY = posY; - for(Element child : childrenElements){ - child.setPositionY(child.getPositionY() + deltaY); - } - } - public void setVisible(boolean draw) { this.visible = draw; } - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - public boolean handleEvent(Event event){ boolean propagate = true; if(event instanceof FocusEvent){ @@ -245,6 +178,7 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle if(this.onFocusCallback != null){ this.onFocusCallback.execute(focusEvent); } else { + this.focused = true; this.setColor(new Vector3f(1,0,0)); propagate = false; } @@ -252,6 +186,7 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle if(this.onLoseFocusCallback != null){ this.onLoseFocusCallback.execute(focusEvent); } else { + this.focused = false; this.setColor(new Vector3f(1,1,1)); propagate = false; } @@ -270,6 +205,14 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle } propagate = false; } + } else if(event instanceof ClickEvent){ + ClickEvent clickEvent = (ClickEvent)event; + if(onClickCallback != null){ + onClickCallback.execute(clickEvent); + } else { + Globals.elementManager.focusElement(this); + propagate = false; + } } return propagate; } @@ -293,5 +236,10 @@ public class TextInput implements DrawableElement, FocusableElement, KeyEventEle public void setOnPress(KeyboardEventCallback callback) { onKeyPressCallback = callback; } + + @Override + public void setOnClick(ClickEventCallback callback) { + onClickCallback = callback; + } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java b/src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java new file mode 100644 index 00000000..e5dacf9e --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java @@ -0,0 +1,151 @@ +package electrosphere.renderer.ui.elements; + +import org.lwjgl.util.yoga.Yoga; + +import electrosphere.renderer.OpenGLState; +import electrosphere.renderer.RenderPipelineState; +import electrosphere.renderer.ui.elementtypes.DrawableElement; +import electrosphere.renderer.ui.elementtypes.Element; +import electrosphere.renderer.ui.elementtypes.ScrollableElement; +import electrosphere.renderer.ui.events.Event; +import electrosphere.renderer.ui.events.ScrollEvent; + +/** + * A scrollable container that renders to it's parent framebuffer instead of a dedicated one + */ +public class VirtualScrollable extends StandardContainerElement implements DrawableElement, ScrollableElement { + + //the current amount of scroll applied to this element + double scroll = 0; + + //the scrollable callback + ScrollEventCallback callback; + + //should we draw this element + boolean visible = true; + + /** + * Constructor + */ + public VirtualScrollable(int width, int height){ + super(); + setWidth(width); + setHeight(height); + Yoga.YGNodeStyleSetOverflow(this.yogaNode, Yoga.YGOverflowScroll); + } + + @Override + public void draw( + RenderPipelineState renderPipelineState, + OpenGLState openGLState, + int parentFramebufferPointer, + int parentPosX, + int parentPosY, + int parentWidth, + int parentHeight + ) { + for(Element child : childList){ + if(child instanceof DrawableElement){ + DrawableElement drawableChild = (DrawableElement) child; + if(childIsInBounds(drawableChild)){ + drawableChild.draw( + renderPipelineState, + openGLState, + parentFramebufferPointer, + parentPosX + internalPositionX, + (int)(parentPosY + internalPositionY + scroll), + parentWidth, + parentHeight + ); + } + } + } + } + + /** + * Checks if a given child element should be visible + * @param element the element + * @return true if visible, false otherwise + */ + private boolean childIsInBounds(DrawableElement element){ + boolean rVal = true; + if(element.getInternalY() + scroll < 0 ||element.getInternalY() + scroll > this.height){ + return false; + } + return rVal; + } + + @Override + public boolean getVisible() { + return visible; + } + + @Override + public void setVisible(boolean draw) { + this.visible = draw; + } + + @Override + public void setWidth(int width) { + this.internalWidth = width; + this.width = width; + Yoga.YGNodeStyleSetWidth(this.yogaNode, width); + } + + @Override + public void setHeight(int height) { + this.internalHeight = height; + this.height = height; + Yoga.YGNodeStyleSetHeight(this.yogaNode, height); + } + + @Override + public int getChildOffsetY(){ + return (int)scroll; + } + + @Override + public void setOnScrollCallback(ScrollEventCallback callback) { + this.callback = callback; + } + + /** + * Default handling for the scroll event + * @param event The scroll event + */ + private void defaultScrollHandling(ScrollEvent event){ + scroll = scroll + event.getScrollAmount(); + if(scroll > 0){ + scroll = 0; + } + //calculate max scroll + double maxScroll = 0; + for(Element child : this.getChildren()){ + if(child.getInternalY() + child.getInternalHeight() > maxScroll){ + maxScroll = child.getInternalY() + child.getInternalHeight() - this.internalHeight; + } + } + if(scroll < - maxScroll){ + scroll = -maxScroll; + } + for(Element childElement : this.getChildren()){ + childElement.setPositionX((int)(childElement.getInternalX() + scroll)); + } + } + + @Override + public boolean handleEvent(Event event){ + boolean propagate = true; + if(event instanceof ScrollEvent){ + ScrollEvent scrollEvent = (ScrollEvent)event; + if(callback != null){ + propagate = callback.execute(scrollEvent); + } else { + defaultScrollHandling(scrollEvent); + propagate = false; + } + } + return propagate; + } + +} diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java b/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java index 01373814..422dbb80 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/ContainerElement.java @@ -2,12 +2,66 @@ package electrosphere.renderer.ui.elementtypes; import java.util.List; +/** + * An element that can contain other elements (label, button, div, etc) + */ public interface ContainerElement extends Element { + /** + * Add a child element to this element + * @param child The child element + */ public void addChild(Element child); + /** + * Gets the list of children elements + * @return The list of child elements + */ public List getChildren(); + /** + * Removes a child from this element + * @param child The child + */ public void removeChild(Element child); + + //gets the offset applied to all children + //ie if you scrolled up, how much are the children offset by that + public int getChildOffsetX(); + public int getChildOffsetY(); + + //Gets the scaling applied to all children + public float getChildScaleX(); + public float getChildScaleY(); + + /** + * Sets the flex layout order of this component + * @param layout The order + */ + public void setDirection(int layout); + + /** + * Sets the flex direction + * @param layout the flex direction + */ + public void setFlexDirection(int layout); + + /** + * Sets the content justification of the container + * @param justification The spacing value + */ + public void setJustifyContent(int justification); + + /** + * Sets the item alignment + * @param alignment The alignment style + */ + public void setAlignItems(int alignment); + + /** + * Sets the content alignment + * @param alignment the alignment style + */ + public void setAlignContent(int alignment); } diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java b/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java index e1ae59ef..d4953da2 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/DrawableElement.java @@ -4,16 +4,33 @@ import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; /** - * - * @author amaterasu + * A UI Element that is actually drawable to the screen */ public interface DrawableElement extends Element { + /** + * Gets if the drawable is currently set to visible + * @return true if visible, false otherwise + */ public boolean getVisible(); + /** + * Sets the visibility status of the element + * @param draw true for visible, false otherwise + */ public void setVisible(boolean draw); - public abstract void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight); + /** + * Draws the element + * @param renderPipelineState The render pipeline state + * @param openGLState The opengl state + * @param parentFramebufferPointer The parent's framebuffer pointer + * @param parentPosX the parent's position x + * @param parentPosY the parent's position y + * @param parentWidth the parent's width + * @param parentHeight the parent's height + */ + public abstract void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentPosX, int parentPosY, int parentWidth, int parentHeight); } diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java index b2eff429..e8e38eea 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java @@ -3,27 +3,84 @@ package electrosphere.renderer.ui.elementtypes; import electrosphere.renderer.ui.events.Event; public interface Element { - + + //width and height public int getWidth(); - public int getHeight(); - - public int getPositionX(); - - public int getPositionY(); - public void setWidth(int width); - public void setHeight(int height); + public void setMaxWidth(int width); + public void setMaxHeight(int height); + public void setMinWidth(int width); + public void setMinHeight(int height); + //position + public int getPositionX(); + public int getPositionY(); public void setPositionX(int positionX); - public void setPositionY(int positionY); + //parent data public void setParentWidth(int width); - public void setParentHeight(int height); + //margin + public void setMarginTop(int marginTop); + public void setMarginRight(int marginRight); + public void setMarginBottom(int marginBottom); + public void setMarginLeft(int marginLeft); + + + + + // + // I N T E R N A L + // + /** + * Gets the internal x position. This is the position x value used by the layout manager. It corresponds to what is actually displayed. + * @return The internal position x coordinate + */ + public int getInternalX(); + /** + * Gets the internal y position. This is the position y value used by the layout manager. It corresponds to what is actually displayed. + * @return The internal position y coordinate + */ + public int getInternalY(); + /** + * Gets the internal width. This is the width value used by the layout manager. It corresponds to what is actually displayed. + * @return The internal width + */ + public int getInternalWidth(); + /** + * Gets the internal height. This is the height value used by the layout manager. It corresponds to what is actually displayed. + * @return The internal height + */ + public int getInternalHeight(); + + + // + //Maintenance related + // + public void destroy(); + + + // + // Y O G A + // + /** + * Gets the yoga node id + * @return the yoga node id + */ + public long getYogaNode(); + /** + * Applies the yoga values to this component + */ + public void applyYoga(); + + + // + // E V E N T S + // /** * * @param event the even to handle diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/ScrollableElement.java b/src/main/java/electrosphere/renderer/ui/elementtypes/ScrollableElement.java new file mode 100644 index 00000000..dc5cabd1 --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/ScrollableElement.java @@ -0,0 +1,30 @@ +package electrosphere.renderer.ui.elementtypes; + +import electrosphere.renderer.ui.events.ScrollEvent; + +/** + * An element that accepts scroll event + */ +public interface ScrollableElement extends Element { + + /** + * Sets the scroll event handler for the element + * @param callback + */ + public void setOnScrollCallback(ScrollEventCallback callback); + + /** + * A callback that handles scroll events + */ + public interface ScrollEventCallback { + + /** + * + * @param event + * @return + */ + public boolean execute(ScrollEvent event); + + } + +} diff --git a/src/main/java/electrosphere/renderer/ui/events/Event.java b/src/main/java/electrosphere/renderer/ui/events/Event.java index c5b999ab..c160d205 100644 --- a/src/main/java/electrosphere/renderer/ui/events/Event.java +++ b/src/main/java/electrosphere/renderer/ui/events/Event.java @@ -1,5 +1,8 @@ package electrosphere.renderer.ui.events; +/** + * A UI Event + */ public interface Event { } diff --git a/src/main/java/electrosphere/renderer/ui/events/ScrollEvent.java b/src/main/java/electrosphere/renderer/ui/events/ScrollEvent.java new file mode 100644 index 00000000..b7a22a33 --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/events/ScrollEvent.java @@ -0,0 +1,49 @@ +package electrosphere.renderer.ui.events; + +/** + * Fired when the user scrolls the mouse wheel + */ +public class ScrollEvent implements Event { + + //the amount scrolled by + double scrollAmount; + + double mouseX; + double mouseY; + + /** + * Constructor + * @param scrollAmount + */ + public ScrollEvent(double mouseX, double mouseY, double scrollAmount){ + this.scrollAmount = scrollAmount; + this.mouseX = mouseX; + this.mouseY = mouseY; + } + + /** + * Gets the amount scrolled by + * @return + */ + public double getScrollAmount(){ + return this.scrollAmount; + } + + /** + * Gets the x position of the mouse + * @return + */ + public double getMouseX(){ + return mouseX; + } + + /** + * Gets the y position of the mouse + * @return + */ + public double getMouseY(){ + return mouseY; + } + + +} diff --git a/src/main/java/electrosphere/renderer/ui/font/FontManager.java b/src/main/java/electrosphere/renderer/ui/font/FontManager.java index 05784e5b..8b3d83a2 100644 --- a/src/main/java/electrosphere/renderer/ui/font/FontManager.java +++ b/src/main/java/electrosphere/renderer/ui/font/FontManager.java @@ -6,7 +6,6 @@ import java.util.HashMap; import java.util.Map; import electrosphere.logger.LoggerInterface; -import electrosphere.renderer.model.Material; import electrosphere.util.FileUtils; /** diff --git a/src/main/java/electrosphere/renderer/ui/font/FontUtils.java b/src/main/java/electrosphere/renderer/ui/font/FontUtils.java index 2b1a11ac..eeaf98d6 100644 --- a/src/main/java/electrosphere/renderer/ui/font/FontUtils.java +++ b/src/main/java/electrosphere/renderer/ui/font/FontUtils.java @@ -93,7 +93,7 @@ public class FontUtils { imageHeight = Math.max(imageHeight, ch.getHeight()); } - int fontHeight = imageHeight; + // int fontHeight = imageHeight; //create font bitmap BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB); diff --git a/src/main/java/electrosphere/renderer/ui/form/FormElement.java b/src/main/java/electrosphere/renderer/ui/form/FormElement.java deleted file mode 100644 index 6d4fc3c3..00000000 --- a/src/main/java/electrosphere/renderer/ui/form/FormElement.java +++ /dev/null @@ -1,203 +0,0 @@ -package electrosphere.renderer.ui.form; - -import java.util.LinkedList; -import java.util.List; - -import electrosphere.renderer.OpenGLState; -import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.ui.elementtypes.ContainerElement; -import electrosphere.renderer.ui.elementtypes.DrawableElement; -import electrosphere.renderer.ui.elementtypes.Element; -import electrosphere.renderer.ui.events.Event; - -public class FormElement implements DrawableElement, ContainerElement { - - List childList = new LinkedList(); - - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { - for(Element child : childList){ - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,parentFramebufferPointer,parentWidth,parentHeight); - } - } - } - - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; - - public boolean visible = false; - - public boolean focused = false; - - public void onFocus(){ - } - - public int getWidth() { - int minX = -1; - int maxX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - if(maxX == -1){ - maxX = child.getPositionX() + child.getWidth(); - } else if(child.getPositionX() + child.getWidth() > maxX){ - maxX = child.getPositionX() + child.getWidth(); - } - } - if(minX == -1){ - minX = 0; - } - if(maxX == -1){ - maxX = 0; - } - return maxX - minX; - } - - public int getHeight() { - int minY = -1; - int maxY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - if(maxY == -1){ - maxY = child.getPositionY() + child.getHeight(); - } else if(child.getPositionY() + child.getHeight() > maxY){ - maxY = child.getPositionY() + child.getHeight(); - } - } - if(minY == -1){ - minY = 0; - } - if(maxY == -1){ - maxY = 0; - } - return maxY - minY; - } - - public int getPositionX() { - int minX = -1; - for(Element child : childList){ - if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); - } - } - if(minX == -1){ - minX = 0; - } - return minX; - } - - public int getPositionY() { - int minY = -1; - for(Element child : childList){ - if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); - } - } - if(minY == -1){ - minY = 0; - } - return minY; - } - - public boolean getVisible() { - return visible; - } - - public boolean isFocused(){ - return focused; - } - - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - public void setPositionY(int positionY) { - this.positionY = positionY; - } - - public void setVisible(boolean draw) { - this.visible = draw; - for(Element child : childList){ - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setVisible(draw); - } - } - } - - public void setParentWidth(int width){ - parentWidth = width; - for(Element child : childList){ - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - } - } - } - - public void setParentHeight(int height){ - this.parentHeight = height; - for(Element child : childList){ - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - } - } - } - - public void setFocused(boolean focused){ - this.focused = focused; - } - - @Override - public void addChild(Element child) { - childList.add(child); - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); - drawableChild.setVisible(false); - } - } - - @Override - public List getChildren() { - return childList; - } - - @Override - public void removeChild(Element child) { - childList.remove(child); - } - - public boolean handleEvent(Event event){ - return true; - } - -} diff --git a/src/main/java/electrosphere/renderer/ui/layout/LayoutScheme.java b/src/main/java/electrosphere/renderer/ui/layout/LayoutScheme.java index 18fb344a..d297c43b 100644 --- a/src/main/java/electrosphere/renderer/ui/layout/LayoutScheme.java +++ b/src/main/java/electrosphere/renderer/ui/layout/LayoutScheme.java @@ -1,10 +1,7 @@ package electrosphere.renderer.ui.layout; -import java.util.LinkedList; -import java.util.List; import electrosphere.renderer.ui.elementtypes.ContainerElement; -import electrosphere.renderer.ui.elementtypes.DrawableElement; /** * diff --git a/src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java b/src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java deleted file mode 100644 index 00fc9565..00000000 --- a/src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java +++ /dev/null @@ -1,178 +0,0 @@ -package electrosphere.renderer.ui.layout; - -import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; -import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; -import static org.lwjgl.opengl.GL11.glClear; -import static org.lwjgl.opengl.GL11.glClearColor; -import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER; -import static org.lwjgl.opengl.GL30.glBindFramebuffer; - -import java.util.LinkedList; -import java.util.List; - -import org.joml.Vector3f; - -import electrosphere.engine.Globals; -import electrosphere.renderer.OpenGLState; -import electrosphere.renderer.RenderPipelineState; -import electrosphere.renderer.debug.DebugRendering; -import electrosphere.renderer.framebuffer.Framebuffer; -import electrosphere.renderer.framebuffer.FramebufferUtils; -import electrosphere.renderer.model.Material; -import electrosphere.renderer.model.Model; -import electrosphere.renderer.ui.elementtypes.DrawableElement; -import electrosphere.renderer.ui.elementtypes.Element; -import electrosphere.renderer.ui.events.Event; - -/** - * - * @author amaterasu - */ -public class LayoutSchemeListScrollable implements DrawableElement,LayoutScheme { - - List childList = new LinkedList(); - Framebuffer widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer(); - Material customMat = new Material(); - - Vector3f boxPosition = new Vector3f(); - Vector3f boxDimensions = new Vector3f(); - Vector3f texPosition = new Vector3f(0,0,0); - Vector3f texScale = new Vector3f(1,1,0); - - static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,1.0f,0.0f); - - public LayoutSchemeListScrollable(int positionX, int positionY, int width, int height, boolean draw){ - customMat.setTexturePointer(widgetBuffer.getTexturePointer()); -// customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Branch.png").getTexturePointer()); - - float ndcX = (float)positionX/Globals.WINDOW_WIDTH; - float ndcY = (float)positionY/Globals.WINDOW_HEIGHT; - float ndcWidth = (float)width/Globals.WINDOW_WIDTH; - float ndcHeight = (float)height/Globals.WINDOW_HEIGHT; - boxPosition = new Vector3f(ndcX,ndcY,0); - boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); - } - - static float aaaa = 0; - - @Override - public void draw(RenderPipelineState renderPipelineState, OpenGLState openGLState, int parentFramebufferPointer, int parentWidth, int parentHeight) { - widgetBuffer.bind(); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - for(Element child : childList){ - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,widgetBuffer.getFramebufferPointer(),width,height); - } - } - //this call binds the screen as the "texture" we're rendering to - //have to call before actually rendering - glBindFramebuffer(GL_FRAMEBUFFER, 0); - aaaa = aaaa + 0.0005f; - if(aaaa > 1){ - aaaa = -1; - } - texPosition.y = aaaa; - Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); - planeModel.pushUniformToMesh("plane", "mPosition", boxPosition); - planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); - planeModel.pushUniformToMesh("plane", "tPosition", texPosition); - planeModel.pushUniformToMesh("plane", "tDimension", texScale); - planeModel.getMeshes().get(0).setMaterial(customMat); - planeModel.drawUI(); - - if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){ - DebugRendering.drawUIBounds(parentFramebufferPointer, boxPosition, boxDimensions, windowDrawDebugColor); - } - } - - public void pack() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - public int width = 1; - public int height = 1; - - public int positionX = 0; - public int positionY = 0; - - public int parentWidth = 1; - public int parentHeight = 1; - - public boolean visible = false; - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getPositionX() { - return positionX; - } - - public int getPositionY() { - return positionY; - } - - public boolean getVisible() { - return visible; - } - - public void setWidth(int width) { - this.width = width; - } - - public void setHeight(int height) { - this.height = height; - } - - public void setPositionX(int positionX) { - this.positionX = positionX; - } - - public void setPositionY(int positionY) { - this.positionY = positionY; - } - - public void setVisible(boolean draw) { - this.visible = draw; - } - - public void setParentWidth(int width){ - parentWidth = width; - } - - public void setParentHeight(int height){ - this.parentHeight = height; - } - - @Override - public void addChild(Element child) { - childList.add(child); - if(child instanceof DrawableElement){ - DrawableElement drawableChild = (DrawableElement) child; - drawableChild.setParentWidth(width); - drawableChild.setParentHeight(height); - drawableChild.setVisible(false); - } - } - - @Override - public List getChildren() { - return childList; - } - - @Override - public void removeChild(Element child) { - childList.remove(child); - } - - public boolean handleEvent(Event event){ - return true; - } - -}