From 9befbb97957e9a76656334c729b8b4dc20505bee Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 24 Apr 2025 22:41:40 +0300 Subject: [PATCH 01/12] add 'ondefocus' ui event --- src/graphics/ui/elements/UINode.cpp | 6 ++++++ src/graphics/ui/elements/UINode.hpp | 7 +++++-- src/graphics/ui/gui_xml.cpp | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index a5b0e4d5..49407b8d 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -74,6 +74,11 @@ UINode* UINode::listenDoubleClick(const onaction& action) { return this; } +UINode* UINode::listenDefocus(const onaction& action) { + defocusCallbacks.listen(action); + return this; +} + void UINode::click(int, int) { pressed = true; } @@ -98,6 +103,7 @@ bool UINode::isPressed() const { void UINode::defocus() { focused = false; + defocusCallbacks.notify(gui); } bool UINode::isFocused() const { diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index aad04343..9fc2edc4 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -114,6 +114,8 @@ namespace gui { ActionsSet actions; /// @brief 'ondoubleclick' callbacks ActionsSet doubleClickCallbacks; + /// @brief 'ondefocus' callbacks + ActionsSet defocusCallbacks; /// @brief element tooltip text std::wstring tooltip; /// @brief element tooltip delay @@ -169,8 +171,9 @@ namespace gui { /// @brief Get element z-index int getZIndex() const; - virtual UINode* listenAction(const onaction &action); - virtual UINode* listenDoubleClick(const onaction &action); + virtual UINode* listenAction(const onaction& action); + virtual UINode* listenDoubleClick(const onaction& action); + virtual UINode* listenDefocus(const onaction& action); virtual void onFocus() {focused = true;} virtual void doubleClick(int x, int y); diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index d76b76b7..f17092a7 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -180,6 +180,10 @@ static void read_uinode( node.listenAction(onclick); } + if (auto ondefocus = create_action(reader, element, "ondefocus")) { + node.listenDefocus(ondefocus); + } + if (auto ondoubleclick = create_action(reader, element, "ondoubleclick")) { node.listenDoubleClick(ondoubleclick); } From 8e8cabf2d1707725a8b38e48a8c183c448a452d1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 24 Apr 2025 22:42:15 +0300 Subject: [PATCH 02/12] add data argument to container:add(...) --- src/logic/scripting/lua/libs/libgui.cpp | 10 +++++++++- src/logic/scripting/scripting.cpp | 16 ++++++++++++++++ src/logic/scripting/scripting.hpp | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 3fb5fcde..e1180e1c 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -83,8 +83,16 @@ static int l_container_add(lua::State* L) { } auto xmlsrc = lua::require_string(L, 2); try { + auto env = docnode.document->getEnvironment(); + if (lua::istable(L, 3)) { + env = create_environment(std::move(env)); + lua::pushenv(L, *env); + lua::pushvalue(L, 3); + lua::setfield(L, "DATA"); + lua::pop(L); + } auto subnode = guiutil::create( - engine->getGUI(), xmlsrc, docnode.document->getEnvironment() + engine->getGUI(), xmlsrc, std::move(env) ); node->add(subnode); UINode::getIndices(subnode, docnode.document->getMapWriteable()); diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 5ebbb42b..2d95fdaa 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -154,6 +154,22 @@ std::unique_ptr scripting::start_coroutine( }); } +[[nodiscard]] scriptenv scripting::create_environment( + const scriptenv& parent +) { + auto L = lua::get_main_state(); + int id = lua::create_environment(L, (parent ? *parent : 0)); + lua::pushenv(L, id); + lua::pushvalue(L, -1); + lua::setfield(L, "CUR_ENV"); + + lua::pop(L); + return std::shared_ptr(new int(id), [=](int* id) { //-V508 + lua::remove_environment(L, *id); + delete id; + }); +} + [[nodiscard]] scriptenv scripting::create_doc_environment( const scriptenv& parent, const std::string& name ) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index e5f4ef32..0f375746 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -58,6 +58,7 @@ namespace scripting { scriptenv get_root_environment(); scriptenv create_pack_environment(const ContentPack& pack); + scriptenv create_environment(const scriptenv& parent); scriptenv create_doc_environment( const scriptenv& parent, const std::string& name ); From 1e90115a26b928fc10b3f87cf8a182bc653f5b29 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 20:16:57 +0300 Subject: [PATCH 03/12] add 'onfocus' ui event & optimize container:add --- src/frontend/UiDocument.cpp | 2 +- src/graphics/ui/elements/Container.cpp | 7 +++++-- src/graphics/ui/elements/Container.hpp | 1 + src/graphics/ui/elements/UINode.cpp | 10 ++++++++++ src/graphics/ui/elements/UINode.hpp | 5 ++++- src/graphics/ui/gui_util.cpp | 2 +- src/graphics/ui/gui_xml.cpp | 8 ++++++-- src/graphics/ui/gui_xml.hpp | 4 ++-- src/logic/scripting/lua/libs/libgui.cpp | 2 +- 9 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/frontend/UiDocument.cpp b/src/frontend/UiDocument.cpp index 5e8df9f1..7c6f8d13 100644 --- a/src/frontend/UiDocument.cpp +++ b/src/frontend/UiDocument.cpp @@ -67,7 +67,7 @@ std::unique_ptr UiDocument::read( ? scripting::create_doc_environment(scripting::get_root_environment(), name) : scripting::create_doc_environment(penv, name); - gui::UiXmlReader reader(gui, env); + gui::UiXmlReader reader(gui, scriptenv(env)); auto view = reader.readXML(file.string(), *xmldoc->getRoot()); view->setId("root"); uidocscript script {}; diff --git a/src/graphics/ui/elements/Container.cpp b/src/graphics/ui/elements/Container.cpp index 72de920b..eddde7e2 100644 --- a/src/graphics/ui/elements/Container.cpp +++ b/src/graphics/ui/elements/Container.cpp @@ -71,6 +71,10 @@ void Container::mouseRelease(int x, int y) { } void Container::act(float delta) { + if (mustRefresh) { + refresh(); + mustRefresh = false; + } for (const auto& node : nodes) { if (node->isVisible()) { node->act(delta); @@ -162,7 +166,7 @@ void Container::add(const std::shared_ptr& node) { nodes.push_back(node); node->setParent(this); node->reposition(); - refresh(); + mustRefresh = true; } void Container::add(const std::shared_ptr& node, glm::vec2 pos) { @@ -202,7 +206,6 @@ void Container::listenInterval(float interval, ontimeout callback, int repeat) { void Container::setSize(glm::vec2 size) { if (size == getSize()) { - refresh(); return; } UINode::setSize(size); diff --git a/src/graphics/ui/elements/Container.hpp b/src/graphics/ui/elements/Container.hpp index d3dbbfc7..459d5b07 100644 --- a/src/graphics/ui/elements/Container.hpp +++ b/src/graphics/ui/elements/Container.hpp @@ -9,6 +9,7 @@ namespace gui { class Container : public UINode, public ::util::ObjectsKeeper { int prevScrollY = -1; + bool mustRefresh = true; protected: std::vector> nodes; std::vector intervalEvents; diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index 49407b8d..1e8f48d6 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -74,6 +74,11 @@ UINode* UINode::listenDoubleClick(const onaction& action) { return this; } +UINode* UINode::listenFocus(const onaction& action) { + focusCallbacks.listen(action); + return this; +} + UINode* UINode::listenDefocus(const onaction& action) { defocusCallbacks.listen(action); return this; @@ -101,6 +106,11 @@ bool UINode::isPressed() const { return pressed; } +void UINode::onFocus() { + focused = true; + focusCallbacks.notify(gui); +} + void UINode::defocus() { focused = false; defocusCallbacks.notify(gui); diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index 9fc2edc4..e03eb91e 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -114,6 +114,8 @@ namespace gui { ActionsSet actions; /// @brief 'ondoubleclick' callbacks ActionsSet doubleClickCallbacks; + /// @brief 'onfocus' callbacks + ActionsSet focusCallbacks; /// @brief 'ondefocus' callbacks ActionsSet defocusCallbacks; /// @brief element tooltip text @@ -173,9 +175,10 @@ namespace gui { virtual UINode* listenAction(const onaction& action); virtual UINode* listenDoubleClick(const onaction& action); + virtual UINode* listenFocus(const onaction& action); virtual UINode* listenDefocus(const onaction& action); - virtual void onFocus() {focused = true;} + virtual void onFocus(); virtual void doubleClick(int x, int y); virtual void click(int x, int y); virtual void clicked(Mousecode button) {} diff --git a/src/graphics/ui/gui_util.cpp b/src/graphics/ui/gui_util.cpp index 76ed43ca..6d28b990 100644 --- a/src/graphics/ui/gui_util.cpp +++ b/src/graphics/ui/gui_util.cpp @@ -21,7 +21,7 @@ std::shared_ptr guiutil::create( if (env == nullptr) { env = scripting::get_root_environment(); } - UiXmlReader reader(gui, env); + UiXmlReader reader(gui, std::move(env)); return reader.readXML("[string]", source); } diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index f17092a7..06262fec 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -63,7 +63,7 @@ static runnable create_runnable( const std::string& name ) { if (element.has(name)) { - std::string text = element.attr(name).getText(); + const std::string& text = element.attr(name).getText(); if (!text.empty()) { return scripting::create_runnable( reader.getEnvironment(), text, reader.getFilename() @@ -180,6 +180,10 @@ static void read_uinode( node.listenAction(onclick); } + if (auto onfocus = create_action(reader, element, "onfocus")) { + node.listenFocus(onfocus); + } + if (auto ondefocus = create_action(reader, element, "ondefocus")) { node.listenDefocus(ondefocus); } @@ -761,7 +765,7 @@ static std::shared_ptr read_iframe( return iframe; } -UiXmlReader::UiXmlReader(gui::GUI& gui, const scriptenv& env) : gui(gui), env(env) { +UiXmlReader::UiXmlReader(gui::GUI& gui, scriptenv&& env) : gui(gui), env(std::move(env)) { contextStack.emplace(""); add("image", read_image); add("canvas", read_canvas); diff --git a/src/graphics/ui/gui_xml.hpp b/src/graphics/ui/gui_xml.hpp index 73350352..4a8a301f 100644 --- a/src/graphics/ui/gui_xml.hpp +++ b/src/graphics/ui/gui_xml.hpp @@ -20,9 +20,9 @@ namespace gui { std::unordered_set ignored; std::stack contextStack; std::string filename; - const scriptenv& env; + scriptenv env; public: - UiXmlReader(gui::GUI& gui, const scriptenv& env); + UiXmlReader(gui::GUI& gui, scriptenv&& env); void add(const std::string& tag, uinode_reader reader); bool hasReader(const std::string& tag) const; diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index e1180e1c..466ea3aa 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -94,8 +94,8 @@ static int l_container_add(lua::State* L) { auto subnode = guiutil::create( engine->getGUI(), xmlsrc, std::move(env) ); - node->add(subnode); UINode::getIndices(subnode, docnode.document->getMapWriteable()); + node->add(std::move(subnode)); } catch (const std::exception& err) { throw std::runtime_error(err.what()); } From f944dfb51d276f7e2662d7504a13c994906f947d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 20:17:37 +0300 Subject: [PATCH 04/12] optimize gui.template --- res/scripts/stdlib.lua | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index a0f18e6d..76872cd6 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -226,15 +226,17 @@ end function gui.template(name, params) local text = file.read(file.find("layouts/templates/"..name..".xml")) - for k,v in pairs(params) do - local arg = tostring(v):gsub("'", "\\'"):gsub('"', '\\"') - text = text:gsub("(%%{"..k.."})", arg) - end - text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''") - text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"") + text = text:gsub("%%{([^}]+)}", function(n) + local s = params[n] + if not s or #s == 0 then + return + end + local e = string.escape(s) + return e:sub(2, #e-1) + end) + text = text:gsub('if%s*=%s*[\'"]%%{%w+}[\'"]', "if=\"\"") -- remove unsolved properties: attr='%{var}' - text = text:gsub("%s*%S+='%%{[^}]+}'%s*", " ") - text = text:gsub('%s*%S+="%%{[^}]+}"%s*', " ") + text = text:gsub('%s*%S+=[\'"]%%{[^}]+}[\'"]%s*', " ") return text end From 032b5ae9dc7bba0b631da69fb2fdc3841be6b545 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 21:58:09 +0300 Subject: [PATCH 05/12] fix --- res/scripts/stdlib.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 76872cd6..d5cd34bd 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -228,7 +228,10 @@ function gui.template(name, params) local text = file.read(file.find("layouts/templates/"..name..".xml")) text = text:gsub("%%{([^}]+)}", function(n) local s = params[n] - if not s or #s == 0 then + if type(s) ~= "string" then + return s + end + if #s == 0 then return end local e = string.escape(s) From 79528a44ea1fdc9aa3803dd9ef0cb7782a81a968 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 22:12:34 +0300 Subject: [PATCH 06/12] add 'region' image property --- src/graphics/ui/elements/Image.cpp | 6 +++++- src/graphics/ui/elements/Image.hpp | 3 +++ src/graphics/ui/gui_xml.cpp | 5 +++++ src/logic/scripting/lua/libs/libgui.cpp | 7 +++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/graphics/ui/elements/Image.cpp b/src/graphics/ui/elements/Image.cpp index 4a1fabd3..ee3ec886 100644 --- a/src/graphics/ui/elements/Image.cpp +++ b/src/graphics/ui/elements/Image.cpp @@ -55,7 +55,7 @@ void Image::draw(const DrawContext& pctx, const Assets& assets) { 0, 0, 0, - UVRegion(), + region, false, true, calcColor() @@ -76,3 +76,7 @@ const std::string& Image::getTexture() const { void Image::setTexture(const std::string& name) { texture = name; } + +void Image::setRegion(const UVRegion& region) { + this->region = region; +} diff --git a/src/graphics/ui/elements/Image.hpp b/src/graphics/ui/elements/Image.hpp index cc5ff17c..579ddd75 100644 --- a/src/graphics/ui/elements/Image.hpp +++ b/src/graphics/ui/elements/Image.hpp @@ -1,11 +1,13 @@ #pragma once #include "UINode.hpp" +#include "maths/UVRegion.hpp" namespace gui { class Image : public UINode { protected: std::string texture; + UVRegion region {}; bool autoresize = false; public: Image(GUI& gui, std::string texture, glm::vec2 size=glm::vec2(32,32)); @@ -16,5 +18,6 @@ namespace gui { virtual bool isAutoResize() const; virtual const std::string& getTexture() const; virtual void setTexture(const std::string& name); + void setRegion(const UVRegion& region); }; } diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index 06262fec..b01e008e 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -544,6 +544,11 @@ static std::shared_ptr read_image( std::string src = element.attr("src", "").getText(); auto image = std::make_shared(reader.getGUI(), src); read_uinode(reader, element, *image); + + if (element.has("region")) { + auto vec = element.attr("region").asVec4(); + image->setRegion(UVRegion(vec.x, vec.y, vec.z, vec.w)); + } return image; } diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 466ea3aa..56bada71 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -659,6 +659,12 @@ static void p_set_src(UINode* node, lua::State* L, int idx) { iframe->setSrc(lua::require_string(L, idx)); } } +static void p_set_region(UINode* node, lua::State* L, int idx) { + if (auto image = dynamic_cast(node)) { + auto vec = lua::tovec4(L, idx); + image->setRegion(UVRegion(vec.x, vec.y, vec.z, vec.w)); + } +} static void p_set_value(UINode* node, lua::State* L, int idx) { if (auto bar = dynamic_cast(node)) { bar->setValue(lua::tonumber(L, idx)); @@ -785,6 +791,7 @@ static int l_gui_setattr(lua::State* L) { {"inventory", p_set_inventory}, {"cursor", p_set_cursor}, {"focused", p_set_focused}, + {"region", p_set_region}, }; auto func = setters.find(attr); if (func != setters.end()) { From 1c8c461904ef76fa0acfeb85aa7ebecb29803daf Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 22:18:25 +0300 Subject: [PATCH 07/12] update doc/*/xml-ui-layouts.md --- doc/en/xml-ui-layouts.md | 3 +++ doc/ru/xml-ui-layouts.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/doc/en/xml-ui-layouts.md b/doc/en/xml-ui-layouts.md index 3f22c748..b25028f2 100644 --- a/doc/en/xml-ui-layouts.md +++ b/doc/en/xml-ui-layouts.md @@ -40,6 +40,8 @@ Examples: - `size-func` - element size provider (two numbers), called when the size of the container in which the element is located changes, or when an element is added to the container. Can be called before on_hud_open is called. - `onclick` - lua function called when an element is clicked. - `ondoubleclick` - lua function called when you double click on an element. +- `onfocus` - lua function called when focusing on an element. +- `ondefocus` - lua function called when the element loses focus. - `tooltip` - tooltip text - `tooltip-delay` - tooltip show-up delay - `gravity` - automatic positioning of the element in the container. (Does not work in automatic containers like panel). Values: *top-left, top-center, top-right, center-left, center-center, center-right, bottom-left, bottom-center, bottom-right*. @@ -112,6 +114,7 @@ Inner text is a button text. - `src` - name of an image stored in textures folder. Extension is not specified. Type: string. Example: *gui/error* +- `region` - image region x1, y1, x2, y2 from 0.0, 0.0 (upper left corner), 1.0, 1.0 (lower right corner) ## *canvas* diff --git a/doc/ru/xml-ui-layouts.md b/doc/ru/xml-ui-layouts.md index df8e08e3..179f1bc0 100644 --- a/doc/ru/xml-ui-layouts.md +++ b/doc/ru/xml-ui-layouts.md @@ -44,6 +44,8 @@ - `size-func` - поставщик размера элемента (два числа), вызываемый при изменении размера контейнера, в котором находится элемент, либо при добавлении элемента в контейнер. Может быть вызван до вызова on_hud_open. - `onclick` - lua функция вызываемая при нажатии на элемент. - `ondoubleclick` - lua функция вызываемая при двойном нажатии на элемент. +- `onfocus` - lua функция вызываемая при фокусировке на элемент. +- `ondefocus` - lua функция вызываемая при потере фокуса элеметом. - `tooltip` - текст всплывающей подсказки - `tooltip-delay` - задержка появления всплывающей подсказки - `gravity` - автоматическое позиционирование элемента в контейнере. (Не работает в автоматических контейнерах, как panel). Значения: *top-left, top-center, top-right, center-left, center-center, center-right, bottom-left, bottom-center, bottom-right*. @@ -113,6 +115,7 @@ ## Изображение - *image* - `src` - имя изображения в папке textures без указания расширения. Тип: строка. Например `gui/error` +- `region` - под-регион изображения x1, y1, x2, y2 от 0.0, 0.0 (левый верхний угол), 1.0, 1.0 (правый нижний угол) ## Холст - *canvas* From 3e336575e86b4789f96d635ebd808810a07c4b3f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 22:22:17 +0300 Subject: [PATCH 08/12] make image.region readable --- src/graphics/ui/elements/Image.cpp | 4 ++++ src/graphics/ui/elements/Image.hpp | 1 + src/logic/scripting/lua/libs/libgui.cpp | 9 +++++++++ 3 files changed, 14 insertions(+) diff --git a/src/graphics/ui/elements/Image.cpp b/src/graphics/ui/elements/Image.cpp index ee3ec886..f321ddf8 100644 --- a/src/graphics/ui/elements/Image.cpp +++ b/src/graphics/ui/elements/Image.cpp @@ -80,3 +80,7 @@ void Image::setTexture(const std::string& name) { void Image::setRegion(const UVRegion& region) { this->region = region; } + +const UVRegion& Image::getRegion() const { + return region; +} diff --git a/src/graphics/ui/elements/Image.hpp b/src/graphics/ui/elements/Image.hpp index 579ddd75..40765a4c 100644 --- a/src/graphics/ui/elements/Image.hpp +++ b/src/graphics/ui/elements/Image.hpp @@ -19,5 +19,6 @@ namespace gui { virtual const std::string& getTexture() const; virtual void setTexture(const std::string& name); void setRegion(const UVRegion& region); + const UVRegion& getRegion() const; }; } diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 56bada71..af317f94 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -345,6 +345,14 @@ static int p_get_src(UINode* node, lua::State* L) { return 0; } +static int p_get_region(UINode* node, lua::State* L) { + if (auto image = dynamic_cast(node)) { + const auto& region = image->getRegion(); + return lua::pushvec4(L, {region.u1, region.v1, region.u2, region.v2}); + } + return 0; +} + static int p_get_data(UINode* node, lua::State* L) { if (auto canvas = dynamic_cast(node)) { return lua::newuserdata(L, canvas->texture(), canvas->data()); @@ -556,6 +564,7 @@ static int l_gui_getattr(lua::State* L) { {"cursor", p_get_cursor}, {"data", p_get_data}, {"parent", p_get_parent}, + {"region", p_get_region}, }; auto func = getters.find(attr); if (func != getters.end()) { From d2b4e096aeed678e28bdfc46cd0689ba28552e05 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 22:23:25 +0300 Subject: [PATCH 09/12] update doc/*/scripting/ui.md --- doc/en/scripting/ui.md | 7 ++++--- doc/ru/scripting/ui.md | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/en/scripting/ui.md b/doc/en/scripting/ui.md index 66315f29..85420fa2 100644 --- a/doc/en/scripting/ui.md +++ b/doc/en/scripting/ui.md @@ -164,9 +164,10 @@ Properties: Properties: -| Name | Type | Read | Write | Description | -| ----- | ------ | ---- | ----- | ------------ | -| src | string | yes | yes | texture name | +| Name | Type | Read | Write | Description | +| ------ | ------ | ---- | ----- | ---------------- | +| src | string | yes | yes | texture name | +| region | vec4 | yes | yes | image sub-region | ## Canvas diff --git a/doc/ru/scripting/ui.md b/doc/ru/scripting/ui.md index cdc7a9bd..8dae3f4d 100644 --- a/doc/ru/scripting/ui.md +++ b/doc/ru/scripting/ui.md @@ -164,9 +164,10 @@ document["worlds-panel"]:clear() Свойства: -| Название | Тип | Чтение | Запись | Описание | -| -------- | ------ | ------ | ------ | --------------------- | -| src | string | да | да | отображаемая текстура | +| Название | Тип | Чтение | Запись | Описание | +| -------- | ------ | ------ | ------ | ---------------------- | +| src | string | да | да | отображаемая текстура | +| region | vec4 | да | да | под-регион изображения | ## Холст (canvas) From cefa26b4976686e3e50fe6906f5be9cf946af27f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 26 Apr 2025 23:03:02 +0300 Subject: [PATCH 10/12] minor refactor --- src/coders/xml.hpp | 4 ++-- src/graphics/ui/gui_xml.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coders/xml.hpp b/src/coders/xml.hpp index 5831c29a..f626dd34 100644 --- a/src/coders/xml.hpp +++ b/src/coders/xml.hpp @@ -53,11 +53,11 @@ namespace xml { /// @brief Get element tag const std::string& getTag() const; - inline bool isText() const { + bool isText() const { return getTag() == "#"; } - inline const std::string& text() const { + const std::string& getInnerText() const { return attr("#").getText(); } diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index b01e008e..2b0a9ab0 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -287,7 +287,7 @@ static std::wstring parse_inner_text( ) { std::wstring text = L""; if (element.size() == 1) { - std::string source = element.sub(0).attr("#").getText(); + std::string source = element.sub(0).getInnerText(); util::trim(source); text = util::str2wstr_utf8(source); if (text[0] == '@') { @@ -387,7 +387,7 @@ static std::shared_ptr read_button( std::shared_ptr