diff --git a/data/layout.xml b/data/layout.xml
index 87b2a66..abec4a7 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -34,13 +34,29 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -52,7 +68,7 @@
-
+
@@ -95,6 +111,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -182,13 +211,13 @@
-
+
-
+
@@ -318,9 +347,11 @@
-
+
-
+
+
+
diff --git a/engine/app.cpp b/engine/app.cpp
index 9fbc3a6..4f38396 100644
--- a/engine/app.cpp
+++ b/engine/app.cpp
@@ -89,6 +89,48 @@ void App::initShaders()
"void main(){"
" frag = col;"
"}";
+ static const char* shader_color_quad_v =
+ SHADER_VERSION
+ "uniform mat4 mvp;"
+ "in vec4 pos;"
+ "in vec2 uvs;"
+ "out vec3 uv;"
+ "void main(){"
+ " gl_Position = mvp * pos;"
+ " uv = vec3(uvs, pos.w);"
+ "}";
+ static const char* shader_color_quad_f =
+ SHADER_VERSION
+ "uniform vec4 col;"
+ "in vec3 uv;"
+ "out vec4 frag;"
+ "void main(){"
+ " vec4 gradient_x = mix(col, vec4(1, 1, 1, 1), uv.x);"
+ " frag = mix(gradient_x, vec4(0, 0, 0, 1), uv.y);"
+ "}";
+ static const char* shader_color_hue_v =
+ SHADER_VERSION
+ "uniform mat4 mvp;"
+ "in vec4 pos;"
+ "in vec2 uvs;"
+ "out vec3 uv;"
+ "void main(){"
+ " gl_Position = mvp * pos;"
+ " uv = vec3(uvs, pos.w);"
+ "}";
+ static const char* shader_color_hue_f =
+ SHADER_VERSION
+ "uniform vec4 col;"
+ "in vec3 uv;"
+ "out vec4 frag;"
+ "vec3 hsv2rgb(vec3 c) {"
+ " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);"
+ " vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);"
+ " return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);"
+ "}"
+ "void main(){"
+ " frag = vec4(hsv2rgb(vec3(uv.y, 1, 1)), 1);"
+ "}";
static const char* shader_font_v =
SHADER_VERSION
"uniform mat4 mvp;"
@@ -115,6 +157,10 @@ void App::initShaders()
LOG("Failed to create shader Texture");
if (!ShaderManager::create(kShader::Color, shader_color_v, shader_color_f))
LOG("Failed to create shader Color");
+ if (!ShaderManager::create(kShader::ColorQuad, shader_color_quad_v, shader_color_quad_f))
+ LOG("Failed to create shader ColorQuad");
+ if (!ShaderManager::create(kShader::ColorHue, shader_color_hue_v, shader_color_hue_f))
+ LOG("Failed to create shader ColorHue");
if (!ShaderManager::create(kShader::UVs, shader_v, shader_uv_f))
LOG("Failed to create shader UVs");
if (!ShaderManager::create(kShader::Font, shader_font_v, shader_font_f))
diff --git a/engine/layout.cpp b/engine/layout.cpp
index 3e52d8d..d951513 100644
--- a/engine/layout.cpp
+++ b/engine/layout.cpp
@@ -418,6 +418,7 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
switch (child_id)
{
#define CASE(W,C) case W: { auto n = new C(); add_child(n); n->load_internal(x_child); break; }
+ CASE(kWidget::Node, Node);
CASE(kWidget::Border, NodeBorder);
CASE(kWidget::Image, NodeImage);
CASE(kWidget::Icon, NodeIcon);
@@ -425,13 +426,16 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
CASE(kWidget::Button , NodeButton);
CASE(kWidget::ButtonCustom, NodeButtonCustom);
CASE(kWidget::SliderCursor, NodeSliderCursor);
- CASE(kWidget::Slider, NodeSlider);
+ CASE(kWidget::SliderH, NodeSliderH);
+ CASE(kWidget::SliderV, NodeSliderV);
+ CASE(kWidget::SliderHue, NodeSliderHue);
CASE(kWidget::PopupMenu, NodePopupMenu);
CASE(kWidget::Viewport, NodeViewport);
CASE(kWidget::CheckBox, NodeCheckBox);
CASE(kWidget::Layer, NodeLayer);
CASE(kWidget::PanelLayers, NodePanelLayers);
CASE(kWidget::PanelBrushes, NodePanelBrushes);
+ CASE(kWidget::ColorQuad, NodeColorQuad);
#undef CASE
case kWidget::Ref:
{
@@ -444,6 +448,7 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
}
default:
{
+ LOG("instancing UNKNOWN node: %s", x_child->Name());
auto n = new Node();
add_child(n);
n->load_internal(x_child);
@@ -460,6 +465,7 @@ Node* Node::clone()
Node* n = clone_instantiate();
clone_copy(n);
clone_children(n);
+ clone_finalize(n);
return n;
}
diff --git a/engine/layout.h b/engine/layout.h
index 5c16f7a..1c92858 100644
--- a/engine/layout.h
+++ b/engine/layout.h
@@ -45,6 +45,7 @@ enum class kAttribute : uint16_t
enum class kWidget : uint16_t
{
+ Node = const_hash("node"),
Border = const_hash("border"),
Shape = const_hash("shape"),
Text = const_hash("text"),
@@ -53,7 +54,9 @@ enum class kWidget : uint16_t
Button = const_hash("button"),
ButtonCustom = const_hash("button-custom"),
SliderCursor = const_hash("slider-cursor"),
- Slider = const_hash("slider"),
+ SliderH = const_hash("slider-h"),
+ SliderV = const_hash("slider-v"),
+ SliderHue = const_hash("slider-hue"),
PopupMenu = const_hash("popup-menu"),
Viewport = const_hash("viewport"),
Ref = const_hash("ref"),
@@ -61,6 +64,7 @@ enum class kWidget : uint16_t
Layer = const_hash("layer"),
PanelLayers = const_hash("panel-layers"),
PanelBrushes = const_hash("panel-brushes"),
+ ColorQuad = const_hash("color-quad"),
};
enum class kShapeType : uint16_t
@@ -240,6 +244,7 @@ public:
virtual Node* clone_instantiate() const;
virtual void clone_copy(Node* dest) const;
virtual void clone_children(Node* dest) const;
+ virtual void clone_finalize(Node* dest) const { /* find controllers and stuff */ };
void watch(std::function observer)
{
observer(this);
@@ -375,21 +380,23 @@ public:
ui::ShaderManager::use(kShader::Color);
ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
- if (m_color.a != 1.f)
- glEnable(GL_BLEND);
-
- ui::ShaderManager::u_vec4(kShaderUniform::Col, m_color);
- m_plane.draw_fill();
+ if (m_color.a > 0.f)
+ {
+ m_color.a < 1.f ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
+ ui::ShaderManager::u_vec4(kShaderUniform::Col, m_color);
+ m_plane.draw_fill();
+ glDisable(GL_BLEND);
+ }
- if (m_thinkness > 0)
+ if (m_thinkness > 0 && m_border_color.a > 0.f)
{
glLineWidth(m_thinkness);
ui::ShaderManager::u_vec4(kShaderUniform::Col, m_border_color);
+ m_border_color.a < 1.f ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
m_plane.draw_stroke();
+ glDisable(GL_BLEND);
}
- if (m_color.a != 1.f)
- glDisable(GL_BLEND);
}
};
@@ -950,16 +957,18 @@ public:
class NodeSliderCursor : public NodeButtonCustom
{
-public:
glm::vec2 drag_start;
glm::vec2 drag_diff;
bool dragging = false;
glm::vec2 old_pos;
+public:
+ glm::vec2 m_mask{ 1, 0 };
virtual Node* clone_instantiate() const override { return new NodeSliderCursor(); }
virtual void clone_copy(Node* dest) const override
{
NodeButtonCustom::clone_copy(dest);
NodeSliderCursor* n = static_cast(dest);
+ n->m_mask = m_mask;
}
virtual kEventResult handle_event(Event* e) override
{
@@ -979,11 +988,10 @@ public:
case kEventType::MouseMove:
if (dragging)
{
- float pw = parent->GetWidth();
- float w = GetWidth();
- drag_diff = old_pos + ((MouseEvent*)e)->m_pos - drag_start;
- float x = glm::clamp(drag_diff.x, 0, pw - w);
- SetPosition(x, 0);
+ auto sz = parent->GetSize() - GetSize();
+ drag_diff = old_pos + (((MouseEvent*)e)->m_pos - drag_start) * m_mask;
+ auto pos = glm::clamp(drag_diff, { 0, 0 }, sz);
+ SetPosition(pos.x, pos.y);
}
break;
default:
@@ -993,18 +1001,69 @@ public:
}
};
-class NodeSlider : public NodeBorder
+class NodeSliderH : public NodeBorder
{
public:
NodeSliderCursor* m_cursor;
- virtual Node* clone_instantiate() const override { return new NodeSlider(); }
+ virtual Node* clone_instantiate() const override { return new NodeSliderH(); }
virtual void init() override
{
- const auto& m_template = (NodeBorder*)init_template("tpl-slider");
+ const auto& m_template = (NodeBorder*)init_template("tpl-slider-h");
m_color = m_template->m_color;
m_border_color = m_template->m_border_color;
m_thinkness = m_thinkness;
m_cursor = find("cursor");
+ m_cursor->m_mask = { 1, 0 };
+ }
+};
+
+class NodeSliderV : public NodeBorder
+{
+public:
+ NodeSliderCursor* m_cursor;
+ virtual Node* clone_instantiate() const override { return new NodeSliderV(); }
+ virtual void init() override
+ {
+ const auto& m_template = (NodeBorder*)init_template("tpl-slider-v");
+ m_color = m_template->m_color;
+ m_border_color = m_template->m_border_color;
+ m_thinkness = m_thinkness;
+ m_cursor = find("cursor");
+ m_cursor->m_mask = { 0, 1 };
+ }
+};
+
+class NodeSliderHue : public NodeBorder
+{
+public:
+ NodeSliderCursor* m_cursor;
+ virtual Node* clone_instantiate() const override { return new NodeSliderHue(); }
+ virtual void clone_finalize(Node* dest) const override
+ {
+ NodeSliderHue* n = static_cast(dest);
+ n->m_cursor = n->find("cursor");
+ n->m_cursor->m_color = glm::vec4(0);
+ n->m_cursor->m_border_color = glm::vec4(0, 0, 0, 1);
+ }
+ virtual void init() override
+ {
+ const auto& m_template = (NodeBorder*)init_template("tpl-slider-hue");
+ m_color = m_template->m_color;
+ m_border_color = m_template->m_border_color;
+ m_thinkness = m_thinkness;
+ m_cursor = find("cursor");
+ m_cursor->m_mask = { 0, 1 };
+ m_cursor->m_thinkness = 1;
+ m_cursor->m_color = glm::vec4(0);
+ m_cursor->m_border_color = glm::vec4(0, 0, 0, 1);
+ }
+ virtual void draw() override
+ {
+ using namespace ui;
+ ui::ShaderManager::use(kShader::ColorHue);
+ ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
+ //ui::ShaderManager::u_vec4(kShaderUniform::Col, m_color);
+ m_plane.draw_fill();
}
};
@@ -1277,7 +1336,8 @@ public:
}
virtual void draw() override
{
- m_color = m_selected ? glm::vec4(1, 0, 0, 1) : color_normal;
+ m_color = m_mouse_inside ? color_hover : color_normal;
+ m_color = m_selected ? glm::vec4(.9, 0, 0, 1) : m_color;
NodeButtonCustom::draw();
}
};
@@ -1321,7 +1381,8 @@ public:
m_current->m_selected = false;
m_current = (NodeButtonBrush*)target;
m_current->m_selected = true;
- on_brush_changed(this, m_current->m_brushID);
+ if (on_brush_changed)
+ on_brush_changed(this, m_current->m_brushID);
}
std::vector FindAllBrushes(std::string folder)
{
@@ -1342,3 +1403,31 @@ public:
return names;
}
};
+
+class NodeColorQuad : public NodeBorder
+{
+public:
+ virtual Node* clone_instantiate() const override { return new NodeColorQuad(); }
+ virtual void draw() override
+ {
+ using namespace ui;
+ ui::ShaderManager::use(kShader::ColorQuad);
+ ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
+
+// if (m_color.a != 1.f)
+// glEnable(GL_BLEND);
+
+ ui::ShaderManager::u_vec4(kShaderUniform::Col, m_color);
+ m_plane.draw_fill();
+
+// if (m_thinkness > 0)
+// {
+// glLineWidth(m_thinkness);
+// ui::ShaderManager::u_vec4(kShaderUniform::Col, m_border_color);
+// m_plane.draw_stroke();
+// }
+
+// if (m_color.a != 1.f)
+// glDisable(GL_BLEND);
+ }
+};
diff --git a/engine/pch.h b/engine/pch.h
index 6c01c82..a760526 100644
--- a/engine/pch.h
+++ b/engine/pch.h
@@ -26,7 +26,7 @@
#include
#include
- #define LOG printf
+ #define LOG(M,...) printf(M"\n", ##__VA_ARGS__)
#endif
#ifdef __cplusplus
diff --git a/engine/shader.h b/engine/shader.h
index 5bddf97..f2f78ba 100644
--- a/engine/shader.h
+++ b/engine/shader.h
@@ -28,6 +28,8 @@ public:
enum class kShader : uint16_t
{
Color = const_hash("color"),
+ ColorQuad = const_hash("color-quad"),
+ ColorHue = const_hash("color-hue"),
Texture = const_hash("texture"),
UVs = const_hash("uvs"),
Font = const_hash("font"),