add panels docking

This commit is contained in:
2019-03-29 09:32:35 +01:00
parent 15db5c233b
commit 3964c4ea26
11 changed files with 396 additions and 17 deletions

View File

@@ -689,6 +689,10 @@ void App::terminate()
stroke.reset();
grid.reset();
presets.reset();
floating_presets.reset();
floating_color.reset();
floating_layers.reset();
floating_picker.reset();
rec_stop();
}

View File

@@ -64,9 +64,11 @@ public:
std::shared_ptr<NodePanelGrid> grid;
std::shared_ptr<NodePanelBrushPreset> presets;
NodePanelQuick* quick;
NodePanelColor* floating_color;
NodeColorPicker* floating_picker;
NodePanelBrushPreset* floating_presets;
Node* floatings_container;
std::shared_ptr<NodePanelColor> floating_color;
std::shared_ptr<NodeColorPicker> floating_picker;
std::shared_ptr<NodePanelBrushPreset> floating_presets;
std::shared_ptr<NodePanelLayer> floating_layers;
NodeCanvas* canvas;
const uint16_t main_id = const_hash("main");
const std::array<int, 6> res_map{ 512, 1024, 1536, 2048, 4096, 8192 };

View File

@@ -102,6 +102,7 @@ void App::init_sidebar()
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
canvas = layout[main_id]->find<NodeCanvas>("paint-canvas");
quick = layout[main_id]->find<NodePanelQuick>("panel-quick");
floatings_container = layout[main_id]->find<Node>("floatings");
//brushes = layout[main_id]->find<NodePanelBrush>("panel-brush");
//layers = layout[main_id]->find<NodePanelLayer>("panel-layer");
@@ -274,6 +275,7 @@ void App::init_sidebar()
auto screen = layout[main_id]->m_size;
glm::vec2 pos = button->m_pos + glm::vec2(button->m_size.x * 0.5f, button->m_size.y);
layout[main_id]->add_child(color);
color->SetSize(350, 350);
auto tick = layout[main_id]->add_child<NodeImage>();
tick->SetPositioning(YGPositionTypeAbsolute);
tick->SetSize(32, 16);
@@ -728,6 +730,153 @@ void App::init_menu_experimental()
}
};
if (auto tick = popup_exp->find<NodeButtonCustom>("experimental-panels-tick")) tick->on_click = [this, popup_exp](Node* b)
{
if (auto menu_time = popup_exp->find<NodePopupMenu>("experimental-panels"))
{
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
auto popup_time = (NodePopupMenu*)layout[const_hash("panels-menu")]->m_children[0]->clone();
popup_time->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup_time->m_size.x + b->m_size.x;
popup_time->SetPositioning(YGPositionTypeAbsolute);
popup_time->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup_time);
layout[main_id]->update();
popup_time->mouse_capture();
popup_time->m_mouse_ignore = false;
popup_time->m_flood_events = true;
popup_time->m_capture_children = false;
auto visible = [this](Node* panel) {
if (!panel)
return false;
for (auto& c : floatings_container->m_children)
{
if (auto fp = std::static_pointer_cast<NodePanelFloating>(c))
{
if (fp->m_container->is_child(panel))
return true;
}
}
return false;
};
popup_time->find<NodeButtonCustom>("panel-presets")->on_click = [this, popup_time, popup_exp, visible](Node*) {
if (visible(floating_presets.get()))
return;
auto fpanel = floatings_container->add_child<NodePanelFloating>();
fpanel->SetMinHeight(300);
if (!floating_presets)
{
floating_presets = fpanel->m_container->add_child_ref<NodePanelBrushPreset>();
floating_presets->SetHeightP(100);
//floating_presets->SetFlexGrow(1);
floating_presets->find("toolbar")->destroy();
floating_presets->on_brush_changed = [this](Node* target, std::shared_ptr<Brush>& b) {
auto c = Canvas::I->m_current_brush->m_tip_color;
*Canvas::I->m_current_brush = *b;
Canvas::I->m_current_brush->m_tip_color = c;
Canvas::I->m_current_brush->load();
brush_update();
};
}
else
{
fpanel->m_container->add_child(floating_presets);
}
popup_time->destroy();
popup_exp->destroy();
};
popup_time->find<NodeButtonCustom>("panel-color")->on_click = [this, popup_time, popup_exp, visible](Node*) {
if (visible(floating_color.get()))
return;
auto fpanel = floatings_container->add_child<NodePanelFloating>();
fpanel->SetMinHeight(300);
if (!floating_color)
{
floating_color = fpanel->m_container->add_child_ref<NodePanelColor>();
floating_color->SetHeightP(100);
//floating_color->SetMinHeight(300);
floating_color->find("title")->destroy();
floating_color->on_color_changed = [this](Node* target, glm::vec4 color) {
Canvas::I->m_current_brush->m_tip_color = color;
brush_update();
};
}
else
{
fpanel->m_container->add_child(floating_color);
}
popup_time->destroy();
popup_exp->destroy();
};
popup_time->find<NodeButtonCustom>("panel-color-adv")->on_click = [this, popup_time, popup_exp, visible](Node*) {
if (visible(floating_picker.get()))
return;
auto fpanel = floatings_container->add_child<NodePanelFloating>();
fpanel->SetHeight(300);
if (!floating_picker)
{
floating_picker = fpanel->m_container->add_child_ref<NodeColorPicker>();
//floating_picker->SetHeightP(100);
floating_picker->SetWidth(250);
floating_picker->m_autohide = false;
floating_picker->on_color_change = [this](Node* target, glm::vec3 color) {
Canvas::I->m_current_brush->m_tip_color = glm::vec4(color, 1.f);
brush_update();
};
}
else
{
fpanel->m_container->add_child(floating_picker);
}
popup_time->destroy();
popup_exp->destroy();
};
popup_time->find<NodeButtonCustom>("panel-layers")->on_click = [this, popup_time, popup_exp, visible](Node*) {
//if (visible(floating_layers.get()))
// return;
//auto fpanel = floatings_container->add_child<NodePanelFloating>();
//if (!floating_layers)
//{
// floating_layers = fpanel->m_container->add_child_ref<NodePanelLayer>();
//}
//else
//{
// fpanel->m_container->add_child(floating_layers);
//}
if (visible(layers.get()))
return;
auto fpanel = floatings_container->add_child<NodePanelFloating>();
fpanel->m_container->add_child(layers);
popup_time->destroy();
popup_exp->destroy();
};
popup_time->find<NodeButtonCustom>("panel-brush")->on_click = [this, popup_time, popup_exp, visible](Node*) {
if (visible(stroke.get()))
return;
auto fpanel = floatings_container->add_child<NodePanelFloating>();
fpanel->m_container->add_child(stroke);
popup_time->destroy();
popup_exp->destroy();
};
popup_time->find<NodeButtonCustom>("panel-grids")->on_click = [this, popup_time, popup_exp, visible](Node*) {
if (visible(grid.get()))
return;
auto fpanel = floatings_container->add_child<NodePanelFloating>();
fpanel->m_container->add_child(grid);
popup_time->destroy();
popup_exp->destroy();
};
}
};
if (auto rtl_btn = popup_exp->find<NodeButtonCustom>("experimental-rtl"))
{
rtl_btn->on_click = [this, popup_exp, rtl_btn](Node* b)
@@ -1085,6 +1234,7 @@ void App::initLayout()
};
}
/*
// test floating panel
auto fp_presets = layout[main_id]->add_child<NodePanelFloating>();
floating_presets = fp_presets->m_container->add_child<NodePanelBrushPreset>();
@@ -1116,6 +1266,7 @@ void App::initLayout()
};
//picker->SetHeightP(100);
//color->find("title")->destroy();
*/
App::I.redraw = true;
};

