From 8e5a8eec1bbe5940f51b6239a3a9af8cfd0d30d7 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Fri, 1 Feb 2019 22:51:25 +0100 Subject: [PATCH] refactor canvas modes --- src/app.cpp | 30 ++-- src/app_layout.cpp | 86 ++++------ src/app_vr.cpp | 10 +- src/canvas.cpp | 22 +-- src/canvas.h | 9 +- src/canvas_modes.cpp | 329 ++++++++++++++++++++----------------- src/canvas_modes.h | 41 +++-- src/node_button.cpp | 17 +- src/node_button.h | 3 + src/node_button_custom.cpp | 20 ++- src/node_button_custom.h | 3 + src/node_canvas.cpp | 28 ++-- 12 files changed, 326 insertions(+), 272 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 4ad1d87..9d44cc5 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -475,18 +475,26 @@ void App::update(float dt) } } - static glm::vec4 color_button_normal{.1, .1, .1, 1}; - static glm::vec4 color_button_hlight{ 1, .0, .0, 1}; - CanvasModePen* mode = (CanvasModePen*)canvas->m_canvas->modes[(int)Canvas::kCanvasMode::Draw][0]; - layout[main_id]->find("btn-pick")->set_color( - mode->m_picking ? color_button_hlight : color_button_normal); - layout[main_id]->find("btn-pen")->set_color( - canvas->m_canvas->m_current_mode == Canvas::kCanvasMode::Draw ? color_button_hlight : color_button_normal); - layout[main_id]->find("btn-erase")->set_color( - canvas->m_canvas->m_current_mode == Canvas::kCanvasMode::Erase ? color_button_hlight : color_button_normal); - layout[main_id]->find("btn-touchlock")->set_color( - canvas->m_canvas->m_touch_lock ? color_button_hlight : color_button_normal); + { + static glm::vec4 color_button_normal{ .1, .1, .1, 1 }; + static glm::vec4 color_button_hlight{ 1, .0, .0, 1 }; + auto mode = Canvas::I->m_current_mode; + + CanvasModePen* pm = (CanvasModePen*)canvas->m_canvas->modes[(int)kCanvasMode::Draw][0]; + layout[main_id]->find("btn-pick")->set_active(mode == kCanvasMode::Draw && pm->m_picking); + layout[main_id]->find("btn-touchlock")->set_active(canvas->m_canvas->m_touch_lock); + + layout[main_id]->find("btn-pen")->set_active(mode == kCanvasMode::Draw); + layout[main_id]->find("btn-erase")->set_active(mode == kCanvasMode::Erase); + layout[main_id]->find("btn-cam")->set_active(mode == kCanvasMode::Camera); + layout[main_id]->find("btn-line")->set_active(mode == kCanvasMode::Line); + layout[main_id]->find("btn-grid")->set_active(mode == kCanvasMode::Grid); + layout[main_id]->find("btn-copy")->set_active(mode == kCanvasMode::Copy); + layout[main_id]->find("btn-cut")->set_active(mode == kCanvasMode::Cut); + layout[main_id]->find("btn-mask-free")->set_active(mode == kCanvasMode::MaskFree); + layout[main_id]->find("btn-mask-line")->set_active(mode == kCanvasMode::MaskLine); + } auto observer = [this](Node* n) { diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 920a286..c68468c 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -6,9 +6,6 @@ #include "node_progress_bar.h" #include "node_dialog_picker.h" -static glm::vec4 color_button_normal{ .1, .1, .1, 1 }; -static glm::vec4 color_button_hlight{ 1, .0, .0, 1 }; - void App::title_update() { static char str[256]; @@ -126,21 +123,8 @@ void App::init_sidebar() grid = find_or_create_panel(panels); //presets = find_or_create_panel(panels); -// if (canvas) -// { -// Canvas::I->m_current_brush->m_tip_color = color->m_color; -// stroke->m_canvas->draw_stroke(); -// } - - //presets->on_brush_changed = [this](Node* target, std::shared_ptr& b) { - // // don't change some params - // b->m_tip_size = Canvas::I->m_current_brush->m_tip_size; - // b->m_tip_color = Canvas::I->m_current_brush->m_tip_color; - // *Canvas::I->m_current_brush = *b; - // stroke->m_preview->draw_stroke(); - // stroke->m_brush_thumb->set_image(b->m_brush_thumb_path); - // stroke->update_controls(); - //}; + canvas->m_canvas->on_mode_changed = [this](kCanvasMode prev, kCanvasMode mode) { + }; color->on_color_changed = [this](Node* target, glm::vec4 color) { Canvas::I->m_current_brush->m_tip_color = color; }; @@ -226,7 +210,7 @@ void App::init_sidebar() button->on_click = [this, button](Node*) { panels->get_child_index(stroke.get()) == -1 ? panels->add_child(stroke) : panels->remove_child(stroke.get()); panels->fix_scroll(); - button->set_color(panels->get_child_index(stroke.get()) == -1 ? color_button_normal : color_button_hlight); + button->set_active(panels->get_child_index(stroke.get()) == -1); }; } //if (auto* button = layout[main_id]->find("btn-brush")) @@ -250,7 +234,7 @@ void App::init_sidebar() button->on_click = [this, button](Node*) { panels->get_child_index(color.get()) == -1 ? panels->add_child(color) : panels->remove_child(color.get()); panels->fix_scroll(); - button->set_color(panels->get_child_index(color.get()) == -1 ? color_button_normal : color_button_hlight); + button->set_active(panels->get_child_index(color.get()) == -1); // auto pick = layout[main_id]->add_child(); // pick->m_color_cur->m_color = Canvas::I->m_current_brush->m_tip_color; }; @@ -260,7 +244,7 @@ void App::init_sidebar() button->on_click = [this, button](Node*) { panels->get_child_index(layers.get()) == -1 ? panels->add_child(layers) : panels->remove_child(layers.get()); panels->fix_scroll(); - button->set_color(panels->get_child_index(layers.get()) == -1 ? color_button_normal : color_button_hlight); + button->set_active(panels->get_child_index(layers.get()) == -1); }; } if (auto* button = layout[main_id]->find("btn-grids-panel")) @@ -268,23 +252,23 @@ void App::init_sidebar() button->on_click = [this, button](Node*) { panels->get_child_index(grid.get()) == -1 ? panels->add_child(grid) : panels->remove_child(grid.get()); panels->fix_scroll(); - button->set_color(panels->get_child_index(grid.get()) == -1 ? color_button_normal : color_button_hlight); + button->set_active(panels->get_child_index(grid.get()) == -1); }; } } template void select_button(Node* main, T* button) { - main->find("btn-pen")->set_color(color_button_normal); - main->find("btn-erase")->set_color(color_button_normal); - main->find("btn-line")->set_color(color_button_normal); - main->find("btn-cam")->set_color(color_button_normal); - main->find("btn-grid")->set_color(color_button_normal); - main->find("btn-copy")->set_color(color_button_normal); - main->find("btn-cut")->set_color(color_button_normal); + main->find("btn-pen")->set_active(false); + main->find("btn-erase")->set_active(false); + main->find("btn-line")->set_active(false); + main->find("btn-cam")->set_active(false); + main->find("btn-grid")->set_active(false); + main->find("btn-copy")->set_active(false); + main->find("btn-cut")->set_active(false); //main->find("btn-fill")->set_color(color_button_normal); - main->find("btn-mask-free")->set_color(color_button_normal); - main->find("btn-mask-line")->set_color(color_button_normal); - button->set_color(color_button_hlight); + main->find("btn-mask-free")->set_active(false); + main->find("btn-mask-line")->set_active(false); + button->set_active(false); }; void App::init_toolbar_draw() @@ -293,16 +277,16 @@ void App::init_toolbar_draw() { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::Draw); + Canvas::set_mode(kCanvasMode::Draw); }; - button->set_color(color_button_hlight); - Canvas::set_mode(Canvas::kCanvasMode::Draw); + //button->set_active(true); + Canvas::set_mode(kCanvasMode::Draw); } if (auto* button = layout[main_id]->find("btn-pick")) { button->on_click = [this](Node*) { - CanvasModePen* mode = (CanvasModePen*)canvas->m_canvas->modes[(int)Canvas::kCanvasMode::Draw][0]; - if (mode && canvas->m_canvas->m_current_mode == Canvas::kCanvasMode::Draw) + CanvasModePen* mode = (CanvasModePen*)canvas->m_canvas->modes[(int)kCanvasMode::Draw][0]; + if (mode && canvas->m_canvas->m_current_mode == kCanvasMode::Draw) { mode->m_picking = !mode->m_picking; } @@ -318,67 +302,67 @@ void App::init_toolbar_draw() { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::Erase); + Canvas::set_mode(kCanvasMode::Erase); }; } if (auto* button = layout[main_id]->find("btn-line")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::Line); + Canvas::set_mode(kCanvasMode::Line); }; } if (auto* button = layout[main_id]->find("btn-cam")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::Camera); + Canvas::set_mode(kCanvasMode::Camera); }; } if (auto* button = layout[main_id]->find("btn-grid")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::Grid); + Canvas::set_mode(kCanvasMode::Grid); }; } if (auto* button = layout[main_id]->find("btn-copy")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - auto m = static_cast(canvas->m_canvas->modes[(int)Canvas::kCanvasMode::Transform][0]); + auto m = static_cast(canvas->m_canvas->modes[(int)kCanvasMode::Copy][0]); m->m_action = CanvasModeTransform::ActionType::Copy; - Canvas::set_mode(Canvas::kCanvasMode::Transform); + Canvas::set_mode(kCanvasMode::Copy); }; } if (auto* button = layout[main_id]->find("btn-cut")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - auto m = static_cast(canvas->m_canvas->modes[(int)Canvas::kCanvasMode::Transform][0]); + auto m = static_cast(canvas->m_canvas->modes[(int)kCanvasMode::Cut][0]); m->m_action = CanvasModeTransform::ActionType::Cut; - Canvas::set_mode(Canvas::kCanvasMode::Transform); + Canvas::set_mode(kCanvasMode::Cut); }; } if (auto* button = layout[main_id]->find("btn-fill")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::Fill); + Canvas::set_mode(kCanvasMode::Fill); }; } if (auto* button = layout[main_id]->find("btn-mask-free")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::MaskFree); + Canvas::set_mode(kCanvasMode::MaskFree); }; } if (auto* button = layout[main_id]->find("btn-mask-line")) { button->on_click = [this, button](Node*) { select_button(layout[main_id], button); - Canvas::set_mode(Canvas::kCanvasMode::MaskLine); + Canvas::set_mode(kCanvasMode::MaskLine); }; } if (auto* button = layout[main_id]->find("btn-bucket")) @@ -426,10 +410,10 @@ void App::init_menu_file() } else { - auto m = static_cast(canvas->m_canvas->modes[(int)Canvas::kCanvasMode::Transform][0]); + auto m = static_cast(canvas->m_canvas->modes[(int)kCanvasMode::Import][0]); m->m_action = CanvasModeTransform::ActionType::Import; m->m_source_image = std::move(img); - Canvas::set_mode(Canvas::kCanvasMode::Transform); + Canvas::set_mode(kCanvasMode::Import); } async_redraw(); async_end(); @@ -701,7 +685,7 @@ void App::init_menu_layer() popup->m_flood_events = true; popup->m_capture_children = false; popup->find("clear-grids")->on_click = [this](Node*) { - CanvasModeGrid* mode = (CanvasModeGrid*)Canvas::modes[(int)Canvas::kCanvasMode::Grid][0]; + CanvasModeGrid* mode = (CanvasModeGrid*)Canvas::modes[(int)kCanvasMode::Grid][0]; mode->clear(); popup->mouse_release(); popup->destroy(); diff --git a/src/app_vr.cpp b/src/app_vr.cpp index 110639e..f6de2f7 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -58,7 +58,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat canvas->m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); - if (canvas->m_canvas->m_state == Canvas::kCanvasMode::Erase && canvas->m_canvas->m_show_tmp && canvas->m_canvas->m_current_layer_idx == layer_index) + if (canvas->m_canvas->m_current_mode == kCanvasMode::Erase && canvas->m_canvas->m_show_tmp && canvas->m_canvas->m_current_layer_idx == layer_index) { sampler.bind(0); ShaderManager::use(kShader::CompErase); @@ -267,13 +267,13 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat glDisable(GL_DEPTH_TEST); if (m_canvas->m_smask_active) { - m_canvas->modes[(int)Canvas::kCanvasMode::MaskFree][0]->on_Draw(ortho_proj, proj, camera); - m_canvas->modes[(int)Canvas::kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera); + m_canvas->modes[(int)kCanvasMode::MaskFree][0]->on_Draw(ortho_proj, proj, camera); + m_canvas->modes[(int)kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera); } // keep drawing the grids - if (m_canvas->m_state != Canvas::kCanvasMode::Grid) - for (auto& mode : Canvas::modes[(int)Canvas::kCanvasMode::Grid]) + if (m_canvas->m_state != kCanvasMode::Grid) + for (auto& mode : Canvas::modes[(int)kCanvasMode::Grid]) mode->on_Draw(ortho_proj, proj, camera); */ diff --git a/src/canvas.cpp b/src/canvas.cpp index fc1ac5b..faa1a1a 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -14,15 +14,17 @@ Canvas* Canvas::I; std::vector Canvas::modes[] = { - { new CanvasModePen, new CanvasModeBasicCamera }, - { new CanvasModePen, new CanvasModeBasicCamera }, - { new CanvasModeLine, new CanvasModeBasicCamera }, - { new CanvasModeCamera, new CanvasModeBasicCamera }, - { new CanvasModeGrid, new CanvasModeBasicCamera }, - { new CanvasModeTransform, new CanvasModeBasicCamera }, - { new CanvasModeFill, new CanvasModeBasicCamera }, - { new CanvasModeMaskFree, new CanvasModeBasicCamera }, - { new CanvasModeMaskLine, new CanvasModeBasicCamera }, + { new CanvasModePen, new CanvasModeBasicCamera }, // brush + { new CanvasModePen, new CanvasModeBasicCamera }, // eraser + { new CanvasModeLine, new CanvasModeBasicCamera }, // line + { new CanvasModeCamera, new CanvasModeBasicCamera }, // parallax + { new CanvasModeGrid, new CanvasModeBasicCamera }, // grids + { new CanvasModeTransform, new CanvasModeBasicCamera }, // import + { new CanvasModeTransform, new CanvasModeBasicCamera }, // cut + { new CanvasModeTransform, new CanvasModeBasicCamera }, // copy + { new CanvasModeFill, new CanvasModeBasicCamera }, // fill + { new CanvasModeMaskFree, new CanvasModeBasicCamera }, // mask-free + { new CanvasModeMaskLine, new CanvasModeBasicCamera }, // mask-poly }; glm::vec3 Canvas::m_plane_origin[6] = { { 0, 0,-1}, // front @@ -800,7 +802,7 @@ void Canvas::stroke_commit() m_sampler_bg.bind(1); m_sampler_mask.bind(2); m_sampler_stencil.bind(3); - if (m_state == kCanvasMode::Erase) + if (m_current_mode == kCanvasMode::Erase) { ShaderManager::use(kShader::CompErase); ShaderManager::u_int(kShaderUniform::Tex, 0); diff --git a/src/canvas.h b/src/canvas.h index 0f296cd..096cbf6 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -193,22 +193,23 @@ public: std::shared_ptr m_current_brush; - enum class kCanvasMode { Draw, Erase, Line, Camera, Grid, Transform, Fill, MaskFree, MaskLine, COUNT }; - kCanvasMode m_state{ kCanvasMode::Draw }; static std::vector modes[]; std::vector* m_mode = nullptr; kCanvasMode m_current_mode = kCanvasMode::Draw; + std::function on_mode_changed; static void set_mode(kCanvasMode mode) { + auto prev = I->m_current_mode; if (I->m_mode) for (auto& m : *I->m_mode) m->leave(); I->m_mode = &modes[(int)mode]; - I->m_state = mode; I->m_current_mode = mode; if (I->m_mode) for (auto& m : *I->m_mode) - m->enter(); + m->enter(prev); + if (I->on_mode_changed) + I->on_mode_changed(prev, mode); } std::vector m_layers_snapshot; diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index 9bac5a5..210c30e 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -9,23 +9,22 @@ #include "util.h" NodeCanvas* CanvasMode::node; -Canvas* CanvasMode::canvas; void CanvasModeBasicCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { switch (me->m_type) { case kEventType::MouseDownL: -// if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) +// if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) // { // m_draggingR = true; // m_dragR_start = me->m_pos; -// m_pan_start = canvas->m_pan; +// m_pan_start = Canvas::I->m_pan; // node->mouse_capture(); // } break; case kEventType::MouseUpL: -// if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) +// if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) // { // m_draggingR = false; // node->mouse_release(); @@ -37,8 +36,8 @@ void CanvasModeBasicCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_zooming = App::I.keys[(int)kKey::KeyCtrl]; m_draggingR = true; m_dragR_start = me->m_pos; - m_pan_start = canvas->m_pan; - m_fov_start = canvas->m_cam_fov; + m_pan_start = Canvas::I->m_pan; + m_fov_start = Canvas::I->m_cam_fov; node->mouse_capture(); break; case kEventType::MouseUpR: @@ -50,20 +49,20 @@ void CanvasModeBasicCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { if (m_zooming) { - canvas->m_cam_fov = m_fov_start - (me->m_pos.x - m_dragR_start.x) * 0.05f; + Canvas::I->m_cam_fov = m_fov_start - (me->m_pos.x - m_dragR_start.x) * 0.05f; } else { auto dir = (App::I.has_vr && App::I.vr_active) ? glm::vec2(1, 1) : glm::vec2(-1, -1); - canvas->m_pan = m_pan_start + (me->m_pos - m_dragR_start) * dir * (canvas->m_cam_fov / 85.f); - auto angle = canvas->m_pan * 0.003f; - canvas->m_cam_rot = glm::eulerAngleXY(angle.y, angle.x); + Canvas::I->m_pan = m_pan_start + (me->m_pos - m_dragR_start) * dir * (Canvas::I->m_cam_fov / 85.f); + auto angle = Canvas::I->m_pan * 0.003f; + Canvas::I->m_cam_rot = glm::eulerAngleXY(angle.y, angle.x); } } break; case kEventType::MouseScroll: m_zoom_canvas += me->m_scroll_delta * 0.1f; - canvas->m_cam_fov -= me->m_scroll_delta * 2.0f; + Canvas::I->m_cam_fov -= me->m_scroll_delta * 2.0f; App::I.brush_update(); break; case kEventType::MouseCancel: @@ -80,15 +79,15 @@ void CanvasModeBasicCamera::on_GestureEvent(GestureEvent* ge) switch (ge->m_type) { case kEventType::GestureStart: - m_pan_start = canvas->m_pan; + m_pan_start = Canvas::I->m_pan; m_zoom_start = m_zoom_canvas; - m_camera_fov = canvas->m_cam_fov; + m_camera_fov = Canvas::I->m_cam_fov; break; case kEventType::GestureMove: - canvas->m_pan = m_pan_start + ge->m_pos_delta * glm::vec2(-1, -1) * 0.3f * (canvas->m_cam_fov / 85.f); - canvas->m_cam_fov = m_camera_fov - ge->m_distance_delta * .05f; - auto angle = canvas->m_pan * 0.003f; - canvas->m_cam_rot = glm::eulerAngleXY(angle.y, angle.x); + Canvas::I->m_pan = m_pan_start + ge->m_pos_delta * glm::vec2(-1, -1) * 0.3f * (Canvas::I->m_cam_fov / 85.f); + Canvas::I->m_cam_fov = m_camera_fov - ge->m_distance_delta * .05f; + auto angle = Canvas::I->m_pan * 0.003f; + Canvas::I->m_cam_rot = glm::eulerAngleXY(angle.y, angle.x); App::I.brush_update(); break; } @@ -109,7 +108,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_draw_tip = (me->m_source == kEventSource::Mouse || me->m_source == kEventSource::Stylus); #endif // _WIN32 - if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) @@ -118,14 +117,14 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) if (App::I.keys[(int)kKey::KeyAlt] || m_picking) { m_picking = true; - canvas->pick_start(); - glm::vec4 pix = canvas->pick_get(loc); - canvas->m_current_brush->m_tip_color = pix; + Canvas::I->pick_start(); + glm::vec4 pix = Canvas::I->pick_get(loc); + Canvas::I->m_current_brush->m_tip_color = pix; App::I.color->set_color(pix); } else { - canvas->stroke_start({ loc, 0 }, me->m_pressure, canvas->m_current_brush); + Canvas::I->stroke_start({ loc, 0 }, me->m_pressure, Canvas::I->m_current_brush); } m_dragging = true; node->mouse_capture(); @@ -134,15 +133,15 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) if (m_dragging && !m_picking) { node->mouse_release(); - canvas->stroke_end(); + Canvas::I->stroke_end(); } if (m_dragging && m_picking) { node->mouse_release(); - glm::vec4 pix = canvas->pick_get(loc); - canvas->m_current_brush->m_tip_color = pix; + glm::vec4 pix = Canvas::I->pick_get(loc); + Canvas::I->m_current_brush->m_tip_color = pix; App::I.color->set_color(pix); - canvas->pick_end(); + Canvas::I->pick_end(); } m_dragging = false; m_picking = false; @@ -153,7 +152,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_resizing = true; m_dragging = true; m_size_pos_start = m_cur_pos; - m_size_value_start = canvas->m_current_brush->m_tip_size; + m_size_value_start = Canvas::I->m_current_brush->m_tip_size; node->mouse_capture(); } break; @@ -167,17 +166,17 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) break; case kEventType::MouseMove: if (m_dragging && !m_picking && !m_resizing) - canvas->stroke_update({ loc, 0 }, me->m_pressure); + Canvas::I->stroke_update({ loc, 0 }, me->m_pressure); if (m_dragging && m_picking) { - glm::vec4 pix = canvas->pick_get(loc); - canvas->m_current_brush->m_tip_color = pix; + glm::vec4 pix = Canvas::I->pick_get(loc); + Canvas::I->m_current_brush->m_tip_color = pix; App::I.color->set_color(pix); } if (m_dragging && m_resizing) { auto diff = m_cur_pos - m_size_pos_start; - canvas->m_current_brush->m_tip_size = glm::max(m_size_value_start + diff.x * 0.001f, 0.001f); + Canvas::I->m_current_brush->m_tip_size = glm::max(m_size_value_start + diff.x * 0.001f, 0.001f); if (App::I.stroke) App::I.stroke->update_controls(); } @@ -186,7 +185,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) case kEventType::MouseCancel: if (m_dragging) { - canvas->stroke_cancel(); + Canvas::I->stroke_cancel(); m_dragging = false; node->mouse_release(); } @@ -206,17 +205,17 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const { auto pos = m_resizing ? m_size_pos_start : m_cur_pos; if (App::I.keys[(int)kKey::KeyAlt] && !m_resizing) - pos.x = pos.x - canvas->m_current_brush->m_tip_size * 500.f; + pos.x = pos.x - Canvas::I->m_current_brush->m_tip_size * 500.f; ShaderManager::use(kShader::StrokePreview); ShaderManager::u_int(kShaderUniform::Tex, 0); float tip_scale_fix = 1.f / glm::tan(glm::radians(Canvas::I->m_cam_fov * 0.5f)); - float tip_scale = canvas->m_current_brush->m_tip_size * 800.f * tip_scale_fix; - float tip_angle = canvas->m_current_brush->m_tip_angle * (float)(M_PI * 2.0); + float tip_scale = Canvas::I->m_current_brush->m_tip_size * 800.f * tip_scale_fix; + float tip_angle = Canvas::I->m_current_brush->m_tip_angle * (float)(M_PI * 2.0); glm::vec2 tip_offset = glm::vec2(0); - auto tip_color = glm::vec4(glm::vec3(canvas->m_current_brush->m_tip_color), 1); - if (canvas->m_current_stroke) + auto tip_color = glm::vec4(glm::vec3(Canvas::I->m_current_brush->m_tip_color), 1); + if (Canvas::I->m_current_stroke) { - const auto& s = canvas->m_current_stroke->m_prev_sample; + const auto& s = Canvas::I->m_current_stroke->m_prev_sample; if (s.size > 0.f) { tip_scale = s.size; @@ -236,10 +235,10 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const bool blend = glIsEnabled(GL_BLEND); glEnable(GL_BLEND); glActiveTexture(GL_TEXTURE0); - auto& tex = *canvas->m_current_brush->m_tip_texture; + auto& tex = *Canvas::I->m_current_brush->m_tip_texture; tex.bind(); - canvas->m_sampler_brush.bind(0); - canvas->m_plane.draw_fill(); + Canvas::I->m_sampler_brush.bind(0); + Canvas::I->m_plane.draw_fill(); tex.unbind(); if (!blend) glDisable(GL_BLEND); } @@ -247,20 +246,20 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const void CanvasModePen::leave() { - *m_brush = *canvas->m_current_brush; + *m_brush = *Canvas::I->m_current_brush; } -void CanvasModePen::enter() +void CanvasModePen::enter(kCanvasMode prev) { m_cur_pos = Canvas::I->m_cur_pos; if (m_brush) { - *canvas->m_current_brush = *m_brush; + *Canvas::I->m_current_brush = *m_brush; App::I.brush_update(); } else { - m_brush = std::make_shared(*canvas->m_current_brush); + m_brush = std::make_shared(*Canvas::I->m_current_brush); } } @@ -268,7 +267,7 @@ void CanvasModePen::enter() void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { - if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { @@ -282,9 +281,9 @@ void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) node->mouse_release(); if (m_dragging) { - canvas->stroke_start({ m_drag_start, 0 }, 1.f, canvas->m_current_brush); - canvas->stroke_update({ m_drag_pos, 0 }, 1.f); - canvas->stroke_end(); + Canvas::I->stroke_start({ m_drag_start, 0 }, 1.f, Canvas::I->m_current_brush); + Canvas::I->stroke_update({ m_drag_pos, 0 }, 1.f); + Canvas::I->stroke_end(); } m_dragging = false; break; @@ -307,12 +306,12 @@ void CanvasModeLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, cons { ShaderManager::use(kShader::Color); ShaderManager::u_mat4(kShaderUniform::MVP, ortho); - ShaderManager::u_vec4(kShaderUniform::Col, canvas->m_current_brush->m_tip_color); + ShaderManager::u_vec4(kShaderUniform::Col, Canvas::I->m_current_brush->m_tip_color); static glm::vec4 AB[2]; AB[0] = { m_drag_start, 0, 1 }; AB[1] = { m_drag_pos, 0, 1 }; - AB[0].y = canvas->m_box.w - AB[0].y - 1; // invert Y - AB[1].y = canvas->m_box.w - AB[1].y - 1; // invert Y + AB[0].y = Canvas::I->m_box.w - AB[0].y - 1; // invert Y + AB[1].y = Canvas::I->m_box.w - AB[1].y - 1; // invert Y m_line.update_vertices(AB); m_line.draw_stroke(); } @@ -327,27 +326,27 @@ void CanvasModeLine::init() void CanvasModeCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { - if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { case kEventType::MouseDownR: - canvas->m_cam_pos = { 0, 0, 0 }; + Canvas::I->m_cam_pos = { 0, 0, 0 }; break; case kEventType::MouseDownL: m_dragging = true; m_drag_start = me->m_pos; - m_pos_start = xy(canvas->m_cam_pos); + m_pos_start = xy(Canvas::I->m_cam_pos); node->mouse_capture(); break; case kEventType::MouseUpL: m_dragging = false; node->mouse_release(); - canvas->m_cam_pos = { 0, 0, 0 }; + Canvas::I->m_cam_pos = { 0, 0, 0 }; break; case kEventType::MouseMove: if (m_dragging) - canvas->m_cam_pos = glm::vec3(m_pos_start + (me->m_pos - m_drag_start) * glm::vec2(1, -1) * 0.001f, canvas->m_cam_pos.z); + Canvas::I->m_cam_pos = glm::vec3(m_pos_start + (me->m_pos - m_drag_start) * glm::vec2(1, -1) * 0.001f, Canvas::I->m_cam_pos.z); break; case kEventType::MouseCancel: m_dragging = false; @@ -362,7 +361,7 @@ void CanvasModeCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) void CanvasModeGrid::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { - if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { @@ -371,7 +370,7 @@ void CanvasModeGrid::on_MouseEvent(MouseEvent* me, glm::vec2& loc) node->mouse_capture(); glm::vec3 ro, rd, hit_o, hit_d; glm::vec2 fb_pos; - if (canvas->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, m_plane_id)) + if (Canvas::I->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, m_plane_id)) { m_lines.push_back({ hit_o, hit_d }); origin = hit_o; @@ -389,7 +388,7 @@ void CanvasModeGrid::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { glm::vec3 ro, rd, hit_o, hit_d; glm::vec2 hit_fb; - if (m_dragging && canvas->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, m_plane_id)) + if (m_dragging && Canvas::I->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, m_plane_id)) { m_lines.back() = { hit_o, hit_d }; origin = hit_o; @@ -444,7 +443,7 @@ void CanvasModeGrid::commit() m_line.update_vertices(AB); m_line.draw_stroke(); }; - canvas->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2)); + Canvas::I->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2)); } void CanvasModeGrid::clear() @@ -461,7 +460,7 @@ void CanvasModeMaskFree::init() void CanvasModeMaskFree::leave() { -// canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(1), std::placeholders::_1, std::placeholders::_2)); +// Canvas::I->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(1), std::placeholders::_1, std::placeholders::_2)); // m_points.clear(); } @@ -477,7 +476,7 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc) static glm::vec2 oldpos; static glm::vec2 oldvec; static float acc = 0.f; - if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { @@ -496,8 +495,8 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_points2d.push_back(loc); m_points.push_back(vert); m_points.push_back(vert); - canvas->m_smask.clear({0, 0, 0, 0}); - canvas->m_smask_active = true; + Canvas::I->m_smask.clear({0, 0, 0, 0}); + Canvas::I->m_smask_active = true; break; } case kEventType::MouseUpL: @@ -507,8 +506,8 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { if (!m_points.empty()) { - m_selection_cam = canvas->get_camera(); - //m_points2d = poly_intersect(poly_remove_duplicate(m_points2d), canvas->face_to_shape2D(0)); + m_selection_cam = Canvas::I->get_camera(); + //m_points2d = poly_intersect(poly_remove_duplicate(m_points2d), Canvas::I->face_to_shape2D(0)); auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) { //glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); @@ -518,21 +517,21 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_shape.draw_fill(); }; // use m_shape to render the mask polygon - auto v = canvas->triangulate(poly_remove_duplicate(m_points2d)); - canvas->project2Dpoints(v); + auto v = Canvas::I->triangulate(poly_remove_duplicate(m_points2d)); + Canvas::I->project2Dpoints(v); m_shape.update_vertices(v.data(), (int)v.size()); - canvas->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask); + Canvas::I->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->m_smask); // close the path and reset m_shape to contour rendering m_points.push_back(m_points.back()); m_points.push_back(m_points.front()); - canvas->project2Dpoints(m_points); + Canvas::I->project2Dpoints(m_points); m_shape.update_vertices(m_points.data(), (int)m_points.size()); } } else { - canvas->m_smask_active = false; + Canvas::I->m_smask_active = false; } break; case kEventType::MouseMove: @@ -626,8 +625,8 @@ void CanvasModeMaskLine::leave() std::vector points; for (int i = 0; i < (int)m_points2d.size(); i++) points.emplace_back(m_points2d[i]); - auto v = canvas->triangulate(poly_remove_duplicate(points)); - canvas->project2Dpoints(v); + auto v = Canvas::I->triangulate(poly_remove_duplicate(points)); + Canvas::I->project2Dpoints(v); LOG("%d points", (int)v.size()); m_shape.update_vertices(v.data(), (int)v.size()); @@ -641,37 +640,37 @@ void CanvasModeMaskLine::leave() ShaderManager::u_vec4(kShaderUniform::Col, {1, 1, 1, 1}); m_shape.draw_fill(); }; - canvas->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask); + Canvas::I->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->m_smask); //m_points.clear(); // close the path m_points.push_back(m_points.back()); m_points.push_back(m_points.back()); m_points.push_back(m_points.front()); - canvas->project2Dpoints(m_points); + Canvas::I->project2Dpoints(m_points); // reset m_shape to contour rendering m_shape.update_vertices(m_points.data(), (int)m_points.size()); } } else { - canvas->m_smask_active = false; + Canvas::I->m_smask_active = false; } m_active_tool = false; } -void CanvasModeMaskLine::enter() +void CanvasModeMaskLine::enter(kCanvasMode prev) { m_points2d.clear(); m_points.clear(); - canvas->m_smask.clear({0, 0, 0, 0}); - canvas->m_smask_active = true; + Canvas::I->m_smask.clear({0, 0, 0, 0}); + Canvas::I->m_smask_active = true; m_active_tool = true; } void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { - if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { @@ -691,6 +690,7 @@ void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) m_dragging = false; if (m_points.size() > 1) { + m_selection_cam = Canvas::I->get_camera(); m_points.push_back(m_points.back()); m_shape.update_vertices(m_points.data(), (int)m_points.size()); } @@ -765,19 +765,19 @@ void CanvasModeFill::leave() ShaderManager::u_vec4(kShaderUniform::Col, {1, 1, 1, 1}); m_shape.draw_fill(); }; - canvas->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask); + Canvas::I->draw_objects_direct(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), Canvas::I->m_smask); m_points.clear(); - canvas->m_smask_active = true; + Canvas::I->m_smask_active = true; } else { - canvas->m_smask_active = false; + Canvas::I->m_smask_active = false; } } void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { - if (canvas->m_touch_lock && me->m_source == kEventSource::Touch) + if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch) return; switch (me->m_type) { @@ -788,7 +788,7 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) glm::vec3 ro, rd, hit_o, hit_d; glm::vec2 hit_fb; int plane_id; - if (canvas->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, 0)) + if (Canvas::I->point_trace_plane(loc, ro, rd, hit_o, hit_d, hit_fb, 0)) { m_dirty_planes[plane_id]++; vertex_t v; @@ -807,7 +807,7 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) } m_shape.update_vertices(m_points.data(), (int)m_points.size()); } - canvas->m_smask.clear({0, 0, 0, 0}); + Canvas::I->m_smask.clear({0, 0, 0, 0}); break; } case kEventType::MouseUpL: @@ -819,7 +819,7 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) glm::vec3 ro, rd, hit_o, hit_d; glm::vec2 fb_pos; int plane_id; - if (m_dragging && canvas->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, plane_id)) + if (m_dragging && Canvas::I->point_trace(loc, ro, rd, hit_o, fb_pos, hit_d, plane_id)) { vertex_t v; v.pos = glm::vec4(hit_o, 1); @@ -871,8 +871,9 @@ void CanvasModeTransform::init() m_xform_local = glm::mat4(1); } -void CanvasModeTransform::enter() +void CanvasModeTransform::enter(kCanvasMode prev) { + m_commit_on_leave = false; for (int i = 0; i < 6; i++) { m_shape[i].clear(); @@ -889,15 +890,15 @@ void CanvasModeTransform::enter() aspect = (float)m_source_image.width / (float)m_source_image.height; } - auto center = zw(canvas->m_box) * 0.5f; + auto center = zw(Canvas::I->m_box) * 0.5f; glm::vec2 bb_sz = glm::vec2(aspect, 1.f) * 100.f * App::I.zoom; glm::vec2 bb_min = center - bb_sz * 0.5f; glm::vec2 bb_max = center + bb_sz * 0.5f; glm::vec2 midpoint = (bb_min + bb_max) * 0.5f; - auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1); - auto center_mat = glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up)); - m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up))); + auto cam_up = glm::inverse(Canvas::I->m_mv) * glm::vec4(0, 1, 0, 1); + auto center_mat = glm::lookAt({ 0, 0, 0 }, Canvas::I->point_trace(midpoint), xyz(cam_up)); + m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, Canvas::I->point_trace(midpoint), xyz(cam_up))); m_xform_local = glm::mat4(1); corners.clear(); @@ -909,7 +910,7 @@ void CanvasModeTransform::enter() corners.emplace_back(midpoint + (bb_max - bb_min) * glm::vec2(0.75f, 0), 0); for (auto& c : corners) - c = center_mat * glm::vec4(canvas->point_trace(c), 1); + c = center_mat * glm::vec4(Canvas::I->point_trace(c), 1); m_points_face[0] = std::vector({ vertex_t(corners[0], { 0, 0 }), @@ -917,18 +918,33 @@ void CanvasModeTransform::enter() vertex_t(corners[1], { 1, 1 }), vertex_t(corners[3], { 0, 1 }), }); - auto shape3d = canvas->triangulate(m_points_face[0]); + auto shape3d = Canvas::I->triangulate(m_points_face[0]); m_shape[0].update_vertices(shape3d.data(), shape3d.size()); + m_commit_on_leave = true; + return; } - auto m = static_cast(canvas->modes[(int)Canvas::kCanvasMode::MaskFree][0]); - canvas->m_smask_active = false; + if (prev != kCanvasMode::MaskFree && prev != kCanvasMode::MaskLine) + { + Canvas::set_mode(prev); + return; + } + + auto m = static_cast(Canvas::I->modes[(int)prev][0]); + + if (m->m_points2d.size() < 3) + { + Canvas::set_mode(prev); + return; + } + + Canvas::I->m_smask_active = false; auto points = m->m_points2d; - canvas->push_camera(); - canvas->set_camera(m->m_selection_cam); + Canvas::I->push_camera(); + Canvas::I->set_camera(m->m_selection_cam); glm::vec2 bb_min(FLT_MAX); glm::vec2 bb_max(-FLT_MAX); @@ -938,9 +954,9 @@ void CanvasModeTransform::enter() bb_max = glm::max(bb_max, p2d); } glm::vec2 midpoint = (bb_min + bb_max) * 0.5f; - auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1); - auto center_mat = glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up)); - m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up))); + auto cam_up = glm::inverse(Canvas::I->m_mv) * glm::vec4(0, 1, 0, 1); + auto center_mat = glm::lookAt({ 0, 0, 0 }, Canvas::I->point_trace(midpoint), xyz(cam_up)); + m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, Canvas::I->point_trace(midpoint), xyz(cam_up))); m_xform_local = glm::mat4(1); corners.clear(); corners.emplace_back(bb_min, 0); @@ -950,37 +966,37 @@ void CanvasModeTransform::enter() corners.emplace_back(midpoint, 0); corners.emplace_back(midpoint + (bb_max-bb_min) * glm::vec2(0.75f, 0), 0); for (auto& c : corners) - c = center_mat * glm::vec4(canvas->point_trace(c), 1); + c = center_mat * glm::vec4(Canvas::I->point_trace(c), 1); for (int plane = 0; plane < 6; plane++) { - auto face = canvas->face_to_shape2D(plane); + auto face = Canvas::I->face_to_shape2D(plane); auto shape2d = poly_intersect(points, face); - if (shape2d.size() < 3) + if (shape2d.size() < 3 || face.empty()) { m_shape[plane].clear(); m_points_face[plane].clear(); continue; } m_points_face[plane].reserve(shape2d.size()); - glm::vec2 bb_min(canvas->m_size); + glm::vec2 bb_min(Canvas::I->m_size); glm::vec2 bb_max(0, 0); for (auto p2d : shape2d) { - p2d.y = canvas->m_box.w - p2d.y - 1; - auto p2d_clip = ((p2d / zw(canvas->m_box)) * 2.f - 1.f); - auto p3d_plane = canvas->m_plane_unproject[plane] * glm::vec4(p2d_clip, 0, 1); + p2d.y = Canvas::I->m_box.w - p2d.y - 1; + auto p2d_clip = ((p2d / zw(Canvas::I->m_box)) * 2.f - 1.f); + auto p3d_plane = Canvas::I->m_plane_unproject[plane] * glm::vec4(p2d_clip, 0, 1); if (p3d_plane.w < 0) continue; auto p3d_norm = -p3d_plane / p3d_plane.z; auto p2d_plane = xy(p3d_norm); - auto p2d_plane_raster = (p2d_plane * 0.5f + 0.5f) * canvas->m_size; - auto p3d_world = canvas->m_plane_transform[plane] * glm::vec4(p2d_plane, -1, 1); + auto p2d_plane_raster = (p2d_plane * 0.5f + 0.5f) * Canvas::I->m_size; + auto p3d_world = Canvas::I->m_plane_transform[plane] * glm::vec4(p2d_plane, -1, 1); bb_min = glm::min(bb_min, p2d_plane_raster); bb_max = glm::max(bb_max, p2d_plane_raster); //glm::vec3 pt_o, pt_d; - //canvas->point_unproject(p2d, pt_o, pt_d); + //Canvas::I->point_unproject(p2d, pt_o, pt_d); vertex_t v; v.pos = glm::vec4(xyz(p3d_world), 1); @@ -998,25 +1014,27 @@ void CanvasModeTransform::enter() auto bb_sz = bb_max - bb_min; for (auto& v : m_points_face[plane]) { - v.uvs2 = v.uvs / canvas->m_size; + v.uvs2 = v.uvs / Canvas::I->m_size; v.uvs = (v.uvs - bb_min) / bb_sz; v.pos = center_mat * v.pos; } - auto shape3d = canvas->triangulate(m_points_face[plane]); + auto shape3d = Canvas::I->triangulate(m_points_face[plane]); m_shape[plane].update_vertices(shape3d.data(), shape3d.size()); - canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].bindFramebuffer(); + Canvas::I->m_layers[Canvas::I->m_current_layer_idx].m_rtt[plane].bindFramebuffer(); m_tex[plane].create(bb_sz.x, bb_sz.y); m_tex[plane].bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y); m_tex[plane].unbind(); - canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].unbindFramebuffer(); + Canvas::I->m_layers[Canvas::I->m_current_layer_idx].m_rtt[plane].unbindFramebuffer(); + + m_commit_on_leave = true; } if (m_action == ActionType::Cut) { - auto& layer = canvas->m_layers[canvas->m_current_layer_idx]; + auto& layer = Canvas::I->m_layers[Canvas::I->m_current_layer_idx]; GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp); @@ -1034,17 +1052,17 @@ void CanvasModeTransform::enter() ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 0 }); auto action = new ActionStroke; - action->was_saved = !canvas->m_unsaved; + action->was_saved = !Canvas::I->m_unsaved; for (int i = 0; i < 6; i++) { - auto plane_camera = glm::lookAt(glm::vec3(0), canvas->m_plane_origin[i], canvas->m_plane_tangent[i]); + auto plane_camera = glm::lookAt(glm::vec3(0), Canvas::I->m_plane_origin[i], Canvas::I->m_plane_tangent[i]); auto mvp = proj * plane_camera * m_xform * m_xform_local; ShaderManager::u_mat4(kShaderUniform::MVP, mvp); layer.m_rtt[i].bindFramebuffer(); - glm::vec2 bb_min(canvas->m_size); + glm::vec2 bb_min(Canvas::I->m_size); glm::vec2 bb_max(0, 0); for (int j = 0; j < 6; j++) { @@ -1054,14 +1072,14 @@ void CanvasModeTransform::enter() auto p_norm = p_clip / p_clip.w; if (p_clip.w < 0 || glm::any(glm::greaterThan(glm::abs(xy(p_norm)), { 1, 1 }))) continue; - auto p_raster = (xy(p_norm) * 0.5f + 0.5f) * canvas->m_size; + auto p_raster = (xy(p_norm) * 0.5f + 0.5f) * Canvas::I->m_size; bb_min = glm::max({ 0, 0 }, glm::min(bb_min, p_raster)); - bb_max = glm::min(canvas->m_size, glm::max(bb_max, p_raster)); + bb_max = glm::min(Canvas::I->m_size, glm::max(bb_max, p_raster)); } } glm::vec2 pad(2); bb_min = glm::max({ 0, 0 }, glm::floor(bb_min) - pad); - bb_max = glm::min(canvas->m_size, glm::ceil(bb_max) + pad); + bb_max = glm::min(Canvas::I->m_size, glm::ceil(bb_max) + pad); auto bb_sz = bb_max - bb_min; if (bb_sz.x <= 0.f || bb_sz.y <= 0.f) @@ -1092,20 +1110,23 @@ void CanvasModeTransform::enter() blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND); glViewport(vp[0], vp[1], vp[2], vp[3]); - action->m_layer_idx = canvas->m_current_layer_idx; - action->m_canvas = canvas; + action->m_layer_idx = Canvas::I->m_current_layer_idx; + action->m_canvas = Canvas::I; //action->m_stroke = std::move(m_current_stroke); ActionManager::add(action); m_source_image.destroy(); } - canvas->pop_camera(); + Canvas::I->pop_camera(); } void CanvasModeTransform::leave() { - auto& layer = canvas->m_layers[canvas->m_current_layer_idx]; + if (!m_commit_on_leave) + return; + + auto& layer = Canvas::I->m_layers[Canvas::I->m_current_layer_idx]; GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp); @@ -1128,18 +1149,18 @@ void CanvasModeTransform::leave() ShaderManager::u_int(kShaderUniform::Lock, false); ShaderManager::u_int(kShaderUniform::Mask, false); ShaderManager::u_int(kShaderUniform::UseFragCoordUV2, true); - ShaderManager::u_vec2(kShaderUniform::Resolution, canvas->m_size); + ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size); ShaderManager::u_int(kShaderUniform::BlendMode, 0); - canvas->m_sampler_bg.bind(1); - canvas->m_sampler_bg.bind(0); + Canvas::I->m_sampler_bg.bind(1); + Canvas::I->m_sampler_bg.bind(0); auto action = new ActionStroke; - action->was_saved = !canvas->m_unsaved; + action->was_saved = !Canvas::I->m_unsaved; for (int i = 0; i < 6; i++) { - auto plane_camera = glm::lookAt(glm::vec3(0), canvas->m_plane_origin[i], canvas->m_plane_tangent[i]); + auto plane_camera = glm::lookAt(glm::vec3(0), Canvas::I->m_plane_origin[i], Canvas::I->m_plane_tangent[i]); auto mv = plane_camera * m_xform * m_xform_local; auto mvp = proj * mv; ShaderManager::u_mat4(kShaderUniform::MVP, mvp); @@ -1169,17 +1190,17 @@ void CanvasModeTransform::leave() auto clipped = poly_intersect(poly2d, face_corners); - glm::vec2 bb_min(canvas->m_size); + glm::vec2 bb_min(Canvas::I->m_size); glm::vec2 bb_max(0, 0); for (auto p_norm : clipped) { - auto p_raster = (p_norm * 0.5f + 0.5f) * canvas->m_size; + auto p_raster = (p_norm * 0.5f + 0.5f) * Canvas::I->m_size; bb_min = glm::max({ 0, 0 }, glm::min(bb_min, p_raster)); - bb_max = glm::min(canvas->m_size, glm::max(bb_max, p_raster)); + bb_max = glm::min(Canvas::I->m_size, glm::max(bb_max, p_raster)); } glm::vec2 pad(2); bb_min = glm::max({ 0, 0 }, glm::floor(bb_min) - pad); - bb_max = glm::min(canvas->m_size, glm::ceil(bb_max) + pad); + bb_max = glm::min(Canvas::I->m_size, glm::ceil(bb_max) + pad); auto bb_sz = bb_max - bb_min; if (clipped.empty() || bb_sz.x <= 0.f || bb_sz.y <= 0.f) @@ -1201,7 +1222,7 @@ void CanvasModeTransform::leave() }; glActiveTexture(GL_TEXTURE0); - canvas->m_tex2[i].bind(); + Canvas::I->m_tex2[i].bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, bb_min.x, bb_min.y, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y); glActiveTexture(GL_TEXTURE1); @@ -1218,12 +1239,12 @@ void CanvasModeTransform::leave() blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND); glViewport(vp[0], vp[1], vp[2], vp[3]); - action->m_layer_idx = canvas->m_current_layer_idx; - action->m_canvas = canvas; + action->m_layer_idx = Canvas::I->m_current_layer_idx; + action->m_canvas = Canvas::I; //action->m_stroke = std::move(m_current_stroke); ActionManager::add(action); - - //auto m = static_cast(canvas->modes[(int)Canvas::kCanvasMode::MaskFree][0]); + layer.optimize(); + //auto m = static_cast(Canvas::I->modes[(int)kCanvasMode::MaskFree][0]); //m->clear(); } @@ -1245,20 +1266,20 @@ void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera * m_xform * m_xform_local); glActiveTexture(GL_TEXTURE0); m_tex[i].bind(); - canvas->m_sampler.bind(0); + Canvas::I->m_sampler.bind(0); m_shape[i].draw_fill(); m_tex[i].unbind(); } ShaderManager::use(kShader::Color); - auto m2d = canvas->m_proj * canvas->m_mv * m_xform * m_xform_local; + auto m2d = Canvas::I->m_proj * Canvas::I->m_mv * m_xform * m_xform_local; for (int i = 0; i < corners.size(); i++) { auto c = m2d * glm::vec4(corners[i], 1); if (c.w < 0) continue; auto c3d = c / c.w; - auto c2d = (xy(c3d) * 0.5f + 0.5f) * zw(canvas->m_box); + auto c2d = (xy(c3d) * 0.5f + 0.5f) * zw(Canvas::I->m_box); ShaderManager::u_mat4(kShaderUniform::MVP, ortho * glm::translate(glm::vec3(c2d, 0)) * glm::scale(glm::vec3(20.f) * App::I.zoom)); @@ -1277,8 +1298,8 @@ void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc) { - auto m2d = glm::scale(glm::vec3(1, -1, 1)) * canvas->m_proj * - canvas->m_mv * m_xform * m_xform_local; + auto m2d = glm::scale(glm::vec3(1, -1, 1)) * Canvas::I->m_proj * + Canvas::I->m_mv * m_xform * m_xform_local; switch (me->m_type) { @@ -1296,7 +1317,7 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc) for (int i = 0; i < corners.size(); i++) { auto c = m2d * glm::vec4(corners[i], 1); - corners2d[i] = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box); + corners2d[i] = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(Canvas::I->m_box); float d = glm::distance(corners2d[i], loc); if (d < 20.f * App::I.zoom) corner_hl = i; @@ -1322,14 +1343,14 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc) for (int i = 0; i < corners.size(); i++) { auto c = m2d * glm::vec4(corners[i], 1); - corners2d[i] = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box); + corners2d[i] = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(Canvas::I->m_box); float d = glm::distance(corners2d[i], loc); if (d < 20.f * App::I.zoom) corner_hl = i; } if (m_dragging) { - auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1); + auto cam_up = glm::inverse(Canvas::I->m_mv) * glm::vec4(0, 1, 0, 1); //auto diff = glm::radians(loc - m_drag_start) * 0.1f; //auto m = glm::eulerAngleXY(-diff.y, -diff.x); //m_xform = m * m_drag_xform; @@ -1341,7 +1362,7 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc) } if (m_drag_corner == 4) { - m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), xyz(cam_up))); + m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, Canvas::I->point_trace(loc), xyz(cam_up))); } if (m_drag_corner == 5) { @@ -1354,11 +1375,11 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc) /* { auto p2d = loc; - //p2d.y = canvas->m_box.w - p2d.y - 1; - auto p2d_clip = ((p2d / zw(canvas->m_box)) * 2.f - 1.f) * glm::vec2(1, -1); - auto p3d_plane = canvas->m_plane_unproject[0] * glm::vec4(p2d_clip, 0, 1); + //p2d.y = Canvas::I->m_box.w - p2d.y - 1; + auto p2d_clip = ((p2d / zw(Canvas::I->m_box)) * 2.f - 1.f) * glm::vec2(1, -1); + auto p3d_plane = Canvas::I->m_plane_unproject[0] * glm::vec4(p2d_clip, 0, 1); auto p2d_plane = -p3d_plane / p3d_plane.z; -// auto p3d_world = canvas->m_plane_transform[0] * glm::vec4(p2d_plane, -1, 1); +// auto p3d_world = Canvas::I->m_plane_transform[0] * glm::vec4(p2d_plane, -1, 1); int x = 0; LOG("pt %f %f %f %f", p2d_plane.x, p2d_plane.y, p2d_plane.z, p2d_plane.w); } diff --git a/src/canvas_modes.h b/src/canvas_modes.h index 82ea8aa..48cf4c0 100644 --- a/src/canvas_modes.h +++ b/src/canvas_modes.h @@ -5,7 +5,21 @@ #include "texture.h" #include -class Canvas; +enum class kCanvasMode +{ + Draw, + Erase, + Line, + Camera, + Grid, + Import, + Cut, + Copy, + Fill, + MaskFree, + MaskLine, + COUNT, +}; struct CameraData { @@ -22,13 +36,13 @@ class CanvasMode { public: static class NodeCanvas* node; - static Canvas* canvas; + //static Canvas* canvas; virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) {} virtual void on_KeyEvent(KeyEvent* ke) {} virtual void on_GestureEvent(GestureEvent* ge) {} virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) {} virtual void init() {} - virtual void enter() {} + virtual void enter(kCanvasMode prev) {} virtual void leave() {} CanvasMode() = default; virtual ~CanvasMode() = default; @@ -71,7 +85,7 @@ public: virtual void on_GestureEvent(GestureEvent* ge) override; virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override; virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override; - virtual void enter() override; + virtual void enter(kCanvasMode prev) override; virtual void leave() override; bool m_picking = false; }; @@ -127,14 +141,20 @@ public: virtual void leave() override; }; -class CanvasModeMaskFree : public CanvasMode +class CanvasModeMaskBase : public CanvasMode { +protected: friend class CanvasModeTransform; DynamicShape m_shape; bool m_dragging = false; std::vector m_points; std::vector m_points2d; CameraData m_selection_cam; +public: +}; + +class CanvasModeMaskFree : public CanvasModeMaskBase +{ public: virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override; virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override; @@ -143,19 +163,15 @@ public: void clear(); }; -class CanvasModeMaskLine : public CanvasMode +class CanvasModeMaskLine : public CanvasModeMaskBase { - DynamicShape m_shape; - bool m_dragging = false; - std::vector m_points; - std::vector m_points2d; std::map m_dirty_planes; bool m_active_tool = false; public: virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override; virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override; virtual void init() override; - virtual void enter() override; + virtual void enter(kCanvasMode prev) override; virtual void leave() override; }; @@ -186,6 +202,7 @@ class CanvasModeTransform : public CanvasMode std::vector m_points_face[6]; std::map m_dirty_planes{}; bool m_active_tool = false; + bool m_commit_on_leave = false; public: enum class ActionType : uint8_t { Copy, Cut, Import }; ActionType m_action; @@ -194,6 +211,6 @@ public: virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override; virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override; virtual void init() override;; - virtual void enter() override; + virtual void enter(kCanvasMode prev) override; virtual void leave() override; }; diff --git a/src/node_button.cpp b/src/node_button.cpp index 8a37d3d..559926c 100644 --- a/src/node_button.cpp +++ b/src/node_button.cpp @@ -24,6 +24,7 @@ void NodeButton::clone_copy(Node* dest) const n->color_normal = color_normal; n->color_hover = color_hover; n->color_down = color_down; + n->color_active = color_active; //n->on_click = on_click; n->m_mouse_ignore = false; } @@ -93,6 +94,14 @@ void NodeButton::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* a // m_text->parse_attributes(ka, attr); } +void NodeButton::set_active(bool active) +{ + if (m_active == active) + return; + m_active = active; + m_border->m_color = m_active ? color_active : (m_mouse_inside ? color_hover : color_normal); +} + void NodeButton::set_color(const glm::vec4& c) { color_normal = c; @@ -108,18 +117,18 @@ kEventResult NodeButton::handle_event(Event* e) m_border->m_color = color_hover; break; case kEventType::MouseLeave: - m_border->m_color = color_normal; + m_border->m_color = m_active ? color_active : color_normal; break; case kEventType::MouseDownL: - m_border->m_color = color_down; + m_border->m_color = m_active ? color_active : color_down; break; case kEventType::MouseUpL: - m_border->m_color = color_normal; + m_border->m_color = m_active ? color_active : color_normal; if (m_mouse_inside && on_click != nullptr) on_click(this); break; case kEventType::MouseCancel: - m_border->m_color = color_normal; + m_border->m_color = m_active ? color_active : color_normal; break; default: return kEventResult::Available; diff --git a/src/node_button.h b/src/node_button.h index 209a455..96385c4 100644 --- a/src/node_button.h +++ b/src/node_button.h @@ -5,12 +5,14 @@ class NodeButton : public Node { + bool m_active = false; public: NodeBorder* m_border; NodeText* m_text; glm::vec4 color_normal{ .1, .1, .1, 1 }; glm::vec4 color_hover{ .2, .2, .2, 1 }; glm::vec4 color_down{ .3, .3, .3, 1 }; + glm::vec4 color_active{ 1, 0, 0, 1 }; std::function on_click; virtual Node* clone_instantiate() const override; virtual void clone_children(Node* dest) const override; @@ -19,6 +21,7 @@ public: virtual void create() override; virtual void loaded() override; virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override; + void set_active(bool active); void set_color(const glm::vec4& c); virtual kEventResult handle_event(Event* e) override; }; diff --git a/src/node_button_custom.cpp b/src/node_button_custom.cpp index 3812ecf..84d307f 100644 --- a/src/node_button_custom.cpp +++ b/src/node_button_custom.cpp @@ -14,6 +14,8 @@ void NodeButtonCustom::clone_copy(Node* dest) const n->color_normal = color_normal; n->color_hover = color_hover; n->color_down = color_down; + n->color_active = color_active; + n->m_active = m_active; n->m_mouse_ignore = false; n->m_color = color_normal; } @@ -27,6 +29,14 @@ void NodeButtonCustom::loaded() m_mouse_ignore = false; } +void NodeButtonCustom::set_active(bool active) +{ + if (m_active == active) + return; + m_active = active; + m_color = m_active ? color_active : (m_mouse_inside ? color_hover : color_normal); +} + void NodeButtonCustom::set_color(const glm::vec4& c) { color_normal = c; @@ -42,24 +52,24 @@ kEventResult NodeButtonCustom::handle_event(Event* e) m_color = color_hover; break; case kEventType::MouseLeave: - m_color = color_normal; + m_color = m_active ? color_active : color_normal; break; case kEventType::MouseDownL: - m_color = color_down; + m_color = m_active ? color_active : color_down; mouse_capture(); break; case kEventType::MouseUpL: // if using touch or stylus, unfocus the button if (((MouseEvent*)e)->m_source == kEventSource::Mouse) - m_color = m_mouse_inside ? color_hover : color_normal; + m_color = m_active ? color_active : (m_mouse_inside ? color_hover : color_normal); else - m_color = color_normal; + m_color = m_active ? color_active : color_normal; mouse_release(); if (m_mouse_inside && on_click != nullptr) on_click(this); break; case kEventType::MouseCancel: - m_color = color_normal; + m_color = m_active ? color_active : color_normal; mouse_release(); break; default: diff --git a/src/node_button_custom.h b/src/node_button_custom.h index 58c52cc..d9789fa 100644 --- a/src/node_button_custom.h +++ b/src/node_button_custom.h @@ -3,14 +3,17 @@ class NodeButtonCustom : public NodeBorder { + bool m_active = false; public: glm::vec4 color_normal{ .2, .2, .2, 1 }; glm::vec4 color_hover{ .3, .3, .3, 1 }; glm::vec4 color_down{ .4, .4, .4, 1 }; + glm::vec4 color_active{ 1, 0, 0, 1 }; std::function on_click; virtual Node* clone_instantiate() const override; virtual void clone_copy(Node* dest) const override; virtual void loaded() override; + void set_active(bool active); void set_color(const glm::vec4& c); virtual kEventResult handle_event(Event* e) override; virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override; diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 4dc5416..e66f374 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -25,8 +25,7 @@ void NodeCanvas::init() m_face_plane.create<1>(2, 2); m_line.create(); CanvasMode::node = this; - CanvasMode::canvas = m_canvas.get(); - for (int i = 0; i < (int)Canvas::kCanvasMode::COUNT; i++) + for (int i = 0; i < (int)kCanvasMode::COUNT; i++) for (auto m : Canvas::modes[i]) m->init(); @@ -44,8 +43,7 @@ void NodeCanvas::restore_context() m_face_plane.create<1>(2, 2); m_canvas->snapshot_restore(); CanvasMode::node = this; - CanvasMode::canvas = m_canvas.get(); - for (int i = 0; i < (int)Canvas::kCanvasMode::COUNT; i++) + for (int i = 0; i < (int)kCanvasMode::COUNT; i++) for (auto m : Canvas::modes[i]) m->init(); } @@ -172,7 +170,7 @@ void NodeCanvas::draw() m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); - if (m_canvas->m_current_stroke && m_canvas->m_state == Canvas::kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) + if (m_canvas->m_current_stroke && m_canvas->m_current_mode == kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) { m_sampler.bind(0); ShaderManager::use(kShader::CompErase); @@ -352,17 +350,15 @@ void NodeCanvas::draw() } glDisable(GL_DEPTH_TEST); - auto transform_mode = static_cast(Canvas::modes[(int)Canvas::kCanvasMode::Transform][0]); - bool importing = transform_mode->m_action == CanvasModeTransform::ActionType::Import; - if (m_canvas->m_smask_active || m_canvas->m_state == Canvas::kCanvasMode::Transform && !importing) + if (m_canvas->m_smask_active || m_canvas->m_current_mode == kCanvasMode::Copy || m_canvas->m_current_mode == kCanvasMode::Cut) { - m_canvas->modes[(int)Canvas::kCanvasMode::MaskFree][0]->on_Draw(ortho_proj, proj, camera); - m_canvas->modes[(int)Canvas::kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera); + m_canvas->modes[(int)kCanvasMode::MaskFree][0]->on_Draw(ortho_proj, proj, camera); + m_canvas->modes[(int)kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera); } // keep drawing the grids - if (m_canvas->m_state != Canvas::kCanvasMode::Grid) - for (auto& mode : Canvas::modes[(int)Canvas::kCanvasMode::Grid]) + if (m_canvas->m_current_mode != kCanvasMode::Grid) + for (auto& mode : Canvas::modes[(int)kCanvasMode::Grid]) mode->on_Draw(ortho_proj, proj, camera); App::I.grid->draw_heightmap(proj, camera, false); @@ -415,8 +411,8 @@ kEventResult NodeCanvas::handle_event(Event* e) if (stylus_eraser != me->m_eraser) { Canvas::set_mode(me->m_eraser ? - Canvas::kCanvasMode::Erase : - Canvas::kCanvasMode::Draw); + kCanvasMode::Erase : + kCanvasMode::Draw); stylus_eraser = me->m_eraser; } case kEventType::MouseScroll: @@ -431,7 +427,7 @@ kEventResult NodeCanvas::handle_event(Event* e) break; case kEventType::KeyDown: if (ke->m_key == kKey::KeyE) - Canvas::set_mode(Canvas::kCanvasMode::Erase); + Canvas::set_mode(kCanvasMode::Erase); if (ke->m_key == kKey::AndroidBack) if (!ActionManager::empty()) ActionManager::undo(); @@ -439,7 +435,7 @@ kEventResult NodeCanvas::handle_event(Event* e) break; case kEventType::KeyUp: if (ke->m_key == kKey::KeyE) - Canvas::set_mode(Canvas::kCanvasMode::Draw); + Canvas::set_mode(kCanvasMode::Draw); if (ke->m_key == kKey::KeyTab) App::I.toggle_ui(); if (ke->m_key == kKey::KeyZ && App::I.keys[(int)kKey::KeyCtrl])