From cbdfb6366336351439b0a4533b09d81e9fa98fa2 Mon Sep 17 00:00:00 2001 From: austin Date: Mon, 5 May 2025 19:44:07 -0400 Subject: [PATCH] button element for html-defined menus --- assets/Data/menu/npcintro.html | 3 ++- assets/Scripts/client/clienthooks.ts | 4 +++- assets/Scripts/client/uihooks.ts | 13 +++++++++++ docs/src/progress/renderertodo.md | 1 + .../client/ui/parsing/HtmlParser.java | 22 +++++++++++++++++++ .../renderer/ui/elements/Button.java | 22 +++++++++++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 assets/Scripts/client/uihooks.ts diff --git a/assets/Data/menu/npcintro.html b/assets/Data/menu/npcintro.html index d74924c0..d83855d2 100644 --- a/assets/Data/menu/npcintro.html +++ b/assets/Data/menu/npcintro.html @@ -4,4 +4,5 @@ testClass { margin-left: "50px"; } -

Hello!

\ No newline at end of file +

Hello!

+ \ No newline at end of file diff --git a/assets/Scripts/client/clienthooks.ts b/assets/Scripts/client/clienthooks.ts index 476f90bc..4470d672 100644 --- a/assets/Scripts/client/clienthooks.ts +++ b/assets/Scripts/client/clienthooks.ts @@ -1,3 +1,4 @@ +import { clientUIButtonHook } from "/Scripts/client/uihooks"; import { Engine } from "/Scripts/types/engine"; import { Hook } from "/Scripts/types/hook"; @@ -64,5 +65,6 @@ export const clientHooks: Hook[] = [ callback: (engine: Engine) => { engine.classes.areaUtils.static.selectAreaRectangular() } - } + }, + clientUIButtonHook, ] \ No newline at end of file diff --git a/assets/Scripts/client/uihooks.ts b/assets/Scripts/client/uihooks.ts new file mode 100644 index 00000000..f50eac58 --- /dev/null +++ b/assets/Scripts/client/uihooks.ts @@ -0,0 +1,13 @@ +import { Engine } from "/Scripts/types/engine"; +import { Hook } from "/Scripts/types/hook"; + +/** + * The hook that fires every time a dynamic button in the ui is clicked + */ +export const clientUIButtonHook: Hook = +{ + signal: "uiButton", + callback: (engine: Engine, data: string) => { + console.log("button clicked " + data) + } +} \ No newline at end of file diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 42865f87..66f66ac4 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1683,6 +1683,7 @@ Scaffolding for structure scanning service Add JSoup dependency Proof of concept of loading html to define ui Styling support for html-defined menus +Dynamic html-defined menus support button elements that call a client hook when clicked diff --git a/src/main/java/electrosphere/client/ui/parsing/HtmlParser.java b/src/main/java/electrosphere/client/ui/parsing/HtmlParser.java index f86ad21a..e925ad91 100644 --- a/src/main/java/electrosphere/client/ui/parsing/HtmlParser.java +++ b/src/main/java/electrosphere/client/ui/parsing/HtmlParser.java @@ -7,6 +7,9 @@ import java.util.stream.Collectors; import org.jsoup.nodes.Node; +import electrosphere.client.script.ClientScriptUtils; +import electrosphere.logger.LoggerInterface; +import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.Div; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elementtypes.ContainerElement; @@ -69,6 +72,25 @@ public class HtmlParser { } } } break; + case "button": { + String onClick = jsoupNode.attr("onclick"); + Runnable callback = null; + if(onClick == null){ + LoggerInterface.loggerUI.WARNING("Button with undefined onclick " + jsoupNode); + callback = () -> {}; + } else { + callback = () -> { + ClientScriptUtils.fireSignal("uiButton", onClick); + }; + } + rVal = Button.createEmptyButton(callback); + for(Node child : jsoupNode.childNodes()){ + Element childEl = HtmlParser.recursivelyParseChildren(child, styleAccumulator); + if(childEl != null){ + ((Button)rVal).addChild(childEl); + } + } + } break; case "style": //silently ignore break; diff --git a/src/main/java/electrosphere/renderer/ui/elements/Button.java b/src/main/java/electrosphere/renderer/ui/elements/Button.java index df6cfd64..ee04820a 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Button.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Button.java @@ -200,6 +200,28 @@ public class Button extends StandardContainerElement implements DrawableElement, return rVal; } + /** + * Creates a button with no label inside + * @param callback The callback to fire when the button is clicked + * @return The button + */ + public static Button createEmptyButton(Runnable callback){ + Button rVal = new Button(); + rVal.setPaddingTop(DEFAULT_PADDING); + rVal.setPaddingRight(DEFAULT_PADDING); + rVal.setPaddingLeft(DEFAULT_PADDING); + rVal.setPaddingBottom(DEFAULT_PADDING); + rVal.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + callback.run(); + if(Globals.virtualAudioSourceManager != null && rVal.audioPathOnClick != null){ + Globals.virtualAudioSourceManager.createUI(rVal.audioPathOnClick); + } + return false; + }}); + rVal.setAlignSelf(YogaAlignment.Start); + return rVal; + } + public boolean getVisible() { return visible; }