From 06b19dc5963822098f6e98cffed698fc14021589 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Thu, 2 Feb 2017 18:26:59 +0000 Subject: [PATCH] ref nodes work fine now but need to complete Widget::clone implementations and add clone() to Shape classes to actually clone the OpenGL data --- data/layout.xml | 99 +++++++++++++++++++++++++++-------------------- engine/app.cpp | 8 ++-- engine/layout.cpp | 44 ++++++++++++++++++--- engine/layout.h | 27 ++++++++++++- 4 files changed, 127 insertions(+), 51 deletions(-) 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)]; } };