diff --git a/src/ui/elements/ui_element.cpp b/src/ui/elements/ui_element.cpp index 27dddf9..43405e0 100644 --- a/src/ui/elements/ui_element.cpp +++ b/src/ui/elements/ui_element.cpp @@ -24,6 +24,7 @@ Element::Element(Element* parent, uint32_t events_enabled, Rml::String base_clas if (parent != nullptr) { base = parent->base->AppendChild(std::move(base_owning)); parent->add_child(this); + this->parent = parent; } else { base = base_owning.get(); @@ -59,6 +60,19 @@ void Element::add_child(Element *child) { } } +void Element::set_parent(Element *new_parent) { + if (parent != nullptr) { + parent->remove_child(this, false); + base_owning = parent->base->RemoveChild(base); + + parent = new_parent; + + base = parent->base->AppendChild(std::move(base_owning), true); + parent->add_child(this); + } + +} + void Element::set_property(Rml::PropertyId property_id, const Rml::Property &property) { assert(base != nullptr); @@ -306,7 +320,7 @@ void Element::clear_children() { children.clear(); } -bool Element::remove_child(ResourceId child) { +bool Element::remove_child(ResourceId child, bool remove_from_context) { bool found = false; ContextId context = get_current_context(); @@ -315,7 +329,9 @@ bool Element::remove_child(ResourceId child) { Element* cur_child = *it; if (cur_child->get_resource_id() == child) { children.erase(it); - context.destroy_resource(cur_child); + if (remove_from_context) { + context.destroy_resource(cur_child); + } found = true; break; } @@ -541,4 +557,8 @@ Element Element::get_element_with_tag_name(std::string_view tag_name) { throw std::runtime_error("Select element has no child with the specified tag name"); } +bool Element::is_pseudo_class_set(Rml::String pseudo_class) { + return base->IsPseudoClassSet(pseudo_class); +} + } // namespace recompui diff --git a/src/ui/elements/ui_element.h b/src/ui/elements/ui_element.h index 35fdff3..848a705 100644 --- a/src/ui/elements/ui_element.h +++ b/src/ui/elements/ui_element.h @@ -32,6 +32,7 @@ private: std::unordered_set style_active_set; std::unordered_multimap style_name_index_map; std::vector callbacks; + Element *parent = nullptr; std::vector children; std::string id; bool shim = false; @@ -67,8 +68,9 @@ public: Element(Element* parent, uint32_t events_enabled = 0, Rml::String base_class = "div", bool can_set_text = false); virtual ~Element(); void clear_children(); - bool remove_child(ResourceId child); - bool remove_child(Element *child) { return remove_child(child->get_resource_id()); } + bool remove_child(ResourceId child, bool remove_from_context = true); + bool remove_child(Element *child, bool remove_from_context = true) { return remove_child(child->get_resource_id(), remove_from_context); } + void set_parent(Element *new_parent); void add_style(Style *style, std::string_view style_name); void add_style(Style *style, const std::initializer_list &style_names); Element get_element_with_tag_name(std::string_view tag_name); @@ -100,6 +102,7 @@ public: void set_input_value_float(float val) { set_input_value(val); } void set_input_value_double(double val) { set_input_value(val); } const std::string& get_id() { return id; } + bool is_pseudo_class_set(Rml::String pseudo_class); Element *select_add_option(std::string_view text, std::string_view value); };