diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index 79ebac67..fc30b16f 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -2,7 +2,6 @@ Server commands client to load a given scene file + there is a sword lying on the ground + when you grab the sword, a tutorial popup appears to tell you how to use in - fix grabbing an item hook for grabbing an item + on clearing the tutorial, continue the game+ when the sword is equipped, create another popup to teach sword controls. it pauses the game hook on equipping an item diff --git a/src/main/java/electrosphere/menu/WindowUtils.java b/src/main/java/electrosphere/menu/WindowUtils.java index 3d5f43ad..43a74c07 100644 --- a/src/main/java/electrosphere/menu/WindowUtils.java +++ b/src/main/java/electrosphere/menu/WindowUtils.java @@ -47,6 +47,9 @@ public class WindowUtils { recursiveSetVisible(child, visible); } } + if(Globals.elementManager.getFocusedElement() == null){ + Globals.elementManager.focusFirstElement(); + } if(visible){ topLevelMenu.applyYoga(0, 0); } diff --git a/src/main/java/electrosphere/menu/debug/ImGuiControls.java b/src/main/java/electrosphere/menu/debug/ImGuiControls.java new file mode 100644 index 00000000..a9ee39b3 --- /dev/null +++ b/src/main/java/electrosphere/menu/debug/ImGuiControls.java @@ -0,0 +1,43 @@ +package electrosphere.menu.debug; + +import electrosphere.engine.Globals; +import electrosphere.renderer.ui.imgui.ImGuiWindow; +import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; +import imgui.ImGui; + +/** + * Controls debug menus + */ +public class ImGuiControls { + + //window for viewing information about the controls state + protected static ImGuiWindow controlsWindow; + + /** + * Creates the windows in this file + */ + protected static void createControlsWindows(){ + createControlsDebugWindow(); + } + + /** + * Client scene entity view + */ + protected static void createControlsDebugWindow(){ + controlsWindow = new ImGuiWindow("Controls"); + controlsWindow.setCallback(new ImGuiWindowCallback() { + @Override + public void exec() { + //ui framework text + ImGui.text("Controls"); + + //control handler stuff + ImGui.text("ControlHandler state: " + Globals.controlHandler.getHandlerState()); + + } + }); + controlsWindow.setOpen(false); + Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(controlsWindow); + } + +} diff --git a/src/main/java/electrosphere/menu/debug/ImGuiUIFramework.java b/src/main/java/electrosphere/menu/debug/ImGuiUIFramework.java new file mode 100644 index 00000000..b86aec7f --- /dev/null +++ b/src/main/java/electrosphere/menu/debug/ImGuiUIFramework.java @@ -0,0 +1,40 @@ +package electrosphere.menu.debug; + +import electrosphere.engine.Globals; +import electrosphere.renderer.ui.imgui.ImGuiWindow; +import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; +import imgui.ImGui; + +/** + * UI Framework debug menus + */ +public class ImGuiUIFramework { + + //window for viewing information about the ui framework + protected static ImGuiWindow uiFrameworkWindow; + + /** + * Creates the windows in this file + */ + protected static void createUIFrameworkWindows(){ + createUIFrameworkDebugWindow(); + } + + /** + * Client scene entity view + */ + protected static void createUIFrameworkDebugWindow(){ + uiFrameworkWindow = new ImGuiWindow("UI Framework"); + uiFrameworkWindow.setCallback(new ImGuiWindowCallback() { + @Override + public void exec() { + //ui framework text + ImGui.text("UI Framework"); + + } + }); + uiFrameworkWindow.setOpen(false); + Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(uiFrameworkWindow); + } + +} diff --git a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java index cc2c7a0c..581b7c8c 100644 --- a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java +++ b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java @@ -58,6 +58,8 @@ public class ImGuiWindowMacros { createPlayerEntityDebugWindow(); createFluidDebugWindow(); ImGuiEntityMacros.createClientEntityWindows(); + ImGuiUIFramework.createUIFrameworkWindows(); + ImGuiControls.createControlsWindows(); } /** @@ -273,6 +275,10 @@ public class ImGuiWindowMacros { if(ImGui.button("Client Entity Debug")){ ImGuiEntityMacros.clientEntityWindow.setOpen(true); } + //controls state debug + if(ImGui.button("Control State Debug")){ + ImGuiControls.controlsWindow.setOpen(true); + } //close button if(ImGui.button("Close")){ mainDebugWindow.setOpen(false); diff --git a/src/main/java/electrosphere/renderer/ui/ElementManager.java b/src/main/java/electrosphere/renderer/ui/ElementManager.java index d8c5594c..a7376425 100644 --- a/src/main/java/electrosphere/renderer/ui/ElementManager.java +++ b/src/main/java/electrosphere/renderer/ui/ElementManager.java @@ -11,6 +11,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import org.joml.Vector2i; import electrosphere.engine.Globals; +import electrosphere.logger.LoggerInterface; import electrosphere.renderer.ui.elements.Window; import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DraggableElement; @@ -50,7 +51,7 @@ public class ElementManager { if(!elementList.contains(w)){ elementList.add(w); } - if(elementList.size() == 1){ + if(elementList.size() < 2){ focusFirstElement(); } } @@ -72,13 +73,19 @@ public class ElementManager { return elementList; } + /** + * Unregisters a window stored at a given window string + * @param name The window string + */ public void unregisterWindow(String name){ Element w = elementMap.remove(name); - if(elementList.contains(w)){ + while(elementList.contains(w)){ elementList.remove(w); } if(elementList.size() > 0){ focusFirstElement(); + } else { + this.currentFocusedElement = null; } } @@ -102,6 +109,12 @@ public class ElementManager { } } + /** + * Gets the list of focusable elements recursively + * @param topLevel The current top level element + * @param input The list to append to + * @return The list to append to + */ List getFocusableList(Element topLevel, List input){ if(topLevel instanceof FocusableElement){ input.add((FocusableElement)topLevel); @@ -127,6 +140,11 @@ public class ElementManager { } currentFocusedElement = focusables.get(0); currentFocusedElement.handleEvent(new FocusEvent(true)); + } else { + if(currentFocusedElement != null){ + currentFocusedElement.handleEvent(new FocusEvent(false)); + } + currentFocusedElement = null; } } @@ -211,13 +229,28 @@ public class ElementManager { * @param event The event * @param el The element to handle the event */ - public void fireEventNoPosition(Event event, Element el){ + public boolean fireEventNoPosition(Event event, Element el){ List ancestryList = constructNonPositionalAncestryList(el); boolean propagate = true; while(ancestryList.size() > 0 && propagate == true){ Element currentElement = ancestryList.remove(0); propagate = currentElement.handleEvent(event); } + return propagate; + } + + /** + * Fires a top level event (ie on all window elements registered) + * @param event The top level event + */ + public void fireTopLevelEvent(Event event){ + boolean propagate = true; + for(Element topLevelEl : this.elementList){ + propagate = fireEventNoPosition(event, topLevelEl); + if(!propagate){ + break; + } + } } /** @@ -228,9 +261,14 @@ public class ElementManager { private List constructNonPositionalAncestryList(Element el){ //a list of elements with 0 being the target of the event, 1 being the parent of the target, 2 being the parent of 1, etc List elementPropagation = new LinkedList(); - elementPropagation.add(el); + + //if we are calling this on the current focused element, it could be null + if(el != null){ + elementPropagation.add(el); + } Element parentElement = null; Element targetElement = el; + //search all window trees while(true){ for(Element window : this.getWindowList()){ if(window instanceof ContainerElement){ @@ -238,6 +276,9 @@ public class ElementManager { } } if(parentElement == null){ + if(targetElement instanceof Window){ } else { + LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Failed to find parent of an element that is not a window!")); + } break; } else { elementPropagation.add(parentElement); @@ -281,16 +322,16 @@ public class ElementManager { * @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 contains x,y, call function on el + if(elementContainsPoint(current,x,y,offsetX,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,xLoc,yLoc,offsetX,offsetY)){ - buildElementPositionalStack(inputStack, el, xLoc, yLoc, offsetX, offsetY); - } + buildElementPositionalStack(inputStack, el, xLoc, yLoc, offsetX, offsetY); } } return inputStack; @@ -438,7 +479,12 @@ public class ElementManager { */ public void navigateBackwards(){ NavigationEvent event = new NavigationEvent(NavigationEventType.BACKWARD); - fireEvent(event,currentFocusedElement.getAbsoluteX(),currentFocusedElement.getAbsoluteY()); + if(currentFocusedElement != null){ + //fires on the currently focused element + fireEventNoPosition(event, currentFocusedElement); + } else if(this.elementList.size() > 0){ + fireTopLevelEvent(event); + } } /** diff --git a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java index 3d0f3cbf..357a2eec 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java @@ -97,14 +97,10 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag } else { customMat.setTexturePointer(Globals.assetManager.fetchTexture(Globals.blackTexture).getTexturePointer()); } - this.internalPositionX = x; - this.absoluteX = x; - this.internalPositionY = y; - this.absoluteY = y; - this.width = width; - this.height = height; - this.internalWidth = width; - this.internalHeight = height; + setPositionX(x); + setPositionY(y); + setWidth(width); + setHeight(height); } /** diff --git a/src/main/java/electrosphere/server/terrain/generation/DefaultChunkGenerator.java b/src/main/java/electrosphere/server/terrain/generation/DefaultChunkGenerator.java index 0422ee04..6b046f24 100644 --- a/src/main/java/electrosphere/server/terrain/generation/DefaultChunkGenerator.java +++ b/src/main/java/electrosphere/server/terrain/generation/DefaultChunkGenerator.java @@ -27,7 +27,7 @@ public class DefaultChunkGenerator implements ChunkGenerator { for(int weightX = 0; weightX < ServerTerrainChunk.CHUNK_DIMENSION; weightX++){ for(int weightZ = 0; weightZ < ServerTerrainChunk.CHUNK_DIMENSION; weightZ++){ weights[weightX][0][weightZ] = 0.1f; - values[weightX][0][weightZ] = 2; + values[weightX][0][weightZ] = 1; } } }