big refactoring to merge node and widgets into a single node hierarchy
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
#include "layout.h"
|
||||
#include "util.h"
|
||||
|
||||
Plane WidgetBorder::m_plane;
|
||||
Plane WidgetImage::m_plane;
|
||||
Sampler WidgetImage::m_sampler;
|
||||
Plane NodeBorder::m_plane;
|
||||
Plane NodeImage::m_plane;
|
||||
Sampler NodeImage::m_sampler;
|
||||
|
||||
Node* Node::find(const char* ids)
|
||||
{
|
||||
@@ -20,23 +20,49 @@ Node* Node::find(const char* ids)
|
||||
kEventResult Node::on_event(Event* e)
|
||||
{
|
||||
for (auto& c : m_children)
|
||||
if (c.on_event(e) == kEventResult::Handled)
|
||||
return kEventResult::Handled;
|
||||
if (m_widget)
|
||||
if (c->on_event(e) == kEventResult::Consumed)
|
||||
return kEventResult::Consumed;
|
||||
switch (e->m_cat)
|
||||
{
|
||||
switch (e->m_cat)
|
||||
case kEventCategory::MouseEvent:
|
||||
{
|
||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||
bool inside = point_in_rect(me->m_pos, m_clip);
|
||||
bool inside_old = m_mouse_inside;
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventCategory::MouseEvent:
|
||||
if (point_in_rect(((MouseEvent*)e)->m_pos, m_clip) && m_widget->on_event(e) == kEventResult::Handled)
|
||||
return kEventResult::Handled;
|
||||
case kEventType::MouseDownL:
|
||||
case kEventType::MouseDownR:
|
||||
case kEventType::MouseUpL:
|
||||
case kEventType::MouseUpR:
|
||||
if (inside && handle_event(e) == kEventResult::Consumed)
|
||||
return kEventResult::Consumed;
|
||||
break;
|
||||
default:
|
||||
if (m_widget->on_event(e) == kEventResult::Handled)
|
||||
return kEventResult::Handled;
|
||||
case kEventType::MouseMove:
|
||||
if (inside_old == false && inside == true)
|
||||
{
|
||||
MouseEvent e2 = *me;
|
||||
e2.m_type = kEventType::MouseEnter;
|
||||
handle_event(&e2);
|
||||
}
|
||||
m_mouse_inside = inside;
|
||||
handle_event(e);
|
||||
if (inside_old == true && inside == false)
|
||||
{
|
||||
MouseEvent e2 = *me;
|
||||
e2.m_type = kEventType::MouseLeave;
|
||||
handle_event(&e2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return kEventResult::UnHandled;
|
||||
default:
|
||||
if (handle_event(e) == kEventResult::Consumed)
|
||||
return kEventResult::Consumed;
|
||||
break;
|
||||
}
|
||||
return kEventResult::Available;
|
||||
}
|
||||
|
||||
void Node::update(float width, float height)
|
||||
@@ -76,20 +102,13 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
|
||||
m_clip = glm::vec4(m_pos, m_size);
|
||||
}
|
||||
|
||||
if (m_widget)
|
||||
{
|
||||
glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f));
|
||||
glm::mat4 scale = glm::scale(glm::vec3(glm::ceil(m_size), 1.f));
|
||||
glm::mat4 pos = glm::translate(glm::vec3(glm::floor(m_pos), 0));
|
||||
m_widget->mvp = proj * pos * scale * pivot;
|
||||
m_widget->pos = pos;
|
||||
m_widget->scale = scale;
|
||||
m_widget->proj = proj;
|
||||
m_widget->clip = m_clip;
|
||||
m_widget->update();
|
||||
}
|
||||
glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f));
|
||||
glm::mat4 scale = glm::scale(glm::vec3(glm::ceil(m_size), 1.f));
|
||||
glm::mat4 pos = glm::translate(glm::vec3(glm::floor(m_pos), 0));
|
||||
m_mvp = proj * pos * scale * pivot;
|
||||
m_proj = proj;
|
||||
for (auto& c : m_children)
|
||||
c.update_internal(m_pos, proj);
|
||||
c->update_internal(m_pos, proj);
|
||||
}
|
||||
|
||||
void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||
@@ -237,8 +256,6 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (m_widget)
|
||||
m_widget->parse_attributes(ka, attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -246,78 +263,104 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||
void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
||||
{
|
||||
m_name = x_node->Name();
|
||||
|
||||
auto attr = x_node->FirstAttribute();
|
||||
|
||||
kWidget widget_id = (kWidget)const_hash(x_node->Name());
|
||||
switch (widget_id)
|
||||
{
|
||||
case kWidget::Border:
|
||||
m_widget = std::make_unique<WidgetBorder>();
|
||||
break;
|
||||
case kWidget::Shape:
|
||||
m_widget = std::make_unique<WidgetShape>();
|
||||
break;
|
||||
case kWidget::Text:
|
||||
m_widget = std::make_unique<WidgetText>();
|
||||
break;
|
||||
case kWidget::Image:
|
||||
m_widget = std::make_unique<WidgetImage>();
|
||||
break;
|
||||
}
|
||||
|
||||
while (attr)
|
||||
{
|
||||
parse_attributes((kAttribute)const_hash(attr->Name()), attr);
|
||||
attr = attr->Next();
|
||||
}
|
||||
|
||||
if (m_widget)
|
||||
m_widget->create();
|
||||
|
||||
if (widget_id == kWidget::Text)
|
||||
SetSize(((WidgetText*)m_widget.get())->m_text_mesh.bb);
|
||||
create();
|
||||
|
||||
auto x_child = x_node->FirstChildElement();
|
||||
while (x_child)
|
||||
{
|
||||
//Node n;
|
||||
if (strcmp("ref", x_child->Name()) == 0)
|
||||
kWidget child_id = (kWidget)const_hash(x_child->Name());
|
||||
switch (child_id)
|
||||
{
|
||||
case kWidget::Border:
|
||||
{
|
||||
auto n = new NodeBorder();
|
||||
m_children.emplace_back(n);
|
||||
n->parent = this;
|
||||
n->m_manager = m_manager;
|
||||
YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node));
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
// case kWidget::Shape:
|
||||
// break;
|
||||
case kWidget::Image:
|
||||
{
|
||||
auto n = new NodeImage();
|
||||
m_children.emplace_back(n);
|
||||
n->parent = this;
|
||||
n->m_manager = m_manager;
|
||||
YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node));
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::Text:
|
||||
{
|
||||
auto n = new NodeText();
|
||||
m_children.emplace_back(n);
|
||||
n->parent = this;
|
||||
n->m_manager = m_manager;
|
||||
YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node));
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
case kWidget::Ref:
|
||||
{
|
||||
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 = this;
|
||||
YGNodeInsertChild(y_node, m_children.back().y_node, YGNodeGetChildCount(y_node));
|
||||
auto n = ref.clone();
|
||||
m_children.emplace_back(n);
|
||||
n->parent = this;
|
||||
n->m_manager = m_manager;
|
||||
YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node));
|
||||
break;
|
||||
}
|
||||
else
|
||||
default:
|
||||
{
|
||||
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);
|
||||
auto n = new Node();
|
||||
m_children.emplace_back(n);
|
||||
n->parent = this;
|
||||
n->m_manager = m_manager;
|
||||
YGNodeInsertChild(y_node, n->y_node, YGNodeGetChildCount(y_node));
|
||||
n->load_internal(x_child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
x_child = x_child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
Node Node::clone()
|
||||
Node* Node::clone()
|
||||
{
|
||||
Node n;
|
||||
YGNodeCopyStyle(n.y_node, y_node);
|
||||
if (m_widget)
|
||||
n.m_widget = m_widget->clone();
|
||||
n.m_manager = m_manager;
|
||||
Node* n = clone_instantiate();
|
||||
clone_copy(n);
|
||||
return n;
|
||||
}
|
||||
|
||||
Node* Node::clone_instantiate() const
|
||||
{
|
||||
return new Node();
|
||||
}
|
||||
|
||||
void Node::clone_copy(Node* dest) const
|
||||
{
|
||||
YGNodeCopyStyle(dest->y_node, y_node);
|
||||
dest->m_manager = m_manager;
|
||||
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));
|
||||
Node* cn = c->clone();
|
||||
dest->m_children.emplace_back(cn);
|
||||
cn->parent = dest;
|
||||
YGNodeInsertChild(dest->y_node, cn->y_node, YGNodeGetChildCount(dest->y_node));
|
||||
}
|
||||
return std::move(n);
|
||||
}
|
||||
|
||||
bool LayoutManager::load(const char* path)
|
||||
@@ -352,15 +395,24 @@ bool LayoutManager::load(const char* path)
|
||||
if (p == m_layouts.end())
|
||||
{
|
||||
auto& node = m_layouts[id];
|
||||
node.m_manager = this;
|
||||
kWidget node_id = (kWidget)const_hash(current->Name());
|
||||
switch (node_id)
|
||||
{
|
||||
case kWidget::Border:
|
||||
node.reset(new NodeBorder());
|
||||
break;
|
||||
default:
|
||||
node.reset(new Node());
|
||||
break;
|
||||
}
|
||||
node->m_manager = this;
|
||||
// try to copy the old size values
|
||||
if (old.count(id))
|
||||
{
|
||||
const auto& old_node = old[id];
|
||||
YGNodeCopyStyle(node.y_node, old_node.y_node);
|
||||
const auto& old_node = *old[id];
|
||||
YGNodeCopyStyle(node->y_node, old_node.y_node);
|
||||
}
|
||||
if (!current->NoChildren())
|
||||
node.load_internal(current->FirstChildElement());
|
||||
node->load_internal(current);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user