ref nodes work fine now but need to complete Widget::clone implementations and add clone() to Shape classes to actually clone the OpenGL data
This commit is contained in:
@@ -1,45 +1,62 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<layout id="main">
|
<root>
|
||||||
<node dir="col" wrap="0" width="100%" height="100%" pad="5">
|
<layout id="button">
|
||||||
<!-- toolbar -->
|
<border width="50" margin="0 5 0 0" color=".1" thickness="2" border-color=".5"></border>
|
||||||
<border height="50" width="100%" pad="5" dir="row" color=".2">
|
</layout>
|
||||||
<border width="50" margin="0 5 0 0" color=".1" thickness="2" border-color="1"></border>
|
<layout id="multi-button">
|
||||||
<border width="50" margin="0 5 0 0" color=".2" thickness="2" border-color="1"></border>
|
<node width="50" margin="0 5 0 0" dir="row" wrap="1">
|
||||||
<border width="50" margin="0 5 0 0" color=".3" thickness="2" border-color="1"></border>
|
<border height="50%" width="50%" color=".1" thickness="2" border-color=".5" />
|
||||||
<separator width="10" />
|
<border height="50%" width="50%" color=".1" thickness="2" border-color=".5" />
|
||||||
<border width="50" margin="0 5 0 0" color=".1" thickness="2" border-color="1"></border>
|
<border height="50%" width="50%" color=".1" thickness="2" border-color=".5" />
|
||||||
<border width="50" margin="0 5 0 0" color=".2" thickness="2" border-color="1"></border>
|
<border height="50%" width="50%" color=".1" thickness="2" border-color=".5" />
|
||||||
<border width="50" margin="0 5 0 0" color=".3" thickness="2" border-color="1"></border>
|
</node>
|
||||||
<separator width="10" />
|
</layout>
|
||||||
<border width="50" margin="0 5 0 0"></border>
|
<layout id="main">
|
||||||
<border width="50" margin="0 5 0 0"></border>
|
<node dir="col" wrap="0" width="100%" height="100%" pad="5">
|
||||||
<border width="50" margin="0 5 0 0"></border>
|
<!-- toolbar -->
|
||||||
</border>
|
<border height="50" width="100%" pad="5" dir="row" color=".2">
|
||||||
<!-- central row -->
|
<ref id="multi-button"></ref>
|
||||||
<plane grow="1" dir="row" wrap="1" height="0">
|
<ref id="multi-button"></ref>
|
||||||
<!-- side bar -->
|
<ref id="multi-button"></ref>
|
||||||
<plane width="200" height="100%" dir="col" color=".2">
|
<ref id="button"></ref>
|
||||||
<plane pad="15" margin="0 0 10 0" color=".3" width="100%" height="auto">
|
<border width="50" margin="0 5 0 0" color=".1" thickness="2" border-color="1"></border>
|
||||||
<plane height="30" color=".4" />
|
<border width="50" margin="0 5 0 0" color=".2" thickness="2" border-color="1"></border>
|
||||||
<plane height="30" color=".4" />
|
<border width="50" margin="0 5 0 0" color=".3" thickness="2" border-color="1"></border>
|
||||||
<plane height="30" color=".4" />
|
<separator width="10" />
|
||||||
<plane height="30" color=".4" />
|
<border width="50" margin="0 5 0 0" color=".1" thickness="2" border-color="1"></border>
|
||||||
|
<border width="50" margin="0 5 0 0" color=".2" thickness="2" border-color="1"></border>
|
||||||
|
<border width="50" margin="0 5 0 0" color=".3" thickness="2" border-color="1"></border>
|
||||||
|
<separator width="10" />
|
||||||
|
<border width="50" margin="0 5 0 0"></border>
|
||||||
|
<border width="50" margin="0 5 0 0"></border>
|
||||||
|
<border width="50" margin="0 5 0 0"></border>
|
||||||
|
</border>
|
||||||
|
<!-- central row -->
|
||||||
|
<plane grow="1" dir="row" wrap="1" height="0">
|
||||||
|
<!-- side bar -->
|
||||||
|
<plane width="200" height="100%" dir="col" color=".2">
|
||||||
|
<plane pad="15" margin="0 0 10 0" color=".3" width="100%" height="auto">
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
</plane>
|
||||||
|
<plane pad="15" margin="0 0 10 0" color=".3" width="100%" height="auto">
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
<plane height="30" color=".4" />
|
||||||
|
</plane>
|
||||||
</plane>
|
</plane>
|
||||||
<plane pad="15" margin="0 0 10 0" color=".3" width="100%" height="auto">
|
<!-- content panel -->
|
||||||
<plane height="30" color=".4" />
|
<plane width="1" grow="1" height="100%" pad="30" wrap="1">
|
||||||
<plane height="30" color=".4" />
|
<border thickness="5" border-color="1" color=".4" height="100%" pad="10">
|
||||||
<plane height="30" color=".4" />
|
<shape type="round-rect" border-color=".5" thickness="4" width="100%" height="100%"></shape>
|
||||||
<plane height="30" color=".4" />
|
</border>
|
||||||
</plane>
|
</plane>
|
||||||
</plane>
|
</plane>
|
||||||
<!-- content panel -->
|
<!-- status bar -->
|
||||||
<plane width="1" grow="1" height="100%" pad="30" wrap="1">
|
<plane height="30" width="100%" />
|
||||||
<border thickness="5" border-color="1" color=".4" height="100%" pad="10">
|
</node>
|
||||||
<shape type="round-rect" border-color=".5" thickness="4" width="100%" height="100%"></shape>
|
</layout>
|
||||||
</border>
|
</root>
|
||||||
</plane>
|
|
||||||
</plane>
|
|
||||||
<!-- status bar -->
|
|
||||||
<plane height="30" width="100%" />
|
|
||||||
</node>
|
|
||||||
</layout>
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void App::init()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
layout.load("data/layout.xml");
|
layout.load("data/layout.xml");
|
||||||
layout["main"].update(width, height);
|
//layout["main"].update(width, height);
|
||||||
|
|
||||||
sampler.create();
|
sampler.create();
|
||||||
ShaderManager::create(kShader::Texture, shader_v, shader_f);
|
ShaderManager::create(kShader::Texture, shader_v, shader_f);
|
||||||
@@ -127,13 +127,13 @@ void App::update(float dt)
|
|||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
//glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
for (auto& n : layout[main_id])
|
for (auto& n : layout[main_id])
|
||||||
{
|
{
|
||||||
if (n.m_widget)
|
if (n.m_widget)
|
||||||
{
|
{
|
||||||
auto box = n.m_widget->clip;
|
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();
|
n.m_widget->draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,6 +145,8 @@ void App::update(float dt)
|
|||||||
void App::resize(float w, float h)
|
void App::resize(float w, float h)
|
||||||
{
|
{
|
||||||
constexpr auto main_id = const_hash("main");
|
constexpr auto main_id = const_hash("main");
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
layout[main_id].update(w, h);
|
layout[main_id].update(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -199,15 +199,45 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
|||||||
while (x_child)
|
while (x_child)
|
||||||
{
|
{
|
||||||
//Node n;
|
//Node n;
|
||||||
m_children.emplace_back();
|
if (strcmp("ref", x_child->Name()) == 0)
|
||||||
auto& n = m_children.back();
|
{
|
||||||
n.parent = this;
|
auto ids = x_child->Attribute("id");
|
||||||
YGNodeInsertChild(y_node, n.y_node, YGNodeGetChildCount(y_node));
|
auto id = const_hash(ids);
|
||||||
n.load_internal(x_child);
|
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();
|
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)
|
bool LayoutManager::load(const char* path)
|
||||||
{
|
{
|
||||||
struct stat tmp_info;
|
struct stat tmp_info;
|
||||||
@@ -225,7 +255,7 @@ bool LayoutManager::load(const char* path)
|
|||||||
if (ret != tinyxml2::XMLError::XML_SUCCESS)
|
if (ret != tinyxml2::XMLError::XML_SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tinyxml2::XMLElement* current = xml.RootElement();
|
tinyxml2::XMLElement* current = xml.RootElement()->FirstChildElement();
|
||||||
while (current)
|
while (current)
|
||||||
{
|
{
|
||||||
auto id_str = current->Attribute("id");
|
auto id_str = current->Attribute("id");
|
||||||
@@ -234,11 +264,13 @@ bool LayoutManager::load(const char* path)
|
|||||||
printf("Layout node without id\n");
|
printf("Layout node without id\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
printf("Parsing layout: %s\n", id_str);
|
||||||
uint16_t id = const_hash(id_str);
|
uint16_t id = const_hash(id_str);
|
||||||
auto& p = m_layouts.try_emplace(id);
|
auto& p = m_layouts.try_emplace(id);
|
||||||
if (p.second)
|
if (p.second)
|
||||||
{
|
{
|
||||||
auto& node = p.first->second;
|
auto& node = p.first->second;
|
||||||
|
node.m_manager = this;
|
||||||
// try to copy the old size values
|
// try to copy the old size values
|
||||||
if (old.count(id))
|
if (old.count(id))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ enum class kWidget : uint16_t
|
|||||||
{
|
{
|
||||||
Border = const_hash("border"),
|
Border = const_hash("border"),
|
||||||
Shape = const_hash("shape"),
|
Shape = const_hash("shape"),
|
||||||
|
Ref = const_hash("ref"),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class kShapeType : uint16_t
|
enum class kShapeType : uint16_t
|
||||||
@@ -46,6 +47,16 @@ class Widget
|
|||||||
public:
|
public:
|
||||||
glm::mat4 mvp;
|
glm::mat4 mvp;
|
||||||
glm::vec4 clip;
|
glm::vec4 clip;
|
||||||
|
virtual std::unique_ptr<Widget> 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 create() { }
|
||||||
virtual void draw() { }
|
virtual void draw() { }
|
||||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) { }
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) { }
|
||||||
@@ -58,6 +69,12 @@ public:
|
|||||||
glm::vec4 m_color;
|
glm::vec4 m_color;
|
||||||
glm::vec4 m_border_color;
|
glm::vec4 m_border_color;
|
||||||
float m_thinkness{ 1 };
|
float m_thinkness{ 1 };
|
||||||
|
virtual std::unique_ptr<Widget> clone() override
|
||||||
|
{
|
||||||
|
auto ret = std::make_unique<WidgetBorder>();
|
||||||
|
*ret = *this;
|
||||||
|
return std::move(ret);
|
||||||
|
}
|
||||||
virtual void draw() override
|
virtual void draw() override
|
||||||
{
|
{
|
||||||
ShaderManager::use(kShader::Color);
|
ShaderManager::use(kShader::Color);
|
||||||
@@ -110,6 +127,12 @@ public:
|
|||||||
glm::vec4 m_border_color;
|
glm::vec4 m_border_color;
|
||||||
float m_thinkness{ 1 };
|
float m_thinkness{ 1 };
|
||||||
float m_radius{ .5f };
|
float m_radius{ .5f };
|
||||||
|
virtual std::unique_ptr<Widget> clone() override
|
||||||
|
{
|
||||||
|
auto ret = std::make_unique<WidgetShape>();
|
||||||
|
//*ret = *this;
|
||||||
|
return std::move(ret);
|
||||||
|
}
|
||||||
virtual void create() override
|
virtual void create() override
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
@@ -186,6 +209,7 @@ class Node
|
|||||||
|
|
||||||
const Node* parent{ nullptr };
|
const Node* parent{ nullptr };
|
||||||
YGNodeRef y_node{ nullptr };
|
YGNodeRef y_node{ nullptr };
|
||||||
|
class LayoutManager* m_manager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<Node> m_children;
|
std::vector<Node> m_children;
|
||||||
@@ -253,6 +277,7 @@ public:
|
|||||||
void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr);
|
void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr);
|
||||||
void load_internal(const tinyxml2::XMLElement* x_node);
|
void load_internal(const tinyxml2::XMLElement* x_node);
|
||||||
void draw();
|
void draw();
|
||||||
|
Node clone();
|
||||||
|
|
||||||
class iterator
|
class iterator
|
||||||
{
|
{
|
||||||
@@ -297,5 +322,5 @@ public:
|
|||||||
bool load(const char* path);
|
bool load(const char* path);
|
||||||
bool reload();
|
bool reload();
|
||||||
Node& operator[](uint16_t id) { return m_layouts[id]; }
|
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)]; }
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user