integrate quick panel and new color picker

This commit is contained in:
2019-03-04 18:38:38 +01:00
parent fb006a6859
commit 6e73a9eee5
13 changed files with 234 additions and 81 deletions

View File

@@ -758,38 +758,49 @@
</border>-->
<border width="300" color=".4" pad="10" dir="col">
<colorwheel id="wheel" width="100%" aspect-ratio="1"/>
<border color="1" pad="5" dir="row" margin="10 0 0 0">
<border border-color="0 0 0 1" thickness="1" id="color-cur" height="30" grow="1" color="1"/>
<border border-color="0 0 0 1" thickness="1" id="color-old" height="30" grow="1" color="0"/>
<border border-color="0 0 0 1" thickness="1" id="color-old1" height="30" grow="1" color="0"/>
<border border-color="0 0 0 1" thickness="1" id="color-old2" height="30" grow="1" color="0"/>
<border color=".3" pad="5" dir="row" margin="10 0 0 0">
<border id="color-cur" height="30" grow="1" color="1"/>
<border id="color-old" height="30" grow="1" color="0" margin="0 10 0 0"/>
<border id="color-old1" height="30" grow="0.5" color="0" margin="0 2 0 0"/>
<border id="color-old2" height="30" grow="0.5" color="0" margin="0 2 0 0"/>
<border id="color-old3" height="30" grow="0.5" color="0" margin="0 2 0 0"/>
<border id="color-old4" height="30" grow="0.5" color="0"/>
</border>
<!--HSV-->
<border pad="5" color=".3" margin="10 0 0 0">
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="H"/></node>
<slider-h id="hsv-h" width="10" grow="1" value="1"/>
</node>
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="S"/></node>
<slider-h id="hsv-s" width="10" grow="1" value="1"/>
</node>
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="V"/></node>
<slider-h id="hsv-v" width="10" grow="1" value="1"/>
</node>
</border>
<!--RGB-->
<border pad="5" color=".3" margin="10 0 0 0">
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="R"/></node>
<slider-h id="rgb-r" width="10" grow="1" value="1"/>
</node>
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="G"/></node>
<slider-h id="rgb-g" width="10" grow="1" value="1"/>
</node>
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="B"/></node>
<slider-h id="rgb-b" width="10" grow="1" value="1"/>
</node>
</border>
<node width="100%" pad="2" height="20" dir="row" align="center" margin="10 0 0 0">
<node width="20"><text text="H"/></node>
<slider-h id="hsv-h" width="10" grow="1" value="1"/>
</node>
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="S"/></node>
<slider-h id="hsv-s" width="10" grow="1" value="1"/>
</node>
<node width="100%" pad="2" height="20" dir="row" align="center">
<node width="20"><text text="V"/></node>
<slider-h id="hsv-v" width="10" grow="1" value="1"/>
</node>
<node width="100%" pad="2" height="20" dir="row" align="center" margin="5 0 0 0">
<node width="20"><text text="R"/></node>
<slider-h id="rgb-r" width="10" grow="1" value="1"/>
<node width="15" margin="0 0 0 5"><text text="G"/></node>
<slider-h id="rgb-g" width="10" grow="1" value="1"/>
<node width="15" margin="0 0 0 5"><text text="B"/></node>
<slider-h id="rgb-b" width="10" grow="1" value="1"/>
</node>
</border>
<node height="33" dir="row" align="flex-end" justify="flex-end">
<!--<node height="33" dir="row" align="flex-end" justify="flex-end">
<button id="btn-ok" text="Reset" width="60" height="30" margin="0 10 0 0"/>
<button id="btn-select" text="Select color" width="100" height="30"/>
</node>
</node>-->
</border>
</layout>
@@ -1413,7 +1424,7 @@ Here's a list of what's available in this release.
</layout>
<!-- quick access -->
<layout id="panel-quick">
<layout id="tpl-panel-quick">
<border color="0 0 0 0.3" width="80" dir="col" pad="5" align="center" mouse-capture="true" shrink="1">
<node dir="row" pad="5">
<!--size-->
@@ -1593,7 +1604,7 @@ Here's a list of what's available in this release.
<!--quick bar-->
<node justify="center" align="center">
<panel-quick/>
<panel-quick id="panel-quick"/>
</node>
<!-- timeline -->

