From 2605df6e54157a00836cb0a8329ebf55c7e4a30d Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Tue, 5 Aug 2025 11:35:22 +0300 Subject: [PATCH] Separated transform commit from deselecting, only one undo required to undo a paste operation --- .../DrawingProgramSelection.cpp | 160 +++++++++--------- .../DrawingProgramSelection.hpp | 2 +- 2 files changed, 79 insertions(+), 83 deletions(-) diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index 242a10c..d3faaa1 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -92,96 +92,92 @@ void DrawingProgramSelection::calculate_aabb() { } } -void DrawingProgramSelection::deselect_all(bool readdObjectsToCache) { +void DrawingProgramSelection::deselect_all() { if(is_something_selected()) { - std::vector a(selectedSet.begin(), selectedSet.end()); - std::vector> transformsFrom; - for(auto& transformedObj : a) - transformsFrom.emplace_back(transformedObj, transformedObj->obj->coords); - + bool cacheWillRebuildAnyway = selectedSet.size() >= DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; + if(cacheWillRebuildAnyway) + drawP.force_rebuild_cache(); + else { + for(auto& obj : selectedSet) + drawP.compCache.add_component(obj); + } reset_selection_data(); - - bool isSingleThread = a.size() < DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; - parallel_loop_container(a, [&](auto& obj) { - obj->obj->coords = selectionTransformCoords.other_coord_space_from_this_space(obj->obj->coords); - obj->obj->commit_transform(drawP, false); - }, isSingleThread); - - if(readdObjectsToCache) { - if(!isSingleThread) - drawP.force_rebuild_cache(); - else { - for(auto& obj : a) - drawP.compCache.add_component(obj); - } - } - reset_transform_data(); - - std::vector> transformsTo; - std::vector> transformsToSend; - for(auto& transformedObj : a) { - transformsToSend.emplace_back(transformedObj->id, transformedObj->obj->coords); - transformsTo.emplace_back(transformedObj, transformedObj->obj->coords); - } - DrawComponent::client_send_transform_many(drawP, transformsToSend); - - drawP.world.undo.push(UndoManager::UndoRedoPair{ - [&, transformsFrom = transformsFrom]() { - std::vector> transformsToSend; - for(auto& [comp, coords] : transformsFrom) { - auto lockObjInfo = comp->obj->collabListInfo.lock(); - if(lockObjInfo) - transformsToSend.emplace_back(lockObjInfo->id, coords); - else - return false; - } - - bool isSingleThread = a.size() < DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; - parallel_loop_container(transformsFrom, [&](auto& p) { - auto& [comp, coords] = p; - comp->obj->coords = coords; - comp->obj->commit_transform(drawP, isSingleThread); - }, isSingleThread); - - DrawComponent::client_send_transform_many(drawP, transformsToSend); - - if(!isSingleThread) - drawP.force_rebuild_cache(); - - return true; - }, - [&, transformsTo = transformsTo]() { - std::vector> transformsToSend; - for(auto& [comp, coords] : transformsTo) { - auto lockObjInfo = comp->obj->collabListInfo.lock(); - if(lockObjInfo) - transformsToSend.emplace_back(lockObjInfo->id, coords); - else - return false; - } - - bool isSingleThread = a.size() < DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; - parallel_loop_container(transformsTo, [&](auto& p) { - auto& [comp, coords] = p; - comp->obj->coords = coords; - comp->obj->commit_transform(drawP, isSingleThread); - }, isSingleThread); - - DrawComponent::client_send_transform_many(drawP, transformsToSend); - - if(!isSingleThread) - drawP.force_rebuild_cache(); - - return true; - } - }); } } void DrawingProgramSelection::commit_transform_selection() { auto selectedSetTemp = selectedSet; - deselect_all(false); + + std::vector a(selectedSet.begin(), selectedSet.end()); + std::vector> transformsFrom; + for(auto& transformedObj : a) + transformsFrom.emplace_back(transformedObj, transformedObj->obj->coords); + bool isSingleThread = a.size() < DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; + parallel_loop_container(a, [&](auto& obj) { + obj->obj->coords = selectionTransformCoords.other_coord_space_from_this_space(obj->obj->coords); + obj->obj->commit_transform(drawP, false); + }, isSingleThread); + std::vector> transformsTo; + std::vector> transformsToSend; + for(auto& transformedObj : a) { + transformsToSend.emplace_back(transformedObj->id, transformedObj->obj->coords); + transformsTo.emplace_back(transformedObj, transformedObj->obj->coords); + } + DrawComponent::client_send_transform_many(drawP, transformsToSend); + drawP.world.undo.push(UndoManager::UndoRedoPair{ + [&, transformsFrom = transformsFrom]() { + std::vector> transformsToSend; + for(auto& [comp, coords] : transformsFrom) { + auto lockObjInfo = comp->obj->collabListInfo.lock(); + if(lockObjInfo) + transformsToSend.emplace_back(lockObjInfo->id, coords); + else + return false; + } + + bool isSingleThread = a.size() < DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; + parallel_loop_container(transformsFrom, [&](auto& p) { + auto& [comp, coords] = p; + comp->obj->coords = coords; + comp->obj->commit_transform(drawP, isSingleThread); + }, isSingleThread); + + DrawComponent::client_send_transform_many(drawP, transformsToSend); + + if(!isSingleThread) + drawP.force_rebuild_cache(); + + return true; + }, + [&, transformsTo = transformsTo]() { + std::vector> transformsToSend; + for(auto& [comp, coords] : transformsTo) { + auto lockObjInfo = comp->obj->collabListInfo.lock(); + if(lockObjInfo) + transformsToSend.emplace_back(lockObjInfo->id, coords); + else + return false; + } + + bool isSingleThread = a.size() < DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; + parallel_loop_container(transformsTo, [&](auto& p) { + auto& [comp, coords] = p; + comp->obj->coords = coords; + comp->obj->commit_transform(drawP, isSingleThread); + }, isSingleThread); + + DrawComponent::client_send_transform_many(drawP, transformsToSend); + + if(!isSingleThread) + drawP.force_rebuild_cache(); + + return true; + } + }); + + reset_selection_data(); + reset_transform_data(); set_to_selection(selectedSetTemp); } diff --git a/src/DrawingProgram/DrawingProgramSelection.hpp b/src/DrawingProgram/DrawingProgramSelection.hpp index 153fc3d..481b0f0 100644 --- a/src/DrawingProgram/DrawingProgramSelection.hpp +++ b/src/DrawingProgram/DrawingProgramSelection.hpp @@ -8,7 +8,7 @@ class DrawingProgramSelection { public: DrawingProgramSelection(DrawingProgram& initDrawP); void add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection& cC); - void deselect_all(bool readdObjectsToCache = true); + void deselect_all(); void update(); void draw_components(SkCanvas* canvas, const DrawData& drawData); void draw_gui(SkCanvas* canvas, const DrawData& drawData);