diff --git a/src/node.cpp b/src/node.cpp index 0d77734..0f1c5e9 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -356,6 +356,12 @@ void Node::add_child(std::shared_ptr n, int index) on_child_added(n.get()); } +void Node::remove_from_parent() +{ + if (m_parent) + m_parent->remove_child(this); +} + void Node::remove_child(Node* n) { auto i = std::find_if(m_children.begin(), m_children.end(), [=](auto& ptr) { return ptr.get() == n; }); diff --git a/src/node.h b/src/node.h index 917c888..9581384 100644 --- a/src/node.h +++ b/src/node.h @@ -269,6 +269,7 @@ public: void add_child(Node* n, int index); void add_child(std::shared_ptr n); void add_child(std::shared_ptr n, int index); + void remove_from_parent(); void remove_child(Node* n); void remove_all_children(); void move_child(Node* n, int index); diff --git a/src/node_panel_floating.cpp b/src/node_panel_floating.cpp index 07ff92e..4502656 100644 --- a/src/node_panel_floating.cpp +++ b/src/node_panel_floating.cpp @@ -42,10 +42,13 @@ void NodePanelFloating::init_controls() void NodePanelFloating::handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size) { - auto newsize = glm::clamp(GetSize(), { 0, 0 }, m_parent->m_size); - SetHeight(newsize.y); - auto newpos = glm::clamp(GetPosition(), { 0, 0 }, m_parent->m_size - m_size); - SetPosition(newpos); + if (m_dock.expired()) + { + auto newsize = glm::clamp(GetSize(), { 0, 0 }, m_parent->m_size); + SetHeight(newsize.y); + auto newpos = glm::clamp(GetPosition(), { 0, 0 }, m_parent->m_size - m_size); + SetPosition(newpos); + } } kEventResult NodePanelFloating::handle_event(Event* e) @@ -79,10 +82,15 @@ kEventResult NodePanelFloating::handle_event(Event* e) m_outline->SetSize(GetSize()); m_outline->m_color = { 0, 0, 0, 0.1 }; m_outline->m_thinkness = 1; + m_drop_placeholder = std::make_shared(); + m_drop_placeholder->SetSize(300, 10); + m_drop_placeholder->m_color = { 0, 0, 0, 0.1 }; + m_drop_placeholder->m_thinkness = 1; } m_drag_start_cur = me->m_pos; mouse_capture(); - m_parent->move_child_front(this); + if (m_dock.expired()) + m_parent->move_child_front(this); ret = kEventResult::Consumed; break; case kEventType::MouseMove: @@ -91,20 +99,46 @@ kEventResult NodePanelFloating::handle_event(Event* e) if (m_action == kDragAction::Move) { auto newpos = glm::clamp(m_drag_start_pos + me->m_pos - m_drag_start_cur, { 0, 0 }, m_parent->m_size - m_size); - SetPosition(newpos); + if (m_dock.expired()) + SetPosition(newpos); m_outline->SetPosition(m_parent->m_pos + m_drag_start_pos + me->m_pos - m_drag_start_cur); m_outline->SetSize(GetSize()); auto nodes = root()->find("ui-root")->get_children_at_point(me->m_pos); + bool docked = false; for (auto const& c : nodes) { if (c->m_nodeID_s.find("drop") == 0) { m_outline->SetPosition(c->m_pos); m_outline->SetSize(c->m_size); + m_drop_placeholder->remove_from_parent(); + int i = 0; + float y = 0; + for (; i < c->m_children.size(); i++) + { + if (c->m_children[i] == m_drop_placeholder) + continue; + float y = c->m_children[i]->m_pos.y - c->m_pos.y + c->m_children[i]->m_size.y / 2.f; + float my = me->m_pos.y - c->m_pos.y; + if (my <= y) + break; + } + i = std::min(i, (int)c->m_children.size()); + if (/*m_parent != c.get() && */m_drop_placeholder->m_parent != c.get()) + { + c->add_child(m_drop_placeholder, i); + } + else + { + c->move_child(m_drop_placeholder.get(), i); + } + docked = true; break; } } + if (!docked && m_drop_placeholder->m_parent) + m_drop_placeholder->remove_from_parent(); } else if (m_action == kDragAction::Reheight) { @@ -123,7 +157,16 @@ kEventResult NodePanelFloating::handle_event(Event* e) m_dragging = false; if (m_action == kDragAction::Move) { - m_outline->destroy(); + if (m_outline) + m_outline->destroy(); + int drop_pos = 0; + if (m_drop_placeholder) + { + if (m_drop_placeholder->m_parent) + drop_pos = std::max(0, m_drop_placeholder->m_parent->get_child_index(m_drop_placeholder.get())); + m_drop_placeholder->destroy(); + m_drop_placeholder->remove_from_parent(); + } auto nodes = root()->find("ui-root")->get_children_at_point(me->m_pos); bool docked = false; auto ref = m_parent->m_children[m_parent->get_child_index(this)]; @@ -131,25 +174,33 @@ kEventResult NodePanelFloating::handle_event(Event* e) { if (c->m_nodeID_s.find("drop") == 0) { - //auto panel = m_container->m_children.front(); - //panel->SetSize(300, 300); - //c->add_child(m_container->m_children.front()); - //destroy(); SetPositioning(YGPositionTypeRelative); - SetWidth(300); SetPosition(0, 0); - c->add_child(ref); + if (m_dock.lock() != c) + { + SetWidth(300); + c->add_child(ref, drop_pos); + m_dock = c; + } + else + { + c->move_child(ref.get(), std::min((int)c->m_children.size() - 1, drop_pos)); + } docked = true; break; } } - if (!docked) + if (!docked && !m_dock.expired()) { auto cont = root()->find("floatings"); SetPositioning(YGPositionTypeAbsolute); - SetPosition(m_outline->m_pos - cont->m_pos); + auto newpos = glm::clamp(m_outline->m_pos - cont->m_pos, { 0, 0 }, cont->m_size - m_size); + SetPosition(newpos); cont->add_child(ref); + m_dock.reset(); } + m_outline = nullptr; + m_drop_placeholder = nullptr; } mouse_release(); ret = kEventResult::Consumed; diff --git a/src/node_panel_floating.h b/src/node_panel_floating.h index 8eaf132..fca1d3c 100644 --- a/src/node_panel_floating.h +++ b/src/node_panel_floating.h @@ -6,11 +6,13 @@ class NodePanelFloating : public NodeBorder { enum class kDragAction : uint8_t { Move, Resize, Reheight } m_action; bool m_dragging = false; + std::weak_ptr m_dock; glm::vec2 m_drag_start_pos; glm::vec2 m_drag_start_cur; NodeButton* m_button_minimize; NodeButton* m_button_close; NodeBorder* m_outline; + std::shared_ptr m_drop_placeholder; public: Node* m_container; using this_class = NodePanelFloating; diff --git a/src/node_panel_quick.cpp b/src/node_panel_quick.cpp index 29292ce..aaba695 100644 --- a/src/node_panel_quick.cpp +++ b/src/node_panel_quick.cpp @@ -38,6 +38,7 @@ void NodePanelQuick::init_controls() m_picker->m_mouse_ignore = false; m_picker->m_flood_events = true; m_picker->m_capture_children = false; + m_picker->SetWidth(300); m_slider_size = find("quick-size"); m_slider_size->on_value_changed = [this](Node* target, float value) { diff --git a/src/node_scroll.cpp b/src/node_scroll.cpp index 9cdfa99..a63d1f0 100644 --- a/src/node_scroll.cpp +++ b/src/node_scroll.cpp @@ -74,7 +74,7 @@ void NodeScroll::draw() glm::vec4 rect = get_children_rect(); glm::vec4 pad = GetPadding(); float sz = m_size.y - (pad[0] + pad[2]); - float h = sz / rect.w * sz; + float h = glm::max(30.f, sz / rect.w * sz); float offset_percent = m_offset.y / (rect.w - sz); float pr = YGNodeLayoutGetPadding(y_node, YGEdgeRight) - 5; glDisable(GL_BLEND);