From a5c9595b13d9b019050b92d4e2f94cf4ab01dc15 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Sun, 28 Sep 2025 11:59:08 +0300 Subject: [PATCH] Added zoom tool --- CMakeLists.txt | 1 + data/icons/hand.svg | 76 +++++++++++++++++++ data/icons/zoom.svg | 68 +++++++++++++++++ src/DrawCamera.cpp | 14 ++-- src/DrawCamera.hpp | 3 +- src/DrawingProgram/DrawingProgram.cpp | 12 +++ src/DrawingProgram/DrawingProgram.hpp | 11 ++- src/DrawingProgram/DrawingProgramToolBase.cpp | 3 + src/DrawingProgram/DrawingProgramToolBase.hpp | 3 +- src/DrawingProgram/ZoomCanvasTool.cpp | 35 +++++++++ src/DrawingProgram/ZoomCanvasTool.hpp | 15 ++++ 11 files changed, 230 insertions(+), 11 deletions(-) create mode 100644 data/icons/hand.svg create mode 100644 data/icons/zoom.svg create mode 100644 src/DrawingProgram/ZoomCanvasTool.cpp create mode 100644 src/DrawingProgram/ZoomCanvasTool.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 59cc691..073bd4f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ set(sources "src/main.cpp" "src/DrawingProgram/EyeDropperTool.cpp" "src/DrawingProgram/ScreenshotTool.cpp" "src/DrawingProgram/EditTool.cpp" + "src/DrawingProgram/ZoomCanvasTool.cpp" "src/DrawingProgram/ImageEditTool.cpp" "src/DrawingProgram/GridModifyTool.cpp" "src/DrawingProgram/DrawingProgramSelection.cpp" diff --git a/data/icons/hand.svg b/data/icons/hand.svg new file mode 100644 index 0000000..dc98b9b --- /dev/null +++ b/data/icons/hand.svg @@ -0,0 +1,76 @@ + + + + diff --git a/data/icons/zoom.svg b/data/icons/zoom.svg new file mode 100644 index 0000000..e7fd3f4 --- /dev/null +++ b/data/icons/zoom.svg @@ -0,0 +1,68 @@ + + + + diff --git a/src/DrawCamera.cpp b/src/DrawCamera.cpp index 2ab9b60..cc6c37b 100755 --- a/src/DrawCamera.cpp +++ b/src/DrawCamera.cpp @@ -1,4 +1,5 @@ #include "DrawCamera.hpp" +#include "DrawingProgram/DrawingProgramToolBase.hpp" #include "Helpers/FixedPoint.hpp" #include "Helpers/MathExtras.hpp" #include "MainProgram.hpp" @@ -106,15 +107,15 @@ void DrawCamera::update_main(World& w) { } else { - bool middleClickDown = w.main.input.mouse.middleDown || w.main.input.pen.buttons[w.main.toolbar.tabletOptions.middleClickButton].held; - bool newIsMiddleClickZooming = middleClickDown && w.main.input.key(InputManager::KEY_GENERIC_LCTRL).held; - if(newIsMiddleClickZooming && !isMiddleClickZooming) { + bool newIsAccurateZooming = (w.drawProg.controls.middleClickHeld && w.main.input.key(InputManager::KEY_GENERIC_LCTRL).held) || (w.drawProg.controls.leftClickHeld && w.drawProg.drawTool->get_type() == DrawingProgramToolType::ZOOM); + + if(newIsAccurateZooming && !isAccurateZooming) { startZoomMousePos = w.get_mouse_world_pos(); startZoomVal = c.inverseScale; startZoomCameraPos = c.pos; } - isMiddleClickZooming = newIsMiddleClickZooming; - if(isMiddleClickZooming) { + isAccurateZooming = newIsAccurateZooming; + if(isAccurateZooming) { WorldScalar zoomFactor(std::pow(1.0 + w.main.toolbar.dragZoomSpeed, w.main.input.mouse.move.y())); c.scale(zoomFactor); if(c.inverseScale < WorldScalar(1)) @@ -125,9 +126,8 @@ void DrawCamera::update_main(World& w) { c.pos = startZoomMousePos + mVec * mX; } } - else if(middleClickDown) { + else if(w.drawProg.controls.middleClickHeld) c.pos -= c.dir_from_space(w.main.input.mouse.move); - } if(w.main.input.mouse.scrollAmount.y() && !w.main.toolbar.io->hoverObstructed) { // Ignore the value of scrollAmount, since that leads to problems on macOS diff --git a/src/DrawCamera.hpp b/src/DrawCamera.hpp index 2848e89..8b00314 100644 --- a/src/DrawCamera.hpp +++ b/src/DrawCamera.hpp @@ -39,5 +39,6 @@ class DrawCamera { WorldScalar startZoomVal; WorldVec startZoomMousePos; WorldVec startZoomCameraPos; - bool isMiddleClickZooming = false; + + bool isAccurateZooming = false; }; diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index b4b2b97..fce5d08 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -199,6 +199,7 @@ void DrawingProgram::toolbar_gui() { if(t.gui.svg_icon_button("LassoSelect Toolbar Button", "data/icons/lassoselect.svg", drawTool->get_type() == DrawingProgramToolType::LASSOSELECT)) { switch_to_tool(DrawingProgramToolType::LASSOSELECT); } if(t.gui.svg_icon_button("Edit Toolbar Button", "data/icons/cursor.svg", drawTool->get_type() == DrawingProgramToolType::EDIT)) { switch_to_tool(DrawingProgramToolType::EDIT); } if(t.gui.svg_icon_button("Eyedropper Toolbar Button", "data/icons/eyedropper.svg", drawTool->get_type() == DrawingProgramToolType::EYEDROPPER)) { switch_to_tool(DrawingProgramToolType::EYEDROPPER); } + if(t.gui.svg_icon_button("Zoom Canvas Toolbar Button", "data/icons/zoom.svg", drawTool->get_type() == DrawingProgramToolType::ZOOM)) { switch_to_tool(DrawingProgramToolType::ZOOM); } CLAY({.layout = {.sizing = {.width = CLAY_SIZING_FIXED(40), .height = CLAY_SIZING_FIXED(40)}}}) { if(t.gui.color_button("Foreground Color", &controls.foregroundColor, &controls.foregroundColor == t.colorLeft)) { t.color_selector_left(&controls.foregroundColor == t.colorLeft ? nullptr : &controls.foregroundColor); @@ -278,6 +279,17 @@ void DrawingProgram::update() { controls.leftClickReleased = true; } + controls.middleClick = controls.cursorHoveringOverCanvas && (world.main.input.mouse.middleClicks || world.main.input.pen.buttons[world.main.toolbar.tabletOptions.middleClickButton].pressed); + if(controls.middleClick) { + controls.middleClickHeld = true; + world.main.toolbar.paintPopupLocation = std::nullopt; + } + if(controls.middleClickHeld && !world.main.input.mouse.middleDown) { + controls.middleClick = false; + controls.middleClickHeld = false; + controls.middleClickReleased = true; + } + if(controls.cursorHoveringOverCanvas && (world.main.input.mouse.rightClicks || world.main.input.pen.buttons[world.main.toolbar.tabletOptions.rightClickButton].pressed)) { if(world.main.toolbar.paintPopupLocation) world.main.toolbar.paintPopupLocation = std::nullopt; diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index f2e3e8a..db98383 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -2,6 +2,7 @@ #include "../DrawData.hpp" #include "DrawingProgramCache.hpp" #include "GridModifyTool.hpp" +#include "ZoomCanvasTool.hpp" #include "cereal/archives/portable_binary.hpp" #include #include @@ -58,6 +59,7 @@ class DrawingProgram { void clear_draw_cache(); void modify_grid(ServerClientID gridToModifyID); + private: std::optional badFrametimeTimePoint; std::optional unorderedObjectsExistTimePoint; @@ -86,8 +88,6 @@ class DrawingProgram { SkPaint select_tool_line_paint(); - std::unique_ptr drawTool; - DrawingProgramSelection selection; bool temporaryEraser = false; @@ -102,11 +102,16 @@ class DrawingProgram { bool leftClick = false; bool leftClickHeld = false; bool leftClickReleased = false; + bool middleClick = false; + bool middleClickHeld = false; + bool middleClickReleased = false; bool cursorHoveringOverCanvas = false; int colorEditing = 0; } controls; + std::unique_ptr drawTool; + uint32_t nextID = 0; friend class EyeDropperTool; @@ -127,4 +132,6 @@ class DrawingProgram { friend class LassoSelectTool; friend class GridEditTool; friend class GridModifyTool; + friend class ZoomCanvasTool; + friend class DrawCamera; }; diff --git a/src/DrawingProgram/DrawingProgramToolBase.cpp b/src/DrawingProgram/DrawingProgramToolBase.cpp index 7c537ca..8d5c92e 100644 --- a/src/DrawingProgram/DrawingProgramToolBase.cpp +++ b/src/DrawingProgram/DrawingProgramToolBase.cpp @@ -11,6 +11,7 @@ #include "ScreenshotTool.hpp" #include "EditTool.hpp" #include "GridModifyTool.hpp" +#include "ZoomCanvasTool.hpp" DrawingProgramToolBase::DrawingProgramToolBase(DrawingProgram& initDrawP): drawP(initDrawP) @@ -42,6 +43,8 @@ std::unique_ptr DrawingProgramToolBase::allocate_tool_ty return std::make_unique(drawP); case DrawingProgramToolType::EDIT: return std::make_unique(drawP); + case DrawingProgramToolType::ZOOM: + return std::make_unique(drawP); } return nullptr; } diff --git a/src/DrawingProgram/DrawingProgramToolBase.hpp b/src/DrawingProgram/DrawingProgramToolBase.hpp index 976501b..5708af3 100644 --- a/src/DrawingProgram/DrawingProgramToolBase.hpp +++ b/src/DrawingProgram/DrawingProgramToolBase.hpp @@ -17,7 +17,8 @@ enum class DrawingProgramToolType : int { EYEDROPPER, SCREENSHOT, GRIDMODIFY, - EDIT + EDIT, + ZOOM }; class DrawingProgramToolBase { diff --git a/src/DrawingProgram/ZoomCanvasTool.cpp b/src/DrawingProgram/ZoomCanvasTool.cpp new file mode 100644 index 0000000..4994f85 --- /dev/null +++ b/src/DrawingProgram/ZoomCanvasTool.cpp @@ -0,0 +1,35 @@ +#include "ZoomCanvasTool.hpp" +#include "DrawingProgram.hpp" +#include "../MainProgram.hpp" +#include "../DrawData.hpp" +#include "DrawingProgramToolBase.hpp" +#include + +ZoomCanvasTool::ZoomCanvasTool(DrawingProgram& initDrawP): + DrawingProgramToolBase(initDrawP) +{ +} + +DrawingProgramToolType ZoomCanvasTool::get_type() { + return DrawingProgramToolType::ZOOM; +} + +void ZoomCanvasTool::gui_toolbox() { + Toolbar& t = drawP.world.main.toolbar; + t.gui.push_id("Zoom canvas tool"); + t.gui.text_label_centered("Zoom tool"); + t.gui.pop_id(); +} + +void ZoomCanvasTool::tool_update() { +} + +bool ZoomCanvasTool::prevent_undo_or_redo() { + return false; +} + +void ZoomCanvasTool::draw(SkCanvas* canvas, const DrawData& drawData) { +} + +void ZoomCanvasTool::switch_tool(DrawingProgramToolType newTool) { +} diff --git a/src/DrawingProgram/ZoomCanvasTool.hpp b/src/DrawingProgram/ZoomCanvasTool.hpp new file mode 100644 index 0000000..13f268e --- /dev/null +++ b/src/DrawingProgram/ZoomCanvasTool.hpp @@ -0,0 +1,15 @@ +#pragma once +#include "DrawingProgramToolBase.hpp" + +class DrawingProgram; + +class ZoomCanvasTool : public DrawingProgramToolBase { + public: + ZoomCanvasTool(DrawingProgram& initDrawP); + virtual DrawingProgramToolType get_type() override; + virtual void gui_toolbox() override; + virtual void tool_update() override; + virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; + virtual bool prevent_undo_or_redo() override; + virtual void switch_tool(DrawingProgramToolType newTool) override; +};