diff --git a/data/layout.xml b/data/layout.xml
index 2dc0550..5870f49 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -1,45 +1,62 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
diff --git a/engine/app.cpp b/engine/app.cpp
index 13d6e75..edd0ffa 100644
--- a/engine/app.cpp
+++ b/engine/app.cpp
@@ -75,7 +75,7 @@ void App::init()
#endif
layout.load("data/layout.xml");
- layout["main"].update(width, height);
+ //layout["main"].update(width, height);
sampler.create();
ShaderManager::create(kShader::Texture, shader_v, shader_f);
@@ -127,13 +127,13 @@ void App::update(float dt)
ShaderManager::u_int(kShaderUniform::Tex, 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- //glEnable(GL_SCISSOR_TEST);
+ glEnable(GL_SCISSOR_TEST);
for (auto& n : layout[main_id])
{
if (n.m_widget)
{
auto box = n.m_widget->clip;
- glScissor(box.x, height - box.y - box.w, box.z, box.w);
+ glScissor((int)box.x, (int)(height - box.y - box.w), (int)box.z, (int)box.w);
n.m_widget->draw();
}
}
@@ -145,6 +145,8 @@ void App::update(float dt)
void App::resize(float w, float h)
{
constexpr auto main_id = const_hash("main");
+ width = w;
+ height = h;
layout[main_id].update(w, h);
}
diff --git a/engine/layout.cpp b/engine/layout.cpp
index 113deb9..87bb1cc 100644
--- a/engine/layout.cpp
+++ b/engine/layout.cpp
@@ -199,15 +199,45 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
while (x_child)
{
//Node n;
- 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);
+ if (strcmp("ref", x_child->Name()) == 0)
+ {
+ auto ids = x_child->Attribute("id");
+ auto id = const_hash(ids);
+ auto& ref = (*m_manager)[id];
+ m_children.push_back(ref.clone());
+ m_children.back().parent = parent;
+ m_children.back().m_manager = m_manager;
+ YGNodeInsertChild(y_node, m_children.back().y_node, YGNodeGetChildCount(y_node));
+ }
+ else
+ {
+ m_children.emplace_back();
+ auto& n = m_children.back();
+ n.parent = this;
+ n.m_manager = m_manager;
+ YGNodeInsertChild(y_node, n.y_node, YGNodeGetChildCount(y_node));
+ n.load_internal(x_child);
+ }
x_child = x_child->NextSiblingElement();
}
}
+Node Node::clone()
+{
+ Node n;
+ YGNodeCopyStyle(n.y_node, y_node);
+ if (m_widget)
+ n.m_widget = m_widget->clone();
+ for (auto& c : m_children)
+ {
+ n.m_children.push_back(std::move(c.clone()));
+ auto& cn = n.m_children.back(); // child node reference
+ cn.parent = &n;
+ YGNodeInsertChild(n.y_node, cn.y_node, YGNodeGetChildCount(n.y_node));
+ }
+ return std::move(n);
+}
+
bool LayoutManager::load(const char* path)
{
struct stat tmp_info;
@@ -225,7 +255,7 @@ bool LayoutManager::load(const char* path)
if (ret != tinyxml2::XMLError::XML_SUCCESS)
return false;
- tinyxml2::XMLElement* current = xml.RootElement();
+ tinyxml2::XMLElement* current = xml.RootElement()->FirstChildElement();
while (current)
{
auto id_str = current->Attribute("id");
@@ -234,11 +264,13 @@ bool LayoutManager::load(const char* path)
printf("Layout node without id\n");
return false;
}
+ printf("Parsing layout: %s\n", id_str);
uint16_t id = const_hash(id_str);
auto& p = m_layouts.try_emplace(id);
if (p.second)
{
auto& node = p.first->second;
+ node.m_manager = this;
// try to copy the old size values
if (old.count(id))
{
diff --git a/engine/layout.h b/engine/layout.h
index b87cb17..c90aee6 100644
--- a/engine/layout.h
+++ b/engine/layout.h
@@ -31,6 +31,7 @@ enum class kWidget : uint16_t
{
Border = const_hash("border"),
Shape = const_hash("shape"),
+ Ref = const_hash("ref"),
};
enum class kShapeType : uint16_t
@@ -46,6 +47,16 @@ class Widget
public:
glm::mat4 mvp;
glm::vec4 clip;
+ virtual std::unique_ptr clone() = 0;
+ virtual void create() { }
+ virtual void draw() { }
+ virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) { }
+};
+
+class WidgetRef : public Widget
+{
+public:
+ uint16_t id;
virtual void create() { }
virtual void draw() { }
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) { }
@@ -58,6 +69,12 @@ public:
glm::vec4 m_color;
glm::vec4 m_border_color;
float m_thinkness{ 1 };
+ virtual std::unique_ptr clone() override
+ {
+ auto ret = std::make_unique();
+ *ret = *this;
+ return std::move(ret);
+ }
virtual void draw() override
{
ShaderManager::use(kShader::Color);
@@ -110,6 +127,12 @@ public:
glm::vec4 m_border_color;
float m_thinkness{ 1 };
float m_radius{ .5f };
+ virtual std::unique_ptr clone() override
+ {
+ auto ret = std::make_unique();
+ //*ret = *this;
+ return std::move(ret);
+ }
virtual void create() override
{
switch (m_type)
@@ -186,6 +209,7 @@ class Node
const Node* parent{ nullptr };
YGNodeRef y_node{ nullptr };
+ class LayoutManager* m_manager;
public:
std::vector m_children;
@@ -253,6 +277,7 @@ public:
void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr);
void load_internal(const tinyxml2::XMLElement* x_node);
void draw();
+ Node clone();
class iterator
{
@@ -297,5 +322,5 @@ public:
bool load(const char* path);
bool reload();
Node& operator[](uint16_t id) { return m_layouts[id]; }
- Node& operator[](const char* ids) { return m_layouts[const_hash(ids)]; }
+ //Node& operator[](const char* ids) { return m_layouts[const_hash(ids)]; }
};