From 2de5c9000603d7e83c0935ab54673593457f04f5 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Sun, 27 Jul 2025 16:53:22 +0300 Subject: [PATCH] Prevent undo and redo at points when they might break the program --- src/DrawingProgram/BrushTool.cpp | 4 ++++ src/DrawingProgram/BrushTool.hpp | 1 + src/DrawingProgram/DrawingProgram.cpp | 26 ++++++++++++++++++++++++++ src/DrawingProgram/DrawingProgram.hpp | 2 ++ src/DrawingProgram/EditTool.cpp | 4 ++++ src/DrawingProgram/EditTool.hpp | 1 + src/DrawingProgram/EllipseDrawTool.cpp | 4 ++++ src/DrawingProgram/EllipseDrawTool.hpp | 2 ++ src/DrawingProgram/EraserTool.cpp | 4 ++++ src/DrawingProgram/EraserTool.hpp | 2 ++ src/DrawingProgram/InkDropperTool.cpp | 4 ++++ src/DrawingProgram/InkDropperTool.hpp | 1 + src/DrawingProgram/RectDrawTool.cpp | 4 ++++ src/DrawingProgram/RectDrawTool.hpp | 2 ++ src/DrawingProgram/RectSelectTool.cpp | 4 ++++ src/DrawingProgram/RectSelectTool.hpp | 3 ++- src/DrawingProgram/ScreenshotTool.cpp | 4 ++++ src/DrawingProgram/ScreenshotTool.hpp | 1 + src/DrawingProgram/TextBoxTool.cpp | 4 ++++ src/DrawingProgram/TextBoxTool.hpp | 2 ++ src/World.cpp | 2 +- 21 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/DrawingProgram/BrushTool.cpp b/src/DrawingProgram/BrushTool.cpp index ee76866..89c840c 100644 --- a/src/DrawingProgram/BrushTool.cpp +++ b/src/DrawingProgram/BrushTool.cpp @@ -168,6 +168,10 @@ void BrushTool::gui_toolbox() { t.gui.pop_id(); } +bool BrushTool::prevent_undo_or_redo() { + return controls.intermediateItem != nullptr; +} + void BrushTool::commit_stroke() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { if(!controls.intermediateItem->d.points.empty()) { diff --git a/src/DrawingProgram/BrushTool.hpp b/src/DrawingProgram/BrushTool.hpp index 45a6607..bed4104 100644 --- a/src/DrawingProgram/BrushTool.hpp +++ b/src/DrawingProgram/BrushTool.hpp @@ -19,6 +19,7 @@ class BrushTool { void tool_update(); void reset_tool(); void draw(SkCanvas* canvas, const DrawData& drawData); + bool prevent_undo_or_redo(); private: void commit_stroke(); bool extensive_point_checking_back(const Vector2f& newPoint); diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index d3919dd..516edf0 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -392,6 +392,32 @@ void DrawingProgram::update() { compCache.test_rebuild(components.client_list()); } +bool DrawingProgram::prevent_undo_or_redo() { + switch(controls.selectedTool) { + case TOOL_BRUSH: + return brushTool.prevent_undo_or_redo(); + case TOOL_ERASER: + return eraserTool.prevent_undo_or_redo(); + case TOOL_RECTSELECT: + return rectSelectTool.prevent_undo_or_redo(); + case TOOL_RECTANGLE: + return rectDrawTool.prevent_undo_or_redo(); + case TOOL_ELLIPSE: + return ellipseDrawTool.prevent_undo_or_redo(); + case TOOL_TEXTBOX: + return textBoxTool.prevent_undo_or_redo(); + case TOOL_INKDROPPER: + return inkDropperTool.prevent_undo_or_redo(); + case TOOL_SCREENSHOT: + return screenshotTool.prevent_undo_or_redo(); + case TOOL_EDIT: + return editTool.prevent_undo_or_redo(); + default: + break; + }; + return false; +} + void DrawingProgram::force_rebuild_cache() { if(controls.selectedTool == TOOL_ERASER) compCache.test_rebuild_dont_include_set_dont_include_nodes(components.client_list(), eraserTool.erasedComponents, eraserTool.erasedBVHNodes, true); diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index 897603b..c36c73f 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -43,6 +43,8 @@ class DrawingProgram { void free_collider_memory(); void allocate_collider_memory(); + bool prevent_undo_or_redo(); + void add_file_to_canvas_by_path(const std::string& filePath, Vector2f dropPos, bool addInSameThread); void add_file_to_canvas_by_data(const std::string& fileName, std::string_view fileBuffer, Vector2f dropPos); diff --git a/src/DrawingProgram/EditTool.cpp b/src/DrawingProgram/EditTool.cpp index 2f2d38c..7d066a0 100644 --- a/src/DrawingProgram/EditTool.cpp +++ b/src/DrawingProgram/EditTool.cpp @@ -219,6 +219,10 @@ void EditTool::tool_update() { } } +bool EditTool::prevent_undo_or_redo() { + return controls.isEditing; +} + void EditTool::draw(SkCanvas* canvas, const DrawData& drawData) { if(controls.isEditing) { std::shared_ptr a = controls.compToEdit.lock(); diff --git a/src/DrawingProgram/EditTool.hpp b/src/DrawingProgram/EditTool.hpp index 0cfc10c..585acc9 100644 --- a/src/DrawingProgram/EditTool.hpp +++ b/src/DrawingProgram/EditTool.hpp @@ -22,6 +22,7 @@ class EditTool { void draw(SkCanvas* canvas, const DrawData& drawData); void add_point_handle(const HandleData& handle); void edit_start(const std::shared_ptr& comp); + bool prevent_undo_or_redo(); struct EditControls { std::vector pointHandles; diff --git a/src/DrawingProgram/EllipseDrawTool.cpp b/src/DrawingProgram/EllipseDrawTool.cpp index 84e4e10..4cad67c 100644 --- a/src/DrawingProgram/EllipseDrawTool.cpp +++ b/src/DrawingProgram/EllipseDrawTool.cpp @@ -139,6 +139,10 @@ void EllipseDrawTool::tool_update() { } } +bool EllipseDrawTool::prevent_undo_or_redo() { + return controls.intermediateItem != nullptr; +} + void EllipseDrawTool::commit() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { controls.intermediateItem->client_send_update_final(drawP); diff --git a/src/DrawingProgram/EllipseDrawTool.hpp b/src/DrawingProgram/EllipseDrawTool.hpp index cbad4fb..8c23013 100644 --- a/src/DrawingProgram/EllipseDrawTool.hpp +++ b/src/DrawingProgram/EllipseDrawTool.hpp @@ -19,6 +19,8 @@ class EllipseDrawTool { void commit_edit_updates(const std::shared_ptr& a, std::any& prevData); bool edit_update(const std::shared_ptr& a); bool edit_gui(const std::shared_ptr& a); + + bool prevent_undo_or_redo(); private: void commit(); diff --git a/src/DrawingProgram/EraserTool.cpp b/src/DrawingProgram/EraserTool.cpp index 49f36b3..070d238 100644 --- a/src/DrawingProgram/EraserTool.cpp +++ b/src/DrawingProgram/EraserTool.cpp @@ -107,6 +107,10 @@ void EraserTool::tool_update() { reset_tool(); } +bool EraserTool::prevent_undo_or_redo() { + return drawP.controls.leftClickHeld; +} + void EraserTool::draw(SkCanvas* canvas, const DrawData& drawData) { if(!drawData.main->toolbar.io->hoverObstructed) { SkColor4f c = drawP.world.main.canvasTheme.toolFrontColor; diff --git a/src/DrawingProgram/EraserTool.hpp b/src/DrawingProgram/EraserTool.hpp index e5c5c39..5541bef 100644 --- a/src/DrawingProgram/EraserTool.hpp +++ b/src/DrawingProgram/EraserTool.hpp @@ -13,6 +13,8 @@ class EraserTool { void reset_tool(); void draw(SkCanvas* canvas, const DrawData& drawData); + bool prevent_undo_or_redo(); + std::unordered_set erasedComponents; std::unordered_set> erasedBVHNodes; private: diff --git a/src/DrawingProgram/InkDropperTool.cpp b/src/DrawingProgram/InkDropperTool.cpp index 6aee012..597a99c 100644 --- a/src/DrawingProgram/InkDropperTool.cpp +++ b/src/DrawingProgram/InkDropperTool.cpp @@ -73,5 +73,9 @@ void InkDropperTool::tool_update() { } } +bool InkDropperTool::prevent_undo_or_redo() { + return false; +} + void InkDropperTool::draw(SkCanvas* canvas, const DrawData& drawData) { } diff --git a/src/DrawingProgram/InkDropperTool.hpp b/src/DrawingProgram/InkDropperTool.hpp index 9a317d2..30de4cc 100644 --- a/src/DrawingProgram/InkDropperTool.hpp +++ b/src/DrawingProgram/InkDropperTool.hpp @@ -11,6 +11,7 @@ class InkDropperTool { void gui_toolbox(); void tool_update(); void draw(SkCanvas* canvas, const DrawData& drawData); + bool prevent_undo_or_redo(); private: DrawingProgram& drawP; diff --git a/src/DrawingProgram/RectDrawTool.cpp b/src/DrawingProgram/RectDrawTool.cpp index eb71581..6f3e780 100644 --- a/src/DrawingProgram/RectDrawTool.cpp +++ b/src/DrawingProgram/RectDrawTool.cpp @@ -139,6 +139,10 @@ void RectDrawTool::tool_update() { } } +bool RectDrawTool::prevent_undo_or_redo() { + return controls.intermediateItem != nullptr; +} + void RectDrawTool::commit_rectangle() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { controls.intermediateItem->client_send_update_final(drawP); diff --git a/src/DrawingProgram/RectDrawTool.hpp b/src/DrawingProgram/RectDrawTool.hpp index 43a8161..e0c2bea 100644 --- a/src/DrawingProgram/RectDrawTool.hpp +++ b/src/DrawingProgram/RectDrawTool.hpp @@ -19,6 +19,8 @@ class RectDrawTool { void commit_edit_updates(const std::shared_ptr& a, std::any& prevData); bool edit_update(const std::shared_ptr& a); bool edit_gui(const std::shared_ptr& a); + + bool prevent_undo_or_redo(); private: void commit_rectangle(); diff --git a/src/DrawingProgram/RectSelectTool.cpp b/src/DrawingProgram/RectSelectTool.cpp index 72628e3..60549e5 100644 --- a/src/DrawingProgram/RectSelectTool.cpp +++ b/src/DrawingProgram/RectSelectTool.cpp @@ -74,6 +74,10 @@ void RectSelectTool::tool_update() { } } +bool RectSelectTool::prevent_undo_or_redo() { + return drawP.selection.is_something_selected() || controls.selectionMode == 1; +} + void RectSelectTool::draw(SkCanvas* canvas, const DrawData& drawData) { if(controls.selectionMode == 1) { canvas->save(); diff --git a/src/DrawingProgram/RectSelectTool.hpp b/src/DrawingProgram/RectSelectTool.hpp index e11f2d8..f7f1ba7 100644 --- a/src/DrawingProgram/RectSelectTool.hpp +++ b/src/DrawingProgram/RectSelectTool.hpp @@ -14,11 +14,12 @@ class RectSelectTool { void tool_update(); void draw(SkCanvas* canvas, const DrawData& drawData); void reset_tool(); + + bool prevent_undo_or_redo(); private: struct RectSelectControls { int selectionMode = 0; - CoordSpaceHelper coords; Vector2f selectStartAt; diff --git a/src/DrawingProgram/ScreenshotTool.cpp b/src/DrawingProgram/ScreenshotTool.cpp index 9ada135..05eaee8 100644 --- a/src/DrawingProgram/ScreenshotTool.cpp +++ b/src/DrawingProgram/ScreenshotTool.cpp @@ -324,6 +324,10 @@ void ScreenshotTool::commit_rect() { controls.circles[7] = {drawP.world.drawData.cam.c.to_space(controls.coords.from_space({controls.rectX2, (controls.rectY1 + controls.rectY2) * 0.5})), DRAG_POINT_RADIUS}; } +bool ScreenshotTool::prevent_undo_or_redo() { + return false; +} + void ScreenshotTool::draw(SkCanvas* canvas, const DrawData& drawData) { if(controls.selectionMode == 1 || controls.selectionMode == 2) { canvas->save(); diff --git a/src/DrawingProgram/ScreenshotTool.hpp b/src/DrawingProgram/ScreenshotTool.hpp index 10c3149..b24d637 100644 --- a/src/DrawingProgram/ScreenshotTool.hpp +++ b/src/DrawingProgram/ScreenshotTool.hpp @@ -15,6 +15,7 @@ class ScreenshotTool { void tool_update(); void draw(SkCanvas* canvas, const DrawData& drawData); void reset_tool(); + bool prevent_undo_or_redo(); private: void commit_rect(); void take_screenshot(const std::filesystem::path& filePath); diff --git a/src/DrawingProgram/TextBoxTool.cpp b/src/DrawingProgram/TextBoxTool.cpp index 987e43b..139f755 100644 --- a/src/DrawingProgram/TextBoxTool.cpp +++ b/src/DrawingProgram/TextBoxTool.cpp @@ -261,6 +261,10 @@ void TextBoxTool::tool_update() { } } +bool TextBoxTool::prevent_undo_or_redo() { + return controls.intermediateItem != nullptr; +} + // Passing a function in, just in case we have to do something before editing the text void TextBoxTool::edit_text(std::function toRun, const std::shared_ptr& textBox) { toRun(); diff --git a/src/DrawingProgram/TextBoxTool.hpp b/src/DrawingProgram/TextBoxTool.hpp index 28591b2..2cde572 100644 --- a/src/DrawingProgram/TextBoxTool.hpp +++ b/src/DrawingProgram/TextBoxTool.hpp @@ -19,6 +19,8 @@ class TextBoxTool { void commit_edit_updates(const std::shared_ptr& a, std::any& prevData); bool edit_update(const std::shared_ptr& a); bool edit_gui(const std::shared_ptr& a); + + bool prevent_undo_or_redo(); private: void edit_text(std::function toRun, const std::shared_ptr& textBox); void update_textbox_network(const std::shared_ptr& textBox); diff --git a/src/World.cpp b/src/World.cpp index 61f6ae3..6add216 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -144,7 +144,7 @@ void World::focus_update() { mousePreviousWorldVec = drawData.cam.c.from_space(main.input.mouse.pos); mouseWorldMove = drawData.cam.c.from_space(main.input.mouse.move); - if(!clientStillConnecting) { + if(!clientStillConnecting && !drawProg.prevent_undo_or_redo()) { if(main.input.key(InputManager::KEY_UNDO).repeat) undo.undo(); else if(main.input.key(InputManager::KEY_REDO).repeat)