View File

@@ -62,7 +62,10 @@ void Node::watch(std::function<bool(Node*)> observer)
if (cont)
{
for (auto& c : m_children)
c->watch(observer);
{
if (!glm::any(glm::lessThanEqual(zw(c->m_clip), { 0, 0 })))
c->watch(observer);
}
}
}
@@ -119,7 +122,7 @@ kEventResult Node::on_event(Event* e)
skip_children |= (e->m_cat == kEventCategory::MouseEvent || e->m_cat == kEventCategory::GestureEvent) &&
(m_mouse_captured) && (root()->current_mouse_capture == this) && m_capture_children; // <-- THIS IS WRONG "!m_capture_children" is correct, but it breaks everything if changed
if (!m_display)
if (!m_display || glm::any(glm::lessThanEqual(zw(m_clip), { 0, 0 })))
return kEventResult::Available;
if (!skip_children)
@@ -257,6 +260,11 @@ void Node::handle_resize(glm::vec2 old_size, glm::vec2 new_size)
}
void Node::handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size)
{
}
void Node::create()
{
@@ -354,6 +362,7 @@ void Node::remove_child(Node* n)
if (i != m_children.end())
{
n->removed(this);
n->m_parent = nullptr;
YGNodeRemoveChild(y_node, n->y_node);
on_child_removed(n);
m_children.erase(i);
@@ -367,6 +376,7 @@ void Node::remove_all_children()
for (auto& n : m_children)
{
n->removed(this);
n->m_parent = nullptr;
YGNodeRemoveChild(y_node, n->y_node);
on_child_removed(n.get());
}
@@ -385,6 +395,12 @@ void Node::move_child(Node* n, int index)
m_children.insert(m_children.begin() + index, tmp);
}
void Node::move_child_front(Node* n)
{
int count = YGNodeGetChildCount(y_node);
move_child(n, count - 1);
}
void Node::move_child_offset(Node* n, int offset)
{
int count = YGNodeGetChildCount(y_node);
@@ -437,6 +453,21 @@ glm::vec4 Node::get_children_rect() const
return ret;
}
std::vector<std::shared_ptr<Node>> Node::get_children_at_point(glm::vec2 point) const
{
std::vector<std::shared_ptr<Node>> ret;
for (const auto& c : m_children)
{
if (point_in_rect(point, c->m_clip))
{
ret.push_back(c);
auto c_ret = c->get_children_at_point(point);
ret.insert(ret.end(), c_ret.begin(), c_ret.end());
}
}
return ret;
}
bool Node::is_child_recursive(Node* o) const
{
for (const auto& c : m_children)
@@ -651,6 +682,26 @@ void Node::SetMaxHeightP(float value)
YGNodeStyleSetMaxHeightPercent(y_node, value);
}
void Node::SetMinWidth(float value)
{
YGNodeStyleSetMinWidth(y_node, value);
}
void Node::SetMinWidthP(float value)
{
YGNodeStyleSetMinWidthPercent(y_node, value);
}
void Node::SetMinHeight(float value)
{
YGNodeStyleSetMinHeight(y_node, value);
}
void Node::SetMinHeightP(float value)
{
YGNodeStyleSetMinHeightPercent(y_node, value);
}
void Node::SetPadding(float t, float r, float b, float l)
{
YGNodeStyleSetPadding(y_node, YGEdgeTop, t);
@@ -887,7 +938,11 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
}
if (m_size != old_size)
{
handle_resize(old_size, m_size);
for (auto& c : m_children)
c->handle_parent_resize(old_size, m_size);
}
for (auto& c : m_children)
c->update_internal(m_pos, proj);

View File

@@ -126,7 +126,9 @@ public:
glm::vec2 m_pos_offset{ 0, 0 }; // artificial position offset for scrolling
glm::vec2 m_pos_offset_childred{ 0, 0 }; // artificial position offset for scrolling
glm::vec2 m_size{ 0, 0 };
// rect: {origin}{size}
glm::vec4 m_clip{ 0, 0, 0, 0 };
// rect: {origin}{size}
glm::vec4 m_clip_uncut{ 0, 0, 0, 0 };
std::string m_name;
bool m_display = true;
@@ -148,6 +150,10 @@ public:
void SetMaxWidthP(float value);
void SetMaxHeight(float value);
void SetMaxHeightP(float value);
void SetMinWidth(float value);
void SetMinWidthP(float value);
void SetMinHeight(float value);
void SetMinHeightP(float value);
void SetPadding(float t, float r, float b, float l);
glm::vec4 GetPadding() const;
@@ -229,11 +235,23 @@ public:
add_child(n);
return n;
}
template<class T> std::shared_ptr<T> add_child_ref()
{
auto n = std::make_shared<T>();
n->m_manager = m_manager;
n->m_parent = m_parent;
n->init();
n->create();
n->loaded();
add_child(n);
return n;
}
virtual void on_tick(float dt) { };
virtual kEventResult on_event(Event* e);
virtual kEventResult handle_event(Event* e);
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size);
virtual void handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size);
virtual void create();
virtual void init();
virtual void loaded();
@@ -254,11 +272,13 @@ public:
void remove_child(Node* n);
void remove_all_children();
void move_child(Node* n, int index);
void move_child_front(Node* n);
void move_child_offset(Node* n, int offset);
int get_child_index(Node* n);
Node* get_child_at(int index);
// returns {origin, size} form
glm::vec4 get_children_rect() const;
std::vector<std::shared_ptr<Node>> get_children_at_point(glm::vec2 point) const;
bool is_child_recursive(Node* o) const;
bool is_child(Node* o) const;
void mouse_capture();