View File

@@ -32,6 +32,7 @@
#include "main.h"
#endif
#include "node_panel_grid.h"
#include "node_panel_quick.h"
class App
{
@@ -64,6 +65,7 @@ public:
std::shared_ptr<NodePanelColor> color;
std::shared_ptr<NodePanelStroke> stroke;
std::shared_ptr<NodePanelGrid> grid;
NodePanelQuick* quick;
NodeCanvas* canvas;
Node* current_panel = nullptr;
NodeScroll* panels;

View File

@@ -110,6 +110,7 @@ void App::init_sidebar()
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
panels = layout[main_id]->find<NodeScroll>("panels");
canvas = layout[main_id]->find<NodeCanvas>("paint-canvas");
quick = layout[main_id]->find<NodePanelQuick>("panel-quick");
//brushes = layout[main_id]->find<NodePanelBrush>("panel-brush");
//layers = layout[main_id]->find<NodePanelLayer>("panel-layer");
@@ -128,6 +129,7 @@ void App::init_sidebar()
color->on_color_changed = [this](Node* target, glm::vec4 color) {
Canvas::I->m_current_brush->m_tip_color = color;
};
stroke->on_brush_changed = [this](Node* target, const std::string& path, const std::string& thumb) {
Canvas::I->m_current_brush->load_tip(path, thumb);
stroke->m_preview->draw_stroke();
@@ -140,6 +142,20 @@ void App::init_sidebar()
Canvas::I->m_current_brush->load_dual(path, thumb);
stroke->m_preview->draw_stroke();
};
stroke->on_stroke_change = [this](Node*) {
quick->m_slider_flow->set_value(stroke->m_tip_flow->get_value());
quick->m_slider_size->set_value(stroke->m_tip_size->get_value());
};
quick->on_color_change = [this](Node*, glm::vec3 color) {
Canvas::I->m_current_brush->m_tip_color = glm::vec4(color, 1.f);
};
quick->on_flow_change = [this](Node*, float value) {
stroke->set_flow(value, true, true);
};
quick->on_size_change = [this](Node*, float value) {
stroke->set_size(value, true, true);
};
layers->on_layer_add = [this](Node*) {
canvas->m_canvas->layer_add(layers->m_layers.back()->m_label_text.c_str());

View File

@@ -29,6 +29,11 @@ void NodeButtonCustom::loaded()
m_mouse_ignore = false;
}
bool NodeButtonCustom::is_active()
{
return m_active;
}
void NodeButtonCustom::set_active(bool active)
{
if (m_active == active)
@@ -40,7 +45,7 @@ void NodeButtonCustom::set_active(bool active)
void NodeButtonCustom::set_color(const glm::vec4& c)
{
color_normal = c;
m_color = color_normal;
m_color = m_active ? color_active : (m_mouse_inside ? color_hover : color_normal);
}
kEventResult NodeButtonCustom::handle_event(Event* e)

View File

@@ -13,6 +13,7 @@ public:
virtual Node* clone_instantiate() const override;
virtual void clone_copy(Node* dest) const override;
virtual void loaded() override;
bool is_active();
void set_active(bool active);
void set_color(const glm::vec4& c);
virtual kEventResult handle_event(Event* e) override;

View File

@@ -48,6 +48,12 @@ kEventResult NodeColorPicker::handle_event(Event* e)
case kEventType::MouseUpL:
if (!m_mouse_inside)
{
if (m_color_cur->m_color != m_color_old->m_color)
{
m_color_old2->m_color = m_color_old1->m_color;
m_color_old1->m_color = m_color_old->m_color;
m_color_old->m_color = m_color_cur->m_color;
}
mouse_release();
parent->remove_child(this);
if (on_popup_close)
@@ -74,34 +80,65 @@ void NodeColorPicker::init_controls()
m_color_old = find<NodeBorder>("color-old");
m_color_old1 = find<NodeBorder>("color-old1");
m_color_old2 = find<NodeBorder>("color-old2");
m_button_select = find<NodeButton>("btn-select");
m_button_select->on_click = [this](Node*)
{
m_color_old2->m_color = m_color_old1->m_color;
m_color_old1->m_color = m_color_old->m_color;
m_color_old->m_color = m_color_cur->m_color;
};
m_wheel->on_value_changed = [this](Node*, glm::vec3 hsv)
{
m_slider_h->m_value.x = hsv.x;
m_slider_s->m_value.x = hsv.y;
m_slider_v->m_value.x = hsv.z;
glm::vec3 rgb = convert_hsv2rgb(hsv);
m_slider_r->m_value.x = rgb.x;
m_slider_g->m_value.x = rgb.y;
m_slider_b->m_value.x = rgb.z;
m_color_cur->m_color = {rgb,1};
m_slider_h->set_value(hsv.x);
m_slider_s->set_value(hsv.y);
m_slider_v->set_value(hsv.z);
m_color_cur->m_color = { rgb, 1 };
if (on_color_change)
on_color_change(this, rgb);
};
auto hsv_setter = [this](Node* target, float v)
{
m_wheel->m_hsv = get_hsv();
glm::vec3 rgb = convert_hsv2rgb(get_hsv());
m_color_cur->m_color = {rgb,1};
auto hsv = get_hsv();
m_wheel->m_hsv = hsv;
glm::vec3 rgb = convert_hsv2rgb(hsv);
m_color_cur->m_color = { rgb, 1 };
m_slider_r->m_value.x = rgb.x;
m_slider_g->m_value.x = rgb.y;
m_slider_b->m_value.x = rgb.z;
if (on_color_change)
on_color_change(this, rgb);
};
m_slider_h->on_value_changed = hsv_setter;
m_slider_s->on_value_changed = hsv_setter;
m_slider_v->on_value_changed = hsv_setter;
auto rgb_setter = [this](Node* target, float v)
{
glm::vec3 rgb = get_rgb();
glm::vec3 hsv = convert_rgb2hsv(rgb);
m_wheel->m_hsv = hsv;
m_color_cur->m_color = { rgb, 1 };
m_slider_h->set_value(hsv.x);
m_slider_s->set_value(hsv.y);
m_slider_v->set_value(hsv.z);
if (on_color_change)
on_color_change(this, rgb);
};
m_slider_r->on_value_changed = rgb_setter;
m_slider_g->on_value_changed = rgb_setter;
m_slider_b->on_value_changed = rgb_setter;
}
void NodeColorPicker::set_color(glm::vec3 rgb)
{
auto hsv = convert_rgb2hsv(rgb);
m_slider_h->set_value(hsv.x);
m_slider_s->set_value(hsv.y);
m_slider_v->set_value(hsv.z);
m_slider_r->set_value(rgb.x);
m_slider_g->set_value(rgb.y);
m_slider_b->set_value(rgb.z);
m_wheel->m_hsv = hsv;
m_color_cur->m_color = { rgb, 1 };
m_color_old->m_color = { rgb, 1 };
}
glm::vec3 NodeColorPicker::get_hsv() const
@@ -111,3 +148,11 @@ glm::vec3 NodeColorPicker::get_hsv() const
float v = m_slider_v->get_value();
return glm::vec3(h, s, v);
}
glm::vec3 NodeColorPicker::get_rgb() const
{
float r = m_slider_r->get_value();
float g = m_slider_g->get_value();
float b = m_slider_b->get_value();
return glm::vec3(r, g, b);
}

View File

@@ -9,6 +9,7 @@ class NodeColorPicker : public NodeBorder
{
public:
std::function<void(Node* target)> on_popup_close;
std::function<void(Node* target, glm::vec3 rgb)> on_color_change;
NodeSliderH* m_slider_h;
NodeSliderH* m_slider_s;
@@ -21,7 +22,6 @@ public:
NodeBorder* m_color_old;
NodeBorder* m_color_old1;
NodeBorder* m_color_old2;
NodeButton* m_button_select;
glm::vec3 m_rgb;
glm::vec3 m_hsv;
@@ -32,6 +32,8 @@ public:
virtual void draw() override;
virtual kEventResult handle_event(Event* e) override;
void init_controls();
void set_color(glm::vec3 rgb);
glm::vec3 get_hsv() const;
glm::vec3 get_rgb() const;
void handle_value_changed();
};

View File

@@ -18,7 +18,7 @@ void NodePanelQuick::clone_finalize(Node* dest) const
void NodePanelQuick::init()
{
parent::init();
auto t = static_cast<const NodeBorder*>(init_template("panel-quick"));
auto t = static_cast<const NodeBorder*>(init_template("tpl-panel-quick"));
init_controls();
}
@@ -39,32 +39,77 @@ void NodePanelQuick::init_controls()
m_picker->m_flood_events = true;
m_picker->m_capture_children = false;
if (auto b = find<NodeButtonCustom>("quick-color1"))
{
b->on_click = [this,b](Node*) {
auto screen = root()->m_size;
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
root()->add_child(m_picker);
auto tick = root()->add_child<NodeImage>();
tick->SetPositioning(YGPositionTypeAbsolute);
tick->SetSize(16, 32);
tick->SetPosition(pos.x, pos.y + (b->m_size.y - 32) * 0.5f);
tick->set_image("data/ui/popup-tick.png");
//float hh = m_picker->m_container->m_children.size() > 10 ? App::I.height / App::I.zoom * .75f : 400.f;
//m_picker->SetHeight(4);
root()->update();
pos.y -= 130;
if ((pos.y + m_picker->m_size.y) > screen.y)
pos.y = screen.y - m_picker->m_size.y;
if (pos.y < 0)
pos.y = 0;
m_picker->SetPosition(pos.x + 16, pos.y);
m_picker->mouse_capture();
root()->update();
m_slider_size = find<NodeSliderV>("quick-size");
m_slider_size->on_value_changed = [this](Node* target, float value) {
if (on_size_change)
on_size_change(target, value);
};
m_slider_flow = find<NodeSliderV>("quick-flow");
m_slider_flow->on_value_changed = [this](Node* target, float value) {
if (on_flow_change)
on_flow_change(target, value);
};
m_picker->on_popup_close = [this, tick](Node*) {
tick->destroy();
};
};
}
m_button_color1 = find<NodeButtonCustom>("quick-color1");
m_button_color2 = find<NodeButtonCustom>("quick-color2");
m_button_color3 = find<NodeButtonCustom>("quick-color3");
m_button_color_current = m_button_color1;
m_button_color_current->set_active(true);
m_button_color1->on_click = std::bind(&this_class::handle_button_color_click, this, std::placeholders::_1);
m_button_color2->on_click = std::bind(&this_class::handle_button_color_click, this, std::placeholders::_1);
m_button_color3->on_click = std::bind(&this_class::handle_button_color_click, this, std::placeholders::_1);
m_button_color1->color_active = { 0, 0, 0, 0.5f };
m_button_color2->color_active = { 0, 0, 0, 0.5f };
m_button_color3->color_active = { 0, 0, 0, 0.5f };
m_button_color1->set_color({ 0, 0, 0, 0 });
m_button_color2->set_color({ 0, 0, 0, 0 });
m_button_color3->set_color({ 0, 0, 0, 0 });
}
void NodePanelQuick::handle_button_color_click(Node* target)
{
// the first time select the box
if (m_button_color_current != target)
{
auto button = static_cast<NodeButtonCustom*>(target);
button->set_active(true);
m_button_color_current->set_active(false);
m_button_color_current = button;
if (on_color_change)
on_color_change(this, static_cast<NodeBorder*>(button->m_children[0].get())->m_color);
return;
}
// if the box is already selected show the popup
auto screen = root()->m_size;
glm::vec2 pos = target->m_pos + glm::vec2(target->m_size.x, 0);
root()->add_child(m_picker);
auto tick = root()->add_child<NodeImage>();
tick->SetPositioning(YGPositionTypeAbsolute);
tick->SetSize(16, 32);
tick->SetPosition(pos.x, pos.y + (target->m_size.y - 32) * 0.5f);
tick->set_image("data/ui/popup-tick.png");
//float hh = m_picker->m_container->m_children.size() > 10 ? App::I.height / App::I.zoom * .75f : 400.f;
//m_picker->SetHeight(4);
root()->update();
pos.y -= 130;
if ((pos.y + m_picker->m_size.y) > screen.y)
pos.y = screen.y - m_picker->m_size.y;
if (pos.y < 0)
pos.y = 0;
m_picker->SetPosition(pos.x + 16, pos.y);
m_picker->mouse_capture();
root()->update();
auto c = static_cast<NodeBorder*>(target->m_children[0].get());
m_picker->set_color(c->m_color);
m_picker->on_popup_close = [this, tick](Node*) {
tick->destroy();
};
m_picker->on_color_change = [this, c](Node*, glm::vec3 rgb) {
c->m_color = glm::vec4(rgb, 1.f);
if (on_color_change)
on_color_change(this, rgb);
};
}

