#include "pch.h" #include "node.h" void Node::restore_context() { for (auto& c : m_children) c->restore_context(); } void Node::clear_context() { for (auto& c : m_children) c->clear_context(); } void Node::update(float width, float height, float zoom) { m_zoom = zoom; YGNodeStyleSetWidth(y_node, (width / zoom)); YGNodeStyleSetHeight(y_node, (height / zoom)); YGNodeCalculateLayout(y_node, YGUndefined, YGUndefined, YGDirectionLTR); m_proj = glm::ortho(0.f, (width / zoom), (height / zoom), 0.f, -1.f, 1.f); update_internal({ 0, 0 }, m_proj, zoom); } void Node::update() { YGNodeCalculateLayout(y_node, YGUndefined, YGUndefined, YGDirectionLTR); update_internal({ 0, 0 }, m_proj, m_zoom); } void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj, float zoom) { float x = YGNodeLayoutGetLeft(y_node); float y = YGNodeLayoutGetTop(y_node); float w = YGNodeLayoutGetWidth(y_node); float h = YGNodeLayoutGetHeight(y_node); auto old_size = m_size; if (YGNodeStyleGetWidth(y_node).unit == YGUnit::YGUnitAuto) w -= m_pos_offset.x; //if (YGNodeStyleGetHeight(y_node).unit == YGUnit::YGUnitAuto) // h -= m_pos_offset.y; m_pos = /*glm::floor*/(origin + glm::vec2(x, y) + m_pos_offset); m_pos_origin = /*glm::floor*/(origin + glm::vec2(x, y)); m_size = /*glm::floor*/(glm::vec2(w, h)); if (m_parent) { // correct the padding clip // should not clip the padded area // useful to draw decorations float pt = YGNodeLayoutGetPadding(m_parent->y_node, YGEdgeTop); float pr = YGNodeLayoutGetPadding(m_parent->y_node, YGEdgeRight); float pb = YGNodeLayoutGetPadding(m_parent->y_node, YGEdgeBottom); float pl = YGNodeLayoutGetPadding(m_parent->y_node, YGEdgeLeft); glm::vec2 off_p(pl, pt); glm::vec2 off_s(pr, pb); glm::vec4 pclip = { xy(m_parent->m_clip) + off_p, zw(m_parent->m_clip) - (off_s + off_p) }; m_clip_uncut = glm::vec4(m_pos - glm::vec2(1), m_size + glm::vec2(2)); m_clip = rect_intersection(m_clip_uncut, m_parent->m_clip); } else { m_clip_uncut = m_clip = glm::vec4(m_pos, m_size); } glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f)); glm::mat4 scale = glm::scale(glm::vec3(m_size, 1.f)); glm::mat4 prescale = glm::scale(glm::vec3(m_scale, 1.f)); glm::mat4 pos = glm::translate(glm::vec3(m_pos, 0)); m_mvp = proj * pos * scale * pivot * prescale; m_proj = proj; if (!glm::any(glm::isnan(m_size)) && m_size != old_size || m_zoom != zoom) { m_zoom = zoom; handle_resize(old_size, m_size, zoom); for (auto& c : m_children) c->handle_parent_resize(old_size, m_size); } for (auto& c : m_children) { c->m_pos_offset = m_pos_offset + m_pos_offset_childred; c->update_internal(m_pos_origin, proj, zoom); } m_children.erase(std::remove_if(m_children.begin(), m_children.end(), [](const auto& n) { return n->m_destroyed; }), m_children.end()); } void Node::tick(float dt) { for (auto& c : m_children) c->tick(dt); on_tick(dt); }