add 'onfocus' ui event & optimize container:add

This commit is contained in:
MihailRis 2025-04-26 20:16:57 +03:00
parent 8e8cabf2d1
commit 1e90115a26
9 changed files with 31 additions and 10 deletions

View File

@ -67,7 +67,7 @@ std::unique_ptr<UiDocument> UiDocument::read(
? scripting::create_doc_environment(scripting::get_root_environment(), name) ? scripting::create_doc_environment(scripting::get_root_environment(), name)
: scripting::create_doc_environment(penv, 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()); auto view = reader.readXML(file.string(), *xmldoc->getRoot());
view->setId("root"); view->setId("root");
uidocscript script {}; uidocscript script {};

View File

@ -71,6 +71,10 @@ void Container::mouseRelease(int x, int y) {
} }
void Container::act(float delta) { void Container::act(float delta) {
if (mustRefresh) {
refresh();
mustRefresh = false;
}
for (const auto& node : nodes) { for (const auto& node : nodes) {
if (node->isVisible()) { if (node->isVisible()) {
node->act(delta); node->act(delta);
@ -162,7 +166,7 @@ void Container::add(const std::shared_ptr<UINode>& node) {
nodes.push_back(node); nodes.push_back(node);
node->setParent(this); node->setParent(this);
node->reposition(); node->reposition();
refresh(); mustRefresh = true;
} }
void Container::add(const std::shared_ptr<UINode>& node, glm::vec2 pos) { void Container::add(const std::shared_ptr<UINode>& node, glm::vec2 pos) {
@ -202,7 +206,6 @@ void Container::listenInterval(float interval, ontimeout callback, int repeat) {
void Container::setSize(glm::vec2 size) { void Container::setSize(glm::vec2 size) {
if (size == getSize()) { if (size == getSize()) {
refresh();
return; return;
} }
UINode::setSize(size); UINode::setSize(size);

View File

@ -9,6 +9,7 @@
namespace gui { namespace gui {
class Container : public UINode, public ::util::ObjectsKeeper { class Container : public UINode, public ::util::ObjectsKeeper {
int prevScrollY = -1; int prevScrollY = -1;
bool mustRefresh = true;
protected: protected:
std::vector<std::shared_ptr<UINode>> nodes; std::vector<std::shared_ptr<UINode>> nodes;
std::vector<IntervalEvent> intervalEvents; std::vector<IntervalEvent> intervalEvents;

View File

@ -74,6 +74,11 @@ UINode* UINode::listenDoubleClick(const onaction& action) {
return this; return this;
} }
UINode* UINode::listenFocus(const onaction& action) {
focusCallbacks.listen(action);
return this;
}
UINode* UINode::listenDefocus(const onaction& action) { UINode* UINode::listenDefocus(const onaction& action) {
defocusCallbacks.listen(action); defocusCallbacks.listen(action);
return this; return this;
@ -101,6 +106,11 @@ bool UINode::isPressed() const {
return pressed; return pressed;
} }
void UINode::onFocus() {
focused = true;
focusCallbacks.notify(gui);
}
void UINode::defocus() { void UINode::defocus() {
focused = false; focused = false;
defocusCallbacks.notify(gui); defocusCallbacks.notify(gui);

View File

@ -114,6 +114,8 @@ namespace gui {
ActionsSet actions; ActionsSet actions;
/// @brief 'ondoubleclick' callbacks /// @brief 'ondoubleclick' callbacks
ActionsSet doubleClickCallbacks; ActionsSet doubleClickCallbacks;
/// @brief 'onfocus' callbacks
ActionsSet focusCallbacks;
/// @brief 'ondefocus' callbacks /// @brief 'ondefocus' callbacks
ActionsSet defocusCallbacks; ActionsSet defocusCallbacks;
/// @brief element tooltip text /// @brief element tooltip text
@ -173,9 +175,10 @@ namespace gui {
virtual UINode* listenAction(const onaction& action); virtual UINode* listenAction(const onaction& action);
virtual UINode* listenDoubleClick(const onaction& action); virtual UINode* listenDoubleClick(const onaction& action);
virtual UINode* listenFocus(const onaction& action);
virtual UINode* listenDefocus(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 doubleClick(int x, int y);
virtual void click(int x, int y); virtual void click(int x, int y);
virtual void clicked(Mousecode button) {} virtual void clicked(Mousecode button) {}

View File

@ -21,7 +21,7 @@ std::shared_ptr<gui::UINode> guiutil::create(
if (env == nullptr) { if (env == nullptr) {
env = scripting::get_root_environment(); env = scripting::get_root_environment();
} }
UiXmlReader reader(gui, env); UiXmlReader reader(gui, std::move(env));
return reader.readXML("[string]", source); return reader.readXML("[string]", source);
} }

View File

@ -63,7 +63,7 @@ static runnable create_runnable(
const std::string& name const std::string& name
) { ) {
if (element.has(name)) { if (element.has(name)) {
std::string text = element.attr(name).getText(); const std::string& text = element.attr(name).getText();
if (!text.empty()) { if (!text.empty()) {
return scripting::create_runnable( return scripting::create_runnable(
reader.getEnvironment(), text, reader.getFilename() reader.getEnvironment(), text, reader.getFilename()
@ -180,6 +180,10 @@ static void read_uinode(
node.listenAction(onclick); node.listenAction(onclick);
} }
if (auto onfocus = create_action(reader, element, "onfocus")) {
node.listenFocus(onfocus);
}
if (auto ondefocus = create_action(reader, element, "ondefocus")) { if (auto ondefocus = create_action(reader, element, "ondefocus")) {
node.listenDefocus(ondefocus); node.listenDefocus(ondefocus);
} }
@ -761,7 +765,7 @@ static std::shared_ptr<UINode> read_iframe(
return 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(""); contextStack.emplace("");
add("image", read_image); add("image", read_image);
add("canvas", read_canvas); add("canvas", read_canvas);

View File

@ -20,9 +20,9 @@ namespace gui {
std::unordered_set<std::string> ignored; std::unordered_set<std::string> ignored;
std::stack<std::string> contextStack; std::stack<std::string> contextStack;
std::string filename; std::string filename;
const scriptenv& env; scriptenv env;
public: public:
UiXmlReader(gui::GUI& gui, const scriptenv& env); UiXmlReader(gui::GUI& gui, scriptenv&& env);
void add(const std::string& tag, uinode_reader reader); void add(const std::string& tag, uinode_reader reader);
bool hasReader(const std::string& tag) const; bool hasReader(const std::string& tag) const;

View File

@ -94,8 +94,8 @@ static int l_container_add(lua::State* L) {
auto subnode = guiutil::create( auto subnode = guiutil::create(
engine->getGUI(), xmlsrc, std::move(env) engine->getGUI(), xmlsrc, std::move(env)
); );
node->add(subnode);
UINode::getIndices(subnode, docnode.document->getMapWriteable()); UINode::getIndices(subnode, docnode.document->getMapWriteable());
node->add(std::move(subnode));
} catch (const std::exception& err) { } catch (const std::exception& err) {
throw std::runtime_error(err.what()); throw std::runtime_error(err.what());
} }