improved docking
This commit is contained in:
@@ -356,6 +356,12 @@ void Node::add_child(std::shared_ptr<Node> 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; });
|
||||
|
||||
@@ -269,6 +269,7 @@ public:
|
||||
void add_child(Node* n, int index);
|
||||
void add_child(std::shared_ptr<Node> n);
|
||||
void add_child(std::shared_ptr<Node> n, int index);
|
||||
void remove_from_parent();
|
||||
void remove_child(Node* n);
|
||||
void remove_all_children();
|
||||
void move_child(Node* n, int index);
|
||||
|
||||
@@ -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<NodeBorder>();
|
||||
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;
|
||||
|
||||
@@ -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<Node> 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<NodeBorder> m_drop_placeholder;
|
||||
public:
|
||||
Node* m_container;
|
||||
using this_class = NodePanelFloating;
|
||||
|
||||
@@ -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<NodeSliderV>("quick-size");
|
||||
m_slider_size->on_value_changed = [this](Node* target, float value) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user