From 676494ff208643b8e221f5824287c74d0489d50c Mon Sep 17 00:00:00 2001 From: austin Date: Tue, 13 May 2025 15:56:29 -0400 Subject: [PATCH] multiple inventory windows drawing --- docs/src/progress/renderertodo.md | 2 + .../ui/menu/ingame/InventoryMainWindow.java | 87 +++++++++++++++- .../renderer/ui/ElementService.java | 6 ++ .../renderer/ui/elements/Window.java | 99 ++++++++++++------- 4 files changed, 155 insertions(+), 39 deletions(-) diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index eed3a1df..fa7664f8 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1752,6 +1752,8 @@ Can open ui menu to view inventories of other entities on client Fix windows not resizing internal framebuffer when yoga changes their dimensions Inventory window max width Natural inventory panel wraps on width limit +Fix target inventory window clearing +Non-ideal implementation of multiple inventory windows drawing at once diff --git a/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java b/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java index 283aa369..d69ace9a 100644 --- a/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java +++ b/src/main/java/electrosphere/client/ui/menu/ingame/InventoryMainWindow.java @@ -14,6 +14,7 @@ import electrosphere.engine.signal.Signal.SignalType; import electrosphere.entity.Entity; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.renderer.ui.elements.Window; +import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment; import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback; import electrosphere.renderer.ui.events.NavigationEvent; @@ -32,6 +33,11 @@ public class InventoryMainWindow { */ public static final int MIN_HEIGHT = 500; + /** + * Margins around the window + */ + public static final int MARGIN = 100; + /** * Views an inventory of an entity * @param entity The entity @@ -54,7 +60,7 @@ public class InventoryMainWindow { Globals.renderingEngine.getPostProcessingPipeline().setApplyBlur(true); // Globals.openInventoriesCount++; - } else if(InventoryUtils.hasNaturalInventory(entity) && Globals.elementService.getWindow(WindowStrings.WINDOW_CHARACTER) != null){ + } else if(Globals.elementService.getWindow(WindowStrings.WINDOW_CHARACTER) != null){ Globals.elementService.closeWindow(WindowStrings.WINDOW_CHARACTER); WindowUtils.clearTooltips(); Globals.renderingEngine.getPostProcessingPipeline().setApplyBlur(false); @@ -79,7 +85,7 @@ public class InventoryMainWindow { Globals.renderingEngine.getPostProcessingPipeline().setApplyBlur(true); // Globals.openInventoriesCount++; - } else if(InventoryUtils.hasNaturalInventory(entity) && Globals.elementService.getWindow(WindowStrings.WINDOW_INVENTORY_TARGET) != null){ + } else if(Globals.elementService.getWindow(WindowStrings.WINDOW_INVENTORY_TARGET) != null){ Globals.elementService.closeWindow(WindowStrings.WINDOW_INVENTORY_TARGET); WindowUtils.clearTooltips(); Globals.renderingEngine.getPostProcessingPipeline().setApplyBlur(false); @@ -88,6 +94,7 @@ public class InventoryMainWindow { } } } + InventoryMainWindow.updateInventoryWindowPositions(); } /** @@ -98,10 +105,22 @@ public class InventoryMainWindow { public static Window createInventoryWindow(Entity entity){ Window rVal = Window.createExpandableCenterAligned(Globals.renderingEngine.getOpenGLState()); rVal.setMaxWidth(Globals.WINDOW_WIDTH / 2); + rVal.setMarginBottom(MARGIN); + rVal.setMarginLeft(MARGIN); + rVal.setMarginRight(MARGIN); + rVal.setMarginTop(MARGIN); + + String windowString; + if(entity == Globals.playerEntity){ + windowString = WindowStrings.WINDOW_CHARACTER; + } else { + windowString = WindowStrings.WINDOW_INVENTORY_TARGET; + } + InventoryMainWindow.updateSpecificInventoryPlacement(rVal,windowString); rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ - WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_CHARACTER), false); - Globals.elementService.unregisterWindow(WindowStrings.WINDOW_CHARACTER); + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(windowString), false); + Globals.elementService.unregisterWindow(windowString); if(Globals.cameraHandler.getTrackPlayerEntity()){ Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME); } else { @@ -143,4 +162,64 @@ public class InventoryMainWindow { return rVal; } + /** + * Updates the inventory window positions + */ + private static void updateInventoryWindowPositions(){ + Window characterWindow = ((Window)Globals.elementService.getWindow(WindowStrings.WINDOW_CHARACTER)); + Window targetWindow = ((Window)Globals.elementService.getWindow(WindowStrings.WINDOW_INVENTORY_TARGET)); + if( + characterWindow != null && + targetWindow != null + ){ + characterWindow.setParentAlignItem(YogaAlignment.Start); + targetWindow.setParentAlignItem(YogaAlignment.End); + Globals.signalSystem.post(SignalType.YOGA_APPLY, characterWindow); + Globals.signalSystem.post(SignalType.YOGA_APPLY, targetWindow); + } else { + if(characterWindow != null){ + characterWindow.setParentAlignItem(YogaAlignment.Center); + Globals.signalSystem.post(SignalType.YOGA_APPLY, characterWindow); + } + if(targetWindow != null){ + targetWindow.setParentAlignItem(YogaAlignment.Center); + Globals.signalSystem.post(SignalType.YOGA_APPLY, targetWindow); + } + } + } + + /** + * Updates a specific inventory's placement + * @param window The window element + * @param windowString The window string for this element + */ + private static void updateSpecificInventoryPlacement(Window window, String windowString){ + Window characterWindow = ((Window)Globals.elementService.getWindow(WindowStrings.WINDOW_CHARACTER)); + Window targetWindow = ((Window)Globals.elementService.getWindow(WindowStrings.WINDOW_INVENTORY_TARGET)); + if(windowString.equals(WindowStrings.WINDOW_CHARACTER)){ + characterWindow = window; + } + if(windowString.equals(WindowStrings.WINDOW_INVENTORY_TARGET)){ + targetWindow = window; + } + if( + characterWindow != null && + targetWindow != null + ){ + characterWindow.setParentAlignItem(YogaAlignment.Start); + targetWindow.setParentAlignItem(YogaAlignment.End); + Globals.signalSystem.post(SignalType.YOGA_APPLY, characterWindow); + Globals.signalSystem.post(SignalType.YOGA_APPLY, targetWindow); + } else { + if(characterWindow != null){ + characterWindow.setParentAlignItem(YogaAlignment.Center); + Globals.signalSystem.post(SignalType.YOGA_APPLY, characterWindow); + } + if(targetWindow != null){ + targetWindow.setParentAlignItem(YogaAlignment.Center); + Globals.signalSystem.post(SignalType.YOGA_APPLY, targetWindow); + } + } + } + } diff --git a/src/main/java/electrosphere/renderer/ui/ElementService.java b/src/main/java/electrosphere/renderer/ui/ElementService.java index fcdb7bda..6629182e 100644 --- a/src/main/java/electrosphere/renderer/ui/ElementService.java +++ b/src/main/java/electrosphere/renderer/ui/ElementService.java @@ -16,6 +16,7 @@ import org.joml.Vector2i; import electrosphere.engine.Globals; import electrosphere.engine.signal.Signal; import electrosphere.engine.signal.Signal.SignalType; +import electrosphere.logger.LoggerInterface; import electrosphere.engine.signal.SignalServiceImpl; import electrosphere.renderer.ui.elements.Window; import electrosphere.renderer.ui.elementtypes.ContainerElement; @@ -73,9 +74,14 @@ public class ElementService extends SignalServiceImpl { */ public void registerWindow(String name, Element w){ lock.lock(); + if(elementMap.containsKey(name)){ + LoggerInterface.loggerUI.ERROR(new Error("Registering element to existing window string " + name)); + } elementMap.put(name,w); if(!elementList.contains(w)){ elementList.add(w); + } else { + LoggerInterface.loggerUI.ERROR(new Error("Registering element to existing window string " + name)); } if(elementList.size() < 2){ focusFirstElement(); diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java index b7653776..e4b50747 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Window.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java @@ -84,6 +84,11 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme */ boolean showDecorations = true; + /** + * Margin size for decorations + */ + static final int DECORATION_MARGIN = 25; + /** * Yoga node for controlling placement of the window on the screen * IE, if you want to place a window in the upper right hand side of the screen, @@ -108,13 +113,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme */ @Deprecated public Window(OpenGLState openGLState, int positionX, int positionY, int width, int height, boolean showDecorations){ - try { - widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height); - } catch(Exception e){ - LoggerInterface.loggerRenderer.ERROR(e); - } - customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); - this.showDecorations = showDecorations; //yoga node for the actually visible part this.yogaNode = Yoga.YGNodeNew(); this.layout = YGNode.create(this.yogaNode).layout(); @@ -127,6 +125,8 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.setFlexDirection(YogaFlexDirection.Column); this.setWidth(width); this.setHeight(height); + this.setShowDecorations(showDecorations); + this.reallocateBuffer(width, height); } /** @@ -134,12 +134,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme * @param openGLState */ private Window(OpenGLState openGLState){ - try { - widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, DEFAULT_POPUP_WIDTH, DEFAULT_POPUP_HEIGHT); - } catch(Exception e){ - LoggerInterface.loggerRenderer.ERROR(e); - } - customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); //yoga node for the actually visible part this.yogaNode = Yoga.YGNodeNew(); this.layout = YGNode.create(this.yogaNode).layout(); @@ -152,6 +146,8 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.setFlexDirection(YogaFlexDirection.Column); this.setMinWidth(DEFAULT_POPUP_WIDTH); this.setMinHeight(DEFAULT_POPUP_HEIGHT); + this.setShowDecorations(showDecorations); + this.reallocateBuffer(DEFAULT_POPUP_WIDTH, DEFAULT_POPUP_HEIGHT); } /** @@ -213,10 +209,12 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme int framebufferPosX, int framebufferPosY ) { + int absoluteX = this.getAbsoluteX(); + int absoluteY = this.getAbsoluteY(); float ndcWidth = (float)this.getWidth()/framebuffer.getWidth(); float ndcHeight = (float)this.getHeight()/framebuffer.getHeight(); - float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth(); - float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight(); + float ndcX = (float)this.absoluteToFramebuffer(absoluteX,framebufferPosX)/framebuffer.getWidth(); + float ndcY = (float)this.absoluteToFramebuffer(absoluteY,framebufferPosY)/framebuffer.getHeight(); Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); @@ -233,7 +231,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - drawableChild.draw(renderPipelineState,openGLState,widgetBuffer,this.getAbsoluteX(),this.getAbsoluteY()); + drawableChild.draw(renderPipelineState,openGLState,widgetBuffer,absoluteX,absoluteY); } } //this call binds the screen as the "texture" we're rendering to @@ -293,6 +291,31 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.clearChildren(); } + /** + * Sets the show decoration value + * @param decoration The show decoration value + */ + private void setShowDecorations(boolean decoration){ + this.showDecorations = decoration; + } + + /** + * Reallocates the render buffer + */ + private void reallocateBuffer(int width, int height){ + int finalWidth = width - this.getPaddingLeft() - this.getPaddingRight(); + int finalHeight = height - this.getPaddingTop() - this.getPaddingBottom(); + try { + if(this.widgetBuffer != null){ + widgetBuffer.free(); + } + widgetBuffer = FramebufferUtils.generateTextureFramebuffer(Globals.renderingEngine.getOpenGLState(), finalWidth, finalHeight); + } catch(Exception e){ + LoggerInterface.loggerRenderer.ERROR(e); + } + customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); + } + @Override public void setWidth(int width){ this.width = width; @@ -361,11 +384,6 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme public int absoluteX = 0; public int absoluteY = 0; - int marginTop = 0; - int marginRight = 0; - int marginBottom = 0; - int marginLeft = 0; - public boolean visible = false; public int getWidth() { @@ -385,35 +403,35 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme } public int getMarginTop(){ - return marginTop; + return (int)Yoga.YGNodeLayoutGetMargin(this.yogaNode, Yoga.YGEdgeTop); } public int getMarginRight(){ - return marginRight; + return (int)Yoga.YGNodeLayoutGetMargin(this.yogaNode, Yoga.YGEdgeRight); } public int getMarginBottom(){ - return marginBottom; + return (int)Yoga.YGNodeLayoutGetMargin(this.yogaNode, Yoga.YGEdgeBottom); } public int getMarginLeft(){ - return marginLeft; + return (int)Yoga.YGNodeLayoutGetMargin(this.yogaNode, Yoga.YGEdgeLeft); } public void setMarginTop(int marginTop){ - this.marginTop = marginTop; + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeTop, marginTop); } public void setMarginRight(int marginRight){ - this.marginRight = marginRight; + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeRight, marginRight); } public void setMarginBottom(int marginBottom){ - this.marginBottom = marginBottom; + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeBottom, marginBottom); } public void setMarginLeft(int marginLeft){ - this.marginLeft = marginLeft; + Yoga.YGNodeStyleSetMargin(this.yogaNode, Yoga.YGEdgeLeft, marginLeft); } //the yoga node id @@ -453,12 +471,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); if(this.width != (int)widthRaw || this.height != (int)heightRaw){ - try { - widgetBuffer.free(); - widgetBuffer = FramebufferUtils.generateTextureFramebuffer(Globals.renderingEngine.getOpenGLState(), (int)widthRaw, (int)heightRaw); - } catch(Exception e){ - LoggerInterface.loggerRenderer.ERROR(e); - } + this.reallocateBuffer((int)widthRaw,(int)heightRaw); } //apply the values to this component this.absoluteX = (int)leftRaw; @@ -891,6 +904,22 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeLeft, paddingLeft); } + public int getPaddingTop(){ + return (int)Yoga.YGNodeLayoutGetPadding(this.yogaNode, Yoga.YGEdgeTop); + } + + public int getPaddingRight(){ + return (int)Yoga.YGNodeLayoutGetPadding(this.yogaNode, Yoga.YGEdgeRight); + } + + public int getPaddingBottom(){ + return (int)Yoga.YGNodeLayoutGetPadding(this.yogaNode, Yoga.YGEdgeBottom); + } + + public int getPaddingLeft(){ + return (int)Yoga.YGNodeLayoutGetPadding(this.yogaNode, Yoga.YGEdgeLeft); + } + /** * Gets the frame decoration texture path * @return The frame decoration texture path