diff --git a/data/layout.xml b/data/layout.xml index 22c5272..c3523d6 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -1,8 +1,8 @@ - + - + @@ -14,7 +14,7 @@ - + @@ -39,5 +39,5 @@ - + diff --git a/engine/layout.cpp b/engine/layout.cpp index 213c617..86c843f 100644 --- a/engine/layout.cpp +++ b/engine/layout.cpp @@ -21,7 +21,7 @@ void Node::update_internal(glm::vec2 origin) m_clip = glm::vec4(m_pos, m_size); else m_clip = rect_intersection(glm::vec4(m_pos, m_size), parent->m_clip); - for (auto& c : children) + for (auto& c : m_children) c.update_internal(m_pos); } @@ -165,7 +165,7 @@ void Node::load(const char* path) m_file_info = tmp_info; m_path = path; - children.clear(); + m_children.clear(); YGNodeReset(y_node); tinyxml2::XMLDocument xml; @@ -177,10 +177,11 @@ void Node::load(const char* path) void Node::load_internal(const tinyxml2::XMLElement* x_node) { + m_name = x_node->Name(); auto attr = x_node->FirstAttribute(); while (attr) { - parse_attributes(att::value(attr->Name()), attr); + parse_attributes((att::kAttribute)att::const_hash(attr->Name()), attr); attr = attr->Next(); } @@ -188,8 +189,8 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node) while (x_child) { //Node n; - children.emplace_back(); - auto& n = children.back(); + m_children.emplace_back(); + auto& n = m_children.back(); n.parent = this; YGNodeInsertChild(y_node, n.y_node, YGNodeGetChildCount(y_node)); n.load_internal(x_child); diff --git a/engine/layout.h b/engine/layout.h index 3d10ef7..ad4f21c 100644 --- a/engine/layout.h +++ b/engine/layout.h @@ -2,13 +2,36 @@ namespace att { - enum class kAttribute : uint8_t { - Width, MinWidth, MaxWidth, - Height, MinHeight, MaxHeight, - Divisions, InnerRadius, OuterRadius, - Grow, Shrink, FlexDir, FlexWrap, - Padding, Margin, - Color + uint16_t constexpr const_hash(char const *input) + { + return *input ? + static_cast(*input) + 33 * const_hash(input + 1) : + 5381; + } + + enum class kAttribute : uint16_t + { + Width = const_hash("width"), + MinWidth = const_hash("max-width"), + MaxWidth = const_hash("min-width"), + Height = const_hash("height"), + MinHeight = const_hash("min-height"), + MaxHeight = const_hash("max-height"), + Divisions = const_hash("divisions"), + InnerRadius = const_hash("inner-radius"), + OuterRadius = const_hash("outer-radius"), + Grow = const_hash("grow"), + Shrink = const_hash("shrink"), + FlexDir = const_hash("dir"), + FlexWrap = const_hash("wrap"), + Padding = const_hash("pad"), + Margin = const_hash("margin"), + Color = const_hash("color"), + }; + + enum class kWidget : uint16_t + { + Border = const_hash("border"), }; struct AttributeBase @@ -27,50 +50,37 @@ namespace att Attribute(V v) : value(v) { id = static_id; } }; - struct typemap + struct kAttributeMap { - const char* name; kAttribute value; + const char* name; }; - static constexpr typemap map[] = + static constexpr kAttributeMap map[] = { - { "width", kAttribute::Width }, - { "min-width", kAttribute::MinWidth }, - { "max-width", kAttribute::MaxWidth }, - { "height", kAttribute::Height }, - { "min-height", kAttribute::MinHeight }, - { "max-height", kAttribute::MaxHeight }, - { "divisions", kAttribute::Divisions }, - { "inner-radius", kAttribute::InnerRadius }, - { "outer-radius", kAttribute::OuterRadius }, - { "grow", kAttribute::Grow }, - { "shrink", kAttribute::Shrink }, - { "dir", kAttribute::FlexDir }, - { "wrap", kAttribute::FlexWrap }, - { "pad", kAttribute::Padding }, - { "margin", kAttribute::Margin }, - { "color", kAttribute::Color }, + { kAttribute::Width, "width" }, + { kAttribute::MinWidth, "min-width" }, + { kAttribute::MaxWidth, "max-width" }, + { kAttribute::Height, "height" }, + { kAttribute::MinHeight, "min-height" }, + { kAttribute::MaxHeight, "max-height" }, + { kAttribute::Divisions, "divisions" }, + { kAttribute::InnerRadius, "inner-radius" }, + { kAttribute::OuterRadius, "outer-radius" }, + { kAttribute::Grow, "grow" }, + { kAttribute::Shrink, "shrink" }, + { kAttribute::FlexDir, "dir" }, + { kAttribute::FlexWrap, "wrap" }, + { kAttribute::Padding, "pad" }, + { kAttribute::Margin, "margin" }, + { kAttribute::Color, "color" }, }; - static constexpr int map_size = sizeof(map) / sizeof(typemap) - 1; - constexpr bool same(const char* a, const char* b) - { - return (*a && *b) ? (*a == *b && same(a + 1, b + 1)) : !(*a || *b); - } - constexpr const kAttribute value(char const *name, int i = 0) - { - return ((i >= map_size) || same(map[i].name, name)) ? - map[i].value : value(name, i + 1); - } + constexpr const char* string(const kAttribute value, int i = 0) { + // no check on size, value MUST be found return (map[i].value == value) ? map[i].name : string(value, i + 1); } - //constexpr const char* string(kAttribute a) { return names[(int)a]; } - - // template - // constexpr const char* string(const Attribute a) { return names[(int)a.id]; } - #define DECLARE_ATTRIBUTE(N,T) \ struct N : public Attribute \ { using Attribute::Attribute; }; @@ -95,6 +105,17 @@ namespace att #undef DECLARE_ATTRIBUTE } +class Widget +{ + +}; + +class WidgetBorder : public Widget +{ +public: + static class Plane* m_plane; +}; + class Node { const Node* parent{ nullptr }; @@ -103,25 +124,27 @@ class Node std::string m_path; public: - std::vector children; - glm::vec4 color; + std::vector m_children; + std::unique_ptr m_widget; glm::vec2 m_pos; glm::vec2 m_size; glm::vec4 m_clip; + glm::vec4 color; + std::string m_name; Node(const Node&) = delete; Node& operator=(const Node&) = delete; Node&& operator=(Node&& o) { return std::forward(o); } Node(Node&& o) { - children = std::move(o.children); - for (auto& c : children) + m_children = std::move(o.m_children); + for (auto& c : m_children) c.parent = this; parent = o.parent; y_node = o.y_node; + color = o.color; m_pos = o.m_pos; m_size = o.m_size; m_clip = o.m_clip; - color = o.color; m_file_info = o.m_file_info; o.y_node = nullptr; o.parent = nullptr; @@ -129,7 +152,7 @@ public: Node() { y_node = YGNodeNew(); } ~Node() { - children.clear(); + m_children.clear(); if (y_node) YGNodeFree(y_node); } @@ -183,7 +206,7 @@ public: iterator& operator++() { m_nodes.pop(); - for (auto& c : m_current->children) + for (auto& c : m_current->m_children) m_nodes.push(&c); m_current = m_nodes.size() ? m_nodes.top() : nullptr; return *this;