From 11bb9e592655327df3f50eb16fd6ff1caa9f75ca Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 15 Feb 2024 14:43:03 +0300 Subject: [PATCH] misc hud-related updates --- res/layouts/inventory.xml | 28 +---- res/layouts/inventory.xml.lua | 4 +- src/delegates.h | 12 +- src/frontend/InventoryView.cpp | 13 ++- src/frontend/UiDocument.cpp | 1 + src/frontend/gui/GUI.cpp | 4 + src/frontend/gui/GUI.h | 2 + src/frontend/gui/UINode.cpp | 27 ++++- src/frontend/gui/UINode.h | 13 ++- src/frontend/gui/controls.cpp | 18 ++- src/frontend/gui/controls.h | 6 +- src/frontend/gui/gui_xml.cpp | 22 ++-- src/frontend/gui/panels.cpp | 8 ++ src/frontend/hud.cpp | 113 +++++++++++++++---- src/frontend/hud.h | 40 ++++++- src/logic/scripting/LuaState.cpp | 12 +- src/logic/scripting/LuaState.h | 5 +- src/logic/scripting/api/libgui.cpp | 5 + src/logic/scripting/api/libgui.h | 2 + src/logic/scripting/scripting.cpp | 66 +---------- src/logic/scripting/scripting.h | 32 +----- src/logic/scripting/scripting_functional.cpp | 92 +++++++++++++++ src/logic/scripting/scripting_functional.h | 40 +++++++ 23 files changed, 400 insertions(+), 165 deletions(-) create mode 100644 src/logic/scripting/scripting_functional.cpp create mode 100644 src/logic/scripting/scripting_functional.h diff --git a/res/layouts/inventory.xml b/res/layouts/inventory.xml index 416778b6..a4e9189d 100644 --- a/res/layouts/inventory.xml +++ b/res/layouts/inventory.xml @@ -1,26 +1,4 @@ - - - - - - - - - - - - 4321.40 - - - - 120.0 - - - - -424.10 - - - - - + + + diff --git a/res/layouts/inventory.xml.lua b/res/layouts/inventory.xml.lua index 2386812c..f38a00e7 100644 --- a/res/layouts/inventory.xml.lua +++ b/res/layouts/inventory.xml.lua @@ -10,6 +10,6 @@ function inventory_share_func(invid, slotid) inventory.set(invid, slotid, 0, 0) end -function time_change(x) - world.set_day_time(x) +function inventory_reposition() + return 10, gui.get_viewport()[2] - document.root.size[2] - 100 end diff --git a/src/delegates.h b/src/delegates.h index 7698c59a..debb7f59 100644 --- a/src/delegates.h +++ b/src/delegates.h @@ -1,17 +1,23 @@ #ifndef DELEGATES_H_ #define DELEGATES_H_ +#include #include #include using runnable = std::function; -using stringconsumer = std::function; + +// data sources using wstringsupplier = std::function; -using wstringconsumer = std::function; using doublesupplier = std::function; -using doubleconsumer = std::function; using boolsupplier = std::function; +using vec2supplier = std::function; + +using stringconsumer = std::function; +using wstringconsumer = std::function; +using doubleconsumer = std::function; using boolconsumer = std::function; +using int_array_consumer = std::function; using wstringchecker = std::function; #endif // DELEGATES_H_ diff --git a/src/frontend/InventoryView.cpp b/src/frontend/InventoryView.cpp index cc8902a7..90304790 100644 --- a/src/frontend/InventoryView.cpp +++ b/src/frontend/InventoryView.cpp @@ -44,6 +44,15 @@ InventoryBuilder::InventoryBuilder() { view = std::make_shared(); } +/** Add slots grid to inventory view + * @param cols grid columns + * @param count total number of grid slots + * @param coord position of the first slot of the grid + * @param padding additional space around the grid + * @param addpanel automatically create panel behind the grid + * with size including padding + * @param slotLayout slot settings (index and position are ignored) + */ void InventoryBuilder::addGrid( int cols, int count, glm::vec2 coord, @@ -70,7 +79,7 @@ void InventoryBuilder::addGrid( if (addpanel) { auto panel = std::make_shared(coord, glm::vec2(width, height)); - view->setColor(glm::vec4(0, 0, 0, 0.5f)); + view->setColor(glm::vec4(0.122f, 0.122f, 0.122f, 0.878f)); view->add(panel); } @@ -416,7 +425,7 @@ static void readSlotsGrid(InventoryView* view, gui::UiXmlReader& reader, xml::xm slotLayout.index = startIndex + idx; slotLayout.position += glm::vec2( padding + col * (slotSize + interval), - padding + row * (slotSize + interval) + padding + (rows-row-1) * (slotSize + interval) ); auto slot = view->addSlot(slotLayout); view->add(slot, slotLayout.position); diff --git a/src/frontend/UiDocument.cpp b/src/frontend/UiDocument.cpp index 301c1f7c..28b90825 100644 --- a/src/frontend/UiDocument.cpp +++ b/src/frontend/UiDocument.cpp @@ -69,6 +69,7 @@ std::unique_ptr UiDocument::read(AssetsLoader& loader, int penv, std auto view = reader.readXML( file.u8string(), xmldoc->getRoot() ); + view->setId("root"); uidocscript script {}; auto scriptFile = fs::path(file.u8string()+".lua"); if (fs::is_regular_file(scriptFile)) { diff --git a/src/frontend/gui/GUI.cpp b/src/frontend/gui/GUI.cpp index f0049a92..0886014c 100644 --- a/src/frontend/gui/GUI.cpp +++ b/src/frontend/gui/GUI.cpp @@ -170,3 +170,7 @@ void GUI::setFocus(std::shared_ptr node) { focus->focus(this); } } + +std::shared_ptr GUI::getContainer() const { + return container; +} diff --git a/src/frontend/gui/GUI.h b/src/frontend/gui/GUI.h index 17ddd493..b893372a 100644 --- a/src/frontend/gui/GUI.h +++ b/src/frontend/gui/GUI.h @@ -76,6 +76,8 @@ namespace gui { std::shared_ptr get(std::string name); void remove(std::string name); void setFocus(std::shared_ptr node); + + std::shared_ptr getContainer() const; }; } diff --git a/src/frontend/gui/UINode.cpp b/src/frontend/gui/UINode.cpp index 1a726cc8..9ca0c150 100644 --- a/src/frontend/gui/UINode.cpp +++ b/src/frontend/gui/UINode.cpp @@ -119,7 +119,18 @@ glm::vec2 UINode::getSize() const { } void UINode::setSize(glm::vec2 size) { - this->size = size; + this->size = glm::vec2( + glm::max(minSize.x, size.x), glm::max(minSize.y, size.y) + ); +} + +glm::vec2 UINode::getMinSize() const { + return minSize; +} + +void UINode::setMinSize(glm::vec2 minSize) { + this->minSize = minSize; + setSize(getSize()); } void UINode::setColor(glm::vec4 color) { @@ -158,6 +169,14 @@ int UINode::getZIndex() const { void UINode::lock() { } +vec2supplier UINode::getPositionFunc() const { + return positionfunc; +} + +void UINode::setPositionFunc(vec2supplier func) { + positionfunc = func; +} + void UINode::setId(const std::string& id) { this->id = id; } @@ -165,3 +184,9 @@ void UINode::setId(const std::string& id) { const std::string& UINode::getId() const { return id; } + +void UINode::reposition() { + if (positionfunc) { + setCoord(positionfunc()); + } +} diff --git a/src/frontend/gui/UINode.h b/src/frontend/gui/UINode.h index 45d6ca8b..25c3133a 100644 --- a/src/frontend/gui/UINode.h +++ b/src/frontend/gui/UINode.h @@ -6,6 +6,7 @@ #include #include #include +#include "../../delegates.h" class GfxContext; class Assets; @@ -26,6 +27,7 @@ namespace gui { protected: glm::vec2 coord; glm::vec2 size; + glm::vec2 minSize {1.0f}; glm::vec4 color {1.0f}; glm::vec4 hoverColor {1.0f}; glm::vec4 margin {1.0f}; @@ -38,6 +40,7 @@ namespace gui { int zindex = 0; Align align = Align::left; UINode* parent = nullptr; + vec2supplier positionfunc = nullptr; UINode(glm::vec2 coord, glm::vec2 size); public: virtual ~UINode(); @@ -112,14 +115,22 @@ namespace gui { /* Calculate screen position of the element */ virtual glm::vec2 calcCoord() const; virtual void setCoord(glm::vec2 coord); - glm::vec2 getCoord() const; + virtual glm::vec2 getCoord() const; virtual glm::vec2 getSize() const; virtual void setSize(glm::vec2 size); + virtual glm::vec2 getMinSize() const; + virtual void setMinSize(glm::vec2 size); virtual void refresh() {}; virtual void lock(); + virtual vec2supplier getPositionFunc() const; + virtual void setPositionFunc(vec2supplier); + void setId(const std::string& id); const std::string& getId() const; + + /* Fetch coord from positionfunc if assigned */ + void reposition(); }; } diff --git a/src/frontend/gui/controls.cpp b/src/frontend/gui/controls.cpp index e2dc7003..481a8c64 100644 --- a/src/frontend/gui/controls.cpp +++ b/src/frontend/gui/controls.cpp @@ -6,6 +6,7 @@ #include "../../assets/Assets.h" #include "../../graphics/Batch2D.h" #include "../../graphics/Font.h" +#include "../../graphics/Texture.h" #include "../../graphics/GfxContext.h" #include "../../util/stringutil.h" #include "GUI.h" @@ -64,9 +65,8 @@ void Label::draw(const GfxContext* pctx, Assets* assets) { font->draw(batch, text, coord.x, coord.y); } -Label* Label::textSupplier(wstringsupplier supplier) { +void Label::textSupplier(wstringsupplier supplier) { this->supplier = supplier; - return this; } // ================================= Image ==================================== @@ -78,12 +78,24 @@ void Image::draw(const GfxContext* pctx, Assets* assets) { glm::vec2 coord = calcCoord(); glm::vec4 color = getColor(); auto batch = pctx->getBatch2D(); - batch->texture(assets->getTexture(texture)); + + auto texture = assets->getTexture(this->texture); + if (texture && autoresize) { + setSize(glm::vec2(texture->width, texture->height)); + } + batch->texture(texture); batch->color = color; batch->rect(coord.x, coord.y, size.x, size.y, 0, 0, 0, UVRegion(), false, true, color); } +void Image::setAutoResize(bool flag) { + autoresize = flag; +} +bool Image::isAutoResize() const { + return autoresize; +} + // ================================= Button =================================== Button::Button(std::shared_ptr content, glm::vec4 padding) : Panel(glm::vec2(), padding, 0) { diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index 954a3905..7ee35c1f 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -31,16 +31,20 @@ namespace gui { virtual void draw(const GfxContext* pctx, Assets* assets) override; - virtual Label* textSupplier(wstringsupplier supplier); + virtual void textSupplier(wstringsupplier supplier); }; class Image : public UINode { protected: std::string texture; + bool autoresize = false; public: Image(std::string texture, glm::vec2 size=glm::vec2(32,32)); virtual void draw(const GfxContext* pctx, Assets* assets) override; + + virtual void setAutoResize(bool flag); + virtual bool isAutoResize() const; }; class Button : public Panel { diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index c4965d24..7463937d 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -21,7 +21,7 @@ static Align align_from_string(const std::string& str, Align def) { } /* Read basic UINode properties */ -static void _readUINode(xml::xmlelement element, UINode& node) { +static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) { if (element->has("id")) { node.setId(element->attr("id").getText()); } @@ -40,13 +40,21 @@ static void _readUINode(xml::xmlelement element, UINode& node) { if (element->has("z-index")) { node.setZIndex(element->attr("z-index").asInt()); } + if (element->has("position-func")) { + auto supplier = scripting::create_vec2_supplier( + reader.getEnvironment().getId(), + element->attr("position-func").getText(), + reader.getFilename()+".lua" + ); + node.setPositionFunc(supplier); + } std::string alignName = element->attr("align", "").getText(); node.setAlign(align_from_string(alignName, node.getAlign())); } static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) { - _readUINode(element, container); + _readUINode(reader, element, container); if (element->has("scrollable")) { container.setScrollable(element->attr("scrollable").asBool()); @@ -66,11 +74,11 @@ void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, Conta } void UiXmlReader::readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) { - _readUINode(element, node); + _readUINode(reader, element, node); } static void _readPanel(UiXmlReader& reader, xml::xmlelement element, Panel& panel) { - _readUINode(element, panel); + _readUINode(reader, element, panel); if (element->has("padding")) { glm::vec4 padding = element->attr("padding").asVec4(); @@ -114,7 +122,7 @@ static std::wstring readAndProcessInnerText(xml::xmlelement element) { static std::shared_ptr readLabel(UiXmlReader& reader, xml::xmlelement element) { std::wstring text = readAndProcessInnerText(element); auto label = std::make_shared