View File

@@ -1,5 +1,6 @@
#include "pch.h"
#include "node_panel_floating.h"
#include "log.h"
Node* NodePanelFloating::clone_instantiate() const
{
@@ -32,6 +33,19 @@ void NodePanelFloating::init_controls()
m_button_minimize->on_click = [this](Node*) {
m_container->ToggleVisibility();
};
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)
{
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)
@@ -43,21 +57,100 @@ kEventResult NodePanelFloating::handle_event(Event* e)
{
case kEventType::MouseDownL:
m_dragging = true;
m_drag_start_pos = m_pos;
if (me->m_pos.y - m_pos.y > m_size.y - 20.f)
{
if (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.1 };
m_outline->m_thinkness = 1;
}
m_drag_start_cur = me->m_pos;
mouse_capture();
m_parent->move_child_front(this);
ret = kEventResult::Consumed;
break;
case kEventType::MouseMove:
if (m_dragging)
{
auto newpos = glm::clamp(m_drag_start_pos + me->m_pos - m_drag_start_cur, { 0, 0 }, root()->m_size - m_size);
SetPosition(newpos);
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);
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);
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);
break;
}
}
}
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)
{
m_outline->destroy();
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)];
for (auto const& c : nodes)
{
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);
docked = true;
break;
}
}
if (!docked)
{
auto cont = root()->find("floatings");
SetPositioning(YGPositionTypeAbsolute);
SetPosition(m_outline->m_pos - cont->m_pos);
cont->add_child(ref);
}
}
mouse_release();
ret = kEventResult::Consumed;
break;

View File

@@ -4,10 +4,13 @@
class NodePanelFloating : public NodeBorder
{
enum class kDragAction : uint8_t { Move, Resize, Reheight } m_action;
bool m_dragging = false;
glm::vec2 m_drag_start_pos;
glm::vec2 m_drag_start_cur;
NodeButton* m_button_minimize;
NodeButton* m_button_close;
NodeBorder* m_outline;
public:
Node* m_container;
using this_class = NodePanelFloating;
@@ -15,6 +18,7 @@ public:
virtual Node* clone_instantiate() const override;
virtual void clone_finalize(Node* dest) const override;
virtual kEventResult handle_event(Event* e) override;
virtual void handle_parent_resize(glm::vec2 old_size, glm::vec2 new_size) override;
virtual void init() override;
void init_controls();
};