Readded clipboard

This commit is contained in:
Yousef Khadadeh 2025-07-28 11:09:59 +03:00
parent 60230cc8ef
commit d9761a84b5
5 changed files with 140 additions and 14 deletions

View file

@ -46,7 +46,8 @@ DrawingProgram::DrawingProgram(World& initWorld):
world.main.drawProgCache.refresh = true;
};
components.clientInsertCallback = [&](const CollabListType::ObjectInfoPtr& c) {
compCache.add_component(c);
if(addToCompCacheOnInsert)
compCache.add_component(c);
DrawComponentType t = c->obj->get_type();
if(t == DRAWCOMPONENT_IMAGE || t == DRAWCOMPONENT_TEXTBOX)
updateableComponents.emplace(c->obj);
@ -547,10 +548,48 @@ void DrawingProgram::add_undo_place_component(const CollabListType::ObjectInfoPt
});
}
void DrawingProgram::add_undo_erase_components(const std::unordered_set<CollabListType::ObjectInfoPtr>& erasedComponents) {
void DrawingProgram::add_undo_place_components(const std::unordered_set<CollabListType::ObjectInfoPtr>& objSetToUndo) {
world.undo.push(UndoManager::UndoRedoPair{
[&, erasedComponents = erasedComponents]() {
std::vector<CollabListType::ObjectInfoPtr> sortedObjects(erasedComponents.begin(), erasedComponents.end());
[&, objSetToUndo = objSetToUndo]() {
for(auto& comp : objSetToUndo)
if(!comp->obj->collabListInfo.lock())
return false;
std::unordered_set<ServerClientID> idsToErase;
for(auto& c : objSetToUndo)
idsToErase.emplace(c->id);
DrawComponent::client_send_erase_set(*this, idsToErase);
components.client_erase_set(objSetToUndo);
reset_tools();
return true;
},
[&, objSetToUndo = objSetToUndo]() {
std::vector<CollabListType::ObjectInfoPtr> sortedObjects(objSetToUndo.begin(), objSetToUndo.end());
std::sort(sortedObjects.begin(), sortedObjects.end(), [](auto& a, auto& b) {
return a->pos < b->pos;
});
for(auto& comp : sortedObjects)
if(comp->obj->collabListInfo.lock())
return false;
components.client_insert_ordered_vector(sortedObjects);
DrawComponent::client_send_place_many(*this, sortedObjects);
reset_tools();
return true;
}
});
}
void DrawingProgram::add_undo_erase_components(const std::unordered_set<CollabListType::ObjectInfoPtr>& objSetToUndo) {
world.undo.push(UndoManager::UndoRedoPair{
[&, objSetToUndo = objSetToUndo]() {
std::vector<CollabListType::ObjectInfoPtr> sortedObjects(objSetToUndo.begin(), objSetToUndo.end());
std::sort(sortedObjects.begin(), sortedObjects.end(), [](auto& a, auto& b) {
return a->pos < b->pos;
});
@ -566,17 +605,17 @@ void DrawingProgram::add_undo_erase_components(const std::unordered_set<CollabLi
return true;
},
[&, erasedComponents = erasedComponents]() {
for(auto& comp : erasedComponents)
[&, objSetToUndo = objSetToUndo]() {
for(auto& comp : objSetToUndo)
if(!comp->obj->collabListInfo.lock())
return false;
std::unordered_set<ServerClientID> idsToErase;
for(auto& c : erasedComponents)
for(auto& c : objSetToUndo)
idsToErase.emplace(c->id);
DrawComponent::client_send_erase_set(*this, idsToErase);
components.client_erase_set(erasedComponents);
components.client_erase_set(objSetToUndo);
reset_tools();

View file

@ -68,6 +68,8 @@ class DrawingProgram {
void force_rebuild_cache();
bool addToCompCacheOnInsert = true;
std::atomic<bool> addFileInNextFrame = false;
std::pair<std::string, Vector2f> addFileInfo;
@ -80,6 +82,7 @@ class DrawingProgram {
void draw_drag_circle(SkCanvas* canvas, const Vector2f& pos, const SkColor4f& c, const DrawData& drawData, float radiusMultiplier = 1.0f);
void add_undo_place_component(const CollabListType::ObjectInfoPtr& objToUndo);
void add_undo_place_components(const std::unordered_set<CollabListType::ObjectInfoPtr>& objSetToUndo);
void add_undo_erase_components(const std::unordered_set<CollabListType::ObjectInfoPtr>& objSetToUndo);
BrushTool brushTool;

View file

@ -59,7 +59,11 @@ void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCo
return false;
});
selectedSet = selectedComponents;
set_to_selection(selectedComponents);
}
void DrawingProgramSelection::set_to_selection(const std::unordered_set<CollabListType::ObjectInfoPtr>& newSelection) {
selectedSet = newSelection;
for(auto& obj : selectedSet)
cache.add_component(obj);
calculate_aabb();
@ -178,16 +182,27 @@ void DrawingProgramSelection::delete_all() {
}
}
// NOTE: Only run this if no transformations happened
void DrawingProgramSelection::selection_to_clipboard() {
auto& clipboard = drawP.world.main.clipboard;
std::unordered_set<ServerClientID> resourceSet;
for(auto& c : selectedSet)
c->obj->get_used_resources(resourceSet);
std::vector<CollabListType::ObjectInfoPtr> compVecSort(selectedSet.begin(), selectedSet.end());
std::sort(compVecSort.begin(), compVecSort.end(), [&](auto& a, auto& b) {
return a->pos < b->pos;
});
clipboard.components.clear();
for(auto& c : compVecSort)
clipboard.components.emplace_back(c->obj);
clipboard.pos = initialSelectionAABB.center();
}
void DrawingProgramSelection::update() {
if(is_something_selected()) {
if(cache.check_if_rebuild_should_occur())
cache.test_rebuild(std::vector<CollabListType::ObjectInfoPtr>(selectedSet.begin(), selectedSet.end()), true);
if(drawP.world.main.input.key(InputManager::KEY_DRAW_UNSELECT).pressed)
deselect_all();
else if(drawP.world.main.input.key(InputManager::KEY_DRAW_DELETE).pressed)
delete_all();
selectionRectPoints[0] = selectionTransformCoords.from_space_world(initialSelectionAABB.min);
selectionRectPoints[1] = selectionTransformCoords.from_space_world(initialSelectionAABB.bottom_left());
selectionRectPoints[2] = selectionTransformCoords.from_space_world(initialSelectionAABB.max);
@ -280,7 +295,50 @@ void DrawingProgramSelection::update() {
transformOpHappening = TransformOperation::NONE;
break;
}
if(drawP.world.main.input.key(InputManager::KEY_DRAW_UNSELECT).pressed)
deselect_all();
else if(drawP.world.main.input.key(InputManager::KEY_DRAW_DELETE).pressed)
delete_all();
else if(drawP.world.main.input.key(InputManager::KEY_COPY).pressed && startingSelectionTransformCoords == CoordSpaceHelper())
selection_to_clipboard();
else if(drawP.world.main.input.key(InputManager::KEY_CUT).pressed && startingSelectionTransformCoords == CoordSpaceHelper()) {
selection_to_clipboard();
delete_all();
}
else if(drawP.world.main.input.key(InputManager::KEY_PASTE).pressed) {
deselect_all();
paste_clipboard();
}
}
else if(drawP.world.main.input.key(InputManager::KEY_PASTE).pressed && !drawP.prevent_undo_or_redo())
paste_clipboard();
}
void DrawingProgramSelection::paste_clipboard() {
auto& clipboard = drawP.world.main.clipboard;
drawP.reset_tools();
drawP.controls.selectedTool = DrawingProgram::TOOL_RECTSELECT;
drawP.controls.previousSelected = DrawingProgram::TOOL_RECTSELECT;
uint64_t allPlacement = drawP.components.client_list().size();
std::vector<std::shared_ptr<DrawComponent>> placedComponents;
WorldVec mousePos = drawP.world.get_mouse_world_pos();
WorldVec moveVec = drawP.world.main.clipboard.pos - mousePos;
std::unordered_map<ServerClientID, ServerClientID> resourceRemapIDs;
for(auto& r : clipboard.resources)
resourceRemapIDs[r.first] = drawP.world.rMan.add_resource(r.second);
for(auto& c : clipboard.components) {
auto& newC = placedComponents.emplace_back(c->copy());
newC->remap_resource_ids(resourceRemapIDs);
newC->coords.translate(-moveVec);
newC->final_update(drawP, false);
}
drawP.addToCompCacheOnInsert = false;
auto compListInserted = drawP.components.client_insert_ordered_vector_items(allPlacement, placedComponents);
drawP.addToCompCacheOnInsert = true;
std::unordered_set<CollabListType::ObjectInfoPtr> compSetInserted(compListInserted.begin(), compListInserted.end());
set_to_selection(compSetInserted);
drawP.add_undo_place_components(compSetInserted);
}
void DrawingProgramSelection::rebuild_cam_space() {

View file

@ -22,6 +22,9 @@ class DrawingProgramSelection {
bool mouse_collided_with_scale_point();
bool mouse_collided_with_rotate_center_handle_point();
bool mouse_collided_with_rotate_handle_point();
void selection_to_clipboard();
void paste_clipboard();
void set_to_selection(const std::unordered_set<CollabListType::ObjectInfoPtr>& newSelection);
void calculate_aabb();
void calculate_initial_rotate_center_location();