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;