236 lines
8.3 KiB
C++
236 lines
8.3 KiB
C++
#include "pch.h"
|
|
#include "node_panel_floating.h"
|
|
#include "log.h"
|
|
|
|
Node* NodePanelFloating::clone_instantiate() const
|
|
{
|
|
return new this_class;
|
|
}
|
|
|
|
void NodePanelFloating::clone_finalize(Node* dest) const
|
|
{
|
|
parent::clone_finalize(dest);
|
|
auto n = static_cast<this_class*>(dest);
|
|
n->init_controls();
|
|
}
|
|
|
|
void NodePanelFloating::init()
|
|
{
|
|
parent::init();
|
|
init_template_file("data/dialogs/panel-floating.xml", "tpl-panel-floating");
|
|
init_controls();
|
|
}
|
|
|
|
void NodePanelFloating::init_controls()
|
|
{
|
|
SetPositioning(YGPositionTypeAbsolute);
|
|
SetPosition({ 0, 0 });
|
|
m_mouse_ignore = false;
|
|
m_flood_events = true;
|
|
m_capture_children = true;
|
|
m_container = find("container");
|
|
m_title = find<NodeText>("title");
|
|
m_button_minimize = find<NodeButton>("button-minimize");
|
|
m_button_minimize->on_click = [this](Node*) {
|
|
m_container->ToggleVisibility();
|
|
if (m_container->m_display)
|
|
{
|
|
SetHeight(m_extended_size.y);
|
|
}
|
|
else
|
|
{
|
|
m_extended_size.y = GetHeight();
|
|
SetHeight(YGUndefined);
|
|
}
|
|
};
|
|
m_button_close = find<NodeButton>("button-close");
|
|
m_button_close->on_click = [this](Node*) {
|
|
m_container->remove_all_children();
|
|
destroy();
|
|
};
|
|
}
|
|
|
|
void NodePanelFloating::handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size)
|
|
{
|
|
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)
|
|
{
|
|
parent::handle_event(e);
|
|
kEventResult ret = kEventResult::Available;
|
|
auto me = static_cast<MouseEvent*>(e);
|
|
switch (e->m_type)
|
|
{
|
|
case kEventType::MouseDownL:
|
|
m_dragging = true;
|
|
if (me->m_pos.y - m_pos.y > m_size.y - 20.f)
|
|
{
|
|
if (m_dock.expired() && me->m_pos.x - m_pos.x > m_size.x - 20.f)
|
|
{
|
|
m_action = kDragAction::Resize;
|
|
}
|
|
else
|
|
{
|
|
m_action = kDragAction::Reheight;
|
|
}
|
|
m_drag_start_pos = GetSize();
|
|
}
|
|
else
|
|
{
|
|
m_drag_start_pos = GetPosition();
|
|
m_action = kDragAction::Move;
|
|
m_outline = root()->add_child<NodeBorder>();
|
|
m_outline->SetPositioning(YGPositionTypeAbsolute);
|
|
m_outline->SetPosition(m_pos);
|
|
m_outline->SetSize(GetSize());
|
|
m_outline->m_color = { 0, 0, 0, 0.25 };
|
|
m_outline->m_thinkness = 1;
|
|
m_drop_placeholder = std::make_shared<NodeBorder>();
|
|
m_drop_placeholder->SetSize(350, 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();
|
|
if (m_dock.expired())
|
|
m_parent->move_child_front(this);
|
|
ret = kEventResult::Consumed;
|
|
break;
|
|
case kEventType::MouseMove:
|
|
if (m_dragging)
|
|
{
|
|
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);
|
|
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());
|
|
|
|
bool docked = false;
|
|
if (m_droppable)
|
|
{
|
|
std::vector<std::shared_ptr<Node>> nodes;
|
|
if (auto uir = root()->find("ui-root"))
|
|
nodes = uir->get_children_at_point(me->m_pos);
|
|
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)
|
|
{
|
|
auto newsize = glm::clamp(m_drag_start_pos + me->m_pos - m_drag_start_cur, { 0, 0 }, m_parent->m_size);
|
|
SetHeight(newsize.y);
|
|
}
|
|
else if (m_action == kDragAction::Resize)
|
|
{
|
|
auto newsize = glm::clamp(m_drag_start_pos + me->m_pos - m_drag_start_cur, { 0, 0 }, m_parent->m_size);
|
|
SetSize(newsize);
|
|
}
|
|
ret = kEventResult::Consumed;
|
|
}
|
|
break;
|
|
case kEventType::MouseUpL:
|
|
m_dragging = false;
|
|
if (m_action == kDragAction::Move)
|
|
{
|
|
glm::vec2 outline_pos(0);
|
|
if (m_outline)
|
|
{
|
|
outline_pos = m_outline->m_pos;
|
|
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();
|
|
}
|
|
bool docked = false;
|
|
if (m_droppable)
|
|
{
|
|
std::vector<std::shared_ptr<Node>> nodes;
|
|
if (auto uir = root()->find("ui-root"))
|
|
nodes = uir->get_children_at_point(me->m_pos);
|
|
for (auto const& c : nodes)
|
|
{
|
|
if (c->m_nodeID_s.find("drop") == 0)
|
|
{
|
|
SetPositioning(YGPositionTypeRelative);
|
|
SetPosition(0, 0);
|
|
if (m_dock.lock() != c)
|
|
{
|
|
SetWidth(350);
|
|
c->add_child(shared_from_this(), drop_pos);
|
|
m_dock = c;
|
|
}
|
|
else
|
|
{
|
|
c->move_child(this, std::min((int)c->m_children.size() - 1, drop_pos));
|
|
}
|
|
docked = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!docked && !m_dock.expired())
|
|
{
|
|
auto cont = root()->find("floatings");
|
|
SetPositioning(YGPositionTypeAbsolute);
|
|
auto newpos = glm::clamp(outline_pos - cont->m_pos, { 0, 0 }, cont->m_size - m_size);
|
|
SetPosition(newpos);
|
|
cont->add_child(shared_from_this());
|
|
m_dock.reset();
|
|
}
|
|
m_outline = nullptr;
|
|
m_drop_placeholder = nullptr;
|
|
}
|
|
mouse_release();
|
|
ret = kEventResult::Consumed;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|