diff --git a/data/layout.xml b/data/layout.xml
index c0e8df1..b910318 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -758,38 +758,49 @@
-->
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -1413,7 +1424,7 @@ Here's a list of what's available in this release.
-
+
@@ -1593,7 +1604,7 @@ Here's a list of what's available in this release.
-
+
diff --git a/src/app.h b/src/app.h
index 6a8525f..b5e88d2 100644
--- a/src/app.h
+++ b/src/app.h
@@ -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 color;
std::shared_ptr stroke;
std::shared_ptr grid;
+ NodePanelQuick* quick;
NodeCanvas* canvas;
Node* current_panel = nullptr;
NodeScroll* panels;
diff --git a/src/app_layout.cpp b/src/app_layout.cpp
index 99b8bdf..c62cc31 100644
--- a/src/app_layout.cpp
+++ b/src/app_layout.cpp
@@ -110,6 +110,7 @@ void App::init_sidebar()
sidebar = layout[main_id]->find("sidebar");
panels = layout[main_id]->find("panels");
canvas = layout[main_id]->find("paint-canvas");
+ quick = layout[main_id]->find("panel-quick");
//brushes = layout[main_id]->find("panel-brush");
//layers = layout[main_id]->find("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());
diff --git a/src/node_button_custom.cpp b/src/node_button_custom.cpp
index 84d307f..9703c0d 100644
--- a/src/node_button_custom.cpp
+++ b/src/node_button_custom.cpp
@@ -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)
diff --git a/src/node_button_custom.h b/src/node_button_custom.h
index d9789fa..f1fa6d0 100644
--- a/src/node_button_custom.h
+++ b/src/node_button_custom.h
@@ -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;
diff --git a/src/node_dialog_picker.cpp b/src/node_dialog_picker.cpp
index abb2e69..b1cf93e 100644
--- a/src/node_dialog_picker.cpp
+++ b/src/node_dialog_picker.cpp
@@ -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("color-old");
m_color_old1 = find("color-old1");
m_color_old2 = find("color-old2");
- m_button_select = find("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);
+}
diff --git a/src/node_dialog_picker.h b/src/node_dialog_picker.h
index fe67c89..b5974ec 100644
--- a/src/node_dialog_picker.h
+++ b/src/node_dialog_picker.h
@@ -9,6 +9,7 @@ class NodeColorPicker : public NodeBorder
{
public:
std::function on_popup_close;
+ std::function 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();
};
diff --git a/src/node_panel_quick.cpp b/src/node_panel_quick.cpp
index bd3a8fd..c2e7f96 100644
--- a/src/node_panel_quick.cpp
+++ b/src/node_panel_quick.cpp
@@ -18,7 +18,7 @@ void NodePanelQuick::clone_finalize(Node* dest) const
void NodePanelQuick::init()
{
parent::init();
- auto t = static_cast(init_template("panel-quick"));
+ auto t = static_cast(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("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();
- 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("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("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("quick-color1");
+ m_button_color2 = find("quick-color2");
+ m_button_color3 = find("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(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(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();
+ 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(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);
+ };
}
diff --git a/src/node_panel_quick.h b/src/node_panel_quick.h
index 70f773e..f558f1d 100644
--- a/src/node_panel_quick.h
+++ b/src/node_panel_quick.h
@@ -7,18 +7,24 @@
class NodePanelQuick : public NodeBorder
{
public:
+ std::function on_color_change;
+ std::function on_flow_change;
+ std::function 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 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);
};
diff --git a/src/node_panel_stroke.cpp b/src/node_panel_stroke.cpp
index a6c7986..ceefacd 100644
--- a/src/node_panel_stroke.cpp
+++ b/src/node_panel_stroke.cpp
@@ -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(("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);
};
};
diff --git a/src/node_panel_stroke.h b/src/node_panel_stroke.h
index b67aa15..8f180b2 100644
--- a/src/node_panel_stroke.h
+++ b/src/node_panel_stroke.h
@@ -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);
diff --git a/src/node_slider.cpp b/src/node_slider.cpp
index d98b880..71b1ae7 100644
--- a/src/node_slider.cpp
+++ b/src/node_slider.cpp
@@ -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()
diff --git a/src/node_slider.h b/src/node_slider.h
index 28a8665..9baa8e9 100644
--- a/src/node_slider.h
+++ b/src/node_slider.h
@@ -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;