Bookmark undo works

This commit is contained in:
Yousef Khadadeh 2026-01-03 13:35:24 +03:00
parent 0e22c8ac3e
commit 974985ffcd
10 changed files with 353 additions and 148 deletions

View file

@ -101,17 +101,90 @@ namespace NetworkingObjects {
moveCallback = func;
}
virtual bool contains(const NetObjID& p) const = 0;
virtual NetObjOrderedListIterator<T> begin() = 0;
virtual NetObjOrderedListIterator<T> end() = 0;
virtual NetObjOrderedListIterator<T> at(uint32_t index) = 0;
virtual NetObjOrderedListIterator<T> get(const NetObjID& id) = 0;
virtual NetObjOrderedListConstIterator<T> begin() const = 0;
virtual NetObjOrderedListConstIterator<T> end() const = 0;
virtual NetObjOrderedListConstIterator<T> at(uint32_t index) const = 0;
virtual NetObjOrderedListConstIterator<T> 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<T> begin() {
return data_list().begin();
}
NetObjOrderedListIterator<T> end() {
return data_list().end();
}
NetObjOrderedListIterator<T> 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<NetObjOrderedListIterator<T>> at_ordered_indices(const std::vector<uint32_t>& orderedIndices) {
auto& data = data_list();
std::vector<NetObjOrderedListIterator<T>> toRet(orderedIndices.size());
auto lastIt = data.end();
uint32_t lastDataIndex = data.size();
for(std::pair<uint32_t&, NetObjOrderedListIterator<T>&> p : std::views::zip(orderedIndices, toRet)) {
uint32_t orderedIndex = std::min(p.first, data.size());
NetObjOrderedListIterator<T>& it = p.second;
for(;;) {
if(lastDataIndex >= orderedIndex) {
it = lastIt;
break;
}
--lastDataIndex;
--lastIt;
}
}
return toRet;
}
NetObjOrderedListIterator<T> get(const NetObjID& id) {
auto it = data_map().find(id);
if(it == data_map().end())
return data_list().end();
return it->second;
}
NetObjOrderedListConstIterator<T> begin() const {
return data_list().begin();
}
NetObjOrderedListConstIterator<T> end() const {
return data_list().end();
}
NetObjOrderedListConstIterator<T> 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<NetObjOrderedListConstIterator<T>> at_ordered_indices(const std::vector<uint32_t>& orderedIndices) const {
auto& data = data_list();
std::vector<NetObjOrderedListConstIterator<T>> toRet(orderedIndices.size());
auto lastIt = data.end();
uint32_t lastDataIndex = data.size();
for(std::pair<uint32_t&, NetObjOrderedListConstIterator<T>&> p : std::views::zip(orderedIndices, toRet)) {
uint32_t orderedIndex = std::min(p.first, data.size());
NetObjOrderedListConstIterator<T>& it = p.second;
for(;;) {
if(lastDataIndex >= orderedIndex) {
it = lastIt;
break;
}
--lastDataIndex;
--lastIt;
}
}
return toRet;
}
NetObjOrderedListConstIterator<T> 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<T> insert_single(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, const NetObjOrderedListIterator<T> it, NetObjOwnerPtr<T> 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<NetObjOrderedListObjectInfo<T>>& data_list() = 0;
virtual const std::list<NetObjOrderedListObjectInfo<T>>& data_list() const = 0;
virtual std::unordered_map<NetworkingObjects::NetObjID, NetObjOrderedListIterator<T>>& data_map() = 0;
virtual const std::unordered_map<NetworkingObjects::NetObjID, NetObjOrderedListIterator<T>>& data_map() const = 0;
virtual std::vector<NetObjOrderedListIterator<T>> insert_ordered_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, std::vector<std::pair<NetObjOrderedListIterator<T>, NetObjOwnerPtr<T>>>& newObj) = 0;
virtual void erase_it_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::vector<NetObjOrderedListIterator<T>>& itList, std::vector<NetObjOwnerPtr<T>>* erasedObjects) = 0;
virtual void write_constructor(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, cereal::PortableBinaryOutputArchive& a) = 0;
@ -167,49 +244,6 @@ namespace NetworkingObjects {
template <typename T> class NetObjOrderedListServer : public NetObjOrderedList<T> {
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<T> begin() override {
return data.begin();
}
virtual NetObjOrderedListIterator<T> end() override {
return data.end();
}
virtual NetObjOrderedListIterator<T> at(uint32_t index) override {
if(index >= data.size())
return data.end();
return std::next(data.begin(), index);
}
virtual NetObjOrderedListIterator<T> get(const NetObjID& id) override {
auto it = idToDataMap.find(id);
if(it == idToDataMap.end())
return data.end();
return it->second;
}
virtual NetObjOrderedListConstIterator<T> begin() const override {
return data.begin();
}
virtual NetObjOrderedListConstIterator<T> end() const override {
return data.end();
}
virtual NetObjOrderedListConstIterator<T> at(uint32_t index) const override {
if(index >= data.size())
return data.end();
return std::next(data.begin(), index);
}
virtual NetObjOrderedListConstIterator<T> 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<NetObjOrderedListObjectInfo<T>>& data_list() override { return data; }
virtual const std::list<NetObjOrderedListObjectInfo<T>>& data_list() const override { return data; }
virtual std::unordered_map<NetworkingObjects::NetObjID, NetObjOrderedListIterator<T>>& data_map() { return idToDataMap; }
virtual const std::unordered_map<NetworkingObjects::NetObjID, NetObjOrderedListIterator<T>>& data_map() const { return idToDataMap; }
virtual std::vector<NetObjOrderedListIterator<T>> insert_ordered_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, std::vector<std::pair<NetObjOrderedListIterator<T>, NetObjOwnerPtr<T>>>& newObjs) override {
if(newObjs.empty())
return {};
@ -360,49 +398,6 @@ namespace NetworkingObjects {
template <typename T> class NetObjOrderedListClient : public NetObjOrderedList<T> {
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<T> begin() override {
return clientData.begin();
}
virtual NetObjOrderedListIterator<T> end() override {
return clientData.end();
}
virtual NetObjOrderedListIterator<T> at(uint32_t index) override {
if(index >= clientData.size())
return clientData.end();
return std::next(clientData.begin(), index);
}
virtual NetObjOrderedListIterator<T> get(const NetObjID& id) override {
auto it = clientIdToDataMap.find(id);
if(it == clientIdToDataMap.end())
return clientData.end();
return it->second;
}
virtual NetObjOrderedListConstIterator<T> begin() const override {
return clientData.begin();
}
virtual NetObjOrderedListConstIterator<T> end() const override {
return clientData.end();
}
virtual NetObjOrderedListConstIterator<T> at(uint32_t index) const override {
if(index >= clientData.size())
return clientData.end();
return std::next(clientData.begin(), index);
}
virtual NetObjOrderedListConstIterator<T> 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<NetObjOrderedListObjectInfo<T>>& data_list() override { return clientData; }
virtual const std::list<NetObjOrderedListObjectInfo<T>>& data_list() const override { return clientData; }
virtual std::unordered_map<NetworkingObjects::NetObjID, NetObjOrderedListIterator<T>>& data_map() { return clientIdToDataMap; }
virtual const std::unordered_map<NetworkingObjects::NetObjID, NetObjOrderedListIterator<T>>& data_map() const { return clientIdToDataMap; }
virtual std::vector<NetObjOrderedListIterator<T>> insert_ordered_list(const NetObjTemporaryPtr<NetObjOrderedList<T>>& l, const std::shared_ptr<NetServer::ClientData>& clientInserting, std::vector<std::pair<NetObjOrderedListIterator<T>, NetObjOwnerPtr<T>>>& newObjs) override {
if(newObjs.empty())
return {};

View file

@ -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>();
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>();
nameData->name = undoData.name;
if(undoData.folderList) {
auto& initFolderList = undoData.folderList.value();
folderData = std::make_unique<BookmarkFolderData>();
folderData->folderList = netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<BookmarkListItem>>();
for(auto& initFolder : initFolderList)
folderData->folderList->emplace_back_direct(folderData->folderList, netObjMan, initFolder);
folderData->folderList = w.netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<BookmarkListItem>>();
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<BookmarkData>(initData.bookmarkData.value());
bookmarkData = std::make_unique<BookmarkData>(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<BookmarkCompleteInitData>();
toRet.folderList = std::vector<BookmarkCompleteUndoData>();
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;

View file

@ -3,6 +3,7 @@
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
#include <Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp>
#include <string>
#include "../WorldUndoManager.hpp"
#include "../CoordSpaceHelper.hpp"
#include <Helpers/VersionNumber.hpp>
@ -18,16 +19,18 @@ struct BookmarkData {
void jump_to(World& world) const;
};
struct BookmarkCompleteInitData {
struct BookmarkCompleteUndoData {
WorldUndoManager::UndoObjectID undoID;
std::string name;
std::optional<std::vector<BookmarkCompleteInitData>> folderList;
std::optional<std::vector<BookmarkCompleteUndoData>> folderList;
std::optional<BookmarkData> 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:

View file

@ -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<BookmarkListItem> tempPtr = world.netObjMan.get_obj_temporary_ref_from_id<BookmarkListItem>(*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<BookmarkListItem>(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<int32_t>()}));
create_bookmark(new BookmarkListItem(world.netObjMan, nameForNew, false, {world.drawData.cam.c, world.main.window.size.cast<int32_t>()}));
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<NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>> BookmarkManager::try_to_create_in_proper_position(BookmarkListItem* newItem) {
std::optional<std::pair<NetworkingObjects::NetObjID, NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>>> 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<NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>> 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<NetworkingObjects::NetObjID, NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>>{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<NetworkingObjects::NetObjID, NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>>{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<BookmarkListItem> BookmarkManager::create_in_proper_position(BookmarkListItem* newItem) {
std::pair<NetworkingObjects::NetObjID, NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>> 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<BookmarkListItem> 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<NetworkingObjects::NetObjID> toEraseParentID = undoMan.get_netid_from_undoid(parentUndoID);
if(!toEraseParentID.has_value())
return false;
std::optional<NetworkingObjects::NetObjID> toEraseID = undoMan.get_netid_from_undoid(undoID);
if(!toEraseID.has_value())
return false;
auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<BookmarkListItem>(toEraseParentID.value())->get_folder_list();
bookmarkList->erase(bookmarkList, bookmarkList->get(toEraseID.value()));
return true;
}
bool redo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toInsertParentID = undoMan.get_netid_from_undoid(parentUndoID);
if(!toInsertParentID.has_value())
return false;
std::optional<NetworkingObjects::NetObjID> toInsertID = undoMan.get_netid_from_undoid(undoID);
if(toInsertID.has_value())
return false;
auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<BookmarkListItem>(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<AddBookmarkWorldUndoAction>(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<NetworkingObjects::NetObjID> toInsertParentID = undoMan.get_netid_from_undoid(parentUndoID);
if(!toInsertParentID.has_value())
return false;
std::optional<NetworkingObjects::NetObjID> toInsertID = undoMan.get_netid_from_undoid(undoID);
if(toInsertID.has_value())
return false;
auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<BookmarkListItem>(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<NetworkingObjects::NetObjID> toEraseParentID = undoMan.get_netid_from_undoid(parentUndoID);
if(!toEraseParentID.has_value())
return false;
std::optional<NetworkingObjects::NetObjID> toEraseID = undoMan.get_netid_from_undoid(undoID);
if(!toEraseID.has_value())
return false;
auto& bookmarkList = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<BookmarkListItem>(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<BookmarkListItem>(parentID)->get_folder_list();
auto it = folderList->get(objectID);
world.undo.push(std::make_unique<DeleteBookmarkWorldUndoAction>(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<NetworkingObjects::NetObjID> toModifyID = undoMan.get_netid_from_undoid(undoID);
if(!toModifyID.has_value())
return false;
auto objPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<BookmarkListItem>(toModifyID.value());
objPtr->set_name(undoMan.world.delayedUpdateObjectManager, nameOld);
return true;
}
bool redo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toModifyID = undoMan.get_netid_from_undoid(undoID);
if(!toModifyID.has_value())
return false;
auto objPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<BookmarkListItem>(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<BookmarkListItem>(oldNetObjID);
if(tempPtr) {
const std::string& currentNameData = tempPtr->get_name();
if(currentNameData != editingBookmarkName.value())
world.undo.push(std::make_unique<EditBookmarkWorldUndoAction>(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<BookmarkListItem>(*selectionData.objsSelected.begin());
if(tempPtr)
editingBookmarkName = tempPtr->get_name();
}
oldSelection = selectionData.objsSelected;
}

View file

@ -20,13 +20,20 @@ class BookmarkManager {
NetworkingObjects::NetObjOwnerPtr<BookmarkListItem> bookmarkListRoot;
private:
NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem> create_in_proper_position(BookmarkListItem* newItem);
std::optional<NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>> try_to_create_in_proper_position(BookmarkListItem* newItem);
std::pair<NetworkingObjects::NetObjID, NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>> create_in_proper_position(BookmarkListItem* newItem);
std::optional<std::pair<NetworkingObjects::NetObjID, NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem>>> try_to_create_in_proper_position(BookmarkListItem* newItem);
NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem> create_bookmark(BookmarkListItem* newItem);
void remove_bookmark(const NetworkingObjects::NetObjID& parentID, const NetworkingObjects::NetObjID& objectID);
GUIStuff::TreeListing::SelectionData selectionData;
std::unordered_set<NetworkingObjects::NetObjID> oldSelection;
std::string nameToEdit;
std::string nameForNew;
std::optional<std::string> editingBookmarkName;
void editing_bookmark_check();
friend class BookmarkListItem;
World& world;

View file

@ -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;

View file

@ -6,6 +6,10 @@
class DrawingProgramLayerListItem;
class DrawingProgramLayerManager;
struct DrawingProgramLayerInitData {
std::vector<std::shared_ptr<CanvasComponentContainer::CopyData>> 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<CanvasComponentContainer::ObjInfo*>& objList) const;
void set_to_erase();
void scale_up(const WorldScalar& scaleUpAmount);
DrawingProgramLayerInitData get_init_data() const;
CanvasComponentContainer::NetListOwnerPtr components;

View file

@ -7,6 +7,10 @@
class DrawingProgramLayerListItem;
class DrawingProgramLayerManager;
struct DrawingProgramLayerFolderInitData {
std::vector<DrawingProgramLayerFolderInitData> folderList;
};
class DrawingProgramLayerFolder {
public:
void draw(SkCanvas* canvas, const DrawData& drawData) const;

View file

@ -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<DrawingProgramLayerFolderInitData> folderData;
std::optional<DrawingProgramLayerInitData> 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;

View file

@ -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<NetworkingObjects::NetObjID> 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<EraseGridWorldUndoAction>(*it->obj, it->pos, world.undo.get_undoid_from_netid(it->obj.get_net_id())));
world.undo.push(std::make_unique<DeleteGridWorldUndoAction>(*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<WorldGrid>& 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<NetworkingObjects::NetObjID> toModifyID = undoMan.get_netid_from_undoid(undoID);
if(!toModifyID.has_value())
std::optional<NetworkingObjects::NetObjID> toEditID = undoMan.get_netid_from_undoid(undoID);
if(!toEditID.has_value())
return false;
auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<WorldGrid>(toModifyID.value());
auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<WorldGrid>(toEditID.value());
*gridPtr = gridDataOld;
undoMan.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(gridPtr, true);
return true;
}
bool redo(WorldUndoManager& undoMan) override {
std::optional<NetworkingObjects::NetObjID> toModifyID = undoMan.get_netid_from_undoid(undoID);
if(!toModifyID.has_value())
std::optional<NetworkingObjects::NetObjID> toEditID = undoMan.get_netid_from_undoid(undoID);
if(!toEditID.has_value())
return false;
auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<WorldGrid>(toModifyID.value());
auto gridPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id<WorldGrid>(toEditID.value());
*gridPtr = gridDataNew;
undoMan.world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(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<ModifyGridWorldUndoAction>(oldGridData, *wGrid, world.undo.get_undoid_from_netid(wGrid.get_net_id())));
world.undo.push(std::make_unique<EditGridWorldUndoAction>(oldGridData, *wGrid, world.undo.get_undoid_from_netid(wGrid.get_net_id())));
world.delayedUpdateObjectManager.send_update_to_all<WorldGrid>(wGrid, true);
}