split app.cpp into multiple files, add NodeScroll and use it to scroll the side panels, some fixes to the events system
This commit is contained in:
816
engine/app.cpp
816
engine/app.cpp
@@ -21,333 +21,6 @@ void App::clear()
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void App::initShaders()
|
||||
{
|
||||
static const char* shader_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec3 uv;"
|
||||
"void main(){"
|
||||
" uv = vec3(uvs, pos.w);"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);"
|
||||
"}";
|
||||
static const char* shader_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
//" frag = texture(tex, uv.xy/uv.z);"
|
||||
" frag = texture(tex, uv.xy);"
|
||||
"}";
|
||||
static const char* shader_uv_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = vec4(uv.xy, 0.0, 1.0);"
|
||||
"}";
|
||||
// TEXTURE ALPHA
|
||||
static const char* shader_alpha_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec3 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" frag = texture(tex, uv.xy) * vec4(1,1,1,alpha);\n"
|
||||
"}\n";
|
||||
|
||||
// TEXTURE ATLAS
|
||||
static const char* shader_atlas_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"uniform vec2 tof;"
|
||||
"uniform vec2 tsz;"
|
||||
"in vec2 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = tof + uvs * tsz;"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);"
|
||||
"}";
|
||||
static const char* shader_atlas_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in mediump vec2 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = texture(tex, uv);"
|
||||
"}";
|
||||
|
||||
// SOLID COLOR
|
||||
static const char* shader_color_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"void main(){"
|
||||
" gl_Position = mvp * pos;"
|
||||
" gl_PointSize = 15.0;"
|
||||
"}";
|
||||
static const char* shader_color_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump vec4 col;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = col;"
|
||||
"}";
|
||||
|
||||
// COLOR QUAD
|
||||
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 mediump vec4 col;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" mediump vec4 gradient_x = mix(col, vec4(1.0, 1.0, 1.0, 1.0), uv.x);"
|
||||
" frag = mix(gradient_x, vec4(0.0, 0.0, 0.0, 1.0), uv.y);"
|
||||
"}";
|
||||
|
||||
// HUE
|
||||
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 mediump vec4 col;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"mediump vec3 hsv2rgb(mediump vec3 c) {"
|
||||
" mediump vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);"
|
||||
" mediump 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.0, 1.0)), 1.0);"
|
||||
"}";
|
||||
|
||||
// FONT
|
||||
static const char* shader_font_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec2 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = uvs;"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);"
|
||||
"}";
|
||||
static const char* shader_font_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;"
|
||||
"uniform mediump vec4 col;"
|
||||
"in mediump vec2 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" mediump float a = texture(tex, uv).r;"
|
||||
" frag = vec4(col.rgb, a);"
|
||||
"}";
|
||||
|
||||
// STROKE
|
||||
static const char* shader_stroke_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main(){\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_stroke_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv).r ) * alpha;\n"
|
||||
" mediump vec4 fg = vec4(col.rgb, brush_alpha);\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||
" if (fg.a < (1.0/255.0)) { frag = bg; return; }\n"
|
||||
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" frag = vec4(rgb, alpha_tot);\n"
|
||||
"}\n";
|
||||
// ALPHA LOCK
|
||||
static const char* shader_stroke_lock_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump sampler2D tex_mask;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv).r ) * alpha;\n"
|
||||
" mediump vec4 fg = vec4(col.rgb, brush_alpha);\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||
" mediump vec4 msk = texture(tex_mask, uv2);\n"
|
||||
" if (fg.a < (1.0/255.0)) { frag = bg; return; }\n"
|
||||
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" frag = vec4(rgb, min(alpha_tot, msk.a));\n"
|
||||
"}\n";
|
||||
// ERASER
|
||||
static const char* shader_stroke_erase_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv).r ) * alpha;\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||
" frag = vec4(bg.rgb, bg.a - bg.a * brush_alpha);\n"
|
||||
"}\n";
|
||||
|
||||
// STROKE LAYER BLEND
|
||||
static const char* shader_stroke_layer_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = uvs;"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);"
|
||||
"}";
|
||||
static const char* shader_stroke_layer_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec4 fg = texture(tex, uv) * vec4(1,1,1,alpha);\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv);\n"
|
||||
" if (fg.a < (1.0/255.0)) { frag = bg; return; }\n"
|
||||
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" frag = vec4(rgb, alpha_tot);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* shader_checkerboard_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main(){\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}";
|
||||
static const char* shader_checkerboard_f =
|
||||
SHADER_VERSION
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" const mediump vec4 c1 = vec4(1.0, 1.0, 1.0, 1.0);\n"
|
||||
" const mediump vec4 c2 = vec4(0.9, 0.9, 0.9, 1.0);\n"
|
||||
" mediump vec2 c = floor(fract(uv * 10.0) * 2.0);\n"
|
||||
" mediump float alpha = mix(c.x, 1.0 - c.x, c.y);\n"
|
||||
" frag = mix(c1, c2, alpha);\n"
|
||||
"}";
|
||||
|
||||
static const char* shader_equirect_v =
|
||||
SHADER_VERSION
|
||||
"#define PI 3.1415926535897932384626433832795\n"
|
||||
"#define TWO_PI 6.283185307179586476925286766559\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main(){\n"
|
||||
" uv = (vec2(1.0) - uvs + vec2(0.25,0.0)) * vec2(TWO_PI, PI);\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}";
|
||||
static const char* shader_equirect_f =
|
||||
SHADER_VERSION
|
||||
"uniform samplerCube tex;\n"
|
||||
"in highp vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" highp float anglex = uv.x;\n"
|
||||
" highp float angley = uv.y;\n"
|
||||
" highp float sx = sin(anglex);\n"
|
||||
" highp float cx = cos(anglex);\n"
|
||||
" highp vec3 dir = vec3(0.0, 0.0, 0.0);\n"
|
||||
" dir.x = sin(angley) * cx;\n"
|
||||
" dir.y = cos(angley);\n"
|
||||
" dir.z = sin(angley) * sx;\n"
|
||||
" frag = texture(tex, dir);\n"
|
||||
"}";
|
||||
|
||||
LOG("initializing shaders");
|
||||
if (!ShaderManager::create(kShader::Texture, shader_v, shader_f))
|
||||
LOG("Failed to create shader Texture");
|
||||
if (!ShaderManager::create(kShader::TextureAlpha, shader_v, shader_alpha_f))
|
||||
LOG("Failed to create shader TextureAlpha");
|
||||
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))
|
||||
LOG("Failed to create shader Font");
|
||||
if (!ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f))
|
||||
LOG("Failed to create shader Atlas");
|
||||
if (!ShaderManager::create(kShader::Stroke, shader_stroke_v, shader_stroke_f))
|
||||
LOG("Failed to create shader Stroke");
|
||||
if (!ShaderManager::create(kShader::StrokeLock, shader_stroke_v, shader_stroke_lock_f))
|
||||
LOG("Failed to create shader StrokeLock");
|
||||
if (!ShaderManager::create(kShader::StrokeErase, shader_stroke_v, shader_stroke_erase_f))
|
||||
LOG("Failed to create shader StrokeErase");
|
||||
if (!ShaderManager::create(kShader::StrokeLayer, shader_stroke_layer_v, shader_stroke_layer_f))
|
||||
LOG("Failed to create shader StrokeLayer");
|
||||
if (!ShaderManager::create(kShader::Checkerboard, shader_checkerboard_v, shader_checkerboard_f))
|
||||
LOG("Failed to create shader Checkerboard");
|
||||
if (!ShaderManager::create(kShader::Equirect, shader_equirect_v, shader_equirect_f))
|
||||
LOG("Failed to create shader Equirect");
|
||||
LOG("shaders initialized");
|
||||
}
|
||||
|
||||
void App::initAssets()
|
||||
{
|
||||
LOG("initializing assets");
|
||||
@@ -364,383 +37,11 @@ void App::initAssets()
|
||||
LOG("initializing assets completed");
|
||||
}
|
||||
|
||||
void App::initLayout()
|
||||
{
|
||||
LOG("initializing layout statics");
|
||||
NodeBorder::static_init();
|
||||
NodeImage::static_init();
|
||||
NodeIcon::static_init();
|
||||
NodeStrokePreview::static_init();
|
||||
|
||||
layout.on_loaded = [&] {
|
||||
LOG("initializing layout updating after load");
|
||||
layout[main_id]->update(width, height, zoom);
|
||||
|
||||
LOG("initializing layout components");
|
||||
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
||||
panels = layout[main_id]->find<Node>("panels");
|
||||
canvas = layout[main_id]->find<NodeCanvas>("paint-canvas");
|
||||
canvas->data_path = data_path;
|
||||
|
||||
//brushes = layout[main_id]->find<NodePanelBrush>("panel-brush");
|
||||
//layers = layout[main_id]->find<NodePanelLayer>("panel-layer");
|
||||
//color = layout[main_id]->find<NodePanelColor>("panel-color");
|
||||
//stroke = layout[main_id]->find<NodePanelStroke>("panel-stroke");
|
||||
|
||||
brushes = std::make_shared<NodePanelBrush>();
|
||||
brushes->m_manager = &layout;
|
||||
brushes->init();
|
||||
brushes->create();
|
||||
brushes->loaded();
|
||||
|
||||
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();
|
||||
|
||||
if (canvas)
|
||||
{
|
||||
stroke->m_canvas->m_brush.m_tip_color = color->m_color;
|
||||
stroke->m_canvas->draw_stroke();
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
}
|
||||
|
||||
brushes->on_brush_changed = [this](Node* target, int index) {
|
||||
auto tid = brushes->get_texture_id(index);
|
||||
stroke->m_canvas->m_brush.m_tex_id = tid;
|
||||
stroke->m_canvas->draw_stroke();
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
if (on_brush_select)
|
||||
on_brush_select(index);
|
||||
};
|
||||
|
||||
color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
||||
stroke->m_canvas->m_brush.m_tip_color = color;
|
||||
// stroke->m_canvas->draw_stroke();
|
||||
if (canvas)
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
if (on_color_change)
|
||||
on_color_change(color);
|
||||
};
|
||||
|
||||
stroke->on_stroke_change = [this](Node*target) {
|
||||
if (canvas)
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
if (on_stroke_change)
|
||||
on_stroke_change();
|
||||
};
|
||||
|
||||
layers->on_layer_add = [this](Node*) {
|
||||
canvas->m_canvas->layer_add(layers->m_layers.back()->m_label_text.c_str());
|
||||
};
|
||||
|
||||
layers->on_layer_change = [this](Node*, int old_idx, int new_idx) {
|
||||
canvas->m_canvas->m_current_layer_idx = canvas->m_canvas->m_order[new_idx];
|
||||
};
|
||||
|
||||
layers->on_layer_order = [this](Node*, int old_idx, int new_idx) {
|
||||
canvas->m_canvas->layer_order(old_idx, new_idx);
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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->layer_add("Default");
|
||||
layers->add_layer("Default");
|
||||
|
||||
static glm::vec4 color_button_normal{.1, .1, .1, 1};
|
||||
static glm::vec4 color_button_hlight{ 1, .0, .0, 1};
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-pen"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Draw);
|
||||
};
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_hlight);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Draw);
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-erase"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Erase);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-line"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Line);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-cam"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Camera);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-grid"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Grid);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-fill"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_hlight);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Fill);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-bucket"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
canvas->m_canvas->clear(canvas->m_brush.m_tip_color);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(stroke.get()) == -1 ? panels->add_child(stroke) : panels->remove_child(stroke.get());
|
||||
button->set_color(panels->get_child_index(stroke.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-brush"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(brushes.get()) == -1 ? panels->add_child(brushes) : panels->remove_child(brushes.get());
|
||||
button->set_color(panels->get_child_index(brushes.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-color"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(color.get()) == -1 ? panels->add_child(color) : panels->remove_child(color.get());
|
||||
button->set_color(panels->get_child_index(color.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-layer"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(layers.get()) == -1 ? panels->add_child(layers) : panels->remove_child(layers.get());
|
||||
button->set_color(panels->get_child_index(layers.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-export"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
canvas->m_canvas->export_equirectangular(data_path);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-anim"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
//canvas->m_canvas->export_anim(data_path);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-open"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
// load thumbnail test
|
||||
auto open_dialog = std::make_shared<NodeDialogOpen>();
|
||||
open_dialog->m_manager = &layout;
|
||||
open_dialog->data_path = data_path;
|
||||
open_dialog->init();
|
||||
open_dialog->create();
|
||||
open_dialog->loaded();
|
||||
|
||||
layout[main_id]->add_child(open_dialog);
|
||||
layout[main_id]->update();
|
||||
|
||||
open_dialog->btn_ok->on_click = [this,open_dialog](Node*)
|
||||
{
|
||||
layers->clear();
|
||||
canvas->m_canvas->project_open(data_path);
|
||||
for (auto& i : canvas->m_canvas->m_order)
|
||||
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
||||
open_dialog->destroy();
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-save"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
canvas->m_canvas->project_save(data_path);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-undo"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (!ActionManager::empty())
|
||||
ActionManager::undo();
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-clean-memory"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
ActionManager::clear();
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-clear"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
//exit(0);
|
||||
if (canvas)
|
||||
canvas->m_canvas->clear({ 0, 0, 0, 0 });
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-popup"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
msgbox = new NodeMessageBox();
|
||||
msgbox->m_manager = &layout;
|
||||
msgbox->init();
|
||||
layout[main_id]->add_child(msgbox);
|
||||
layout[main_id]->update();
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-settings"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
settings = new NodeSettings();
|
||||
settings->m_manager = &layout;
|
||||
settings->init();
|
||||
layout[main_id]->add_child(settings);
|
||||
layout[main_id]->update();
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-file"))
|
||||
{
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("file-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-edit"))
|
||||
{
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("edit-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-layers"))
|
||||
{
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("layers-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
popup->find<NodeButtonCustom>("clear-grids")->on_click = [this](Node*) {
|
||||
CanvasModeGrid* mode = (CanvasModeGrid*)ui::Canvas::modes[(int)ui::Canvas::kCanvasMode::Grid][0];
|
||||
mode->clear();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
};
|
||||
}
|
||||
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
||||
{
|
||||
toolbar->m_flood_events = true;
|
||||
}
|
||||
};
|
||||
LOG("initializing layout xml");
|
||||
if (layout.m_loaded)
|
||||
{
|
||||
LOG("restore layout");
|
||||
layout.restore_context();
|
||||
if (panels->get_child_index(brushes.get()) == -1) brushes->restore_context();
|
||||
if (panels->get_child_index(layers.get()) == -1) layers->restore_context();
|
||||
if (panels->get_child_index(color.get()) == -1) color->restore_context();
|
||||
if (panels->get_child_index(stroke.get()) == -1) stroke->restore_context();
|
||||
}
|
||||
else
|
||||
layout.load("data/layout.xml");
|
||||
LOG("initializing layout completed");
|
||||
}
|
||||
|
||||
void App::initLog()
|
||||
{
|
||||
LogRemote::I.start();
|
||||
}
|
||||
|
||||
void App::init()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@@ -836,121 +137,6 @@ void App::update(float dt)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
void App::resize(float w, float h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
if (auto* main = layout[main_id])
|
||||
main->update(w , h, zoom);
|
||||
}
|
||||
|
||||
bool App::mouse_down(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_move(float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseMove;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
kEventResult ret = kEventResult::Available;
|
||||
if (auto* main = layout[main_id])
|
||||
ret = main->on_event(&e);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_up(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseUpR : kEventType::MouseUpL;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_scroll(float x, float y, float delta)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseScroll;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
e.m_scroll_delta = delta * 0.1f;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_cancel(int button)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseCancel;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::gesture_start(const glm::vec2& p0, const glm::vec2& p1)
|
||||
{
|
||||
GestureEvent e;
|
||||
glm::vec2 p = glm::lerp(p0, p1, 0.5f);
|
||||
e.m_type = kEventType::GestureStart;
|
||||
e.m_pos = p;
|
||||
e.m_distance = glm::distance(p0, p1);
|
||||
gesture_p0 = p0;
|
||||
gesture_p1 = p1;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::gesture_move(const glm::vec2& p0, const glm::vec2& p1)
|
||||
{
|
||||
GestureEvent e;
|
||||
glm::vec2 p = glm::lerp(p0, p1, 0.5f);
|
||||
e.m_type = kEventType::GestureMove;
|
||||
e.m_pos = p;
|
||||
e.m_distance = glm::distance(p0, p1);
|
||||
e.m_distance_delta = e.m_distance - glm::distance(gesture_p0, gesture_p1);
|
||||
e.m_pos_delta = p - glm::lerp(gesture_p0, gesture_p1, 0.5f);
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::gesture_end()
|
||||
{
|
||||
GestureEvent e;
|
||||
e.m_type = kEventType::GestureEnd;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_down(kKey key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyDown;
|
||||
e.m_key = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_up(kKey key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyUp;
|
||||
e.m_key = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_char(char key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyChar;
|
||||
e.m_char = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
|
||||
void App::terminate()
|
||||
{
|
||||
|
||||
121
engine/app_events.cpp
Normal file
121
engine/app_events.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
|
||||
using namespace ui;
|
||||
|
||||
void App::resize(float w, float h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
if (auto* main = layout[main_id])
|
||||
main->update(w , h, zoom);
|
||||
}
|
||||
|
||||
bool App::mouse_down(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_move(float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseMove;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
kEventResult ret = kEventResult::Available;
|
||||
if (auto* main = layout[main_id])
|
||||
ret = main->on_event(&e);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_up(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseUpR : kEventType::MouseUpL;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_scroll(float x, float y, float delta)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseScroll;
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
e.m_scroll_delta = delta * 0.1f;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
LOG("wheel x %.2f y %.2f", x, y);
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::mouse_cancel(int button)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseCancel;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::gesture_start(const glm::vec2& p0, const glm::vec2& p1)
|
||||
{
|
||||
GestureEvent e;
|
||||
glm::vec2 p = glm::lerp(p0, p1, 0.5f);
|
||||
e.m_type = kEventType::GestureStart;
|
||||
e.m_pos = p;
|
||||
e.m_distance = glm::distance(p0, p1);
|
||||
gesture_p0 = p0;
|
||||
gesture_p1 = p1;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::gesture_move(const glm::vec2& p0, const glm::vec2& p1)
|
||||
{
|
||||
GestureEvent e;
|
||||
glm::vec2 p = glm::lerp(p0, p1, 0.5f);
|
||||
e.m_type = kEventType::GestureMove;
|
||||
e.m_pos = p;
|
||||
e.m_distance = glm::distance(p0, p1);
|
||||
e.m_distance_delta = e.m_distance - glm::distance(gesture_p0, gesture_p1);
|
||||
e.m_pos_delta = p - glm::lerp(gesture_p0, gesture_p1, 0.5f);
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::gesture_end()
|
||||
{
|
||||
GestureEvent e;
|
||||
e.m_type = kEventType::GestureEnd;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_down(kKey key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyDown;
|
||||
e.m_key = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_up(kKey key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyUp;
|
||||
e.m_key = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
bool App::key_char(char key)
|
||||
{
|
||||
KeyEvent e;
|
||||
e.m_type = kEventType::KeyChar;
|
||||
e.m_char = key;
|
||||
auto ret = layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
return ret == kEventResult::Consumed;
|
||||
}
|
||||
385
engine/app_layout.cpp
Normal file
385
engine/app_layout.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "node_icon.h"
|
||||
#include "node_dialog_open.h"
|
||||
|
||||
using namespace ui;
|
||||
|
||||
void App::initLayout()
|
||||
{
|
||||
LOG("initializing layout statics");
|
||||
NodeBorder::static_init();
|
||||
NodeImage::static_init();
|
||||
NodeIcon::static_init();
|
||||
NodeStrokePreview::static_init();
|
||||
|
||||
layout.on_loaded = [&] {
|
||||
LOG("initializing layout updating after load");
|
||||
layout[main_id]->update(width, height, zoom);
|
||||
|
||||
LOG("initializing layout components");
|
||||
sidebar = layout[main_id]->find<NodeBorder>("sidebar");
|
||||
panels = layout[main_id]->find<Node>("panels");
|
||||
canvas = layout[main_id]->find<NodeCanvas>("paint-canvas");
|
||||
canvas->data_path = data_path;
|
||||
|
||||
//brushes = layout[main_id]->find<NodePanelBrush>("panel-brush");
|
||||
//layers = layout[main_id]->find<NodePanelLayer>("panel-layer");
|
||||
//color = layout[main_id]->find<NodePanelColor>("panel-color");
|
||||
//stroke = layout[main_id]->find<NodePanelStroke>("panel-stroke");
|
||||
|
||||
brushes = std::make_shared<NodePanelBrush>();
|
||||
brushes->m_manager = &layout;
|
||||
brushes->init();
|
||||
brushes->create();
|
||||
brushes->loaded();
|
||||
|
||||
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();
|
||||
|
||||
if (canvas)
|
||||
{
|
||||
stroke->m_canvas->m_brush.m_tip_color = color->m_color;
|
||||
stroke->m_canvas->draw_stroke();
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
}
|
||||
|
||||
brushes->on_brush_changed = [this](Node* target, int index) {
|
||||
auto tid = brushes->get_texture_id(index);
|
||||
stroke->m_canvas->m_brush.m_tex_id = tid;
|
||||
stroke->m_canvas->draw_stroke();
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
if (on_brush_select)
|
||||
on_brush_select(index);
|
||||
};
|
||||
|
||||
color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
||||
stroke->m_canvas->m_brush.m_tip_color = color;
|
||||
// stroke->m_canvas->draw_stroke();
|
||||
if (canvas)
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
if (on_color_change)
|
||||
on_color_change(color);
|
||||
};
|
||||
|
||||
stroke->on_stroke_change = [this](Node*target) {
|
||||
if (canvas)
|
||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||
if (on_stroke_change)
|
||||
on_stroke_change();
|
||||
};
|
||||
|
||||
layers->on_layer_add = [this](Node*) {
|
||||
canvas->m_canvas->layer_add(layers->m_layers.back()->m_label_text.c_str());
|
||||
};
|
||||
|
||||
layers->on_layer_change = [this](Node*, int old_idx, int new_idx) {
|
||||
canvas->m_canvas->m_current_layer_idx = canvas->m_canvas->m_order[new_idx];
|
||||
};
|
||||
|
||||
layers->on_layer_order = [this](Node*, int old_idx, int new_idx) {
|
||||
canvas->m_canvas->layer_order(old_idx, new_idx);
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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->layer_add("Default");
|
||||
layers->add_layer("Default");
|
||||
|
||||
static glm::vec4 color_button_normal{.1, .1, .1, 1};
|
||||
static glm::vec4 color_button_hlight{ 1, .0, .0, 1};
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-pen"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Draw);
|
||||
};
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_hlight);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Draw);
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-erase"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Erase);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-line"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Line);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-cam"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Camera);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-grid"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_hlight);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_normal);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Grid);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-fill"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
layout[main_id]->find<NodeButton>("btn-pen")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-erase")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-line")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-cam")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-grid")->set_color(color_button_normal);
|
||||
layout[main_id]->find<NodeButton>("btn-fill")->set_color(color_button_hlight);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Fill);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-bucket"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
canvas->m_canvas->clear(canvas->m_brush.m_tip_color);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(stroke.get()) == -1 ? panels->add_child(stroke) : panels->remove_child(stroke.get());
|
||||
button->set_color(panels->get_child_index(stroke.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-brush"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(brushes.get()) == -1 ? panels->add_child(brushes) : panels->remove_child(brushes.get());
|
||||
button->set_color(panels->get_child_index(brushes.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-color"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(color.get()) == -1 ? panels->add_child(color) : panels->remove_child(color.get());
|
||||
button->set_color(panels->get_child_index(color.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-layer"))
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
panels->get_child_index(layers.get()) == -1 ? panels->add_child(layers) : panels->remove_child(layers.get());
|
||||
button->set_color(panels->get_child_index(layers.get()) == -1 ? color_button_normal : color_button_hlight);
|
||||
};
|
||||
}
|
||||
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-export"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
canvas->m_canvas->export_equirectangular(data_path);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-anim"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
//canvas->m_canvas->export_anim(data_path);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-open"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
// load thumbnail test
|
||||
auto open_dialog = std::make_shared<NodeDialogOpen>();
|
||||
open_dialog->m_manager = &layout;
|
||||
open_dialog->data_path = data_path;
|
||||
open_dialog->init();
|
||||
open_dialog->create();
|
||||
open_dialog->loaded();
|
||||
|
||||
layout[main_id]->add_child(open_dialog);
|
||||
layout[main_id]->update();
|
||||
|
||||
open_dialog->btn_ok->on_click = [this,open_dialog](Node*)
|
||||
{
|
||||
layers->clear();
|
||||
canvas->m_canvas->project_open(data_path);
|
||||
for (auto& i : canvas->m_canvas->m_order)
|
||||
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
||||
open_dialog->destroy();
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-save"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (canvas)
|
||||
{
|
||||
canvas->m_canvas->project_save(data_path);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-undo"))
|
||||
{
|
||||
button->on_click = [this,button](Node*) {
|
||||
if (!ActionManager::empty())
|
||||
ActionManager::undo();
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-clean-memory"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
ActionManager::clear();
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-clear"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
//exit(0);
|
||||
if (canvas)
|
||||
canvas->m_canvas->clear({ 0, 0, 0, 0 });
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-popup"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
msgbox = new NodeMessageBox();
|
||||
msgbox->m_manager = &layout;
|
||||
msgbox->init();
|
||||
layout[main_id]->add_child(msgbox);
|
||||
layout[main_id]->update();
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-settings"))
|
||||
{
|
||||
button->on_click = [this](Node*) {
|
||||
settings = new NodeSettings();
|
||||
settings->m_manager = &layout;
|
||||
settings->init();
|
||||
layout[main_id]->add_child(settings);
|
||||
layout[main_id]->update();
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-file"))
|
||||
{
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("file-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
popup->m_flood_events = true;
|
||||
popup->m_capture_children = false;
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-edit"))
|
||||
{
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("edit-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
popup->m_flood_events = true;
|
||||
popup->m_capture_children = false;
|
||||
};
|
||||
}
|
||||
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-layers"))
|
||||
{
|
||||
menu_file->on_click = [=](Node*) {
|
||||
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
|
||||
popup = (NodePopupMenu*)layout[const_hash("layers-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(pos.x, pos.y);
|
||||
layout[main_id]->add_child(popup);
|
||||
layout[main_id]->update();
|
||||
popup->mouse_capture();
|
||||
popup->m_mouse_ignore = false;
|
||||
popup->m_flood_events = true;
|
||||
popup->m_capture_children = false;
|
||||
popup->find<NodeButtonCustom>("clear-grids")->on_click = [this](Node*) {
|
||||
CanvasModeGrid* mode = (CanvasModeGrid*)ui::Canvas::modes[(int)ui::Canvas::kCanvasMode::Grid][0];
|
||||
mode->clear();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
};
|
||||
}
|
||||
if (auto* toolbar = layout[main_id]->find<Node>("toolbar"))
|
||||
{
|
||||
toolbar->m_flood_events = true;
|
||||
}
|
||||
};
|
||||
LOG("initializing layout xml");
|
||||
if (layout.m_loaded)
|
||||
{
|
||||
LOG("restore layout");
|
||||
layout.restore_context();
|
||||
if (panels->get_child_index(brushes.get()) == -1) brushes->restore_context();
|
||||
if (panels->get_child_index(layers.get()) == -1) layers->restore_context();
|
||||
if (panels->get_child_index(color.get()) == -1) color->restore_context();
|
||||
if (panels->get_child_index(stroke.get()) == -1) stroke->restore_context();
|
||||
}
|
||||
else
|
||||
layout.load("data/layout.xml");
|
||||
LOG("initializing layout completed");
|
||||
}
|
||||
334
engine/app_shaders.cpp
Normal file
334
engine/app_shaders.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "shader.h"
|
||||
|
||||
using namespace ui;
|
||||
|
||||
void App::initShaders()
|
||||
{
|
||||
static const char* shader_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec3 uv;"
|
||||
"void main(){"
|
||||
" uv = vec3(uvs, pos.w);"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);"
|
||||
"}";
|
||||
static const char* shader_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
//" frag = texture(tex, uv.xy/uv.z);"
|
||||
" frag = texture(tex, uv.xy);"
|
||||
"}";
|
||||
static const char* shader_uv_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = vec4(uv.xy, 0.0, 1.0);"
|
||||
"}";
|
||||
// TEXTURE ALPHA
|
||||
static const char* shader_alpha_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec3 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" frag = texture(tex, uv.xy) * vec4(1,1,1,alpha);\n"
|
||||
"}\n";
|
||||
|
||||
// TEXTURE ATLAS
|
||||
static const char* shader_atlas_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"uniform vec2 tof;"
|
||||
"uniform vec2 tsz;"
|
||||
"in vec2 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = tof + uvs * tsz;"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);"
|
||||
"}";
|
||||
static const char* shader_atlas_f =
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in mediump vec2 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = texture(tex, uv);"
|
||||
"}";
|
||||
|
||||
// SOLID COLOR
|
||||
static const char* shader_color_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"void main(){"
|
||||
" gl_Position = mvp * pos;"
|
||||
" gl_PointSize = 15.0;"
|
||||
"}";
|
||||
static const char* shader_color_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump vec4 col;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = col;"
|
||||
"}";
|
||||
|
||||
// COLOR QUAD
|
||||
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 mediump vec4 col;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" mediump vec4 gradient_x = mix(col, vec4(1.0, 1.0, 1.0, 1.0), uv.x);"
|
||||
" frag = mix(gradient_x, vec4(0.0, 0.0, 0.0, 1.0), uv.y);"
|
||||
"}";
|
||||
|
||||
// HUE
|
||||
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 mediump vec4 col;"
|
||||
"in mediump vec3 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"mediump vec3 hsv2rgb(mediump vec3 c) {"
|
||||
" mediump vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);"
|
||||
" mediump 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.0, 1.0)), 1.0);"
|
||||
"}";
|
||||
|
||||
// FONT
|
||||
static const char* shader_font_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec2 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = uvs;"
|
||||
" gl_Position = mvp * vec4(pos, 0.0, 1.0);"
|
||||
"}";
|
||||
static const char* shader_font_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;"
|
||||
"uniform mediump vec4 col;"
|
||||
"in mediump vec2 uv;"
|
||||
"out mediump vec4 frag;"
|
||||
"void main(){"
|
||||
" mediump float a = texture(tex, uv).r;"
|
||||
" frag = vec4(col.rgb, a);"
|
||||
"}";
|
||||
|
||||
// STROKE
|
||||
static const char* shader_stroke_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main(){\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
static const char* shader_stroke_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv).r ) * alpha;\n"
|
||||
" mediump vec4 fg = vec4(col.rgb, brush_alpha);\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||
" if (fg.a < (1.0/255.0)) { frag = bg; return; }\n"
|
||||
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" frag = vec4(rgb, alpha_tot);\n"
|
||||
"}\n";
|
||||
// ALPHA LOCK
|
||||
static const char* shader_stroke_lock_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump sampler2D tex_mask;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv).r ) * alpha;\n"
|
||||
" mediump vec4 fg = vec4(col.rgb, brush_alpha);\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||
" mediump vec4 msk = texture(tex_mask, uv2);\n"
|
||||
" if (fg.a < (1.0/255.0)) { frag = bg; return; }\n"
|
||||
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" frag = vec4(rgb, min(alpha_tot, msk.a));\n"
|
||||
"}\n";
|
||||
// ERASER
|
||||
static const char* shader_stroke_erase_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump vec4 col;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||
" mediump float brush_alpha = ( 1.0 - texture(tex, uv).r ) * alpha;\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||
" frag = vec4(bg.rgb, bg.a - bg.a * brush_alpha);\n"
|
||||
"}\n";
|
||||
|
||||
// STROKE LAYER BLEND
|
||||
static const char* shader_stroke_layer_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"in vec2 uvs;"
|
||||
"out vec2 uv;"
|
||||
"void main(){"
|
||||
" uv = uvs;"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);"
|
||||
"}";
|
||||
static const char* shader_stroke_layer_f =
|
||||
SHADER_VERSION
|
||||
"uniform mediump sampler2D tex;\n"
|
||||
"uniform mediump sampler2D tex_bg;\n"
|
||||
"uniform mediump vec2 resolution;\n"
|
||||
"uniform mediump float alpha;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" mediump vec4 fg = texture(tex, uv) * vec4(1,1,1,alpha);\n"
|
||||
" mediump vec4 bg = texture(tex_bg, uv);\n"
|
||||
" if (fg.a < (1.0/255.0)) { frag = bg; return; }\n"
|
||||
" mediump float alpha_tot = fg.a + (1.0 - fg.a) * bg.a;"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" frag = vec4(rgb, alpha_tot);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* shader_checkerboard_v =
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main(){\n"
|
||||
" uv = uvs;\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}";
|
||||
static const char* shader_checkerboard_f =
|
||||
SHADER_VERSION
|
||||
"in mediump vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" const mediump vec4 c1 = vec4(1.0, 1.0, 1.0, 1.0);\n"
|
||||
" const mediump vec4 c2 = vec4(0.9, 0.9, 0.9, 1.0);\n"
|
||||
" mediump vec2 c = floor(fract(uv * 10.0) * 2.0);\n"
|
||||
" mediump float alpha = mix(c.x, 1.0 - c.x, c.y);\n"
|
||||
" frag = mix(c1, c2, alpha);\n"
|
||||
"}";
|
||||
|
||||
static const char* shader_equirect_v =
|
||||
SHADER_VERSION
|
||||
"#define PI 3.1415926535897932384626433832795\n"
|
||||
"#define TWO_PI 6.283185307179586476925286766559\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"in vec4 pos;\n"
|
||||
"in vec2 uvs;\n"
|
||||
"out vec2 uv;\n"
|
||||
"void main(){\n"
|
||||
" uv = (vec2(1.0) - uvs + vec2(0.25,0.0)) * vec2(TWO_PI, PI);\n"
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.0);\n"
|
||||
"}";
|
||||
static const char* shader_equirect_f =
|
||||
SHADER_VERSION
|
||||
"uniform samplerCube tex;\n"
|
||||
"in highp vec2 uv;\n"
|
||||
"out mediump vec4 frag;\n"
|
||||
"void main(){\n"
|
||||
" highp float anglex = uv.x;\n"
|
||||
" highp float angley = uv.y;\n"
|
||||
" highp float sx = sin(anglex);\n"
|
||||
" highp float cx = cos(anglex);\n"
|
||||
" highp vec3 dir = vec3(0.0, 0.0, 0.0);\n"
|
||||
" dir.x = sin(angley) * cx;\n"
|
||||
" dir.y = cos(angley);\n"
|
||||
" dir.z = sin(angley) * sx;\n"
|
||||
" frag = texture(tex, dir);\n"
|
||||
"}";
|
||||
|
||||
LOG("initializing shaders");
|
||||
if (!ShaderManager::create(kShader::Texture, shader_v, shader_f))
|
||||
LOG("Failed to create shader Texture");
|
||||
if (!ShaderManager::create(kShader::TextureAlpha, shader_v, shader_alpha_f))
|
||||
LOG("Failed to create shader TextureAlpha");
|
||||
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))
|
||||
LOG("Failed to create shader Font");
|
||||
if (!ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f))
|
||||
LOG("Failed to create shader Atlas");
|
||||
if (!ShaderManager::create(kShader::Stroke, shader_stroke_v, shader_stroke_f))
|
||||
LOG("Failed to create shader Stroke");
|
||||
if (!ShaderManager::create(kShader::StrokeLock, shader_stroke_v, shader_stroke_lock_f))
|
||||
LOG("Failed to create shader StrokeLock");
|
||||
if (!ShaderManager::create(kShader::StrokeErase, shader_stroke_v, shader_stroke_erase_f))
|
||||
LOG("Failed to create shader StrokeErase");
|
||||
if (!ShaderManager::create(kShader::StrokeLayer, shader_stroke_layer_v, shader_stroke_layer_f))
|
||||
LOG("Failed to create shader StrokeLayer");
|
||||
if (!ShaderManager::create(kShader::Checkerboard, shader_checkerboard_v, shader_checkerboard_f))
|
||||
LOG("Failed to create shader Checkerboard");
|
||||
if (!ShaderManager::create(kShader::Equirect, shader_equirect_v, shader_equirect_f))
|
||||
LOG("Failed to create shader Equirect");
|
||||
LOG("shaders initialized");
|
||||
}
|
||||
|
||||
|
||||
@@ -659,20 +659,30 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
App::I.mouse_down(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp));
|
||||
SetCapture(hWnd);
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
App::I.mouse_up(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp));
|
||||
ReleaseCapture();
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
App::I.mouse_down(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp));
|
||||
SetCapture(hWnd);
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
App::I.mouse_up(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp));
|
||||
ReleaseCapture();
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
App::I.mouse_scroll((float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp),
|
||||
{
|
||||
POINT pt;
|
||||
pt.x = GET_X_LPARAM(lp);
|
||||
pt.y = GET_Y_LPARAM(lp);
|
||||
ScreenToClient(hWnd, &pt);
|
||||
App::I.mouse_scroll((float)pt.x, (float)pt.y,
|
||||
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
||||
break;
|
||||
}
|
||||
case WM_POINTERUPDATE:
|
||||
{
|
||||
POINTER_TOUCH_INFO touchInfo;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "node_color_quad.h"
|
||||
#include "node_stroke_preview.h"
|
||||
#include "node_canvas.h"
|
||||
#include "node_scroll.h"
|
||||
|
||||
void Node::watch(std::function<void(Node*)> observer)
|
||||
{
|
||||
@@ -47,26 +48,35 @@ Node* Node::root()
|
||||
|
||||
kEventResult Node::on_event(Event* e)
|
||||
{
|
||||
kEventResult ret = kEventResult::Available;
|
||||
|
||||
if (current_mouse_capture)
|
||||
return current_mouse_capture->on_event(e);
|
||||
|
||||
kEventResult ret = kEventResult::Available;
|
||||
for (auto it = m_children.rbegin(); it != m_children.rend(); ++it)
|
||||
bool skip_children = false;
|
||||
skip_children |= (e->m_cat == kEventCategory::MouseEvent) &&
|
||||
(m_mouse_captured) && (root()->current_mouse_capture == this) && m_capture_children;
|
||||
|
||||
if (!skip_children)
|
||||
{
|
||||
if ((*it)->on_event(e) == kEventResult::Consumed)
|
||||
for (auto it = m_children.rbegin(); it != m_children.rend(); ++it)
|
||||
{
|
||||
if (m_flood_events)
|
||||
if ((*it)->on_event(e) == kEventResult::Consumed)
|
||||
{
|
||||
ret = kEventResult::Consumed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kEventResult::Consumed;
|
||||
if (m_flood_events)
|
||||
{
|
||||
ret = kEventResult::Consumed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == kEventResult::Consumed)
|
||||
return ret;
|
||||
}
|
||||
if (ret == kEventResult::Consumed)
|
||||
return ret;
|
||||
|
||||
switch (e->m_cat)
|
||||
{
|
||||
case kEventCategory::MouseEvent:
|
||||
@@ -79,6 +89,7 @@ kEventResult Node::on_event(Event* e)
|
||||
m_mouse_inside = inside;
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseScroll:
|
||||
case kEventType::MouseDownL:
|
||||
case kEventType::MouseDownR:
|
||||
case kEventType::MouseUpL:
|
||||
@@ -240,24 +251,39 @@ int Node::get_child_index(Node* n)
|
||||
return -1;
|
||||
}
|
||||
|
||||
glm::vec4 Node::get_children_rect() const
|
||||
{
|
||||
if (m_children.empty())
|
||||
return glm::vec4(0);
|
||||
glm::vec4 ret = m_children[0]->m_clip_uncut;
|
||||
for (auto& c : m_children)
|
||||
ret = rect_union(ret, c->m_clip_uncut);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Node::mouse_capture()
|
||||
{
|
||||
root()->current_mouse_capture = this; m_mouse_captured = true;
|
||||
root()->current_mouse_capture = this;
|
||||
m_mouse_captured = true;
|
||||
}
|
||||
|
||||
void Node::mouse_release()
|
||||
{
|
||||
root()->current_mouse_capture = nullptr; m_mouse_captured = false;
|
||||
if (root()->current_mouse_capture == this)
|
||||
root()->current_mouse_capture = nullptr;
|
||||
m_mouse_captured = false;
|
||||
}
|
||||
|
||||
void Node::key_capture()
|
||||
{
|
||||
root()->current_key_capture = this; m_key_captured = true;
|
||||
root()->current_key_capture = this;
|
||||
m_key_captured = true;
|
||||
}
|
||||
|
||||
void Node::key_release()
|
||||
{
|
||||
root()->current_key_capture = nullptr; m_key_captured = false;
|
||||
root()->current_key_capture = nullptr;
|
||||
m_key_captured = false;
|
||||
}
|
||||
|
||||
Node&& Node::operator=(Node&& o)
|
||||
@@ -335,6 +361,15 @@ void Node::SetPadding(float t, float r, float b, float l)
|
||||
YGNodeStyleSetPadding(y_node, YGEdgeLeft, l);
|
||||
}
|
||||
|
||||
glm::vec4 Node::GetPadding() const
|
||||
{
|
||||
float t = YGNodeLayoutGetPadding(y_node, YGEdgeTop);
|
||||
float r = YGNodeLayoutGetPadding(y_node, YGEdgeRight);
|
||||
float b = YGNodeLayoutGetPadding(y_node, YGEdgeBottom);
|
||||
float l = YGNodeLayoutGetPadding(y_node, YGEdgeLeft);
|
||||
return{ t, r, b, l };
|
||||
}
|
||||
|
||||
void Node::SetPosition(const glm::vec2 pos)
|
||||
{
|
||||
SetPosition(pos.x, pos.y);
|
||||
@@ -414,12 +449,26 @@ glm::vec2 Node::GetSize()
|
||||
return{ GetWidth(), GetHeight() };
|
||||
}
|
||||
|
||||
glm::vec4 Node::rect_intersection(glm::vec4 a, glm::vec4 b)
|
||||
glm::vec4 Node::rect_intersection(glm::vec4 a, glm::vec4 b) const
|
||||
{
|
||||
// convert from [x,y,w,h] to [x1,y1,x2,y1]
|
||||
a = glm::vec4(a.xy(), a.xy() + a.zw());
|
||||
b = glm::vec4(b.xy(), b.xy() + b.zw());
|
||||
// compute intersection
|
||||
auto o = glm::vec4(glm::max(a.xy(), b.xy()), glm::min(a.zw(), b.zw()));
|
||||
// back to rect form
|
||||
o = glm::vec4(o.xy(), glm::max({ 0, 0 }, o.zw() - o.xy()));
|
||||
return o;
|
||||
}
|
||||
|
||||
glm::vec4 Node::rect_union(glm::vec4 a, glm::vec4 b) const
|
||||
{
|
||||
// convert from rect [x,y,w,h] to bb [x1,y1,x2,y1]
|
||||
a = glm::vec4(a.xy(), a.xy() + a.zw());
|
||||
b = glm::vec4(b.xy(), b.xy() + b.zw());
|
||||
// compute union
|
||||
glm::vec4 o = { glm::min(a.xy(), b.xy()), glm::max(a.zw(), b.zw()) };
|
||||
// back to rect form
|
||||
o = glm::vec4(o.xy(), glm::max({ 0, 0 }, o.zw() - o.xy()));
|
||||
return o;
|
||||
}
|
||||
@@ -459,7 +508,9 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
|
||||
float w = YGNodeLayoutGetWidth(y_node);
|
||||
float h = YGNodeLayoutGetHeight(y_node);
|
||||
auto old_size = m_size;
|
||||
m_pos = glm::floor(origin + glm::vec2(x, y));
|
||||
glm::vec2 parent_offset = parent ? parent->m_pos_offset_childred : glm::vec2(0.f);
|
||||
m_pos = glm::floor(origin + glm::vec2(x, y) + m_pos_offset + parent_offset);
|
||||
m_pos_origin = glm::floor(origin + glm::vec2(x, y));
|
||||
m_size = glm::floor(glm::vec2(w, h));
|
||||
|
||||
if (parent)
|
||||
@@ -478,7 +529,7 @@ void Node::update_internal(const glm::vec2& origin, const glm::mat4& proj)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clip = glm::vec4(m_pos, m_size);
|
||||
m_clip_uncut = m_clip = glm::vec4(m_pos, m_size);
|
||||
}
|
||||
|
||||
glm::mat4 pivot = glm::translate(glm::vec3(.5f, .5f, 0.f));
|
||||
@@ -726,6 +777,7 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
||||
CASE(kWidget::ColorQuad, NodeColorQuad);
|
||||
CASE(kWidget::StrokePreview, NodeStrokePreview);
|
||||
CASE(kWidget::Canvas, NodeCanvas);
|
||||
CASE(kWidget::Scroll, NodeScroll);
|
||||
#undef CASE
|
||||
case kWidget::Ref:
|
||||
{
|
||||
|
||||
@@ -67,6 +67,7 @@ enum class kWidget : uint16_t
|
||||
ColorQuad = const_hash("color-quad"),
|
||||
StrokePreview = const_hash("stroke-preview"),
|
||||
Canvas = const_hash("canvas"),
|
||||
Scroll = const_hash("scroll"),
|
||||
};
|
||||
|
||||
class Node
|
||||
@@ -88,12 +89,16 @@ public:
|
||||
glm::mat4 m_mvp;
|
||||
bool m_mouse_inside = false;
|
||||
bool m_flood_events = false;
|
||||
bool m_capture_children = true; // wether to capture children events when xx_capture() is used
|
||||
bool m_destroyed = false;
|
||||
|
||||
bool m_mouse_ignore = true;
|
||||
float m_zoom = 1.f;
|
||||
glm::vec2 m_scale{ 1.f };
|
||||
glm::vec2 m_pos;
|
||||
glm::vec2 m_pos_origin; // original layout position without offset
|
||||
glm::vec2 m_pos_offset; // artificial position offset for scrolling
|
||||
glm::vec2 m_pos_offset_childred; // artificial position offset for scrolling
|
||||
glm::vec2 m_size;
|
||||
glm::vec4 m_clip;
|
||||
glm::vec4 m_clip_uncut;
|
||||
@@ -114,6 +119,7 @@ public:
|
||||
void SetSize(float w, float h);
|
||||
|
||||
void SetPadding(float t, float r, float b, float l);
|
||||
glm::vec4 GetPadding() const;
|
||||
void SetPosition(float l, float t, float r, float b);
|
||||
void SetPosition(float l, float t);
|
||||
void SetPosition(const glm::vec2 pos);
|
||||
@@ -132,7 +138,8 @@ public:
|
||||
float GetHeight();
|
||||
glm::vec2 GetSize();
|
||||
|
||||
glm::vec4 rect_intersection(glm::vec4 a, glm::vec4 b);
|
||||
glm::vec4 rect_intersection(glm::vec4 a, glm::vec4 b) const;
|
||||
glm::vec4 rect_union(glm::vec4 a, glm::vec4 b) const;
|
||||
|
||||
virtual void restore_context();;
|
||||
virtual void clear_context();
|
||||
@@ -177,6 +184,7 @@ public:
|
||||
void move_child(Node* n, int index);
|
||||
void move_child_offset(Node* n, int offset);
|
||||
int get_child_index(Node* n);
|
||||
glm::vec4 get_children_rect() const;
|
||||
void mouse_capture();
|
||||
void mouse_release();
|
||||
void key_capture();
|
||||
|
||||
@@ -46,11 +46,16 @@ kEventResult NodeButtonCustom::handle_event(Event* e)
|
||||
break;
|
||||
case kEventType::MouseDownL:
|
||||
m_color = color_down;
|
||||
mouse_capture();
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
m_color = m_mouse_inside ? color_hover : color_normal;
|
||||
if (m_mouse_inside && on_click != nullptr)
|
||||
on_click(this);
|
||||
mouse_release();
|
||||
break;
|
||||
case kEventType::MouseCancel:
|
||||
mouse_release();
|
||||
break;
|
||||
default:
|
||||
return kEventResult::Available;
|
||||
|
||||
@@ -162,12 +162,12 @@ kEventResult NodeCanvas::handle_event(Event* e)
|
||||
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseScroll:
|
||||
case kEventType::MouseDownL:
|
||||
case kEventType::MouseUpL:
|
||||
case kEventType::MouseDownR:
|
||||
case kEventType::MouseUpR:
|
||||
case kEventType::MouseMove:
|
||||
case kEventType::MouseScroll:
|
||||
case kEventType::MouseCancel:
|
||||
for (auto& mode : *m_canvas->m_mode)
|
||||
mode->on_MouseEvent(me, loc);
|
||||
|
||||
@@ -15,6 +15,7 @@ void NodePopupMenu::init()
|
||||
SetHeight(400);
|
||||
SetPositioning(YGPositionTypeAbsolute);
|
||||
m_mouse_ignore = false;
|
||||
m_capture_children = false;
|
||||
}
|
||||
|
||||
kEventResult NodePopupMenu::handle_event(Event* e)
|
||||
|
||||
50
engine/node_scroll.cpp
Normal file
50
engine/node_scroll.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "pch.h"
|
||||
#include "log.h"
|
||||
#include "node_scroll.h"
|
||||
#include "event.h"
|
||||
|
||||
Node* NodeScroll::clone_instantiate() const
|
||||
{
|
||||
return new NodeScroll;
|
||||
}
|
||||
|
||||
kEventResult NodeScroll::handle_event(Event* e)
|
||||
{
|
||||
NodeBorder::handle_event(e);
|
||||
auto me = static_cast<MouseEvent*>(e);
|
||||
auto loc = (me->m_pos - m_pos) * root()->m_zoom;
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
m_dragging = true;
|
||||
m_drag_start = me->m_pos;
|
||||
m_offset_start = m_offset;
|
||||
mouse_capture();
|
||||
break;
|
||||
case kEventType::MouseMove:
|
||||
if (m_dragging)
|
||||
{
|
||||
auto pad = GetPadding();
|
||||
glm::vec2 padoff = { pad.y + pad.w, pad.x + pad.z };
|
||||
auto rect = get_children_rect();
|
||||
m_offset = m_offset_start + (me->m_pos - m_drag_start) * m_mask;
|
||||
m_offset = glm::clamp(m_offset, -rect.zw() + m_clip_uncut.zw() - padoff, { 0, 0 });
|
||||
m_pos_offset_childred = m_offset;
|
||||
}
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
mouse_release();
|
||||
m_dragging = false;
|
||||
break;
|
||||
// case kEventType::MouseScroll:
|
||||
// break;
|
||||
case kEventType::MouseCancel:
|
||||
mouse_release();
|
||||
m_dragging = false;
|
||||
break;
|
||||
default:
|
||||
return kEventResult::Available;
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
14
engine/node_scroll.h
Normal file
14
engine/node_scroll.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "node_border.h"
|
||||
|
||||
class NodeScroll : public NodeBorder
|
||||
{
|
||||
bool m_dragging = false;
|
||||
glm::vec2 m_drag_start;
|
||||
glm::vec2 m_offset_start;
|
||||
glm::vec2 m_offset;
|
||||
glm::vec2 m_mask{ 0, 1 };
|
||||
public:
|
||||
virtual Node* clone_instantiate() const override;
|
||||
virtual kEventResult handle_event(Event* e) override;
|
||||
};
|
||||
Reference in New Issue
Block a user