From 6b3ce01e94e0974b9c7dba01b8a0ab3f032415e2 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Sun, 16 Nov 2025 12:40:56 +0300 Subject: [PATCH] Can now undo/redo grid operations --- src/DrawingProgram/GridModifyTool.cpp | 3 +- src/DrawingProgram/GridModifyTool.hpp | 2 + src/GridManager.cpp | 59 ++++++++++++++++++++++++++- src/GridManager.hpp | 2 +- src/Toolbar.cpp | 3 +- 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/DrawingProgram/GridModifyTool.cpp b/src/DrawingProgram/GridModifyTool.cpp index a85f06b..b1c10b5 100644 --- a/src/DrawingProgram/GridModifyTool.cpp +++ b/src/DrawingProgram/GridModifyTool.cpp @@ -14,6 +14,7 @@ void GridModifyTool::set_grid_id(ServerClientID newGridID) { auto gridFoundIt = drawP.world.gridMan.grids.find(gridID); if(gridFoundIt != drawP.world.gridMan.grids.end()) { WorldGrid& g = gridFoundIt->second; + oldGrid = g; CoordSpaceHelper newCam; newCam.inverseScale = g.size / WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE); newCam.pos = g.offset - drawP.world.main.window.size.cast() * newCam.inverseScale * WorldScalar(0.5); @@ -173,5 +174,5 @@ void GridModifyTool::draw(SkCanvas* canvas, const DrawData& drawData) { } void GridModifyTool::switch_tool(DrawingProgramToolType newTool) { - drawP.world.gridMan.send_grid_info(gridID); + drawP.world.gridMan.send_grid_info(oldGrid, gridID); } diff --git a/src/DrawingProgram/GridModifyTool.hpp b/src/DrawingProgram/GridModifyTool.hpp index 786826e..06b603f 100644 --- a/src/DrawingProgram/GridModifyTool.hpp +++ b/src/DrawingProgram/GridModifyTool.hpp @@ -1,5 +1,6 @@ #pragma once #include "DrawingProgramToolBase.hpp" +#include "../WorldGrid.hpp" class DrawingProgram; @@ -14,6 +15,7 @@ class GridModifyTool : public DrawingProgramToolBase { virtual bool prevent_undo_or_redo() override; virtual void switch_tool(DrawingProgramToolType newTool) override; private: + WorldGrid oldGrid; ServerClientID gridID; unsigned selectionMode = 0; }; diff --git a/src/GridManager.cpp b/src/GridManager.cpp index 129f1d1..a811c52 100644 --- a/src/GridManager.cpp +++ b/src/GridManager.cpp @@ -32,22 +32,77 @@ ServerClientID GridManager::add_default_grid(const std::string& newName) { g.size = world.drawData.cam.c.inverseScale * WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE); g.offset = world.drawData.cam.c.pos + world.drawData.cam.c.dir_from_space(world.main.window.size.cast() * 0.5f); grids[newID] = g; + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, newID, g); + changed = true; + + world.undo.push({[&world = world, &changed = changed, &grids = grids, newID]() { + grids.erase(newID); + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, newID); + changed = true; + return true; + }, + [&world = world, &changed = changed, &grids = grids, g, newID]() { + grids[newID] = g; + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, newID, g); + changed = true; + return true; + }}); + return newID; } -void GridManager::send_grid_info(ServerClientID gridID) { +void GridManager::send_grid_info(WorldGrid oldGrid, ServerClientID gridID) { auto gridFoundIt = grids.find(gridID); if(gridFoundIt != grids.end()) { WorldGrid& g = gridFoundIt->second; world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, g); + + world.undo.push({[&world = world, &changed = changed, &grids = grids, gridID, oldGrid]() { + auto gridFoundIt = grids.find(gridID); + if(gridFoundIt == grids.end()) + return false; + gridFoundIt->second = oldGrid; + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, oldGrid); + changed = true; + return true; + }, + [&world = world, &changed = changed, &grids = grids, gridID, g]() { + auto gridFoundIt = grids.find(gridID); + if(gridFoundIt == grids.end()) + return false; + gridFoundIt->second = g; + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, g); + changed = true; + return true; + }}); + + changed = true; } } void GridManager::remove_grid(ServerClientID idToRemove) { - grids.erase(idToRemove); world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, idToRemove); changed = true; + auto it = grids.find(idToRemove); + if(it == grids.end()) + return; + + WorldGrid g = it->second; + grids.erase(it); + + world.undo.push({[&world = world, &changed = changed, &grids = grids, idToRemove, g]() { + grids[idToRemove] = g; + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, idToRemove, g); + changed = true; + return true; + }, + [&world = world, &changed = changed, &grids = grids, idToRemove]() { + grids.erase(idToRemove); + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, idToRemove); + changed = true; + return true; + }}); } const std::vector& GridManager::sorted_grid_ids() { diff --git a/src/GridManager.hpp b/src/GridManager.hpp index 6ed1ff3..99aa866 100644 --- a/src/GridManager.hpp +++ b/src/GridManager.hpp @@ -19,7 +19,7 @@ class GridManager { changed = true; } - void send_grid_info(ServerClientID gridID); + void send_grid_info(WorldGrid oldGrid, ServerClientID gridID); void remove_grid(ServerClientID idToRemove); void draw_back(SkCanvas* canvas, const DrawData& drawData); void draw_front(SkCanvas* canvas, const DrawData& drawData); diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index b3121a6..6ec7d2a 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -690,8 +690,9 @@ void Toolbar::grid_menu(bool justOpened) { }) { if(gui.svg_icon_button_transparent("visibility eye", grid.visible ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", false, entryHeight, false)) { miniButtonClicked = true; + WorldGrid oldGrid = grid; grid.visible = !grid.visible; - main.world->gridMan.send_grid_info(gridID); + main.world->gridMan.send_grid_info(oldGrid, gridID); } if(gui.svg_icon_button_transparent("edit pencil", "data/icons/pencil.svg", false, entryHeight, false)) { miniButtonClicked = true;