Merge branch 'main' into render-update
This commit is contained in:
+2
-2
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ template<> void ContentUnitLoader<Block>::loadUnit(
|
||||
if (auto found = root.at("emission")) {
|
||||
const auto& emissionarr = *found;
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
def.emission[i] = std::clamp(emissionarr[i].asInteger(), static_cast<integer_t>(0), static_cast<integer_t>(15));
|
||||
def.emission[i] = glm::clamp(emissionarr[i].asInteger(), static_cast<integer_t>(0), static_cast<integer_t>(15));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ std::unique_ptr<UiDocument> 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 {};
|
||||
|
||||
@@ -71,6 +71,7 @@ void Container::mouseRelease(int x, int y) {
|
||||
}
|
||||
|
||||
void Container::act(float delta) {
|
||||
UINode::act(delta);
|
||||
for (const auto& node : nodes) {
|
||||
if (node->isVisible()) {
|
||||
node->act(delta);
|
||||
@@ -162,7 +163,13 @@ void Container::add(const std::shared_ptr<UINode>& node) {
|
||||
nodes.push_back(node);
|
||||
node->setParent(this);
|
||||
node->reposition();
|
||||
refresh();
|
||||
mustRefresh = true;
|
||||
|
||||
auto parent = getParent();
|
||||
while (parent) {
|
||||
parent->setMustRefresh();
|
||||
parent = parent->getParent();
|
||||
}
|
||||
}
|
||||
|
||||
void Container::add(const std::shared_ptr<UINode>& node, glm::vec2 pos) {
|
||||
@@ -202,7 +209,6 @@ void Container::listenInterval(float interval, ontimeout callback, int repeat) {
|
||||
|
||||
void Container::setSize(glm::vec2 size) {
|
||||
if (size == getSize()) {
|
||||
refresh();
|
||||
return;
|
||||
}
|
||||
UINode::setSize(size);
|
||||
|
||||
@@ -55,7 +55,7 @@ void Image::draw(const DrawContext& pctx, const Assets& assets) {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
UVRegion(),
|
||||
region,
|
||||
false,
|
||||
true,
|
||||
calcColor()
|
||||
@@ -76,3 +76,11 @@ const std::string& Image::getTexture() const {
|
||||
void Image::setTexture(const std::string& name) {
|
||||
texture = name;
|
||||
}
|
||||
|
||||
void Image::setRegion(const UVRegion& region) {
|
||||
this->region = region;
|
||||
}
|
||||
|
||||
const UVRegion& Image::getRegion() const {
|
||||
return region;
|
||||
}
|
||||
|
||||
@@ -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,7 @@ namespace gui {
|
||||
virtual bool isAutoResize() const;
|
||||
virtual const std::string& getTexture() const;
|
||||
virtual void setTexture(const std::string& name);
|
||||
void setRegion(const UVRegion& region);
|
||||
const UVRegion& getRegion() const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,16 @@ 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;
|
||||
}
|
||||
|
||||
void UINode::click(int, int) {
|
||||
pressed = true;
|
||||
}
|
||||
@@ -96,8 +106,14 @@ bool UINode::isPressed() const {
|
||||
return pressed;
|
||||
}
|
||||
|
||||
void UINode::onFocus() {
|
||||
focused = true;
|
||||
focusCallbacks.notify(gui);
|
||||
}
|
||||
|
||||
void UINode::defocus() {
|
||||
focused = false;
|
||||
defocusCallbacks.notify(gui);
|
||||
}
|
||||
|
||||
bool UINode::isFocused() const {
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace gui {
|
||||
class UINode : public std::enable_shared_from_this<UINode> {
|
||||
protected:
|
||||
GUI& gui;
|
||||
bool mustRefresh = true;
|
||||
private:
|
||||
/// @brief element identifier used for direct access in UiDocument
|
||||
std::string id = "";
|
||||
@@ -114,6 +115,10 @@ namespace gui {
|
||||
ActionsSet actions;
|
||||
/// @brief 'ondoubleclick' callbacks
|
||||
ActionsSet doubleClickCallbacks;
|
||||
/// @brief 'onfocus' callbacks
|
||||
ActionsSet focusCallbacks;
|
||||
/// @brief 'ondefocus' callbacks
|
||||
ActionsSet defocusCallbacks;
|
||||
/// @brief element tooltip text
|
||||
std::wstring tooltip;
|
||||
/// @brief element tooltip delay
|
||||
@@ -127,7 +132,12 @@ namespace gui {
|
||||
|
||||
/// @brief Called every frame for all visible elements
|
||||
/// @param delta delta timУ
|
||||
virtual void act(float delta) {};
|
||||
virtual void act(float delta) {
|
||||
if (mustRefresh) {
|
||||
mustRefresh = false;
|
||||
refresh();
|
||||
}
|
||||
};
|
||||
virtual void draw(const DrawContext& pctx, const Assets& assets) = 0;
|
||||
|
||||
virtual void setVisible(bool flag);
|
||||
@@ -169,10 +179,12 @@ 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* 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) {}
|
||||
@@ -269,5 +281,9 @@ namespace gui {
|
||||
const std::shared_ptr<UINode>& node,
|
||||
const std::string& id
|
||||
);
|
||||
|
||||
void setMustRefresh() {
|
||||
mustRefresh = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ std::shared_ptr<gui::UINode> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,14 @@ 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);
|
||||
}
|
||||
|
||||
if (auto ondoubleclick = create_action(reader, element, "ondoubleclick")) {
|
||||
node.listenDoubleClick(ondoubleclick);
|
||||
}
|
||||
@@ -279,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] == '@') {
|
||||
@@ -379,7 +387,7 @@ static std::shared_ptr<UINode> read_button(
|
||||
|
||||
std::shared_ptr<Button> button;
|
||||
auto& elements = element.getElements();
|
||||
if (!elements.empty() && elements[0]->getTag() != "#") {
|
||||
if (!elements.empty() && !elements[0]->isText()) {
|
||||
auto inner = reader.readUINode(*elements.at(0));
|
||||
if (inner != nullptr) {
|
||||
button = std::make_shared<Button>(gui, inner, padding);
|
||||
@@ -536,6 +544,11 @@ static std::shared_ptr<UINode> read_image(
|
||||
std::string src = element.attr("src", "").getText();
|
||||
auto image = std::make_shared<Image>(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;
|
||||
}
|
||||
|
||||
@@ -757,7 +770,7 @@ static std::shared_ptr<UINode> 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);
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace gui {
|
||||
std::unordered_set<std::string> ignored;
|
||||
std::stack<std::string> 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;
|
||||
|
||||
@@ -83,11 +83,19 @@ 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());
|
||||
node->add(std::move(subnode));
|
||||
} catch (const std::exception& err) {
|
||||
throw std::runtime_error(err.what());
|
||||
}
|
||||
@@ -337,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<Image*>(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<Canvas*>(node)) {
|
||||
return lua::newuserdata<lua::LuaCanvas>(L, canvas->texture(), canvas->data());
|
||||
@@ -548,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()) {
|
||||
@@ -651,6 +668,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<Image*>(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<TrackBar*>(node)) {
|
||||
bar->setValue(lua::tonumber(L, idx));
|
||||
@@ -777,6 +800,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()) {
|
||||
|
||||
@@ -154,6 +154,22 @@ std::unique_ptr<Process> 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<int>(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
|
||||
) {
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user