diff --git a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp index 644fe2a..4b3456c 100644 --- a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp @@ -101,17 +101,90 @@ namespace NetworkingObjects { moveCallback = func; } - virtual bool contains(const NetObjID& p) const = 0; - virtual NetObjOrderedListIterator begin() = 0; - virtual NetObjOrderedListIterator end() = 0; - virtual NetObjOrderedListIterator at(uint32_t index) = 0; - virtual NetObjOrderedListIterator get(const NetObjID& id) = 0; - virtual NetObjOrderedListConstIterator begin() const = 0; - virtual NetObjOrderedListConstIterator end() const = 0; - virtual NetObjOrderedListConstIterator at(uint32_t index) const = 0; - virtual NetObjOrderedListConstIterator get(const NetObjID& id) const = 0; - virtual uint32_t size() const = 0; - virtual bool empty() const = 0; + + bool contains(const NetObjID& id) const { + return data_map().contains(id); + } + uint32_t size() const { + return data_list().size(); + } + NetObjOrderedListIterator begin() { + return data_list().begin(); + } + NetObjOrderedListIterator end() { + return data_list().end(); + } + NetObjOrderedListIterator at(uint32_t index) { + auto& data = data_list(); + if(index >= data.size()) + return data.end(); + return std::prev(data.end(), data.size() - index); + } + std::vector> at_ordered_indices(const std::vector& orderedIndices) { + auto& data = data_list(); + std::vector> toRet(orderedIndices.size()); + auto lastIt = data.end(); + uint32_t lastDataIndex = data.size(); + for(std::pair&> p : std::views::zip(orderedIndices, toRet)) { + uint32_t orderedIndex = std::min(p.first, data.size()); + NetObjOrderedListIterator& it = p.second; + for(;;) { + if(lastDataIndex >= orderedIndex) { + it = lastIt; + break; + } + --lastDataIndex; + --lastIt; + } + } + return toRet; + } + NetObjOrderedListIterator get(const NetObjID& id) { + auto it = data_map().find(id); + if(it == data_map().end()) + return data_list().end(); + return it->second; + } + NetObjOrderedListConstIterator begin() const { + return data_list().begin(); + } + NetObjOrderedListConstIterator end() const { + return data_list().end(); + } + NetObjOrderedListConstIterator at(uint32_t index) const { + auto& data = data_list(); + if(index >= data.size()) + return data.end(); + return std::prev(data.begin(), data.size() - index); + } + std::vector> at_ordered_indices(const std::vector& orderedIndices) const { + auto& data = data_list(); + std::vector> toRet(orderedIndices.size()); + auto lastIt = data.end(); + uint32_t lastDataIndex = data.size(); + for(std::pair&> p : std::views::zip(orderedIndices, toRet)) { + uint32_t orderedIndex = std::min(p.first, data.size()); + NetObjOrderedListConstIterator& it = p.second; + for(;;) { + if(lastDataIndex >= orderedIndex) { + it = lastIt; + break; + } + --lastDataIndex; + --lastIt; + } + } + return toRet; + } + NetObjOrderedListConstIterator get(const NetObjID& id) const { + auto it = data_map().find(id); + if(it == data_map().end()) + return data_list().end(); + return it->second; + } + bool empty() const { + return data_list().empty(); + } virtual ~NetObjOrderedList() {} protected: NetObjOrderedListIterator insert_single(const NetObjTemporaryPtr>& l, const std::shared_ptr& clientInserting, const NetObjOrderedListIterator it, NetObjOwnerPtr newObj) { @@ -119,6 +192,10 @@ namespace NetworkingObjects { toInsert.emplace_back(it, std::move(newObj)); return insert_ordered_list(l, clientInserting, toInsert).back(); } + virtual std::list>& data_list() = 0; + virtual const std::list>& data_list() const = 0; + virtual std::unordered_map>& data_map() = 0; + virtual const std::unordered_map>& data_map() const = 0; virtual std::vector> insert_ordered_list(const NetObjTemporaryPtr>& l, const std::shared_ptr& clientInserting, std::vector, NetObjOwnerPtr>>& newObj) = 0; virtual void erase_it_list(const NetObjTemporaryPtr>& l, const std::vector>& itList, std::vector>* erasedObjects) = 0; virtual void write_constructor(const NetObjTemporaryPtr>& l, cereal::PortableBinaryOutputArchive& a) = 0; @@ -167,49 +244,6 @@ namespace NetworkingObjects { template class NetObjOrderedListServer : public NetObjOrderedList { public: NetObjOrderedListServer() {} - virtual bool contains(const NetObjID& id) const override { - return idToDataMap.contains(id); - } - virtual uint32_t size() const override { - return data.size(); - } - virtual NetObjOrderedListIterator begin() override { - return data.begin(); - } - virtual NetObjOrderedListIterator end() override { - return data.end(); - } - virtual NetObjOrderedListIterator at(uint32_t index) override { - if(index >= data.size()) - return data.end(); - return std::next(data.begin(), index); - } - virtual NetObjOrderedListIterator get(const NetObjID& id) override { - auto it = idToDataMap.find(id); - if(it == idToDataMap.end()) - return data.end(); - return it->second; - } - virtual NetObjOrderedListConstIterator begin() const override { - return data.begin(); - } - virtual NetObjOrderedListConstIterator end() const override { - return data.end(); - } - virtual NetObjOrderedListConstIterator at(uint32_t index) const override { - if(index >= data.size()) - return data.end(); - return std::next(data.begin(), index); - } - virtual NetObjOrderedListConstIterator get(const NetObjID& id) const override { - auto it = idToDataMap.find(id); - if(it == idToDataMap.end()) - return data.end(); - return it->second; - } - virtual bool empty() const override { - return data.empty(); - } virtual void reassign_netobj_ids_call() override { idToDataMap.clear(); for(auto it = data.begin(); it != data.end(); ++it) { @@ -218,6 +252,10 @@ namespace NetworkingObjects { } } protected: + virtual std::list>& data_list() override { return data; } + virtual const std::list>& data_list() const override { return data; } + virtual std::unordered_map>& data_map() { return idToDataMap; } + virtual const std::unordered_map>& data_map() const { return idToDataMap; } virtual std::vector> insert_ordered_list(const NetObjTemporaryPtr>& l, const std::shared_ptr& clientInserting, std::vector, NetObjOwnerPtr>>& newObjs) override { if(newObjs.empty()) return {}; @@ -360,49 +398,6 @@ namespace NetworkingObjects { template class NetObjOrderedListClient : public NetObjOrderedList { public: NetObjOrderedListClient() {} - virtual bool contains(const NetObjID& id) const override { - return clientIdToDataMap.contains(id); - } - virtual uint32_t size() const override { - return clientData.size(); - } - virtual NetObjOrderedListIterator begin() override { - return clientData.begin(); - } - virtual NetObjOrderedListIterator end() override { - return clientData.end(); - } - virtual NetObjOrderedListIterator at(uint32_t index) override { - if(index >= clientData.size()) - return clientData.end(); - return std::next(clientData.begin(), index); - } - virtual NetObjOrderedListIterator get(const NetObjID& id) override { - auto it = clientIdToDataMap.find(id); - if(it == clientIdToDataMap.end()) - return clientData.end(); - return it->second; - } - virtual NetObjOrderedListConstIterator begin() const override { - return clientData.begin(); - } - virtual NetObjOrderedListConstIterator end() const override { - return clientData.end(); - } - virtual NetObjOrderedListConstIterator at(uint32_t index) const override { - if(index >= clientData.size()) - return clientData.end(); - return std::next(clientData.begin(), index); - } - virtual NetObjOrderedListConstIterator get(const NetObjID& id) const override { - auto it = clientIdToDataMap.find(id); - if(it == clientIdToDataMap.end()) - return clientData.end(); - return it->second; - } - virtual bool empty() const override { - return clientData.empty(); - } virtual void reassign_netobj_ids_call() override { serverData.clear(); serverIdToDataMap.clear(); @@ -415,6 +410,10 @@ namespace NetworkingObjects { } } protected: + virtual std::list>& data_list() override { return clientData; } + virtual const std::list>& data_list() const override { return clientData; } + virtual std::unordered_map>& data_map() { return clientIdToDataMap; } + virtual const std::unordered_map>& data_map() const { return clientIdToDataMap; } virtual std::vector> insert_ordered_list(const NetObjTemporaryPtr>& l, const std::shared_ptr& clientInserting, std::vector, NetObjOwnerPtr>>& newObjs) override { if(newObjs.empty()) return {}; diff --git a/src/Bookmarks/BookmarkListItem.cpp b/src/Bookmarks/BookmarkListItem.cpp index 3990392..f202b22 100644 --- a/src/Bookmarks/BookmarkListItem.cpp +++ b/src/Bookmarks/BookmarkListItem.cpp @@ -15,20 +15,27 @@ void BookmarkData::scale_up(const WorldScalar& scaleUpAmount) { coords.scale_about(WorldVec{0, 0}, scaleUpAmount, true); } +void BookmarkCompleteUndoData::scale_up(const WorldScalar& scaleUpAmount) { + if(bookmarkData) + bookmarkData.value().scale_up(scaleUpAmount); +} + BookmarkListItem::BookmarkListItem() {} -BookmarkListItem::BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const BookmarkCompleteInitData& initData) { - nameData = netObjMan.make_obj(); - nameData->name = initData.name; - if(initData.folderList) { - auto& initFolderList = initData.folderList.value(); +BookmarkListItem::BookmarkListItem(World& w, const BookmarkCompleteUndoData& undoData) { + nameData = w.netObjMan.make_obj(); + nameData->name = undoData.name; + if(undoData.folderList) { + auto& initFolderList = undoData.folderList.value(); folderData = std::make_unique(); - folderData->folderList = netObjMan.make_obj>(); - for(auto& initFolder : initFolderList) - folderData->folderList->emplace_back_direct(folderData->folderList, netObjMan, initFolder); + folderData->folderList = w.netObjMan.make_obj>(); + for(auto& initFolder : initFolderList) { + auto it = folderData->folderList->emplace_back_direct(folderData->folderList, w, initFolder); + w.undo.register_new_netid_to_existing_undoid(initFolder.undoID, it->obj.get_net_id()); + } } else - bookmarkData = std::make_unique(initData.bookmarkData.value()); + bookmarkData = std::make_unique(undoData.bookmarkData.value()); } BookmarkListItem::BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const std::string& initName, bool isFolder, const BookmarkData& initBookmarkData) { @@ -42,14 +49,16 @@ BookmarkListItem::BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, nameData->name = initName; } -BookmarkCompleteInitData BookmarkListItem::get_complete_init_data() { - BookmarkCompleteInitData toRet; +BookmarkCompleteUndoData BookmarkListItem::get_complete_undo_data(WorldUndoManager& u) { + BookmarkCompleteUndoData toRet; toRet.name = nameData->name; if(folderData) { - toRet.folderList = std::vector(); + toRet.folderList = std::vector(); auto& folderListToRet = toRet.folderList.value(); - for(auto& b : *folderData->folderList) - folderListToRet.emplace_back(b.obj->get_complete_init_data()); + for(auto& b : *folderData->folderList) { + folderListToRet.emplace_back(b.obj->get_complete_undo_data(u)); + folderListToRet.back().undoID = u.get_undoid_from_netid(b.obj.get_net_id()); + } } else toRet.bookmarkData = *bookmarkData; diff --git a/src/Bookmarks/BookmarkListItem.hpp b/src/Bookmarks/BookmarkListItem.hpp index c1e4f70..b88491f 100644 --- a/src/Bookmarks/BookmarkListItem.hpp +++ b/src/Bookmarks/BookmarkListItem.hpp @@ -3,6 +3,7 @@ #include #include #include +#include "../WorldUndoManager.hpp" #include "../CoordSpaceHelper.hpp" #include @@ -18,16 +19,18 @@ struct BookmarkData { void jump_to(World& world) const; }; -struct BookmarkCompleteInitData { +struct BookmarkCompleteUndoData { + WorldUndoManager::UndoObjectID undoID; std::string name; - std::optional> folderList; + std::optional> folderList; std::optional bookmarkData; + void scale_up(const WorldScalar& scaleUpAmount); }; class BookmarkListItem { public: BookmarkListItem(); - BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const BookmarkCompleteInitData& initData); + BookmarkListItem(World& w, const BookmarkCompleteUndoData& undoData); BookmarkListItem(NetworkingObjects::NetObjManager& netObjMan, const std::string& initName, bool isFolder, const BookmarkData& initBookmarkData); bool is_folder() const; const BookmarkData& get_bookmark_data() const; @@ -40,7 +43,8 @@ class BookmarkListItem { void scale_up(const WorldScalar& scaleUpAmount); void save_file(cereal::PortableBinaryOutputArchive& a) const; void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version, BookmarkManager& bMan); - BookmarkCompleteInitData get_complete_init_data(); + + BookmarkCompleteUndoData get_complete_undo_data(WorldUndoManager& u); void set_name(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, const std::string& newName); private: diff --git a/src/Bookmarks/BookmarkManager.cpp b/src/Bookmarks/BookmarkManager.cpp index 96b27e0..4584a17 100644 --- a/src/Bookmarks/BookmarkManager.cpp +++ b/src/Bookmarks/BookmarkManager.cpp @@ -16,7 +16,7 @@ void BookmarkManager::server_init_no_file() { void BookmarkManager::refresh_gui_data() { selectionData = GUIStuff::TreeListing::SelectionData(); - oldSelection.clear(); + editing_bookmark_check(); nameToEdit.clear(); nameForNew.clear(); } @@ -123,23 +123,20 @@ void BookmarkManager::setup_list_gui(const std::string& id) { if(selectionData.objsSelected != oldSelection) { - oldSelection = selectionData.objsSelected; + editing_bookmark_check(); if(selectionData.objsSelected.size() == 1) { NetObjTemporaryPtr tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); if(tempPtr) nameToEdit = tempPtr->get_name(); - else { + else nameToEdit.clear(); - } } else nameToEdit.clear(); } - if(toDeleteObject.has_value()) { - auto& folderList = world.netObjMan.get_obj_temporary_ref_from_id(toDeleteParent.value())->get_folder_list(); - folderList->erase(folderList, folderList->get(toDeleteObject.value())); - } + if(toDeleteObject.has_value()) + remove_bookmark(toDeleteParent.value(), toDeleteObject.value()); } gui.left_to_right_line_layout([&]() { @@ -149,9 +146,9 @@ void BookmarkManager::setup_list_gui(const std::string& id) { }); if(gui.svg_icon_button("create new bookmark", "data/icons/plusbold.svg", false, gui.SMALL_BUTTON_SIZE) || addByEnter) - create_in_proper_position(new BookmarkListItem(world.netObjMan, nameForNew, false, {world.drawData.cam.c, world.main.window.size.cast()})); + create_bookmark(new BookmarkListItem(world.netObjMan, nameForNew, false, {world.drawData.cam.c, world.main.window.size.cast()})); else if(gui.svg_icon_button("create new folder", "data/icons/folderbold.svg", false, gui.SMALL_BUTTON_SIZE)) { - auto newFolderObjInfo = create_in_proper_position(new BookmarkListItem(world.netObjMan, nameForNew, true, {})); + auto newFolderObjInfo = create_bookmark(new BookmarkListItem(world.netObjMan, nameForNew, true, {})); newFolderObjInfo->obj->set_folder_open(true); } }); @@ -169,7 +166,7 @@ void BookmarkManager::setup_list_gui(const std::string& id) { } } -std::optional> BookmarkManager::try_to_create_in_proper_position(BookmarkListItem* newItem) { +std::optional>> BookmarkManager::try_to_create_in_proper_position(BookmarkListItem* newItem) { using namespace NetworkingObjects; if(selectionData.orderedObjsSelected.empty()) return std::nullopt; @@ -182,18 +179,126 @@ std::optional> Bo return std::nullopt; if(objectPtr->is_folder()) { objectPtr->set_folder_open(true); - return objectPtr->get_folder_list()->push_back_and_send_create(objectPtr->get_folder_list(), newItem); + return std::pair>{objectPtr.get_net_id(), objectPtr->get_folder_list()->push_back_and_send_create(objectPtr->get_folder_list(), newItem)}; } - return parentPtr->get_folder_list()->insert_and_send_create(parentPtr->get_folder_list(), std::next(parentPtr->get_folder_list()->get(objectPtr.get_net_id())), newItem); + return std::pair>{parentPtr.get_net_id(), parentPtr->get_folder_list()->insert_and_send_create(parentPtr->get_folder_list(), std::next(parentPtr->get_folder_list()->get(objectPtr.get_net_id())), newItem)}; } -NetworkingObjects::NetObjOrderedListIterator BookmarkManager::create_in_proper_position(BookmarkListItem* newItem) { +std::pair> BookmarkManager::create_in_proper_position(BookmarkListItem* newItem) { auto toRet = try_to_create_in_proper_position(newItem); if(!toRet) - return bookmarkListRoot->get_folder_list()->push_back_and_send_create(bookmarkListRoot->get_folder_list(), newItem); + return {bookmarkListRoot.get_net_id(), bookmarkListRoot->get_folder_list()->push_back_and_send_create(bookmarkListRoot->get_folder_list(), newItem)}; return toRet.value(); } +NetworkingObjects::NetObjOrderedListIterator BookmarkManager::create_bookmark(BookmarkListItem* newItem) { + class AddBookmarkWorldUndoAction : public WorldUndoAction { + public: + AddBookmarkWorldUndoAction(const BookmarkCompleteUndoData& initBookmarkData, uint32_t newPos, WorldUndoManager::UndoObjectID initParentUndoID, WorldUndoManager::UndoObjectID initUndoID): + bookmarkData(initBookmarkData), + pos(newPos), + parentUndoID(initParentUndoID), + undoID(initUndoID) + {} + std::string get_name() const override { + return bookmarkData.folderList ? "Add Bookmark Folder" : "Add Bookmark"; + } + bool undo(WorldUndoManager& undoMan) override { + std::optional toEraseParentID = undoMan.get_netid_from_undoid(parentUndoID); + if(!toEraseParentID.has_value()) + return false; + std::optional toEraseID = undoMan.get_netid_from_undoid(undoID); + if(!toEraseID.has_value()) + return false; + + auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toEraseParentID.value())->get_folder_list(); + bookmarkList->erase(bookmarkList, bookmarkList->get(toEraseID.value())); + return true; + } + bool redo(WorldUndoManager& undoMan) override { + std::optional toInsertParentID = undoMan.get_netid_from_undoid(parentUndoID); + if(!toInsertParentID.has_value()) + return false; + std::optional toInsertID = undoMan.get_netid_from_undoid(undoID); + if(toInsertID.has_value()) + return false; + + auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toInsertParentID.value())->get_folder_list(); + auto insertedIt = bookmarkList->emplace_direct(bookmarkList, bookmarkList->at(pos), undoMan.world, bookmarkData); + undoMan.register_new_netid_to_existing_undoid(undoID, insertedIt->obj.get_net_id()); + return true; + } + void scale_up(const WorldScalar& scaleAmount) override { + bookmarkData.scale_up(scaleAmount); + } + ~AddBookmarkWorldUndoAction() {} + + BookmarkCompleteUndoData bookmarkData; + uint32_t pos; + WorldUndoManager::UndoObjectID parentUndoID; + WorldUndoManager::UndoObjectID undoID; + }; + + auto insertedBookmarkPair = create_in_proper_position(newItem); + auto& it = insertedBookmarkPair.second; + world.undo.push(std::make_unique(it->obj->get_complete_undo_data(world.undo), it->pos, world.undo.get_undoid_from_netid(insertedBookmarkPair.first), world.undo.get_undoid_from_netid(it->obj.get_net_id()))); + return it; +} + +void BookmarkManager::remove_bookmark(const NetworkingObjects::NetObjID& parentID, const NetworkingObjects::NetObjID& objectID) { + class DeleteBookmarkWorldUndoAction : public WorldUndoAction { + public: + DeleteBookmarkWorldUndoAction(const BookmarkCompleteUndoData& initBookmarkData, uint32_t newPos, WorldUndoManager::UndoObjectID initParentUndoID, WorldUndoManager::UndoObjectID initUndoID): + bookmarkData(initBookmarkData), + pos(newPos), + parentUndoID(initParentUndoID), + undoID(initUndoID) + {} + std::string get_name() const override { + return bookmarkData.folderList ? "Delete Bookmark Folder" : "Delete Bookmark"; + } + bool undo(WorldUndoManager& undoMan) override { + std::optional toInsertParentID = undoMan.get_netid_from_undoid(parentUndoID); + if(!toInsertParentID.has_value()) + return false; + std::optional toInsertID = undoMan.get_netid_from_undoid(undoID); + if(toInsertID.has_value()) + return false; + + auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toInsertParentID.value())->get_folder_list(); + auto insertedIt = bookmarkList->emplace_direct(bookmarkList, bookmarkList->at(pos), undoMan.world, bookmarkData); + undoMan.register_new_netid_to_existing_undoid(undoID, insertedIt->obj.get_net_id()); + return true; + } + bool redo(WorldUndoManager& undoMan) override { + std::optional toEraseParentID = undoMan.get_netid_from_undoid(parentUndoID); + if(!toEraseParentID.has_value()) + return false; + std::optional toEraseID = undoMan.get_netid_from_undoid(undoID); + if(!toEraseID.has_value()) + return false; + + auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toEraseParentID.value())->get_folder_list(); + bookmarkList->erase(bookmarkList, bookmarkList->get(toEraseID.value())); + return true; + } + void scale_up(const WorldScalar& scaleAmount) override { + bookmarkData.scale_up(scaleAmount); + } + ~DeleteBookmarkWorldUndoAction() {} + + BookmarkCompleteUndoData bookmarkData; + uint32_t pos; + WorldUndoManager::UndoObjectID parentUndoID; + WorldUndoManager::UndoObjectID undoID; + }; + + auto& folderList = world.netObjMan.get_obj_temporary_ref_from_id(parentID)->get_folder_list(); + auto it = folderList->get(objectID); + world.undo.push(std::make_unique(it->obj->get_complete_undo_data(world.undo), it->pos, world.undo.get_undoid_from_netid(parentID), world.undo.get_undoid_from_netid(objectID))); + folderList->erase(folderList, it); +} + void BookmarkManager::scale_up(const WorldScalar& scaleUpAmount) { bookmarkListRoot->scale_up(scaleUpAmount); } @@ -221,3 +326,55 @@ void BookmarkManager::load_file(cereal::PortableBinaryInputArchive& a, VersionNu bookmarkListRoot->get_folder_list()->push_back_and_send_create(bookmarkListRoot->get_folder_list(), new BookmarkListItem(world.netObjMan, name, false, bData)); } } + +void BookmarkManager::editing_bookmark_check() { + class EditBookmarkWorldUndoAction : public WorldUndoAction { + public: + EditBookmarkWorldUndoAction(const std::string& initNameOld, const std::string& initNameNew, WorldUndoManager::UndoObjectID initUndoID): + nameOld(initNameOld), + nameNew(initNameNew), + undoID(initUndoID) + {} + std::string get_name() const override { + return "Edit Bookmark"; + } + bool undo(WorldUndoManager& undoMan) override { + std::optional toModifyID = undoMan.get_netid_from_undoid(undoID); + if(!toModifyID.has_value()) + return false; + auto objPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toModifyID.value()); + objPtr->set_name(undoMan.world.delayedUpdateObjectManager, nameOld); + return true; + } + bool redo(WorldUndoManager& undoMan) override { + std::optional toModifyID = undoMan.get_netid_from_undoid(undoID); + if(!toModifyID.has_value()) + return false; + auto objPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toModifyID.value()); + objPtr->set_name(undoMan.world.delayedUpdateObjectManager, nameNew); + return true; + } + ~EditBookmarkWorldUndoAction() {} + + std::string nameOld; + std::string nameNew; + WorldUndoManager::UndoObjectID undoID; + }; + + if(oldSelection.size() == 1 && editingBookmarkName.has_value()) { + const NetworkingObjects::NetObjID& oldNetObjID = *oldSelection.begin(); + auto tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(oldNetObjID); + if(tempPtr) { + const std::string& currentNameData = tempPtr->get_name(); + if(currentNameData != editingBookmarkName.value()) + world.undo.push(std::make_unique(editingBookmarkName.value(), currentNameData, world.undo.get_undoid_from_netid(oldNetObjID))); + } + } + editingBookmarkName = std::nullopt; + if(selectionData.objsSelected.size() == 1) { + auto tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); + if(tempPtr) + editingBookmarkName = tempPtr->get_name(); + } + oldSelection = selectionData.objsSelected; +} diff --git a/src/Bookmarks/BookmarkManager.hpp b/src/Bookmarks/BookmarkManager.hpp index e5d2916..15f1481 100644 --- a/src/Bookmarks/BookmarkManager.hpp +++ b/src/Bookmarks/BookmarkManager.hpp @@ -20,13 +20,20 @@ class BookmarkManager { NetworkingObjects::NetObjOwnerPtr bookmarkListRoot; private: - NetworkingObjects::NetObjOrderedListIterator create_in_proper_position(BookmarkListItem* newItem); - std::optional> try_to_create_in_proper_position(BookmarkListItem* newItem); + std::pair> create_in_proper_position(BookmarkListItem* newItem); + std::optional>> try_to_create_in_proper_position(BookmarkListItem* newItem); + NetworkingObjects::NetObjOrderedListIterator create_bookmark(BookmarkListItem* newItem); + void remove_bookmark(const NetworkingObjects::NetObjID& parentID, const NetworkingObjects::NetObjID& objectID); + GUIStuff::TreeListing::SelectionData selectionData; std::unordered_set oldSelection; std::string nameToEdit; std::string nameForNew; + std::optional editingBookmarkName; + + void editing_bookmark_check(); + friend class BookmarkListItem; World& world; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayer.cpp b/src/DrawingProgram/Layers/DrawingProgramLayer.cpp index d1426fd..919837d 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayer.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayer.cpp @@ -9,6 +9,13 @@ void DrawingProgramLayer::draw(SkCanvas* canvas, const DrawData& drawData) const p.obj->draw(canvas, drawData); } +DrawingProgramLayerInitData DrawingProgramLayer::get_init_data() const { + DrawingProgramLayerInitData toRet; + for(auto& p : *components) + toRet.components.emplace_back(p.obj->get_data_copy()); + return toRet; +} + void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerListItem& layerListItem, DrawingProgramLayerManager& layerMan) { auto insertCallback = [&](const CanvasComponentContainer::ObjInfoIterator& c) { c->obj->objInfo = c; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayer.hpp b/src/DrawingProgram/Layers/DrawingProgramLayer.hpp index a8e1802..ee1b217 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayer.hpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayer.hpp @@ -6,6 +6,10 @@ class DrawingProgramLayerListItem; class DrawingProgramLayerManager; +struct DrawingProgramLayerInitData { + std::vector> components; +}; + class DrawingProgramLayer { public: void draw(SkCanvas* canvas, const DrawData& drawData) const; @@ -13,6 +17,7 @@ class DrawingProgramLayer { void get_flattened_component_list(std::vector& objList) const; void set_to_erase(); void scale_up(const WorldScalar& scaleUpAmount); + DrawingProgramLayerInitData get_init_data() const; CanvasComponentContainer::NetListOwnerPtr components; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp b/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp index 06ecfbd..8ccc89d 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerFolder.hpp @@ -7,6 +7,10 @@ class DrawingProgramLayerListItem; class DrawingProgramLayerManager; +struct DrawingProgramLayerFolderInitData { + std::vector folderList; +}; + class DrawingProgramLayerFolder { public: void draw(SkCanvas* canvas, const DrawData& drawData) const; diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp b/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp index afec8a0..bcc60a3 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerListItem.hpp @@ -13,10 +13,23 @@ class DrawingProgramLayer; class World; class DrawingProgramLayerManager; +struct DrawingProgramLayerListItemMetaInfoInitData { + std::string name; + float alpha = 1.0f; + SerializedBlendMode blendMode = SerializedBlendMode::SRC_OVER; +}; + +struct DrawingProgramLayerListItemInitData { + DrawingProgramLayerListItemMetaInfoInitData metaInfo; + std::optional folderData; + std::optional layerData; +}; + class DrawingProgramLayerListItem { public: DrawingProgramLayerListItem(); DrawingProgramLayerListItem(NetworkingObjects::NetObjManager& netObjMan, const std::string& initName, bool isFolder); + DrawingProgramLayerListItem(NetworkingObjects::NetObjManager& netObjMan, const DrawingProgramLayerListItemInitData& initData); bool is_folder() const; DrawingProgramLayerFolder& get_folder() const; DrawingProgramLayer& get_layer() const; diff --git a/src/GridManager.cpp b/src/GridManager.cpp index e285264..773e7d9 100644 --- a/src/GridManager.cpp +++ b/src/GridManager.cpp @@ -63,15 +63,15 @@ void GridManager::add_default_grid(const std::string& newName) { void GridManager::remove_grid(uint32_t indexToRemove) { if(grids) { - class EraseGridWorldUndoAction : public WorldUndoAction { + class DeleteGridWorldUndoAction : public WorldUndoAction { public: - EraseGridWorldUndoAction(const WorldGrid& initGridData, uint32_t newPos, WorldUndoManager::UndoObjectID initUndoID): + DeleteGridWorldUndoAction(const WorldGrid& initGridData, uint32_t newPos, WorldUndoManager::UndoObjectID initUndoID): gridData(initGridData), pos(newPos), undoID(initUndoID) {} std::string get_name() const override { - return "Remove Grid"; + return "Delete Grid"; } bool undo(WorldUndoManager& undoMan) override { std::optional toInsertID = undoMan.get_netid_from_undoid(undoID); @@ -93,7 +93,7 @@ void GridManager::remove_grid(uint32_t indexToRemove) { void scale_up(const WorldScalar& scaleAmount) override { gridData.scale_up(scaleAmount); } - ~EraseGridWorldUndoAction() {} + ~DeleteGridWorldUndoAction() {} WorldGrid gridData; uint32_t pos; @@ -101,36 +101,36 @@ void GridManager::remove_grid(uint32_t indexToRemove) { }; auto it = grids->at(indexToRemove); - world.undo.push(std::make_unique(*it->obj, it->pos, world.undo.get_undoid_from_netid(it->obj.get_net_id()))); + world.undo.push(std::make_unique(*it->obj, it->pos, world.undo.get_undoid_from_netid(it->obj.get_net_id()))); grids->erase(grids, it); } } void GridManager::finalize_grid_modify(const NetworkingObjects::NetObjTemporaryPtr& wGrid, const WorldGrid& oldGridData) { - class ModifyGridWorldUndoAction : public WorldUndoAction { + class EditGridWorldUndoAction : public WorldUndoAction { public: - ModifyGridWorldUndoAction(const WorldGrid& initGridDataOld, const WorldGrid& initGridDataNew, WorldUndoManager::UndoObjectID initUndoID): + EditGridWorldUndoAction(const WorldGrid& initGridDataOld, const WorldGrid& initGridDataNew, WorldUndoManager::UndoObjectID initUndoID): gridDataOld(initGridDataOld), gridDataNew(initGridDataNew), undoID(initUndoID) {} std::string get_name() const override { - return "Modify Grid"; + return "Edit Grid"; } bool undo(WorldUndoManager& undoMan) override { - std::optional toModifyID = undoMan.get_netid_from_undoid(undoID); - if(!toModifyID.has_value()) + std::optional toEditID = undoMan.get_netid_from_undoid(undoID); + if(!toEditID.has_value()) return false; - auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toModifyID.value()); + auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toEditID.value()); *gridPtr = gridDataOld; undoMan.world.delayedUpdateObjectManager.send_update_to_all(gridPtr, true); return true; } bool redo(WorldUndoManager& undoMan) override { - std::optional toModifyID = undoMan.get_netid_from_undoid(undoID); - if(!toModifyID.has_value()) + std::optional toEditID = undoMan.get_netid_from_undoid(undoID); + if(!toEditID.has_value()) return false; - auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toModifyID.value()); + auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(toEditID.value()); *gridPtr = gridDataNew; undoMan.world.delayedUpdateObjectManager.send_update_to_all(gridPtr, true); return true; @@ -139,14 +139,14 @@ void GridManager::finalize_grid_modify(const NetworkingObjects::NetObjTemporaryP gridDataOld.scale_up(scaleAmount); gridDataNew.scale_up(scaleAmount); } - ~ModifyGridWorldUndoAction() {} + ~EditGridWorldUndoAction() {} WorldGrid gridDataOld; WorldGrid gridDataNew; WorldUndoManager::UndoObjectID undoID; }; - world.undo.push(std::make_unique(oldGridData, *wGrid, world.undo.get_undoid_from_netid(wGrid.get_net_id()))); + world.undo.push(std::make_unique(oldGridData, *wGrid, world.undo.get_undoid_from_netid(wGrid.get_net_id()))); world.delayedUpdateObjectManager.send_update_to_all(wGrid, true); }