From 7c8e536f809bf2bd7b3dc022ee41bb3aadf14318 Mon Sep 17 00:00:00 2001 From: austin Date: Thu, 4 Apr 2024 18:15:10 -0400 Subject: [PATCH] bare minimum working ui update --- assets/Shaders/font/bitmapchar/bitmapchar.vs | 15 +- assets/Shaders/plane/plane.fs | 2 +- assets/Shaders/plane/plane.vs | 16 +- assets/Textures/ui/uiFrame1.png | Bin 0 -> 5868 bytes assets/Textures/ui/uiFrame2.png | Bin 0 -> 5868 bytes buildNumber.properties | 4 +- .../creatures/creatureideas.md | 4 + .../creatures/creaturesindex.md | 1 + .../creatures/mechanicsideas.md | 4 +- docs/src/progress/renderertodo.md | 6 + pom.xml | 14 + .../electrosphere/controls/CameraHandler.java | 1 - .../java/electrosphere/controls/Control.java | 20 ++ .../controls/ControlHandler.java | 124 +++++---- .../electrosphere/controls/MouseCallback.java | 11 +- .../controls/ScrollCallback.java | 44 +++ .../java/electrosphere/engine/Globals.java | 10 +- .../electrosphere/logger/LoggerInterface.java | 2 + .../electrosphere/menu/MenuGenerators.java | 94 ++----- .../java/electrosphere/menu/WindowUtils.java | 12 +- .../menu/ingame/MenuGeneratorsInGame.java | 70 +++-- .../menu/ingame/MenuGeneratorsInventory.java | 6 +- .../menu/mainmenu/MenuGeneratorsArena.java | 13 +- .../menu/mainmenu/MenuGeneratorsDebug.java | 6 +- .../mainmenu/MenuGeneratorsLevelEditor.java | 41 +-- .../mainmenu/MenuGeneratorsMultiplayer.java | 32 +-- .../mainmenu/MenuGeneratorsTitleMenu.java | 27 +- .../mainmenu/MenuGeneratorsUITesting.java | 68 +++++ .../java/electrosphere/net/server/Server.java | 2 + .../renderer/RenderingEngine.java | 5 +- .../renderer/debug/DebugRendering.java | 13 +- .../renderer/pipelines/UIPipeline.java | 7 +- .../renderer/ui/ElementManager.java | 52 +++- .../renderer/ui/WidgetUtils.java | 10 +- .../electrosphere/renderer/ui/Window.java | 246 +++++++++++++++-- .../renderer/ui/elements/ActorPanel.java | 80 ++---- .../BitmapCharacter.java | 104 +++---- .../renderer/ui/elements/Button.java | 245 ++++++----------- .../renderer/ui/elements/Div.java | 245 +---------------- .../renderer/ui/elements/FormElement.java | 68 +++++ .../renderer/ui/elements/ImagePanel.java | 62 +---- .../renderer/ui/elements/Label.java | 196 ++++--------- .../ui/elements/ScrollableContainer.java | 158 +++-------- .../renderer/ui/elements/Slider.java | 62 +---- .../ui/elements/StandardContainerElement.java | 260 ++++++++++++++++++ .../renderer/ui/elements/StandardElement.java | 180 ++++++++++++ .../renderer/ui/elements/StringCarousel.java | 163 ++--------- .../renderer/ui/elements/TextBox.java | 77 +----- .../renderer/ui/elements/TextInput.java | 242 +++++++--------- .../ui/elements/VirtualScrollable.java | 151 ++++++++++ .../ui/elementtypes/ContainerElement.java | 54 ++++ .../ui/elementtypes/DrawableElement.java | 23 +- .../renderer/ui/elementtypes/Element.java | 77 +++++- .../ui/elementtypes/ScrollableElement.java | 30 ++ .../renderer/ui/events/Event.java | 3 + .../renderer/ui/events/ScrollEvent.java | 49 ++++ .../renderer/ui/font/FontManager.java | 1 - .../renderer/ui/font/FontUtils.java | 2 +- .../renderer/ui/form/FormElement.java | 203 -------------- .../renderer/ui/layout/LayoutScheme.java | 3 - .../ui/layout/LayoutSchemeListScrollable.java | 178 ------------ 61 files changed, 1971 insertions(+), 1927 deletions(-) create mode 100644 assets/Textures/ui/uiFrame1.png create mode 100644 assets/Textures/ui/uiFrame2.png create mode 100644 docs/src/highlevel-design/creatures/creatureideas.md create mode 100644 src/main/java/electrosphere/controls/ScrollCallback.java create mode 100644 src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsUITesting.java rename src/main/java/electrosphere/renderer/ui/{font/bitmapchar => elements}/BitmapCharacter.java (62%) create mode 100644 src/main/java/electrosphere/renderer/ui/elements/FormElement.java create mode 100644 src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java create mode 100644 src/main/java/electrosphere/renderer/ui/elements/StandardElement.java create mode 100644 src/main/java/electrosphere/renderer/ui/elements/VirtualScrollable.java create mode 100644 src/main/java/electrosphere/renderer/ui/elementtypes/ScrollableElement.java create mode 100644 src/main/java/electrosphere/renderer/ui/events/ScrollEvent.java delete mode 100644 src/main/java/electrosphere/renderer/ui/form/FormElement.java delete mode 100644 src/main/java/electrosphere/renderer/ui/layout/LayoutSchemeListScrollable.java 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 0000000000000000000000000000000000000000..731ae74af5d329ea8a1b30b2c05b10d9fd8d1fed GIT binary patch literal 5868 zcmeAS@N?(olHy`uVBq!ia0y~yV15C@9Be=l-^Ev+FfcH-W;#0ucse^P6cpvBW#*(Z zFlbDyooMTEI6$P;KX|Es;fa8w2b)%OEZ&kNs551o(`r67{lCp>yq;a%iyuT4 zd`RE;>cOKmtD9FVaQthqu(r_L<X;Ih_p;Nl?&e1hFD~=c+5p=z( z5r1Omnu2?e)`Y!YQ|tflP=aIh$%47pID{gcgfu%Q1iG_^Ms!?SH!(@c_qic|{f&>y zPpD2_&E(d{dS!uA(VqwPAF8*d6;_?{#RAj> z4m(KR2L~uP?~e+C3qx`OWVG0%MLjZFY*JQiVy%Woi%qhMO;ELt5p<(vDX3zmay>Fy zmX4OCG${A57KRiGViX8iONmiIVp{K`W$9>HN?F&N7R4r3Ge_H{G$@}(%hKWBF8vU{ i^y|hHV2iOKM*ii0zO~Ae&+Gy67(8A5T-G@yGywq1KlA_q literal 0 HcmV?d00001 diff --git a/assets/Textures/ui/uiFrame2.png b/assets/Textures/ui/uiFrame2.png new file mode 100644 index 0000000000000000000000000000000000000000..6437b467787be0dd0442d01cd730278ab04b016e GIT binary patch literal 5868 zcmeAS@N?(olHy`uVBq!ia0y~yV15C@9Be=l-^Ev+FfcH-WI8(scse^P6cpvBW#*(Z zFlbDyooMTEI6$P;|8kbA7GIe_;fa8`IvrgWUfN;@oieqzyh`|V$v)%Kge5yHxYn_< z*Nd&@(>u4zY6n--1OAT9&65{(PpOCx$`E|a+g~%M{QSeczZn)rrmm8l!4h)T=u+p5 z8K>8G9SmoAA^gC3{ShDAnUQA>ZQl28W&bO^Q=9kv{yJ4VhZZmk*%!r@{p>A1nb?@#)|+GHC!;3j9jjArs4cDak*Cll(Dame zk)HOP?G~%AT4m3leBU7CLYPs^a?>uBX%k$ylv1t)I*N)d`f}aFaN@GRGurEqd|ZA) zb@FN^w?5V@3!IAnJjnl0y)CV<>Xa|n(S~{AxBp2nH|=&$48rQGeOnCuYgSw!N|Yb)VXM#_84vK1|k=oTU6Slk=$3hdQ_OQ`p<`8vmJ==e@0+ zW5*CV>*^=of&z}7=^E8{AK$CJTl{i3waw17+eqXuXIb0++b|Tz}d7l zOM4eX&&3IMdOzHWUiZ6_8EB?Y=%gn%wg-b!(2T`j1H&bOj0C%8J|M*=3nUDH>4_oX z0wa(d6{IXcBuZf6+2F_y3(rwOPy!=AKn^SbrecV89#9?uhv%puIDwHIAe_Je1cx0Y z?}PP&^ZuwHxG*FqKt_vATGS(>#U^FNCb(KhFLg(YP4bFOSgDCp4ULwipynmn#U|Do zXS6IGElX)o?qMwqDHI$nOGnF6a+-@+%RO2Mj+UjPW$9>H3L1wYxtol&y*E?@2Wh+X m!G5nvTkKYe0E5xsJo}Z2fruntime + + + + 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; - } - -}