Improved mask also work on erase. Improved shaders for layer opacity, now when drawing doesn't change opacity. Improved layers panel layout to be similar to PS. Added layer blending option and visibility. Added custom icons to checkboxes and fixed the combobox items.
This commit is contained in:
@@ -35,15 +35,14 @@
|
|||||||
|
|
||||||
<!--layer template-->
|
<!--layer template-->
|
||||||
<layout id="tpl-layer">
|
<layout id="tpl-layer">
|
||||||
<border height="30" border-color="1" thickness="1" color=".4" dir="row" margin="1 0 1 0">
|
<border height="30" border-color="1" thickness="1" color=".4" dir="col" margin="1 0 1 0">
|
||||||
<node width="30" pad="1">
|
<node dir="row" height="30">
|
||||||
<checkbox id="cb"></checkbox>
|
<node width="30" pad="1">
|
||||||
</node>
|
<checkbox id="cb" icon="data/ui/check-layer-visibility.png"></checkbox>
|
||||||
<node width="1" grow="1" justify="center" pad="5">
|
</node>
|
||||||
<text id="label" text="Layer0" font-face="arial" font-size="11"/>
|
<node width="1" grow="1" justify="center" pad="5">
|
||||||
</node>
|
<text id="label" font-face="arial" font-size="11"/>
|
||||||
<node color=".4" width="100" pad="5">
|
</node>
|
||||||
<slider-h id="sl-opacity" value="1"/>
|
|
||||||
</node>
|
</node>
|
||||||
</border>
|
</border>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -54,6 +53,17 @@
|
|||||||
<border height="30" color=".5" align="center" justify="center" margin="0 0 0 0">
|
<border height="30" color=".5" align="center" justify="center" margin="0 0 0 0">
|
||||||
<text text="Layers" font-face="arial" font-size="11" color="1 1 1 1"/>
|
<text text="Layers" font-face="arial" font-size="11" color="1 1 1 1"/>
|
||||||
</border>
|
</border>
|
||||||
|
|
||||||
|
<border height="35" color=".5" dir="row" align="center" flood-events="1" pad="0 0 5 0">
|
||||||
|
<checkbox id="alpha-lock" icon="data/ui/check-lock-transparency.png" width="30" margin="0 5 0 5"></checkbox>
|
||||||
|
<combobox id="blend-mode" width="100" height="30" margin="0 5 0 0" combo-list="Normal,-,Multiply,Screen,-,Color Dodge,Overlay" default="0"/>
|
||||||
|
<slider-h id="opacity" value="1" grow="1" width="1" margin="0 5 0 0"/>
|
||||||
|
</border>
|
||||||
|
|
||||||
|
<border id="layers-container" pad="5" color=".4" dir="col" flood-events="1">
|
||||||
|
<!--layers list-->
|
||||||
|
</border>
|
||||||
|
|
||||||
<border height="40" color=".5" dir="row" align="center" flood-events="1">
|
<border height="40" color=".5" dir="row" align="center" flood-events="1">
|
||||||
<button-custom id="btn-add" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 5">
|
<button-custom id="btn-add" thickness="1" color="0 0" border-color=".0" shrink="1" margin="0 2 0 5">
|
||||||
<icon width="30" icon="add"/>
|
<icon width="30" icon="add"/>
|
||||||
@@ -69,9 +79,6 @@
|
|||||||
<icon width="30" icon="bin_closed"/>
|
<icon width="30" icon="bin_closed"/>
|
||||||
</button-custom>
|
</button-custom>
|
||||||
</border>
|
</border>
|
||||||
<border id="layers-container" pad="5" color=".4" dir="col" flood-events="1">
|
|
||||||
<!--layers list-->
|
|
||||||
</border>
|
|
||||||
</node>
|
</node>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
||||||
@@ -1116,7 +1123,7 @@ Here's a list of what's available in this release.
|
|||||||
<!--Brushes-->
|
<!--Brushes-->
|
||||||
<!--<panel-brush id="panel-brush"/>-->
|
<!--<panel-brush id="panel-brush"/>-->
|
||||||
<!--Layers-->
|
<!--Layers-->
|
||||||
<!--<panel-layer id="panel-layer"/>-->
|
<panel-layer id="panel-layer"/>
|
||||||
<!--Colors-->
|
<!--Colors-->
|
||||||
<!--<panel-color id="panel-color"/>-->
|
<!--<panel-color id="panel-color"/>-->
|
||||||
<!--Grids-->
|
<!--Grids-->
|
||||||
|
|||||||
BIN
data/ui/check-layer-visibility.png
Normal file
BIN
data/ui/check-layer-visibility.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
data/ui/check-lock-transparency.png
Normal file
BIN
data/ui/check-lock-transparency.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 892 B |
BIN
data/ui/check-test.png
Normal file
BIN
data/ui/check-test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
extra/ui/checkbox-icons.psd
Normal file
BIN
extra/ui/checkbox-icons.psd
Normal file
Binary file not shown.
@@ -44,10 +44,7 @@ void App::open_document(std::string path)
|
|||||||
async_start();
|
async_start();
|
||||||
title_update();
|
title_update();
|
||||||
for (auto& i : canvas->m_canvas->m_order)
|
for (auto& i : canvas->m_canvas->m_order)
|
||||||
{
|
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
||||||
auto* l = layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
|
||||||
l->m_opacity->m_value.x = canvas->m_canvas->m_layers[i].m_opacity;
|
|
||||||
}
|
|
||||||
async_end();
|
async_end();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -88,6 +88,26 @@ void App::init_toolbar_main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T> std::shared_ptr<T> find_or_create_panel(NodeScroll* panels)
|
||||||
|
{
|
||||||
|
std::shared_ptr<T> ret;
|
||||||
|
auto node_find = std::find_if(panels->m_children.begin(), panels->m_children.end(),
|
||||||
|
[](const std::shared_ptr<Node>&p) { return (bool)std::dynamic_pointer_cast<T>(p); });
|
||||||
|
if (node_find != panels->m_children.end())
|
||||||
|
{
|
||||||
|
ret = std::static_pointer_cast<T>(*node_find);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = std::make_shared<T>();
|
||||||
|
ret->m_manager = panels->m_manager;
|
||||||
|
ret->init();
|
||||||
|
ret->create();
|
||||||
|
ret->loaded();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void App::init_sidebar()
|
void App::init_sidebar()
|
||||||
{
|
{
|
||||||
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
||||||
@@ -99,50 +119,12 @@ void App::init_sidebar()
|
|||||||
//color = layout[main_id]->find<NodePanelColor>("panel-color");
|
//color = layout[main_id]->find<NodePanelColor>("panel-color");
|
||||||
//stroke = layout[main_id]->find<NodePanelStroke>("panel-stroke");
|
//stroke = layout[main_id]->find<NodePanelStroke>("panel-stroke");
|
||||||
|
|
||||||
brushes = std::make_shared<NodePanelBrush>();
|
brushes = find_or_create_panel<NodePanelBrush>(panels);
|
||||||
brushes->m_manager = &layout;
|
layers = find_or_create_panel<NodePanelLayer>(panels);
|
||||||
brushes->init();
|
color = find_or_create_panel<NodePanelColor>(panels);
|
||||||
brushes->create();
|
stroke = find_or_create_panel<NodePanelStroke>(panels);
|
||||||
brushes->loaded();
|
grid = find_or_create_panel<NodePanelGrid>(panels);
|
||||||
|
presets = find_or_create_panel<NodePanelBrushPreset>(panels);
|
||||||
layers = std::make_shared<NodePanelLayer>();
|
|
||||||
layers->m_manager = &layout;
|
|
||||||
layers->init();
|
|
||||||
layers->create();
|
|
||||||
layers->loaded();
|
|
||||||
|
|
||||||
color = std::make_shared<NodePanelColor>();
|
|
||||||
color->m_manager = &layout;
|
|
||||||
color->init();
|
|
||||||
color->create();
|
|
||||||
color->loaded();
|
|
||||||
|
|
||||||
stroke = std::make_shared<NodePanelStroke>();
|
|
||||||
stroke->m_manager = &layout;
|
|
||||||
stroke->init();
|
|
||||||
stroke->create();
|
|
||||||
stroke->loaded();
|
|
||||||
|
|
||||||
auto grid_find = std::find_if(panels->m_children.begin(), panels->m_children.end(),
|
|
||||||
[](const std::shared_ptr<Node>&p) { return (bool)std::dynamic_pointer_cast<NodePanelGrid>(p); });
|
|
||||||
if (grid_find != panels->m_children.end())
|
|
||||||
{
|
|
||||||
grid = std::static_pointer_cast<NodePanelGrid>(*grid_find);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grid = std::make_shared<NodePanelGrid>();
|
|
||||||
grid->m_manager = &layout;
|
|
||||||
grid->init();
|
|
||||||
grid->create();
|
|
||||||
grid->loaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
presets = std::make_shared<NodePanelBrushPreset>();
|
|
||||||
presets->m_manager = &layout;
|
|
||||||
presets->init();
|
|
||||||
presets->create();
|
|
||||||
presets->loaded();
|
|
||||||
|
|
||||||
// if (canvas)
|
// if (canvas)
|
||||||
// {
|
// {
|
||||||
@@ -175,6 +157,8 @@ void App::init_sidebar()
|
|||||||
|
|
||||||
layers->on_layer_add = [this](Node*) {
|
layers->on_layer_add = [this](Node*) {
|
||||||
canvas->m_canvas->layer_add(layers->m_layers.back()->m_label_text.c_str());
|
canvas->m_canvas->layer_add(layers->m_layers.back()->m_label_text.c_str());
|
||||||
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_change = [this](Node*, int old_idx, int new_idx) {
|
layers->on_layer_change = [this](Node*, int old_idx, int new_idx) {
|
||||||
@@ -183,18 +167,38 @@ void App::init_sidebar()
|
|||||||
|
|
||||||
layers->on_layer_order = [this](Node*, int old_idx, int new_idx) {
|
layers->on_layer_order = [this](Node*, int old_idx, int new_idx) {
|
||||||
canvas->m_canvas->layer_order(old_idx, new_idx);
|
canvas->m_canvas->layer_order(old_idx, new_idx);
|
||||||
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_delete = [this](Node*, int idx) {
|
layers->on_layer_delete = [this](Node*, int idx) {
|
||||||
canvas->m_canvas->layer_remove(idx);
|
canvas->m_canvas->layer_remove(idx);
|
||||||
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_opacity_changed = [this](Node*, int idx, float value) {
|
layers->on_layer_opacity_changed = [this](Node*, int idx, float value) {
|
||||||
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]].m_opacity = value;
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]].m_opacity = value;
|
||||||
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_visibility_changed = [this](Node*, int idx, bool visible) {
|
layers->on_layer_visibility_changed = [this](Node*, int idx, bool visible) {
|
||||||
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]].m_alpha_locked = visible;
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]].m_visible = visible;
|
||||||
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
title_update();
|
||||||
|
};
|
||||||
|
|
||||||
|
layers->on_layer_alpha_lock_changed = [this](Node*, int idx, bool locked) {
|
||||||
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]].m_alpha_locked = locked;
|
||||||
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
title_update();
|
||||||
|
};
|
||||||
|
|
||||||
|
layers->on_layer_blend_mode_changed = [this](Node*, int idx, int mode) {
|
||||||
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]].m_blend_mode = mode;
|
||||||
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_highlight_changed = [this](Node*, int idx, bool highlight) {
|
layers->on_layer_highlight_changed = [this](Node*, int idx, bool highlight) {
|
||||||
|
|||||||
@@ -77,17 +77,32 @@ void App::initShaders()
|
|||||||
SHADER_VERSION
|
SHADER_VERSION
|
||||||
"uniform sampler2D tex;\n"
|
"uniform sampler2D tex;\n"
|
||||||
"uniform sampler2D tex_stroke;\n"
|
"uniform sampler2D tex_stroke;\n"
|
||||||
|
"uniform sampler2D tex_mask;\n"
|
||||||
"uniform mediump float alpha;\n"
|
"uniform mediump float alpha;\n"
|
||||||
|
"uniform mediump float stroke_alpha;\n"
|
||||||
"uniform mediump vec2 resolution;\n"
|
"uniform mediump vec2 resolution;\n"
|
||||||
"uniform bool fragUV2;\n"
|
"uniform bool fragUV2;\n"
|
||||||
|
"uniform bool mask;\n"
|
||||||
"in mediump vec2 uv;\n"
|
"in mediump vec2 uv;\n"
|
||||||
"out mediump vec4 frag;\n"
|
"out mediump vec4 frag;\n"
|
||||||
|
"mediump vec4 blur(sampler2D t, mediump vec2 uv){\n"
|
||||||
|
" mediump vec4 sum = texture(t, uv);\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2(-1, -1));\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2(-1, 0));\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2(-1, 1));\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2( 0, -1));\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2( 0, 1));\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2( 1, -1));\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2( 1, 0));\n"
|
||||||
|
" sum += textureOffset(t, uv, ivec2( 1, 1));\n"
|
||||||
|
" return sum / vec4(9.0);\n"
|
||||||
|
"}\n"
|
||||||
"void main(){\n"
|
"void main(){\n"
|
||||||
" mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n"
|
" mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n"
|
||||||
" mediump vec4 base = texture(tex, uv2);\n"
|
" mediump vec4 base = texture(tex, uv2);\n"
|
||||||
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
||||||
" mediump float a = base.a - (stroke.a * alpha);\n"
|
" stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv2).r : stroke.a * stroke_alpha;\n"
|
||||||
" frag = vec4(base.rgb, clamp(a, 0.0, 1.0));\n"
|
" frag = vec4(base.rgb, clamp((base.a - stroke.a) * alpha, 0.0, 1.0));\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
// TEXTURE COMP DRAW
|
// TEXTURE COMP DRAW
|
||||||
static const char* shader_comp_draw_f =
|
static const char* shader_comp_draw_f =
|
||||||
@@ -97,6 +112,7 @@ void App::initShaders()
|
|||||||
"uniform sampler2D tex_mask;\n"
|
"uniform sampler2D tex_mask;\n"
|
||||||
"uniform sampler2D tex_stencil;\n"
|
"uniform sampler2D tex_stencil;\n"
|
||||||
"uniform mediump float alpha;\n"
|
"uniform mediump float alpha;\n"
|
||||||
|
"uniform mediump float stroke_alpha;\n"
|
||||||
"uniform mediump int blend_mode;\n"
|
"uniform mediump int blend_mode;\n"
|
||||||
"uniform mediump vec2 resolution;\n"
|
"uniform mediump vec2 resolution;\n"
|
||||||
"uniform bool lock;\n"
|
"uniform bool lock;\n"
|
||||||
@@ -141,13 +157,12 @@ void App::initShaders()
|
|||||||
" mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n"
|
" mediump vec2 uv2 = fragUV2 ? (gl_FragCoord.st / resolution) : uv;\n"
|
||||||
" mediump vec4 base = texture(tex, uv2);\n"
|
" mediump vec4 base = texture(tex, uv2);\n"
|
||||||
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
" mediump vec4 stroke = texture(tex_stroke, uv);\n"
|
||||||
" stroke.a = mask ? stroke.a * alpha * blur(tex_mask, uv2).r : stroke.a * alpha;\n"
|
" stroke.a = mask ? stroke.a * stroke_alpha * blur(tex_mask, uv2).r : stroke.a * stroke_alpha;\n"
|
||||||
|
" if (!lock && base.a == 0.0) { frag = stroke * vec4(1.0, 1.0, 1.0, alpha); return; }\n"
|
||||||
" if (!lock && base.a == 0.0) { frag = stroke; return; }\n"
|
|
||||||
" mediump float contribution = (1.0 - base.a) * stroke.a;\n"
|
" mediump float contribution = (1.0 - base.a) * stroke.a;\n"
|
||||||
" mediump float alpha_tot = base.a + contribution;"
|
" mediump float alpha_tot = base.a + contribution;"
|
||||||
" mediump vec3 rgb = blend(base, stroke, alpha_tot, blend_mode);\n"
|
" mediump vec3 rgb = blend(base, stroke, alpha_tot, blend_mode);\n"
|
||||||
" frag = vec4(rgb, (lock ? base.a : alpha_tot));\n"
|
" frag = vec4(rgb, (lock ? base.a : alpha_tot) * alpha);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
// TEXTURE ATLAS
|
// TEXTURE ATLAS
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
|||||||
auto layer_index = canvas->m_canvas->m_order[i];
|
auto layer_index = canvas->m_canvas->m_order[i];
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
{
|
{
|
||||||
if (canvas->m_canvas->m_layers[layer_index].m_opacity == .0f)
|
if (!canvas->m_canvas->m_layers[layer_index].m_visible || canvas->m_canvas->m_layers[layer_index].m_opacity == .0f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int z = (int)(canvas->m_canvas->m_order.size() - i);
|
int z = (int)(canvas->m_canvas->m_order.size() - i);
|
||||||
@@ -62,10 +62,11 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
|||||||
ShaderManager::use(kShader::CompErase);
|
ShaderManager::use(kShader::CompErase);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
//ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, canvas->m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_layers[layer_index].m_opacity);
|
||||||
//ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
|
//ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
|
||||||
//ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
canvas->m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
|
canvas->m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
|
||||||
@@ -90,7 +91,8 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
|||||||
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
ShaderManager::u_vec2(kShaderUniform::Resolution, canvas->m_canvas->m_size);
|
ShaderManager::u_vec2(kShaderUniform::Resolution, canvas->m_canvas->m_size);
|
||||||
//ShaderManager::u_int(kShaderUniform::TexStencil, 3);
|
//ShaderManager::u_int(kShaderUniform::TexStencil, 3);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, canvas->m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_layers[layer_index].m_opacity);
|
||||||
ShaderManager::u_int(kShaderUniform::Lock, canvas->m_canvas->m_layers[layer_index].m_alpha_locked);
|
ShaderManager::u_int(kShaderUniform::Lock, canvas->m_canvas->m_layers[layer_index].m_alpha_locked);
|
||||||
ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active);
|
ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active);
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, canvas->m_canvas->m_current_stroke->m_brush.m_blend_mode);
|
ShaderManager::u_int(kShaderUniform::BlendMode, canvas->m_canvas->m_current_stroke->m_brush.m_blend_mode);
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ void Canvas::pick_update(int plane)
|
|||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
for (auto layer_index : m_order)
|
for (auto layer_index : m_order)
|
||||||
{
|
{
|
||||||
|
if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == 0.f)
|
||||||
|
continue;
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
||||||
m_layers[layer_index].m_rtt[i].bindTexture();
|
m_layers[layer_index].m_rtt[i].bindTexture();
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
@@ -242,7 +244,7 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
|||||||
auto layer_index = m_current_layer_idx;
|
auto layer_index = m_current_layer_idx;
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
{
|
{
|
||||||
if (m_layers[layer_index].m_opacity == .0f)
|
if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == .0f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)m_mixer.getWidth() / m_mixer.getHeight(), 0.1f, 1000.f);
|
glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)m_mixer.getWidth() / m_mixer.getHeight(), 0.1f, 1000.f);
|
||||||
@@ -293,7 +295,8 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
|||||||
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
||||||
//ShaderManager::u_int(kShaderUniform::TexStencil, 3);
|
//ShaderManager::u_int(kShaderUniform::TexStencil, 3);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||||
ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index].m_alpha_locked);
|
ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index].m_alpha_locked);
|
||||||
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
||||||
@@ -804,9 +807,11 @@ void Canvas::stroke_commit()
|
|||||||
ShaderManager::use(kShader::CompErase);
|
ShaderManager::use(kShader::CompErase);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
//ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@@ -831,7 +836,8 @@ void Canvas::stroke_commit()
|
|||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||||
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush.m_blend_mode);
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_current_stroke->m_brush.m_blend_mode);
|
||||||
@@ -1009,6 +1015,7 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
|||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1); // source
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1); // source
|
||||||
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
//ShaderManager::u_vec2(kShaderUniform::Resolution, m_size);
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
||||||
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, 1);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[source_idx].m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[source_idx].m_opacity);
|
||||||
ShaderManager::u_int(kShaderUniform::Lock, false);
|
ShaderManager::u_int(kShaderUniform::Lock, false);
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, 0); // TODO: defaulted to normal, change to layer blend mode when implemented
|
ShaderManager::u_int(kShaderUniform::BlendMode, 0); // TODO: defaulted to normal, change to layer blend mode when implemented
|
||||||
@@ -1284,6 +1291,8 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
m_sampler_mask.bind(0);
|
m_sampler_mask.bind(0);
|
||||||
for (auto layer_index : m_order)
|
for (auto layer_index : m_order)
|
||||||
{
|
{
|
||||||
|
if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == 0.f)
|
||||||
|
continue;
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
||||||
m_layers[layer_index].m_rtt[i].bindTexture();
|
m_layers[layer_index].m_rtt[i].bindTexture();
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
bool m_alpha_locked = false;
|
bool m_alpha_locked = false;
|
||||||
float m_opacity = 1.f;
|
float m_opacity = 1.f;
|
||||||
bool m_hightlight = false;
|
bool m_hightlight = false;
|
||||||
|
bool m_blend_mode = 0;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
int w = 0;
|
int w = 0;
|
||||||
int h = 0;
|
int h = 0;
|
||||||
|
|||||||
@@ -1112,6 +1112,7 @@ void CanvasModeTransform::leave()
|
|||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
ShaderManager::u_float(kShaderUniform::Alpha, 1);
|
||||||
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, 1);
|
||||||
ShaderManager::u_int(kShaderUniform::Lock, false);
|
ShaderManager::u_int(kShaderUniform::Lock, false);
|
||||||
ShaderManager::u_int(kShaderUniform::Mask, false);
|
ShaderManager::u_int(kShaderUniform::Mask, false);
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, true);
|
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, true);
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ void NodeCanvas::draw()
|
|||||||
auto layer_index = m_canvas->m_order[i];
|
auto layer_index = m_canvas->m_order[i];
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
{
|
{
|
||||||
if (m_canvas->m_layers[layer_index].m_opacity == .0f)
|
if (!m_canvas->m_layers[layer_index].m_visible || m_canvas->m_layers[layer_index].m_opacity == .0f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int z = (int)(m_canvas->m_order.size() - i);
|
int z = (int)(m_canvas->m_order.size() - i);
|
||||||
@@ -153,11 +153,12 @@ void NodeCanvas::draw()
|
|||||||
ShaderManager::use(kShader::CompErase);
|
ShaderManager::use(kShader::CompErase);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
//ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
||||||
//ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
|
//ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
|
||||||
//ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
|
m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture();
|
||||||
@@ -182,7 +183,8 @@ void NodeCanvas::draw()
|
|||||||
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
//ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom);
|
//ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom);
|
||||||
//ShaderManager::u_int(kShaderUniform::TexStencil, 3);
|
//ShaderManager::u_int(kShaderUniform::TexStencil, 3);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
ShaderManager::u_float(kShaderUniform::StrokeAlpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity);
|
||||||
ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
|
ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index].m_alpha_locked);
|
||||||
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, false);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "node_checkbox.h"
|
#include "node_checkbox.h"
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
Node* NodeCheckBox::clone_instantiate() const
|
Node* NodeCheckBox::clone_instantiate() const
|
||||||
{
|
{
|
||||||
@@ -13,7 +14,9 @@ void NodeCheckBox::clone_children(Node* dest) const
|
|||||||
NodeCheckBox* n = static_cast<NodeCheckBox*>(dest);
|
NodeCheckBox* n = static_cast<NodeCheckBox*>(dest);
|
||||||
n->m_outer = (NodeBorder*)n->m_children[0].get();
|
n->m_outer = (NodeBorder*)n->m_children[0].get();
|
||||||
n->m_inner = (NodeBorder*)n->m_outer->m_children[0].get();
|
n->m_inner = (NodeBorder*)n->m_outer->m_children[0].get();
|
||||||
|
n->m_icon = n->m_inner->m_children.empty() ? nullptr : (NodeImage*)n->m_inner->m_children[0].get();
|
||||||
n->m_mouse_ignore = false;
|
n->m_mouse_ignore = false;
|
||||||
|
n->m_icon_path = m_icon_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeCheckBox::init()
|
void NodeCheckBox::init()
|
||||||
@@ -43,6 +46,8 @@ void NodeCheckBox::create()
|
|||||||
{
|
{
|
||||||
m_outer->create();
|
m_outer->create();
|
||||||
m_inner->create();
|
m_inner->create();
|
||||||
|
if (!m_icon_path.empty())
|
||||||
|
set_icon(m_icon_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
kEventResult NodeCheckBox::handle_event(Event* e)
|
kEventResult NodeCheckBox::handle_event(Event* e)
|
||||||
@@ -58,6 +63,7 @@ kEventResult NodeCheckBox::handle_event(Event* e)
|
|||||||
break;
|
break;
|
||||||
case kEventType::MouseUpL:
|
case kEventType::MouseUpL:
|
||||||
checked = !checked;
|
checked = !checked;
|
||||||
|
update_icon();
|
||||||
if (on_value_changed)
|
if (on_value_changed)
|
||||||
on_value_changed(this, checked);
|
on_value_changed(this, checked);
|
||||||
break;
|
break;
|
||||||
@@ -73,3 +79,42 @@ void NodeCheckBox::draw()
|
|||||||
m_inner->m_color = checked ? glm::vec4(.4, .4, .4, 1) : glm::vec4(.8, .8, .8, 1);
|
m_inner->m_color = checked ? glm::vec4(.4, .4, .4, 1) : glm::vec4(.8, .8, .8, 1);
|
||||||
Node::draw();
|
Node::draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeCheckBox::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||||
|
{
|
||||||
|
switch (ka)
|
||||||
|
{
|
||||||
|
case kAttribute::Icon:
|
||||||
|
m_icon_path = attr->Value();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Node::parse_attributes(ka, attr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeCheckBox::set_icon(const std::string& icon_path)
|
||||||
|
{
|
||||||
|
if (icon_path.empty() || !TextureManager::load(icon_path.c_str()))
|
||||||
|
{
|
||||||
|
if (m_icon)
|
||||||
|
m_icon->destroy();
|
||||||
|
m_icon = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_icon_path = icon_path;
|
||||||
|
update_icon();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeCheckBox::update_icon()
|
||||||
|
{
|
||||||
|
auto& t = TextureManager::get(const_hash(m_icon_path.c_str()));
|
||||||
|
if (!m_icon)
|
||||||
|
m_icon = m_inner->add_child<NodeImage>();
|
||||||
|
auto region = checked ? glm::vec4(.5f, 0, 1, 1) : glm::vec4(0, 0, .5f, 1);
|
||||||
|
m_icon->m_region = region * glm::vec4(t.size(), t.size());
|
||||||
|
m_icon->m_use_atlas = true;
|
||||||
|
m_icon->set_image(m_icon_path);
|
||||||
|
m_icon->SetWidthP(100);
|
||||||
|
m_icon->SetHeightP(100);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "node_border.h"
|
#include "node_border.h"
|
||||||
|
#include "node_image.h"
|
||||||
|
|
||||||
class NodeCheckBox : public Node
|
class NodeCheckBox : public Node
|
||||||
{
|
{
|
||||||
@@ -8,6 +9,8 @@ public:
|
|||||||
std::function<void(Node* target, bool checked)> on_value_changed;
|
std::function<void(Node* target, bool checked)> on_value_changed;
|
||||||
NodeBorder* m_outer;
|
NodeBorder* m_outer;
|
||||||
NodeBorder* m_inner;
|
NodeBorder* m_inner;
|
||||||
|
NodeImage* m_icon;
|
||||||
|
std::string m_icon_path;
|
||||||
bool checked = false;
|
bool checked = false;
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void clone_children(Node* dest) const override;
|
virtual void clone_children(Node* dest) const override;
|
||||||
@@ -15,4 +18,8 @@ public:
|
|||||||
virtual void create() override;
|
virtual void create() override;
|
||||||
virtual kEventResult handle_event(Event* e) override;
|
virtual kEventResult handle_event(Event* e) override;
|
||||||
virtual void draw() override;
|
virtual void draw() override;
|
||||||
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
||||||
|
void set_icon(const std::string& icon_path);
|
||||||
|
void set_value(bool checked) { this->checked = checked; update_icon(); }
|
||||||
|
void update_icon();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ void NodeComboBox::clone_copy(Node* dest) const
|
|||||||
NodeButton::clone_copy(dest);
|
NodeButton::clone_copy(dest);
|
||||||
NodeComboBox* n = static_cast<NodeComboBox*>(dest);
|
NodeComboBox* n = static_cast<NodeComboBox*>(dest);
|
||||||
n->m_data = m_data;
|
n->m_data = m_data;
|
||||||
|
n->m_items = m_items;
|
||||||
n->m_current_index = m_current_index;
|
n->m_current_index = m_current_index;
|
||||||
|
n->m_selected_child_index = m_selected_child_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeComboBox::loaded()
|
void NodeComboBox::loaded()
|
||||||
@@ -85,6 +87,9 @@ void NodeComboBox::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute*
|
|||||||
case kAttribute::ComboList:
|
case kAttribute::ComboList:
|
||||||
{
|
{
|
||||||
m_data = split(attr->Value(), ',');
|
m_data = split(attr->Value(), ',');
|
||||||
|
m_items.clear();
|
||||||
|
for (auto& i : m_data)
|
||||||
|
if (i != "-") m_items.push_back(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kAttribute::Default:
|
case kAttribute::Default:
|
||||||
@@ -94,3 +99,12 @@ void NodeComboBox::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute*
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeComboBox::set_index(int index)
|
||||||
|
{
|
||||||
|
m_current_index = index;
|
||||||
|
m_selected_child_index = index;
|
||||||
|
m_text->set_text(m_items[index].c_str());
|
||||||
|
//if (on_select)
|
||||||
|
// on_select(this, index);
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ public:
|
|||||||
virtual void clone_copy(Node* dest) const override;
|
virtual void clone_copy(Node* dest) const override;
|
||||||
virtual void loaded() override;
|
virtual void loaded() override;
|
||||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
||||||
|
void set_index(int index);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -105,3 +105,19 @@ void NodeImage::draw()
|
|||||||
TextureManager::get(m_tex_id).unbind();
|
TextureManager::get(m_tex_id).unbind();
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NodeImage::set_image(const std::string& path)
|
||||||
|
{
|
||||||
|
m_path = path;
|
||||||
|
m_tex_id = const_hash(path.c_str());
|
||||||
|
if (!m_path.empty() && TextureManager::load(m_path.c_str(), m_use_mipmaps))
|
||||||
|
{
|
||||||
|
auto tex_sz = TextureManager::get(m_tex_id).size();
|
||||||
|
m_off = xy(m_region) / tex_sz;
|
||||||
|
m_sz = (zw(m_region) - xy(m_region)) / tex_sz;
|
||||||
|
if (m_autosize)
|
||||||
|
SetAspectRatio(tex_sz.x / tex_sz.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,4 +24,5 @@ public:
|
|||||||
virtual void restore_context() override;
|
virtual void restore_context() override;
|
||||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
||||||
virtual void draw() override;
|
virtual void draw() override;
|
||||||
|
bool set_image(const std::string& path);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "node_panel_layer.h"
|
#include "node_panel_layer.h"
|
||||||
|
#include "canvas.h"
|
||||||
|
#include "node_combobox.h"
|
||||||
|
|
||||||
Node* NodeLayer::clone_instantiate() const
|
Node* NodeLayer::clone_instantiate() const
|
||||||
{
|
{
|
||||||
@@ -31,7 +33,6 @@ void NodeLayer::init()
|
|||||||
m_thinkness = m_template->m_thinkness;
|
m_thinkness = m_template->m_thinkness;
|
||||||
m_label = find<NodeText>("label");
|
m_label = find<NodeText>("label");
|
||||||
m_visibility = find<NodeCheckBox>("cb");
|
m_visibility = find<NodeCheckBox>("cb");
|
||||||
m_opacity = find<NodeSliderH>("sl-opacity");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeLayer::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
void NodeLayer::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||||
@@ -54,10 +55,6 @@ void NodeLayer::loaded()
|
|||||||
NodeBorder::loaded();
|
NodeBorder::loaded();
|
||||||
if (!m_label_text.empty())
|
if (!m_label_text.empty())
|
||||||
m_label->set_text(m_label_text.c_str());
|
m_label->set_text(m_label_text.c_str());
|
||||||
m_opacity->on_value_changed = [this](Node*, float value) {
|
|
||||||
if (on_opacity_changed)
|
|
||||||
on_opacity_changed(this, value);
|
|
||||||
};
|
|
||||||
m_visibility->on_value_changed = [this](Node*, bool checked) {
|
m_visibility->on_value_changed = [this](Node*, bool checked) {
|
||||||
if (on_visibility_changed)
|
if (on_visibility_changed)
|
||||||
on_visibility_changed(this, checked);
|
on_visibility_changed(this, checked);
|
||||||
@@ -159,6 +156,18 @@ void NodePanelLayer::init()
|
|||||||
on_layer_order(this, old_idx, new_idx);
|
on_layer_order(this, old_idx, new_idx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
m_opacity = find<NodeSliderH>("opacity");
|
||||||
|
m_opacity->on_value_changed = [this](Node*, float value) {
|
||||||
|
handle_layer_opacity(m_current_layer, value);
|
||||||
|
};
|
||||||
|
m_alpha_lock = find<NodeCheckBox>("alpha-lock");
|
||||||
|
m_alpha_lock->on_value_changed = [this](Node*, bool locked) {
|
||||||
|
handle_layer_alpha_lock(m_current_layer, locked);
|
||||||
|
};
|
||||||
|
m_blend_mode = find<NodeComboBox>("blend-mode");
|
||||||
|
m_blend_mode->on_select = [this](Node*, int index) {
|
||||||
|
handle_layer_blend_mode(m_current_layer, index);
|
||||||
|
};
|
||||||
LOG("done init");
|
LOG("done init");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,8 +179,8 @@ NodeLayer* NodePanelLayer::add_layer(const char* name)
|
|||||||
l->create();
|
l->create();
|
||||||
l->loaded();
|
l->loaded();
|
||||||
l->set_name(name);
|
l->set_name(name);
|
||||||
|
l->m_visibility->set_value(true);
|
||||||
l->on_selected = std::bind(&NodePanelLayer::handle_layer_selected, this, std::placeholders::_1);
|
l->on_selected = std::bind(&NodePanelLayer::handle_layer_selected, this, std::placeholders::_1);
|
||||||
l->on_opacity_changed = std::bind(&NodePanelLayer::handle_layer_opacity, this, std::placeholders::_1, std::placeholders::_2);
|
|
||||||
l->on_visibility_changed = std::bind(&NodePanelLayer::handle_layer_visibility, this, std::placeholders::_1, std::placeholders::_2);
|
l->on_visibility_changed = std::bind(&NodePanelLayer::handle_layer_visibility, this, std::placeholders::_1, std::placeholders::_2);
|
||||||
l->on_highlight = std::bind(&NodePanelLayer::handle_layer_highlight, this, std::placeholders::_1, std::placeholders::_2);
|
l->on_highlight = std::bind(&NodePanelLayer::handle_layer_highlight, this, std::placeholders::_1, std::placeholders::_2);
|
||||||
if (m_current_layer)
|
if (m_current_layer)
|
||||||
@@ -179,6 +188,7 @@ NodeLayer* NodePanelLayer::add_layer(const char* name)
|
|||||||
m_current_layer = l;
|
m_current_layer = l;
|
||||||
m_current_layer->m_selected = true;
|
m_current_layer->m_selected = true;
|
||||||
m_layers.push_back(l);
|
m_layers.push_back(l);
|
||||||
|
update_attributes();
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +218,7 @@ void NodePanelLayer::remove_layer(NodeLayer* layer)
|
|||||||
on_layer_delete(this, old_idx);
|
on_layer_delete(this, old_idx);
|
||||||
if (on_layer_change)
|
if (on_layer_change)
|
||||||
on_layer_change(this, -1, i);
|
on_layer_change(this, -1, i);
|
||||||
|
update_attributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePanelLayer::handle_layer_opacity(NodeLayer* target, float value)
|
void NodePanelLayer::handle_layer_opacity(NodeLayer* target, float value)
|
||||||
@@ -228,6 +239,18 @@ void NodePanelLayer::handle_layer_visibility(NodeLayer* target, bool visible)
|
|||||||
on_layer_visibility_changed(this, m_layers_container->get_child_index(target), visible);
|
on_layer_visibility_changed(this, m_layers_container->get_child_index(target), visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodePanelLayer::handle_layer_alpha_lock(NodeLayer* target, bool locked)
|
||||||
|
{
|
||||||
|
if (on_layer_alpha_lock_changed)
|
||||||
|
on_layer_alpha_lock_changed(this, m_layers_container->get_child_index(target), locked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodePanelLayer::handle_layer_blend_mode(NodeLayer* target, int mode)
|
||||||
|
{
|
||||||
|
if (on_layer_blend_mode_changed)
|
||||||
|
on_layer_blend_mode_changed(this, m_layers_container->get_child_index(target), mode);
|
||||||
|
}
|
||||||
|
|
||||||
void NodePanelLayer::handle_layer_selected(NodeLayer* target)
|
void NodePanelLayer::handle_layer_selected(NodeLayer* target)
|
||||||
{
|
{
|
||||||
if (m_current_layer)
|
if (m_current_layer)
|
||||||
@@ -236,6 +259,7 @@ void NodePanelLayer::handle_layer_selected(NodeLayer* target)
|
|||||||
m_current_layer->m_selected = true;
|
m_current_layer->m_selected = true;
|
||||||
if (on_layer_change)
|
if (on_layer_change)
|
||||||
on_layer_change(this, -1, m_layers_container->get_child_index(m_current_layer));
|
on_layer_change(this, -1, m_layers_container->get_child_index(m_current_layer));
|
||||||
|
update_attributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodePanelLayer::clear()
|
void NodePanelLayer::clear()
|
||||||
@@ -244,3 +268,11 @@ void NodePanelLayer::clear()
|
|||||||
m_layers.clear();
|
m_layers.clear();
|
||||||
m_current_layer = nullptr;
|
m_current_layer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodePanelLayer::update_attributes()
|
||||||
|
{
|
||||||
|
auto& l = Canvas::I->m_layers[Canvas::I->m_current_layer_idx];
|
||||||
|
m_opacity->set_value(l.m_opacity);
|
||||||
|
m_alpha_lock->set_value(l.m_alpha_locked);
|
||||||
|
m_blend_mode->set_index(l.m_blend_mode);
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
#include "node_checkbox.h"
|
#include "node_checkbox.h"
|
||||||
#include "node_slider.h"
|
#include "node_slider.h"
|
||||||
#include "node_button_custom.h"
|
#include "node_button_custom.h"
|
||||||
|
#include "node_combobox.h"
|
||||||
|
|
||||||
class NodeLayer : public NodeBorder
|
class NodeLayer : public NodeBorder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::function<void(NodeLayer* target)> on_selected;
|
std::function<void(NodeLayer* target)> on_selected;
|
||||||
std::function<void(NodeLayer* target, float opacity)> on_opacity_changed;
|
|
||||||
std::function<void(NodeLayer* target, bool visible)> on_visibility_changed;
|
std::function<void(NodeLayer* target, bool visible)> on_visibility_changed;
|
||||||
std::function<void(NodeLayer* target, bool highlight)> on_highlight;
|
std::function<void(NodeLayer* target, bool highlight)> on_highlight;
|
||||||
bool m_selected = false;
|
bool m_selected = false;
|
||||||
@@ -19,7 +19,6 @@ public:
|
|||||||
std::string m_label_text;
|
std::string m_label_text;
|
||||||
NodeText* m_label;
|
NodeText* m_label;
|
||||||
NodeCheckBox* m_visibility;
|
NodeCheckBox* m_visibility;
|
||||||
NodeSliderH* m_opacity;
|
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void clone_children(Node* dest) const override;
|
virtual void clone_children(Node* dest) const override;
|
||||||
virtual void clone_copy(Node* dest) const override;
|
virtual void clone_copy(Node* dest) const override;
|
||||||
@@ -42,13 +41,18 @@ public:
|
|||||||
std::function<void(Node* target, int old_idx, int new_idx)> on_layer_change;
|
std::function<void(Node* target, int old_idx, int new_idx)> on_layer_change;
|
||||||
std::function<void(Node* target, int idx, float value)> on_layer_opacity_changed;
|
std::function<void(Node* target, int idx, float value)> on_layer_opacity_changed;
|
||||||
std::function<void(Node* target, int idx, bool visible)> on_layer_visibility_changed;
|
std::function<void(Node* target, int idx, bool visible)> on_layer_visibility_changed;
|
||||||
|
std::function<void(Node* target, int idx, bool locked)> on_layer_alpha_lock_changed;
|
||||||
std::function<void(Node* target, int idx, bool highlight)> on_layer_highlight_changed;
|
std::function<void(Node* target, int idx, bool highlight)> on_layer_highlight_changed;
|
||||||
|
std::function<void(Node* target, int idx, int mode)> on_layer_blend_mode_changed;
|
||||||
std::function<void(Node* target, int index)> on_layer_delete;
|
std::function<void(Node* target, int index)> on_layer_delete;
|
||||||
std::function<void(Node* target)> on_layer_add;
|
std::function<void(Node* target)> on_layer_add;
|
||||||
std::function<void(Node* target, int old_idx, int new_idx)> on_layer_order;
|
std::function<void(Node* target, int old_idx, int new_idx)> on_layer_order;
|
||||||
NodeLayer* m_current_layer = nullptr;
|
NodeLayer* m_current_layer = nullptr;
|
||||||
std::vector<NodeLayer*> m_layers;
|
std::vector<NodeLayer*> m_layers;
|
||||||
NodeBorder* m_layers_container;
|
NodeBorder* m_layers_container;
|
||||||
|
NodeSliderH* m_opacity;
|
||||||
|
NodeCheckBox* m_alpha_lock;
|
||||||
|
NodeComboBox* m_blend_mode;
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void init() override;
|
virtual void init() override;
|
||||||
void add_layer();
|
void add_layer();
|
||||||
@@ -57,7 +61,10 @@ public:
|
|||||||
void remove_layer(NodeLayer* layer);
|
void remove_layer(NodeLayer* layer);
|
||||||
void handle_layer_opacity(NodeLayer* target, float value);
|
void handle_layer_opacity(NodeLayer* target, float value);
|
||||||
void handle_layer_visibility(NodeLayer* target, bool visible);
|
void handle_layer_visibility(NodeLayer* target, bool visible);
|
||||||
|
void handle_layer_alpha_lock(NodeLayer* target, bool locked);
|
||||||
void handle_layer_highlight(NodeLayer* target, bool highlight);
|
void handle_layer_highlight(NodeLayer* target, bool highlight);
|
||||||
|
void handle_layer_blend_mode(NodeLayer* target, int mode);
|
||||||
void handle_layer_selected(NodeLayer* target);
|
void handle_layer_selected(NodeLayer* target);
|
||||||
void clear();
|
void clear();
|
||||||
|
void update_attributes();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ void NodeSliderH::draw()
|
|||||||
void NodeSliderH::set_value(float value)
|
void NodeSliderH::set_value(float value)
|
||||||
{
|
{
|
||||||
m_value = glm::vec2(value) * m_mask;
|
m_value = glm::vec2(value) * m_mask;
|
||||||
if (on_value_changed)
|
//if (on_value_changed)
|
||||||
on_value_changed(this, glm::length(m_value));
|
// on_value_changed(this, glm::length(m_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
float NodeSliderH::get_value()
|
float NodeSliderH::get_value()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ enum class kShaderUniform : uint16_t
|
|||||||
StencilOffset = const_hash("stencil_offset"),
|
StencilOffset = const_hash("stencil_offset"),
|
||||||
StencilAlpha = const_hash("stencil_alpha"),
|
StencilAlpha = const_hash("stencil_alpha"),
|
||||||
MixAlpha = const_hash("mix_alpha"),
|
MixAlpha = const_hash("mix_alpha"),
|
||||||
|
StrokeAlpha = const_hash("stroke_alpha"),
|
||||||
Wet = const_hash("wet"),
|
Wet = const_hash("wet"),
|
||||||
Lock = const_hash("lock"),
|
Lock = const_hash("lock"),
|
||||||
Col = const_hash("col"),
|
Col = const_hash("col"),
|
||||||
|
|||||||
Reference in New Issue
Block a user