View File

@@ -7,18 +7,24 @@
class NodePanelQuick : public NodeBorder
{
public:
std::function<void(Node* target, glm::vec3 rgb)> on_color_change;
std::function<void(Node* target, float value)> on_flow_change;
std::function<void(Node* target, float value)> on_size_change;
using this_class = NodePanelQuick;
using parent = NodeBorder;
NodeButtonCustom* m_slider_size;
NodeButtonCustom* m_slider_flow;
NodeSliderV* m_slider_size;
NodeSliderV* m_slider_flow;
NodeButtonCustom* m_button_color1;
NodeButtonCustom* m_button_color2;
NodeButtonCustom* m_button_color3;
NodeButtonCustom* m_button_color_current;
std::shared_ptr<NodeColorPicker> m_picker;
virtual Node* clone_instantiate() const override;
virtual void clone_finalize(Node* dest) const override;
virtual void init() override;
private:
void init_controls();
void handle_button_color_click(Node* target);
};

View File

@@ -218,6 +218,18 @@ void NodePanelStroke::update_controls()
m_pattern_thumb->set_image(b->m_pattern_thumb_path);
}
void NodePanelStroke::set_flow(float value, bool normalized, bool propagate)
{
float v = normalized ? value : m_curves[m_tip_flow].to_slider(value);
m_tip_flow->set_value(v, propagate);
}
void NodePanelStroke::set_size(float value, bool normalized, bool propagate)
{
float v = normalized ? value : m_curves[m_tip_size].to_value(value);
m_tip_size->set_value(v, propagate);
}
void NodePanelStroke::init_fold(const std::string& name)
{
if (auto b = find<NodeButton>(("button-unfold-" + name).c_str())) {
@@ -316,6 +328,8 @@ void NodePanelStroke::init_controls()
m_dual_brush_thumb->set_image(b->m_dual_thumb_path);
m_pattern_thumb->set_image(b->m_pattern_thumb_path);
update_controls();
if (on_stroke_change)
on_stroke_change(this);
};
};

View File

@@ -107,6 +107,9 @@ public:
bool import_abr(const std::string& path);
void init_controls();
void update_controls();
void set_flow(float value, bool normalized, bool propagate);
void set_size(float value, bool normalized, bool propagate);
void init_fold(const std::string& name);
void init_slider(NodeSliderH*& slider, const char* id, float Brush::* prop);

View File

@@ -39,11 +39,14 @@ void NodeSliderH::draw()
m_plane.draw_fill();
}
void NodeSliderH::set_value(float value)
void NodeSliderH::set_value(float value, bool propagate)
{
// don't accept external values while user interaction
if (dragging)
return;
m_value = glm::vec2(value) * m_mask;
//if (on_value_changed)
// on_value_changed(this, glm::length(m_value));
if (propagate && on_value_changed)
on_value_changed(this, glm::length(m_value));
}
float NodeSliderH::get_value()

View File

@@ -14,7 +14,7 @@ public:
virtual void clone_copy(Node* dest) const override;
virtual void init() override;
virtual void draw() override;
void set_value(float value);
void set_value(float value, bool propagate = false);
float get_value();
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
virtual kEventResult handle_event(Event* e) override;