From b4c35124c3866c4f8c22808528f2d8374a362785 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Mon, 30 Mar 2026 17:05:24 +0300 Subject: [PATCH] More GUI code moved to events, code now compiles but application doesn't run --- src/Bookmarks/BookmarkManager.cpp | 536 +++++++-------- src/DrawCamera.cpp | 2 +- src/DrawingProgram/DrawingProgram.cpp | 9 +- .../DrawingProgramSelection.cpp | 31 +- .../Layers/DrawingProgramLayerManagerGUI.cpp | 612 +++++++++--------- src/DrawingProgram/Tools/EditTool.cpp | 7 +- .../Tools/EditTools/BrushEditTool.cpp | 23 +- .../Tools/EditTools/BrushEditTool.hpp | 2 +- .../EditTools/DrawingProgramEditToolBase.cpp | 3 +- .../EditTools/DrawingProgramEditToolBase.hpp | 4 +- .../Tools/EditTools/EllipseDrawEditTool.cpp | 42 +- .../Tools/EditTools/EllipseDrawEditTool.hpp | 2 +- .../Tools/EditTools/ImageEditTool.cpp | 42 +- .../Tools/EditTools/ImageEditTool.hpp | 2 +- .../Tools/EditTools/RectDrawEditTool.cpp | 43 +- .../Tools/EditTools/RectDrawEditTool.hpp | 2 +- .../Tools/EditTools/TextBoxEditTool.cpp | 251 +++---- .../Tools/EditTools/TextBoxEditTool.hpp | 4 +- src/DrawingProgram/Tools/GridModifyTool.cpp | 2 +- src/DrawingProgram/Tools/LineDrawTool.cpp | 2 +- src/GUIStuff/ElementHelpers/ButtonHelpers.cpp | 6 +- src/GUIStuff/ElementHelpers/ButtonHelpers.hpp | 6 +- .../ElementHelpers/ColorPickerHelpers.hpp | 39 +- .../ColorPickerItemsHelpers.hpp | 39 ++ .../ElementHelpers/NumberSliderHelpers.hpp | 6 +- .../ElementHelpers/TextBoxHelpers.cpp | 3 +- .../ElementHelpers/TextBoxHelpers.hpp | 17 +- src/GUIStuff/Elements/ColorPicker.decl.hpp | 9 - src/GUIStuff/Elements/ColorPicker.impl.hpp | 14 +- .../Elements/ColorPickerButton.decl.hpp | 4 +- .../Elements/ColorPickerButton.impl.hpp | 7 +- .../Elements/ColorRectangleDisplay.cpp | 2 + src/GUIStuff/Elements/PaintCircleMenu.cpp | 3 +- src/GUIStuff/Elements/PaintCircleMenu.hpp | 3 +- src/GUIStuff/Elements/TextBox.impl.hpp | 8 +- src/Toolbar.cpp | 4 +- src/Toolbar.hpp | 1 - 37 files changed, 913 insertions(+), 879 deletions(-) create mode 100644 src/GUIStuff/ElementHelpers/ColorPickerItemsHelpers.hpp diff --git a/src/Bookmarks/BookmarkManager.cpp b/src/Bookmarks/BookmarkManager.cpp index 3e6fafa..d14fd1e 100644 --- a/src/Bookmarks/BookmarkManager.cpp +++ b/src/Bookmarks/BookmarkManager.cpp @@ -24,300 +24,300 @@ void BookmarkManager::refresh_gui_data() { } void BookmarkManager::setup_list_gui(const char* id) { - using namespace NetworkingObjects; - if(bookmarkListRoot) { - auto& gui = world.main.toolbar.gui; - gui.push_id(id); - if(bookmarkListRoot->get_folder_list()->empty()) { - gui.text_label_centered("No bookmarks yet..."); - selectionData = GUIStuff::TreeListing::SelectionData(); - oldSelection.clear(); - nameToEdit.clear(); - } - else { - std::optional toDeleteParent; - std::optional toDeleteObject; - gui.tree_listing("list", bookmarkListRoot.get_net_id(), GUIStuff::TreeListing::DisplayData{ - .getObjInListAtIndex = [&](NetObjID parentId, size_t index) -> std::optional { - NetObjOrderedList& bookmarkParentFolder = *world.netObjMan.get_obj_temporary_ref_from_id(parentId)->get_folder_list(); - if(bookmarkParentFolder.size() <= index) - return std::nullopt; - auto itemAtIndex = bookmarkParentFolder.at(index); - return GUIStuff::TreeListing::DisplayData::ObjInList{ - .id = itemAtIndex->obj.get_net_id(), - .isDirectory = itemAtIndex->obj->is_folder(), - .isDirectoryOpen = itemAtIndex->obj->is_folder() ? itemAtIndex->obj->is_folder_open() : false - }; - }, - .getIndexOfObjInList = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { - return world.netObjMan.get_obj_temporary_ref_from_id(idPair.parent)->get_folder_list()->get(idPair.object)->pos; - }, - .setDirectoryOpen = [&](NetObjID netID, bool newDirectoryOpen) { - world.netObjMan.get_obj_temporary_ref_from_id(netID)->set_folder_open(newDirectoryOpen); - }, - .drawNonDirectoryObjIconGUI = [&](NetObjID netID) { - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, - .padding = CLAY_PADDING_ALL(2), - }, - }) { - gui.svg_icon("bookmark ico", "data/icons/bookmark.svg"); - } - return false; - }, - .drawObjGUI = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { - auto tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(idPair.object); - bool isButtonClicked = false; - if(Clay_Hovered() && gui.io->mouse.leftClick >= 2 && !tempPtr->is_folder() && selectionData.objsSelected.contains(idPair.object) && !gui.io->key.leftCtrl && !gui.io->key.leftShift) - tempPtr->get_bookmark_data().jump_to(world); - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, - .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} - }, - }) { - gui.text_label(tempPtr->get_name()); - } - if(!tempPtr->is_folder() && gui.svg_icon_button_transparent("jump button", "data/icons/jump.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { - tempPtr->get_bookmark_data().jump_to(world); - isButtonClicked = true; - } - if(gui.svg_icon_button_transparent("delete button", "data/icons/trash.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { - toDeleteParent = idPair.parent; - toDeleteObject = idPair.object; - isButtonClicked = true; - } - return isButtonClicked; - }, - .moveObjectsToListAtIndex = [&](NetObjID listObj, size_t index, const std::vector& objsToInsert) { - std::unordered_map, std::vector>> toEraseMapUndo; - WorldUndoManager::UndoObjectID insertParentUndoID; - uint32_t insertUndoPosition; - std::vector insertedUndoIDs; + //using namespace NetworkingObjects; + //if(bookmarkListRoot) { + // auto& gui = world.main.toolbar.gui; + // gui.push_id(id); + // if(bookmarkListRoot->get_folder_list()->empty()) { + // gui.text_label_centered("No bookmarks yet..."); + // selectionData = GUIStuff::TreeListing::SelectionData(); + // oldSelection.clear(); + // nameToEdit.clear(); + // } + // else { + // std::optional toDeleteParent; + // std::optional toDeleteObject; + // gui.tree_listing("list", bookmarkListRoot.get_net_id(), GUIStuff::TreeListing::DisplayData{ + // .getObjInListAtIndex = [&](NetObjID parentId, size_t index) -> std::optional { + // NetObjOrderedList& bookmarkParentFolder = *world.netObjMan.get_obj_temporary_ref_from_id(parentId)->get_folder_list(); + // if(bookmarkParentFolder.size() <= index) + // return std::nullopt; + // auto itemAtIndex = bookmarkParentFolder.at(index); + // return GUIStuff::TreeListing::DisplayData::ObjInList{ + // .id = itemAtIndex->obj.get_net_id(), + // .isDirectory = itemAtIndex->obj->is_folder(), + // .isDirectoryOpen = itemAtIndex->obj->is_folder() ? itemAtIndex->obj->is_folder_open() : false + // }; + // }, + // .getIndexOfObjInList = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { + // return world.netObjMan.get_obj_temporary_ref_from_id(idPair.parent)->get_folder_list()->get(idPair.object)->pos; + // }, + // .setDirectoryOpen = [&](NetObjID netID, bool newDirectoryOpen) { + // world.netObjMan.get_obj_temporary_ref_from_id(netID)->set_folder_open(newDirectoryOpen); + // }, + // .drawNonDirectoryObjIconGUI = [&](NetObjID netID) { + // CLAY_AUTO_ID({ + // .layout = { + // .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + // .padding = CLAY_PADDING_ALL(2), + // }, + // }) { + // gui.svg_icon("bookmark ico", "data/icons/bookmark.svg"); + // } + // return false; + // }, + // .drawObjGUI = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { + // auto tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(idPair.object); + // bool isButtonClicked = false; + // if(Clay_Hovered() && gui.io->mouse.leftClick >= 2 && !tempPtr->is_folder() && selectionData.objsSelected.contains(idPair.object) && !gui.io->key.leftCtrl && !gui.io->key.leftShift) + // tempPtr->get_bookmark_data().jump_to(world); + // CLAY_AUTO_ID({ + // .layout = { + // .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + // .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} + // }, + // }) { + // gui.text_label(tempPtr->get_name()); + // } + // if(!tempPtr->is_folder() && gui.svg_icon_button_transparent("jump button", "data/icons/jump.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { + // tempPtr->get_bookmark_data().jump_to(world); + // isButtonClicked = true; + // } + // if(gui.svg_icon_button_transparent("delete button", "data/icons/trash.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { + // toDeleteParent = idPair.parent; + // toDeleteObject = idPair.object; + // isButtonClicked = true; + // } + // return isButtonClicked; + // }, + // .moveObjectsToListAtIndex = [&](NetObjID listObj, size_t index, const std::vector& objsToInsert) { + // std::unordered_map, std::vector>> toEraseMapUndo; + // WorldUndoManager::UndoObjectID insertParentUndoID; + // uint32_t insertUndoPosition; + // std::vector insertedUndoIDs; - world.netObjMan.send_multi_update_messsage([&]() { - std::unordered_map>> toEraseMap; - uint32_t newIndex = index; - std::vector> toInsertObjPtrs; - auto& listPtr = world.netObjMan.get_obj_temporary_ref_from_id(listObj)->get_folder_list(); + // world.netObjMan.send_multi_update_messsage([&]() { + // std::unordered_map>> toEraseMap; + // uint32_t newIndex = index; + // std::vector> toInsertObjPtrs; + // auto& listPtr = world.netObjMan.get_obj_temporary_ref_from_id(listObj)->get_folder_list(); - // Map parent folders to list of objects that should be erased from them - for(size_t i = 0; i < objsToInsert.size(); i++) { - auto& parentListPtr = world.netObjMan.get_obj_temporary_ref_from_id(objsToInsert[i].parent)->get_folder_list(); - toEraseMap[objsToInsert[i].parent].emplace_back(parentListPtr->get(objsToInsert[i].object)); - if(newIndex != 0 && objsToInsert[i].parent == listObj && listPtr->get(objsToInsert[i].object)->pos <= index) - newIndex--; - } + // // Map parent folders to list of objects that should be erased from them + // for(size_t i = 0; i < objsToInsert.size(); i++) { + // auto& parentListPtr = world.netObjMan.get_obj_temporary_ref_from_id(objsToInsert[i].parent)->get_folder_list(); + // toEraseMap[objsToInsert[i].parent].emplace_back(parentListPtr->get(objsToInsert[i].object)); + // if(newIndex != 0 && objsToInsert[i].parent == listObj && listPtr->get(objsToInsert[i].object)->pos <= index) + // newIndex--; + // } - // Prepare erase map for undo - for(auto& [parentNetID, objsToEraseList] : toEraseMap) { - auto& undoEraseListPairForParent = toEraseMapUndo[world.undo.get_undoid_from_netid(parentNetID)]; - uint32_t i = 0; - for(auto& objToErase : objsToEraseList) { - undoEraseListPairForParent.first.emplace_back(objToErase->pos - i); - undoEraseListPairForParent.second.emplace_back(world.undo.get_undoid_from_netid(objToErase->obj.get_net_id())); - i++; - } - } + // // Prepare erase map for undo + // for(auto& [parentNetID, objsToEraseList] : toEraseMap) { + // auto& undoEraseListPairForParent = toEraseMapUndo[world.undo.get_undoid_from_netid(parentNetID)]; + // uint32_t i = 0; + // for(auto& objToErase : objsToEraseList) { + // undoEraseListPairForParent.first.emplace_back(objToErase->pos - i); + // undoEraseListPairForParent.second.emplace_back(world.undo.get_undoid_from_netid(objToErase->obj.get_net_id())); + // i++; + // } + // } - // Erase the list of objects we previously mapped to each parent, and move the erased objects to vector toInsertObjPtrs - for(auto& [listToEraseFrom, setToErase] : toEraseMap) { - auto& listToEraseFromPtr = world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder_list(); - listToEraseFromPtr->erase_list(listToEraseFromPtr, setToErase, &toInsertObjPtrs); - } + // // Erase the list of objects we previously mapped to each parent, and move the erased objects to vector toInsertObjPtrs + // for(auto& [listToEraseFrom, setToErase] : toEraseMap) { + // auto& listToEraseFromPtr = world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder_list(); + // listToEraseFromPtr->erase_list(listToEraseFromPtr, setToErase, &toInsertObjPtrs); + // } - // Insert objects in toInsertObjPtrs into the folder we have selected - std::vector, NetObjOwnerPtr>> toInsert; - auto insertIt = listPtr->at(newIndex); - for(uint32_t i = 0; i < objsToInsert.size(); i++) { - auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i].object](NetObjOwnerPtr& objPtr) { - return objPtr.get_net_id() == id; - }); - toInsert.emplace_back(insertIt, std::move(*it)); - toInsert.back().second.reassign_ids(); - } - std::vector> insertedIterators = listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); + // // Insert objects in toInsertObjPtrs into the folder we have selected + // std::vector, NetObjOwnerPtr>> toInsert; + // auto insertIt = listPtr->at(newIndex); + // for(uint32_t i = 0; i < objsToInsert.size(); i++) { + // auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i].object](NetObjOwnerPtr& objPtr) { + // return objPtr.get_net_id() == id; + // }); + // toInsert.emplace_back(insertIt, std::move(*it)); + // toInsert.back().second.reassign_ids(); + // } + // std::vector> insertedIterators = listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); - // Prepare insert list for undo - insertParentUndoID = world.undo.get_undoid_from_netid(listObj); - insertUndoPosition = newIndex; - for(auto& it : insertedIterators) - insertedUndoIDs.emplace_back(world.undo.get_undoid_from_netid(it->obj.get_net_id())); - }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); + // // Prepare insert list for undo + // insertParentUndoID = world.undo.get_undoid_from_netid(listObj); + // insertUndoPosition = newIndex; + // for(auto& it : insertedIterators) + // insertedUndoIDs.emplace_back(world.undo.get_undoid_from_netid(it->obj.get_net_id())); + // }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); - class MoveBookmarksWorldUndoAction : public WorldUndoAction { - public: - // If the undo ID maps to the net id, we can also assume that the object is definitely inside the list we want to move it from, and not inside some other list - // If it was moved to another list, there would be an undo move that would move it back to this list, and if it was moved by another player the undo id wouldnt map back to the net id, and the undo would fail - // We can also assume all objects in all lists remain in the same order for the same reason, so no need to sort anything if it was sorted when the undo action was generated - MoveBookmarksWorldUndoAction(const std::unordered_map, std::vector>>& initUndoEraseMap, - WorldUndoManager::UndoObjectID initInsertParentUndoID, - uint32_t initInsertPosition, - std::vector initInsertedUndoIDs): - undoEraseMap(initUndoEraseMap), - insertParentUndoID(initInsertParentUndoID), - insertPosition(initInsertPosition), - insertedUndoIDs(initInsertedUndoIDs) - {} - std::string get_name() const override { - return "Move Bookmarks"; - } - bool undo(WorldUndoManager& undoMan) override { - std::vector> toMoveObjs; - std::vector> toEraseList; - NetObjTemporaryPtr> eraseListPtr; - std::unordered_map*, std::vector>> toInsertToMap; + // class MoveBookmarksWorldUndoAction : public WorldUndoAction { + // public: + // // If the undo ID maps to the net id, we can also assume that the object is definitely inside the list we want to move it from, and not inside some other list + // // If it was moved to another list, there would be an undo move that would move it back to this list, and if it was moved by another player the undo id wouldnt map back to the net id, and the undo would fail + // // We can also assume all objects in all lists remain in the same order for the same reason, so no need to sort anything if it was sorted when the undo action was generated + // MoveBookmarksWorldUndoAction(const std::unordered_map, std::vector>>& initUndoEraseMap, + // WorldUndoManager::UndoObjectID initInsertParentUndoID, + // uint32_t initInsertPosition, + // std::vector initInsertedUndoIDs): + // undoEraseMap(initUndoEraseMap), + // insertParentUndoID(initInsertParentUndoID), + // insertPosition(initInsertPosition), + // insertedUndoIDs(initInsertedUndoIDs) + // {} + // std::string get_name() const override { + // return "Move Bookmarks"; + // } + // bool undo(WorldUndoManager& undoMan) override { + // std::vector> toMoveObjs; + // std::vector> toEraseList; + // NetObjTemporaryPtr> eraseListPtr; + // std::unordered_map*, std::vector>> toInsertToMap; - { - std::optional eraseListNetID = undoMan.get_netid_from_undoid(insertParentUndoID); - if(!eraseListNetID.has_value()) - return false; - eraseListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(eraseListNetID.value())->get_folder_list(); - } + // { + // std::optional eraseListNetID = undoMan.get_netid_from_undoid(insertParentUndoID); + // if(!eraseListNetID.has_value()) + // return false; + // eraseListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(eraseListNetID.value())->get_folder_list(); + // } - { - std::vector toEraseNetIDList; - if(!undoMan.fill_netid_list_from_undoid_list(toEraseNetIDList, insertedUndoIDs)) - return false; - toEraseList = eraseListPtr->get_list(toEraseNetIDList); - } + // { + // std::vector toEraseNetIDList; + // if(!undoMan.fill_netid_list_from_undoid_list(toEraseNetIDList, insertedUndoIDs)) + // return false; + // toEraseList = eraseListPtr->get_list(toEraseNetIDList); + // } - { - for(auto& [undoID, indexUndoIdListPair] : undoEraseMap) { - std::optional netID = undoMan.get_netid_from_undoid(undoID); - if(!netID.has_value()) - return false; - auto& insertMapEntry = toInsertToMap[netID.value()]; - insertMapEntry.first = &indexUndoIdListPair.first; - if(!undoMan.fill_netid_list_from_undoid_list(insertMapEntry.second, indexUndoIdListPair.second)) - return false; - } - } + // { + // for(auto& [undoID, indexUndoIdListPair] : undoEraseMap) { + // std::optional netID = undoMan.get_netid_from_undoid(undoID); + // if(!netID.has_value()) + // return false; + // auto& insertMapEntry = toInsertToMap[netID.value()]; + // insertMapEntry.first = &indexUndoIdListPair.first; + // if(!undoMan.fill_netid_list_from_undoid_list(insertMapEntry.second, indexUndoIdListPair.second)) + // return false; + // } + // } - undoMan.world.netObjMan.send_multi_update_messsage([&]() { - eraseListPtr->erase_list(eraseListPtr, toEraseList, &toMoveObjs); + // undoMan.world.netObjMan.send_multi_update_messsage([&]() { + // eraseListPtr->erase_list(eraseListPtr, toEraseList, &toMoveObjs); - for(auto& [parentNetID, indexNetIDListPair] : toInsertToMap) { - auto& parentListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(parentNetID)->get_folder_list(); - std::vector> insertIteratorList = parentListPtr->at_ordered_indices(*indexNetIDListPair.first); - auto& insertNetIDList = indexNetIDListPair.second; - std::vector, NetObjOwnerPtr>> toInsert; - for(auto [insertIt, netID] : std::views::zip(insertIteratorList, insertNetIDList)) { - auto it = std::find_if(toMoveObjs.begin(), toMoveObjs.end(), [id = netID](NetObjOwnerPtr& objPtr) { - return objPtr.get_net_id() == id; - }); - toInsert.emplace_back(insertIt, std::move(*it)); - toInsert.back().second.reassign_ids(); - } - parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); - } - }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); - return true; - } - bool redo(WorldUndoManager& undoMan) override { - std::unordered_map> toEraseMap; - NetObjTemporaryPtr> listPtr; - std::vector objsToInsert; + // for(auto& [parentNetID, indexNetIDListPair] : toInsertToMap) { + // auto& parentListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(parentNetID)->get_folder_list(); + // std::vector> insertIteratorList = parentListPtr->at_ordered_indices(*indexNetIDListPair.first); + // auto& insertNetIDList = indexNetIDListPair.second; + // std::vector, NetObjOwnerPtr>> toInsert; + // for(auto [insertIt, netID] : std::views::zip(insertIteratorList, insertNetIDList)) { + // auto it = std::find_if(toMoveObjs.begin(), toMoveObjs.end(), [id = netID](NetObjOwnerPtr& objPtr) { + // return objPtr.get_net_id() == id; + // }); + // toInsert.emplace_back(insertIt, std::move(*it)); + // toInsert.back().second.reassign_ids(); + // } + // parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); + // } + // }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); + // return true; + // } + // bool redo(WorldUndoManager& undoMan) override { + // std::unordered_map> toEraseMap; + // NetObjTemporaryPtr> listPtr; + // std::vector objsToInsert; - { - for(auto& [undoID, indexUndoIDListPair] : undoEraseMap) { - std::optional netID = undoMan.get_netid_from_undoid(undoID); - if(!netID.has_value()) - return false; - if(!undoMan.fill_netid_list_from_undoid_list(toEraseMap[netID.value()], indexUndoIDListPair.second)) - return false; - } - } + // { + // for(auto& [undoID, indexUndoIDListPair] : undoEraseMap) { + // std::optional netID = undoMan.get_netid_from_undoid(undoID); + // if(!netID.has_value()) + // return false; + // if(!undoMan.fill_netid_list_from_undoid_list(toEraseMap[netID.value()], indexUndoIDListPair.second)) + // return false; + // } + // } - { - std::optional netID = undoMan.get_netid_from_undoid(insertParentUndoID); - if(!netID.has_value()) - return false; - listPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(netID.value())->get_folder_list(); - } + // { + // std::optional netID = undoMan.get_netid_from_undoid(insertParentUndoID); + // if(!netID.has_value()) + // return false; + // listPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(netID.value())->get_folder_list(); + // } - { - if(!undoMan.fill_netid_list_from_undoid_list(objsToInsert, insertedUndoIDs)) - return false; - } + // { + // if(!undoMan.fill_netid_list_from_undoid_list(objsToInsert, insertedUndoIDs)) + // return false; + // } - undoMan.world.netObjMan.send_multi_update_messsage([&]() { - std::vector> toInsertObjPtrs; + // undoMan.world.netObjMan.send_multi_update_messsage([&]() { + // std::vector> toInsertObjPtrs; - for(auto& [listToEraseFrom, setToErase] : toEraseMap) { - auto& listToEraseFromPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder_list(); - listToEraseFromPtr->erase_list(listToEraseFromPtr, listToEraseFromPtr->get_list(setToErase), &toInsertObjPtrs); - } + // for(auto& [listToEraseFrom, setToErase] : toEraseMap) { + // auto& listToEraseFromPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder_list(); + // listToEraseFromPtr->erase_list(listToEraseFromPtr, listToEraseFromPtr->get_list(setToErase), &toInsertObjPtrs); + // } - std::vector, NetObjOwnerPtr>> toInsert; - auto insertIt = listPtr->at(insertPosition); - for(uint32_t i = 0; i < objsToInsert.size(); i++) { - auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i]](NetObjOwnerPtr& objPtr) { - return objPtr.get_net_id() == id; - }); - toInsert.emplace_back(insertIt, std::move(*it)); - toInsert.back().second.reassign_ids(); - } - listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); - }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); + // std::vector, NetObjOwnerPtr>> toInsert; + // auto insertIt = listPtr->at(insertPosition); + // for(uint32_t i = 0; i < objsToInsert.size(); i++) { + // auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i]](NetObjOwnerPtr& objPtr) { + // return objPtr.get_net_id() == id; + // }); + // toInsert.emplace_back(insertIt, std::move(*it)); + // toInsert.back().second.reassign_ids(); + // } + // listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); + // }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); - return true; - } - ~MoveBookmarksWorldUndoAction() {} + // return true; + // } + // ~MoveBookmarksWorldUndoAction() {} - std::unordered_map, std::vector>> undoEraseMap; - WorldUndoManager::UndoObjectID insertParentUndoID; - uint32_t insertPosition; - std::vector insertedUndoIDs; - }; - world.undo.push(std::make_unique(toEraseMapUndo, insertParentUndoID, insertUndoPosition, insertedUndoIDs)); - } - }, selectionData); + // std::unordered_map, std::vector>> undoEraseMap; + // WorldUndoManager::UndoObjectID insertParentUndoID; + // uint32_t insertPosition; + // std::vector insertedUndoIDs; + // }; + // world.undo.push(std::make_unique(toEraseMapUndo, insertParentUndoID, insertUndoPosition, insertedUndoIDs)); + // } + // }, selectionData); - if(selectionData.objsSelected != oldSelection) { - 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 - nameToEdit.clear(); - } - else - nameToEdit.clear(); - } + // if(selectionData.objsSelected != oldSelection) { + // 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 + // nameToEdit.clear(); + // } + // else + // nameToEdit.clear(); + // } - if(toDeleteObject.has_value()) - remove_bookmark(toDeleteParent.value(), toDeleteObject.value()); - } + // if(toDeleteObject.has_value()) + // remove_bookmark(toDeleteParent.value(), toDeleteObject.value()); + // } - gui.left_to_right_line_layout([&]() { - bool addByEnter = false; - gui.input_text("input new name", &nameForNew, true, [&](GUIStuff::SelectionHelper& s) { - addByEnter = s.selected && gui.io->key.enter; - }); - - if(gui.svg_icon_button("create new bookmark", "data/icons/plusbold.svg", false, gui.SMALL_BUTTON_SIZE) || addByEnter) - 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_bookmark(new BookmarkListItem(world.netObjMan, nameForNew, true, {})); - newFolderObjInfo->obj->set_folder_open(true); - } - }); + // gui.left_to_right_line_layout([&]() { + // bool addByEnter = false; + // gui.input_text("input new name", &nameForNew, true, [&](GUIStuff::SelectionHelper& s) { + // addByEnter = s.selected && gui.io->key.enter; + // }); + // + // if(gui.svg_icon_button("create new bookmark", "data/icons/plusbold.svg", false, gui.SMALL_BUTTON_SIZE) || addByEnter) + // 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_bookmark(new BookmarkListItem(world.netObjMan, nameForNew, true, {})); + // newFolderObjInfo->obj->set_folder_open(true); + // } + // }); - if(selectionData.objsSelected.size() == 1) { - NetObjTemporaryPtr tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); - if(tempPtr) { - gui.text_label_centered(tempPtr->is_folder() ? "Edit Bookmark Folder" : "Edit Bookmark"); - gui.input_text_field("input edit name", "Name", &nameToEdit); - tempPtr->set_name(world.delayedUpdateObjectManager, nameToEdit); - } - } + // if(selectionData.objsSelected.size() == 1) { + // NetObjTemporaryPtr tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); + // if(tempPtr) { + // gui.text_label_centered(tempPtr->is_folder() ? "Edit Bookmark Folder" : "Edit Bookmark"); + // gui.input_text_field("input edit name", "Name", &nameToEdit); + // tempPtr->set_name(world.delayedUpdateObjectManager, nameToEdit); + // } + // } - gui.pop_id(); - } + // gui.pop_id(); + //} } std::optional>> BookmarkManager::try_to_create_in_proper_position(BookmarkListItem* newItem) { diff --git a/src/DrawCamera.cpp b/src/DrawCamera.cpp index eb21d44..b10c2aa 100755 --- a/src/DrawCamera.cpp +++ b/src/DrawCamera.cpp @@ -178,7 +178,7 @@ void DrawCamera::input_mouse_motion_callback(World& w, const InputManager::Mouse } void DrawCamera::input_mouse_wheel_callback(World& w, const InputManager::MouseWheelCallbackArgs& wheel) { - if(!smoothMove.occurring && !isTouchTransforming && wheel.tickAmount.y() && w.main.toolbar.check_if_position_isnt_obstructed(wheel.mousePos)) { + if(!smoothMove.occurring && !isTouchTransforming && wheel.tickAmount.y()) { WorldVec mouseWorldPos = c.from_space(wheel.mousePos); WorldScalar zoomFactor(1.0 + w.main.toolbar.scrollZoomSpeed); diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 8997432..db22e43 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -59,7 +59,7 @@ void DrawingProgram::on_tab_out() { } void DrawingProgram::input_drop_file_callback(const InputManager::DropCallbackArgs& drop) { - if(world.main.toolbar.check_if_position_isnt_obstructed(drop.pos) && std::filesystem::is_regular_file(drop.data)) { + if(std::filesystem::is_regular_file(drop.data)) { #ifdef __EMSCRIPTEN_ add_file_to_canvas_by_path(drop.data, world.main.input.mouse.pos, true); #else @@ -69,7 +69,7 @@ void DrawingProgram::input_drop_file_callback(const InputManager::DropCallbackAr } void DrawingProgram::input_drop_text_callback(const InputManager::DropCallbackArgs& drop) { - if(world.main.toolbar.check_if_position_isnt_obstructed(drop.pos) && is_valid_http_url(drop.data)) { + if(is_valid_http_url(drop.data)) { CanvasComponentContainer* newContainer = new CanvasComponentContainer(world.netObjMan, CanvasComponentType::IMAGE); ImageCanvasComponent& img = static_cast(newContainer->get_comp()); newContainer->coords = world.drawData.cam.c; @@ -88,8 +88,7 @@ void DrawingProgram::input_mouse_button_callback(const InputManager::MouseButton drawTool->input_mouse_button_on_canvas_callback(b); }; - bool isHoveringOverCanvas = world.main.toolbar.check_if_position_isnt_obstructed(button.pos); - if(isHoveringOverCanvas && button.down) { + if(button.down) { if(button.button == InputManager::MouseButton::RIGHT) { if(!controls.middleClickHeld && !controls.leftClickHeld) { if(world.main.toolbar.rightClickPopupLocation) @@ -457,7 +456,7 @@ void DrawingProgram::modify_grid(const NetworkingObjects::NetObjWeakPtr #endif +#include "../GUIStuff/ElementHelpers/TextLabelHelpers.hpp" +#include "../GUIStuff/ElementHelpers/RadioButtonHelpers.hpp" +#include "../GUIStuff/ElementHelpers/LayoutHelpers.hpp" + DrawingProgramSelection::DrawingProgramSelection(DrawingProgram& initDrawP): drawP(initDrawP) {} void DrawingProgramSelection::selection_gui() { + using namespace GUIStuff; + using namespace ElementHelpers; + auto& t = drawP.world.main.toolbar; t.gui.push_id("general selection gui"); - t.gui.text_label("Select from:"); - if(t.gui.radio_button_field("layer edited", "Layer being edited", drawP.controls.layerSelector == DrawingProgramLayerManager::LayerSelector::LAYER_BEING_EDITED)) - drawP.controls.layerSelector = DrawingProgramLayerManager::LayerSelector::LAYER_BEING_EDITED; - if(t.gui.radio_button_field("all visible", "All visible layers", drawP.controls.layerSelector == DrawingProgramLayerManager::LayerSelector::ALL_VISIBLE_LAYERS)) - drawP.controls.layerSelector = DrawingProgramLayerManager::LayerSelector::ALL_VISIBLE_LAYERS; + text_label(t.gui, "Select from:"); + radio_button_selector(t.gui, "layer selector", &drawP.controls.layerSelector, { + {"Layer being edited", DrawingProgramLayerManager::LayerSelector::LAYER_BEING_EDITED}, + {"All visible layers", DrawingProgramLayerManager::LayerSelector::ALL_VISIBLE_LAYERS} + }); if(is_something_selected()) { - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Stroke Color Button", &strokeColorChangeData.newColor, &strokeColorChangeData.newColor == t.colorRight)) { - if(strokeColorChangeData.newColor.w() == 0.0f) - strokeColorChangeData.newColor.w() = 1.0f; - t.color_selector_right(&strokeColorChangeData.newColor == t.colorRight ? nullptr : &strokeColorChangeData.newColor); - } - t.gui.text_label("Stroke Color"); + left_to_right_line_layout(t.gui, [&]() { + //if(t.gui.color_button_big("Stroke Color Button", &strokeColorChangeData.newColor, &strokeColorChangeData.newColor == t.colorRight)) { + // if(strokeColorChangeData.newColor.w() == 0.0f) + // strokeColorChangeData.newColor.w() = 1.0f; + // t.color_selector_right(&strokeColorChangeData.newColor == t.colorRight ? nullptr : &strokeColorChangeData.newColor); + //} + text_label(t.gui, "Stroke Color"); }); update_selection_stroke_color(); } diff --git a/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp b/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp index c8d48e9..77be32e 100644 --- a/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp +++ b/src/DrawingProgram/Layers/DrawingProgramLayerManagerGUI.cpp @@ -24,338 +24,338 @@ void DrawingProgramLayerManagerGUI::refresh_gui_data() { } void DrawingProgramLayerManagerGUI::setup_list_gui(const char* id, bool& hoveringOverDropdown) { - using namespace NetworkingObjects; - auto& world = layerMan.drawP.world; - if(layerMan.layerTreeRoot) { - auto& gui = world.main.toolbar.gui; - gui.push_id(id); - if(layerMan.layerTreeRoot->get_folder().folderList->empty()) { - gui.text_label_centered("No layers exist."); - selectionData = GUIStuff::TreeListing::SelectionData(); - oldSelection.clear(); - nameToEdit.clear(); - } - else { - std::optional toDeleteParent; - std::optional toDeleteObject; - gui.tree_listing("list", layerMan.layerTreeRoot.get_net_id(), GUIStuff::TreeListing::DisplayData{ - .getObjInListAtIndex = [&](NetObjID parentId, size_t index) -> std::optional { - NetObjOrderedList& parentFolder = *world.netObjMan.get_obj_temporary_ref_from_id(parentId)->get_folder().folderList; - if(parentFolder.size() <= index) - return std::nullopt; - return GUIStuff::TreeListing::DisplayData::ObjInList{ - .id = parentFolder.at(index)->obj.get_net_id(), - .isDirectory = parentFolder.at(index)->obj->is_folder(), - .isDirectoryOpen = parentFolder.at(index)->obj->is_folder() ? parentFolder.at(index)->obj->get_folder().isFolderOpen : false - }; - }, - .getIndexOfObjInList = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { - return world.netObjMan.get_obj_temporary_ref_from_id(idPair.parent)->get_folder().folderList->get(idPair.object)->pos; - }, - .setDirectoryOpen = [&](NetObjID netID, bool newDirectoryOpen) { - world.netObjMan.get_obj_temporary_ref_from_id(netID)->get_folder().isFolderOpen = newDirectoryOpen; - }, - .drawNonDirectoryObjIconGUI = [&](NetObjID netID) { - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, - .padding = CLAY_PADDING_ALL(2), - }, - }) { - gui.svg_icon("ico", "data/icons/layer.svg"); - } - return false; - }, - .drawObjGUI = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { - auto tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(idPair.object); - bool isButtonClicked = false; - if(Clay_Hovered() && gui.io->mouse.leftClick >= 2 && !tempPtr->is_folder() && selectionData.objsSelected.contains(idPair.object) && !gui.io->key.leftCtrl && !gui.io->key.leftShift) - layerMan.editingLayer = tempPtr; - if(!tempPtr->is_folder()) { - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_FIXED(GUIStuff::TreeListing::ENTRY_HEIGHT), .height = CLAY_SIZING_FIXED(GUIStuff::TreeListing::ENTRY_HEIGHT)}, - .padding = CLAY_PADDING_ALL(2), - }, - }) { - if(tempPtr.get_net_id() == layerMan.editingLayer.get_net_id()) - gui.svg_icon("edit ico", "data/icons/pencil.svg"); - } - } - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, - .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} - }, - }) { - gui.text_label(tempPtr->get_name()); - } - if(gui.svg_icon_button_transparent("edit button", "data/icons/pencil.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { - layerMan.editingLayer = tempPtr; - isButtonClicked = true; - } - if(gui.svg_icon_button_transparent("visible button", tempPtr->get_visible() ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { - tempPtr->set_visible(layerMan, !tempPtr->get_visible()); - isButtonClicked = true; - } - if(gui.svg_icon_button_transparent("delete button", "data/icons/trash.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { - toDeleteParent = idPair.parent; - toDeleteObject = idPair.object; - isButtonClicked = true; - } - return isButtonClicked; - }, - .moveObjectsToListAtIndex = [&](NetObjID listObj, size_t index, const std::vector& objsToInsert) { - std::unordered_map, std::vector>> toEraseMapUndo; - WorldUndoManager::UndoObjectID insertParentUndoID; - uint32_t insertUndoPosition; - std::vector insertedUndoIDs; + //using namespace NetworkingObjects; + //auto& world = layerMan.drawP.world; + //if(layerMan.layerTreeRoot) { + // auto& gui = world.main.toolbar.gui; + // gui.push_id(id); + // if(layerMan.layerTreeRoot->get_folder().folderList->empty()) { + // gui.text_label_centered("No layers exist."); + // selectionData = GUIStuff::TreeListing::SelectionData(); + // oldSelection.clear(); + // nameToEdit.clear(); + // } + // else { + // std::optional toDeleteParent; + // std::optional toDeleteObject; + // gui.tree_listing("list", layerMan.layerTreeRoot.get_net_id(), GUIStuff::TreeListing::DisplayData{ + // .getObjInListAtIndex = [&](NetObjID parentId, size_t index) -> std::optional { + // NetObjOrderedList& parentFolder = *world.netObjMan.get_obj_temporary_ref_from_id(parentId)->get_folder().folderList; + // if(parentFolder.size() <= index) + // return std::nullopt; + // return GUIStuff::TreeListing::DisplayData::ObjInList{ + // .id = parentFolder.at(index)->obj.get_net_id(), + // .isDirectory = parentFolder.at(index)->obj->is_folder(), + // .isDirectoryOpen = parentFolder.at(index)->obj->is_folder() ? parentFolder.at(index)->obj->get_folder().isFolderOpen : false + // }; + // }, + // .getIndexOfObjInList = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { + // return world.netObjMan.get_obj_temporary_ref_from_id(idPair.parent)->get_folder().folderList->get(idPair.object)->pos; + // }, + // .setDirectoryOpen = [&](NetObjID netID, bool newDirectoryOpen) { + // world.netObjMan.get_obj_temporary_ref_from_id(netID)->get_folder().isFolderOpen = newDirectoryOpen; + // }, + // .drawNonDirectoryObjIconGUI = [&](NetObjID netID) { + // CLAY_AUTO_ID({ + // .layout = { + // .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + // .padding = CLAY_PADDING_ALL(2), + // }, + // }) { + // gui.svg_icon("ico", "data/icons/layer.svg"); + // } + // return false; + // }, + // .drawObjGUI = [&](const GUIStuff::TreeListing::ParentObjectIDPair& idPair) { + // auto tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(idPair.object); + // bool isButtonClicked = false; + // if(Clay_Hovered() && gui.io->mouse.leftClick >= 2 && !tempPtr->is_folder() && selectionData.objsSelected.contains(idPair.object) && !gui.io->key.leftCtrl && !gui.io->key.leftShift) + // layerMan.editingLayer = tempPtr; + // if(!tempPtr->is_folder()) { + // CLAY_AUTO_ID({ + // .layout = { + // .sizing = {.width = CLAY_SIZING_FIXED(GUIStuff::TreeListing::ENTRY_HEIGHT), .height = CLAY_SIZING_FIXED(GUIStuff::TreeListing::ENTRY_HEIGHT)}, + // .padding = CLAY_PADDING_ALL(2), + // }, + // }) { + // if(tempPtr.get_net_id() == layerMan.editingLayer.get_net_id()) + // gui.svg_icon("edit ico", "data/icons/pencil.svg"); + // } + // } + // CLAY_AUTO_ID({ + // .layout = { + // .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + // .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} + // }, + // }) { + // gui.text_label(tempPtr->get_name()); + // } + // if(gui.svg_icon_button_transparent("edit button", "data/icons/pencil.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { + // layerMan.editingLayer = tempPtr; + // isButtonClicked = true; + // } + // if(gui.svg_icon_button_transparent("visible button", tempPtr->get_visible() ? "data/icons/eyeopen.svg" : "data/icons/eyeclose.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { + // tempPtr->set_visible(layerMan, !tempPtr->get_visible()); + // isButtonClicked = true; + // } + // if(gui.svg_icon_button_transparent("delete button", "data/icons/trash.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { + // toDeleteParent = idPair.parent; + // toDeleteObject = idPair.object; + // isButtonClicked = true; + // } + // return isButtonClicked; + // }, + // .moveObjectsToListAtIndex = [&](NetObjID listObj, size_t index, const std::vector& objsToInsert) { + // std::unordered_map, std::vector>> toEraseMapUndo; + // WorldUndoManager::UndoObjectID insertParentUndoID; + // uint32_t insertUndoPosition; + // std::vector insertedUndoIDs; - world.netObjMan.send_multi_update_messsage([&]() { - std::unordered_map>> toEraseMap; - uint32_t newIndex = index; - std::vector> toInsertObjPtrs; - auto& listPtr = world.netObjMan.get_obj_temporary_ref_from_id(listObj)->get_folder().folderList; + // world.netObjMan.send_multi_update_messsage([&]() { + // std::unordered_map>> toEraseMap; + // uint32_t newIndex = index; + // std::vector> toInsertObjPtrs; + // auto& listPtr = world.netObjMan.get_obj_temporary_ref_from_id(listObj)->get_folder().folderList; - // Map parent folders to list of objects that should be erased from them - for(size_t i = 0; i < objsToInsert.size(); i++) { - auto& parentListPtr = world.netObjMan.get_obj_temporary_ref_from_id(objsToInsert[i].parent)->get_folder().folderList; - toEraseMap[objsToInsert[i].parent].emplace_back(parentListPtr->get(objsToInsert[i].object)); - if(newIndex != 0 && objsToInsert[i].parent == listObj && listPtr->get(objsToInsert[i].object)->pos <= index) - newIndex--; - } + // // Map parent folders to list of objects that should be erased from them + // for(size_t i = 0; i < objsToInsert.size(); i++) { + // auto& parentListPtr = world.netObjMan.get_obj_temporary_ref_from_id(objsToInsert[i].parent)->get_folder().folderList; + // toEraseMap[objsToInsert[i].parent].emplace_back(parentListPtr->get(objsToInsert[i].object)); + // if(newIndex != 0 && objsToInsert[i].parent == listObj && listPtr->get(objsToInsert[i].object)->pos <= index) + // newIndex--; + // } - // Prepare erase map for undo - for(auto& [parentNetID, objsToEraseList] : toEraseMap) { - auto& undoEraseListPairForParent = toEraseMapUndo[world.undo.get_undoid_from_netid(parentNetID)]; - uint32_t i = 0; - for(auto& objToErase : objsToEraseList) { - undoEraseListPairForParent.first.emplace_back(objToErase->pos - i); - undoEraseListPairForParent.second.emplace_back(world.undo.get_undoid_from_netid(objToErase->obj.get_net_id())); - i++; - } - } + // // Prepare erase map for undo + // for(auto& [parentNetID, objsToEraseList] : toEraseMap) { + // auto& undoEraseListPairForParent = toEraseMapUndo[world.undo.get_undoid_from_netid(parentNetID)]; + // uint32_t i = 0; + // for(auto& objToErase : objsToEraseList) { + // undoEraseListPairForParent.first.emplace_back(objToErase->pos - i); + // undoEraseListPairForParent.second.emplace_back(world.undo.get_undoid_from_netid(objToErase->obj.get_net_id())); + // i++; + // } + // } - // Erase the list of objects we previously mapped to each parent, and move the erased objects to vector toInsertObjPtrs - for(auto& [listToEraseFrom, setToErase] : toEraseMap) { - auto& listToEraseFromPtr = world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder().folderList; - listToEraseFromPtr->erase_list(listToEraseFromPtr, setToErase, &toInsertObjPtrs); - } + // // Erase the list of objects we previously mapped to each parent, and move the erased objects to vector toInsertObjPtrs + // for(auto& [listToEraseFrom, setToErase] : toEraseMap) { + // auto& listToEraseFromPtr = world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder().folderList; + // listToEraseFromPtr->erase_list(listToEraseFromPtr, setToErase, &toInsertObjPtrs); + // } - // Insert objects in toInsertObjPtrs into the folder we have selected - std::vector, NetObjOwnerPtr>> toInsert; - auto insertIt = listPtr->at(newIndex); - for(uint32_t i = 0; i < objsToInsert.size(); i++) { - auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i].object](NetObjOwnerPtr& objPtr) { - return objPtr.get_net_id() == id; - }); - toInsert.emplace_back(insertIt, std::move(*it)); - toInsert.back().second.reassign_ids(); - } - std::vector> insertedIterators = listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); + // // Insert objects in toInsertObjPtrs into the folder we have selected + // std::vector, NetObjOwnerPtr>> toInsert; + // auto insertIt = listPtr->at(newIndex); + // for(uint32_t i = 0; i < objsToInsert.size(); i++) { + // auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i].object](NetObjOwnerPtr& objPtr) { + // return objPtr.get_net_id() == id; + // }); + // toInsert.emplace_back(insertIt, std::move(*it)); + // toInsert.back().second.reassign_ids(); + // } + // std::vector> insertedIterators = listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); - // Prepare insert list for undo - insertParentUndoID = world.undo.get_undoid_from_netid(listObj); - insertUndoPosition = newIndex; - for(auto& it : insertedIterators) - insertedUndoIDs.emplace_back(world.undo.get_undoid_from_netid(it->obj.get_net_id())); - }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); + // // Prepare insert list for undo + // insertParentUndoID = world.undo.get_undoid_from_netid(listObj); + // insertUndoPosition = newIndex; + // for(auto& it : insertedIterators) + // insertedUndoIDs.emplace_back(world.undo.get_undoid_from_netid(it->obj.get_net_id())); + // }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); - class MoveLayersWorldUndoAction : public WorldUndoAction { - public: - // If the undo ID maps to the net id, we can also assume that the object is definitely inside the list we want to move it from, and not inside some other list - // If it was moved to another list, there would be an undo move that would move it back to this list, and if it was moved by another player the undo id wouldnt map back to the net id, and the undo would fail - // We can also assume all objects in all lists remain in the same order for the same reason, so no need to sort anything if it was sorted when the undo action was generated - MoveLayersWorldUndoAction(const std::unordered_map, std::vector>>& initUndoEraseMap, - WorldUndoManager::UndoObjectID initInsertParentUndoID, - uint32_t initInsertPosition, - std::vector initInsertedUndoIDs): - undoEraseMap(initUndoEraseMap), - insertParentUndoID(initInsertParentUndoID), - insertPosition(initInsertPosition), - insertedUndoIDs(initInsertedUndoIDs) - {} - std::string get_name() const override { - return "Move Layers"; - } - bool undo(WorldUndoManager& undoMan) override { - std::vector> toMoveObjs; - std::vector> toEraseList; - NetObjTemporaryPtr> eraseListPtr; - std::unordered_map*, std::vector>> toInsertToMap; + // class MoveLayersWorldUndoAction : public WorldUndoAction { + // public: + // // If the undo ID maps to the net id, we can also assume that the object is definitely inside the list we want to move it from, and not inside some other list + // // If it was moved to another list, there would be an undo move that would move it back to this list, and if it was moved by another player the undo id wouldnt map back to the net id, and the undo would fail + // // We can also assume all objects in all lists remain in the same order for the same reason, so no need to sort anything if it was sorted when the undo action was generated + // MoveLayersWorldUndoAction(const std::unordered_map, std::vector>>& initUndoEraseMap, + // WorldUndoManager::UndoObjectID initInsertParentUndoID, + // uint32_t initInsertPosition, + // std::vector initInsertedUndoIDs): + // undoEraseMap(initUndoEraseMap), + // insertParentUndoID(initInsertParentUndoID), + // insertPosition(initInsertPosition), + // insertedUndoIDs(initInsertedUndoIDs) + // {} + // std::string get_name() const override { + // return "Move Layers"; + // } + // bool undo(WorldUndoManager& undoMan) override { + // std::vector> toMoveObjs; + // std::vector> toEraseList; + // NetObjTemporaryPtr> eraseListPtr; + // std::unordered_map*, std::vector>> toInsertToMap; - { - std::optional eraseListNetID = undoMan.get_netid_from_undoid(insertParentUndoID); - if(!eraseListNetID.has_value()) - return false; - eraseListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(eraseListNetID.value())->get_folder().folderList; - } + // { + // std::optional eraseListNetID = undoMan.get_netid_from_undoid(insertParentUndoID); + // if(!eraseListNetID.has_value()) + // return false; + // eraseListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(eraseListNetID.value())->get_folder().folderList; + // } - { - std::vector toEraseNetIDList; - if(!undoMan.fill_netid_list_from_undoid_list(toEraseNetIDList, insertedUndoIDs)) - return false; - toEraseList = eraseListPtr->get_list(toEraseNetIDList); - } + // { + // std::vector toEraseNetIDList; + // if(!undoMan.fill_netid_list_from_undoid_list(toEraseNetIDList, insertedUndoIDs)) + // return false; + // toEraseList = eraseListPtr->get_list(toEraseNetIDList); + // } - { - for(auto& [undoID, indexUndoIdListPair] : undoEraseMap) { - std::optional netID = undoMan.get_netid_from_undoid(undoID); - if(!netID.has_value()) - return false; - auto& insertMapEntry = toInsertToMap[netID.value()]; - insertMapEntry.first = &indexUndoIdListPair.first; - if(!undoMan.fill_netid_list_from_undoid_list(insertMapEntry.second, indexUndoIdListPair.second)) - return false; - } - } + // { + // for(auto& [undoID, indexUndoIdListPair] : undoEraseMap) { + // std::optional netID = undoMan.get_netid_from_undoid(undoID); + // if(!netID.has_value()) + // return false; + // auto& insertMapEntry = toInsertToMap[netID.value()]; + // insertMapEntry.first = &indexUndoIdListPair.first; + // if(!undoMan.fill_netid_list_from_undoid_list(insertMapEntry.second, indexUndoIdListPair.second)) + // return false; + // } + // } - undoMan.world.netObjMan.send_multi_update_messsage([&]() { - eraseListPtr->erase_list(eraseListPtr, toEraseList, &toMoveObjs); + // undoMan.world.netObjMan.send_multi_update_messsage([&]() { + // eraseListPtr->erase_list(eraseListPtr, toEraseList, &toMoveObjs); - for(auto& [parentNetID, indexNetIDListPair] : toInsertToMap) { - auto& parentListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(parentNetID)->get_folder().folderList; - std::vector> insertIteratorList = parentListPtr->at_ordered_indices(*indexNetIDListPair.first); - auto& insertNetIDList = indexNetIDListPair.second; - std::vector, NetObjOwnerPtr>> toInsert; - for(auto [insertIt, netID] : std::views::zip(insertIteratorList, insertNetIDList)) { - auto it = std::find_if(toMoveObjs.begin(), toMoveObjs.end(), [id = netID](NetObjOwnerPtr& objPtr) { - return objPtr.get_net_id() == id; - }); - toInsert.emplace_back(insertIt, std::move(*it)); - toInsert.back().second.reassign_ids(); - } - parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); - } - }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); - return true; - } - bool redo(WorldUndoManager& undoMan) override { - std::unordered_map> toEraseMap; - NetObjTemporaryPtr> listPtr; - std::vector objsToInsert; + // for(auto& [parentNetID, indexNetIDListPair] : toInsertToMap) { + // auto& parentListPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(parentNetID)->get_folder().folderList; + // std::vector> insertIteratorList = parentListPtr->at_ordered_indices(*indexNetIDListPair.first); + // auto& insertNetIDList = indexNetIDListPair.second; + // std::vector, NetObjOwnerPtr>> toInsert; + // for(auto [insertIt, netID] : std::views::zip(insertIteratorList, insertNetIDList)) { + // auto it = std::find_if(toMoveObjs.begin(), toMoveObjs.end(), [id = netID](NetObjOwnerPtr& objPtr) { + // return objPtr.get_net_id() == id; + // }); + // toInsert.emplace_back(insertIt, std::move(*it)); + // toInsert.back().second.reassign_ids(); + // } + // parentListPtr->insert_sorted_list_and_send_create(parentListPtr, toInsert); + // } + // }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); + // return true; + // } + // bool redo(WorldUndoManager& undoMan) override { + // std::unordered_map> toEraseMap; + // NetObjTemporaryPtr> listPtr; + // std::vector objsToInsert; - { - for(auto& [undoID, indexUndoIDListPair] : undoEraseMap) { - std::optional netID = undoMan.get_netid_from_undoid(undoID); - if(!netID.has_value()) - return false; - if(!undoMan.fill_netid_list_from_undoid_list(toEraseMap[netID.value()], indexUndoIDListPair.second)) - return false; - } - } + // { + // for(auto& [undoID, indexUndoIDListPair] : undoEraseMap) { + // std::optional netID = undoMan.get_netid_from_undoid(undoID); + // if(!netID.has_value()) + // return false; + // if(!undoMan.fill_netid_list_from_undoid_list(toEraseMap[netID.value()], indexUndoIDListPair.second)) + // return false; + // } + // } - { - std::optional netID = undoMan.get_netid_from_undoid(insertParentUndoID); - if(!netID.has_value()) - return false; - listPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(netID.value())->get_folder().folderList; - } + // { + // std::optional netID = undoMan.get_netid_from_undoid(insertParentUndoID); + // if(!netID.has_value()) + // return false; + // listPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(netID.value())->get_folder().folderList; + // } - { - if(!undoMan.fill_netid_list_from_undoid_list(objsToInsert, insertedUndoIDs)) - return false; - } + // { + // if(!undoMan.fill_netid_list_from_undoid_list(objsToInsert, insertedUndoIDs)) + // return false; + // } - undoMan.world.netObjMan.send_multi_update_messsage([&]() { - std::vector> toInsertObjPtrs; + // undoMan.world.netObjMan.send_multi_update_messsage([&]() { + // std::vector> toInsertObjPtrs; - for(auto& [listToEraseFrom, setToErase] : toEraseMap) { - auto& listToEraseFromPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder().folderList; - listToEraseFromPtr->erase_list(listToEraseFromPtr, listToEraseFromPtr->get_list(setToErase), &toInsertObjPtrs); - } + // for(auto& [listToEraseFrom, setToErase] : toEraseMap) { + // auto& listToEraseFromPtr = undoMan.world.netObjMan.get_obj_temporary_ref_from_id(listToEraseFrom)->get_folder().folderList; + // listToEraseFromPtr->erase_list(listToEraseFromPtr, listToEraseFromPtr->get_list(setToErase), &toInsertObjPtrs); + // } - std::vector, NetObjOwnerPtr>> toInsert; - auto insertIt = listPtr->at(insertPosition); - for(uint32_t i = 0; i < objsToInsert.size(); i++) { - auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i]](NetObjOwnerPtr& objPtr) { - return objPtr.get_net_id() == id; - }); - toInsert.emplace_back(insertIt, std::move(*it)); - toInsert.back().second.reassign_ids(); - } - listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); - }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); + // std::vector, NetObjOwnerPtr>> toInsert; + // auto insertIt = listPtr->at(insertPosition); + // for(uint32_t i = 0; i < objsToInsert.size(); i++) { + // auto it = std::find_if(toInsertObjPtrs.begin(), toInsertObjPtrs.end(), [id = objsToInsert[i]](NetObjOwnerPtr& objPtr) { + // return objPtr.get_net_id() == id; + // }); + // toInsert.emplace_back(insertIt, std::move(*it)); + // toInsert.back().second.reassign_ids(); + // } + // listPtr->insert_sorted_list_and_send_create(listPtr, toInsert); + // }, NetObjManager::SendUpdateType::SEND_TO_ALL, nullptr); - return true; - } - ~MoveLayersWorldUndoAction() {} + // return true; + // } + // ~MoveLayersWorldUndoAction() {} - std::unordered_map, std::vector>> undoEraseMap; - WorldUndoManager::UndoObjectID insertParentUndoID; - uint32_t insertPosition; - std::vector insertedUndoIDs; - }; - world.undo.push(std::make_unique(toEraseMapUndo, insertParentUndoID, insertUndoPosition, insertedUndoIDs)); - } - }, selectionData); + // std::unordered_map, std::vector>> undoEraseMap; + // WorldUndoManager::UndoObjectID insertParentUndoID; + // uint32_t insertPosition; + // std::vector insertedUndoIDs; + // }; + // world.undo.push(std::make_unique(toEraseMapUndo, insertParentUndoID, insertUndoPosition, insertedUndoIDs)); + // } + // }, selectionData); - if(selectionData.objsSelected != oldSelection) { - editing_layer_check(); - oldSelection = selectionData.objsSelected; - if(selectionData.objsSelected.size() == 1) { - NetObjTemporaryPtr tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); - if(tempPtr) { - nameToEdit = tempPtr->get_name(); - alphaValToEdit = tempPtr->get_alpha(); - auto it = std::find(get_blend_mode_useful_list().begin(), get_blend_mode_useful_list().end(), tempPtr->get_blend_mode()); - blendModeValToEdit = (it == get_blend_mode_useful_list().end()) ? 0 : (it - get_blend_mode_useful_list().begin()); - } - else { - nameToEdit.clear(); - alphaValToEdit = 0.0f; - blendModeValToEdit = 0; - } - } - else { - nameToEdit.clear(); - alphaValToEdit = 0.0f; - blendModeValToEdit = 0; - } - } + // if(selectionData.objsSelected != oldSelection) { + // editing_layer_check(); + // oldSelection = selectionData.objsSelected; + // if(selectionData.objsSelected.size() == 1) { + // NetObjTemporaryPtr tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); + // if(tempPtr) { + // nameToEdit = tempPtr->get_name(); + // alphaValToEdit = tempPtr->get_alpha(); + // auto it = std::find(get_blend_mode_useful_list().begin(), get_blend_mode_useful_list().end(), tempPtr->get_blend_mode()); + // blendModeValToEdit = (it == get_blend_mode_useful_list().end()) ? 0 : (it - get_blend_mode_useful_list().begin()); + // } + // else { + // nameToEdit.clear(); + // alphaValToEdit = 0.0f; + // blendModeValToEdit = 0; + // } + // } + // else { + // nameToEdit.clear(); + // alphaValToEdit = 0.0f; + // blendModeValToEdit = 0; + // } + // } - if(toDeleteObject.has_value()) - remove_layer(toDeleteParent.value(), toDeleteObject.value()); - } + // if(toDeleteObject.has_value()) + // remove_layer(toDeleteParent.value(), toDeleteObject.value()); + // } - gui.left_to_right_line_layout([&]() { - bool addByEnter = false; - gui.input_text("input new name", &nameForNew, true, [&](GUIStuff::SelectionHelper& s) { - addByEnter = s.selected && gui.io->key.enter; - }); - - if(gui.svg_icon_button("create new layer", "data/icons/plusbold.svg", false, gui.SMALL_BUTTON_SIZE) || addByEnter) { - auto newLayerObjInfo = create_layer(new DrawingProgramLayerListItem(world.netObjMan, nameForNew, false)); - layerMan.editingLayer = newLayerObjInfo->obj; - } - else if(gui.svg_icon_button("create new folder", "data/icons/folderbold.svg", false, gui.SMALL_BUTTON_SIZE)) { - auto newFolderObjInfo = create_layer(new DrawingProgramLayerListItem(world.netObjMan, nameForNew, true)); - newFolderObjInfo->obj->get_folder().isFolderOpen = true; - } - }); + // gui.left_to_right_line_layout([&]() { + // bool addByEnter = false; + // gui.input_text("input new name", &nameForNew, true, [&](GUIStuff::SelectionHelper& s) { + // addByEnter = s.selected && gui.io->key.enter; + // }); + // + // if(gui.svg_icon_button("create new layer", "data/icons/plusbold.svg", false, gui.SMALL_BUTTON_SIZE) || addByEnter) { + // auto newLayerObjInfo = create_layer(new DrawingProgramLayerListItem(world.netObjMan, nameForNew, false)); + // layerMan.editingLayer = newLayerObjInfo->obj; + // } + // else if(gui.svg_icon_button("create new folder", "data/icons/folderbold.svg", false, gui.SMALL_BUTTON_SIZE)) { + // auto newFolderObjInfo = create_layer(new DrawingProgramLayerListItem(world.netObjMan, nameForNew, true)); + // newFolderObjInfo->obj->get_folder().isFolderOpen = true; + // } + // }); - if(selectionData.objsSelected.size() == 1) { - NetObjTemporaryPtr tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); - if(tempPtr) { - gui.text_label_centered(tempPtr->is_folder() ? "Edit Layer Folder" : "Edit Layer"); - gui.input_text_field("input edit name", "Name", &nameToEdit); - tempPtr->set_name(world.delayedUpdateObjectManager, nameToEdit); - gui.slider_scalar_field("input alpha slider", "Alpha", &alphaValToEdit, 0.0f, 1.0f, 2); - tempPtr->set_alpha(layerMan, alphaValToEdit); - gui.left_to_right_line_layout([&]() { - gui.text_label("Blend Mode"); - gui.dropdown_select("input blend mode", &blendModeValToEdit, get_blend_mode_useful_name_list(), 190.0f, [&hoveringOverDropdown]() { - if(Clay_Hovered()) - hoveringOverDropdown = true; - }); - }); - tempPtr->set_blend_mode(layerMan, get_blend_mode_useful_list()[blendModeValToEdit]); - } - } + // if(selectionData.objsSelected.size() == 1) { + // NetObjTemporaryPtr tempPtr = world.netObjMan.get_obj_temporary_ref_from_id(*selectionData.objsSelected.begin()); + // if(tempPtr) { + // gui.text_label_centered(tempPtr->is_folder() ? "Edit Layer Folder" : "Edit Layer"); + // gui.input_text_field("input edit name", "Name", &nameToEdit); + // tempPtr->set_name(world.delayedUpdateObjectManager, nameToEdit); + // gui.slider_scalar_field("input alpha slider", "Alpha", &alphaValToEdit, 0.0f, 1.0f, 2); + // tempPtr->set_alpha(layerMan, alphaValToEdit); + // gui.left_to_right_line_layout([&]() { + // gui.text_label("Blend Mode"); + // gui.dropdown_select("input blend mode", &blendModeValToEdit, get_blend_mode_useful_name_list(), 190.0f, [&hoveringOverDropdown]() { + // if(Clay_Hovered()) + // hoveringOverDropdown = true; + // }); + // }); + // tempPtr->set_blend_mode(layerMan, get_blend_mode_useful_list()[blendModeValToEdit]); + // } + // } - gui.pop_id(); - } + // gui.pop_id(); + //} } std::optional>> DrawingProgramLayerManagerGUI::try_to_create_in_proper_position(DrawingProgramLayerListItem* newItem) { diff --git a/src/DrawingProgram/Tools/EditTool.cpp b/src/DrawingProgram/Tools/EditTool.cpp index 2e1e7cf..bde599c 100644 --- a/src/DrawingProgram/Tools/EditTool.cpp +++ b/src/DrawingProgram/Tools/EditTool.cpp @@ -30,11 +30,8 @@ void EditTool::gui_toolbox() { using namespace ElementHelpers; Toolbar& t = drawP.world.main.toolbar; - if(objInfoBeingEdited) { - bool editHappened = compEditTool->edit_gui(objInfoBeingEdited); - if(editHappened) - objInfoBeingEdited->obj->commit_update(drawP); - } + if(objInfoBeingEdited) + compEditTool->edit_gui(objInfoBeingEdited); else { t.gui.push_id("edit tool"); text_label_centered(t.gui, "Edit"); diff --git a/src/DrawingProgram/Tools/EditTools/BrushEditTool.cpp b/src/DrawingProgram/Tools/EditTools/BrushEditTool.cpp index 6376c23..3c4e218 100644 --- a/src/DrawingProgram/Tools/EditTools/BrushEditTool.cpp +++ b/src/DrawingProgram/Tools/EditTools/BrushEditTool.cpp @@ -4,25 +4,26 @@ #include "../../../MainProgram.hpp" #include "../EditTool.hpp" +#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/LayoutHelpers.hpp" + BrushEditTool::BrushEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -bool BrushEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { - auto& a = static_cast(comp->obj->get_comp()); +void BrushEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { + using namespace GUIStuff; + using namespace ElementHelpers; + Toolbar& t = drawP.world.main.toolbar; t.gui.push_id("edit tool brush"); - t.gui.text_label_centered("Edit Brush Stroke"); - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Outline Color", &a.d.color, &a.d.color == t.colorRight)) - t.color_selector_right(&a.d.color == t.colorRight ? nullptr : &a.d.color); - t.gui.text_label("Outline Color"); + text_label_centered(t.gui, "Edit Brush Stroke"); + left_to_right_line_layout(t.gui, [&]() { + //if(t.gui.color_button_big("Outline Color", &a.d.color, &a.d.color == t.colorRight)) + // t.color_selector_right(&a.d.color == t.colorRight ? nullptr : &a.d.color); + text_label(t.gui, "Outline Color"); }); t.gui.pop_id(); - - bool editHappened = a.d.color != oldColor; - oldColor = a.d.color; - return editHappened; } void BrushEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) { diff --git a/src/DrawingProgram/Tools/EditTools/BrushEditTool.hpp b/src/DrawingProgram/Tools/EditTools/BrushEditTool.hpp index 50e0a69..027fb39 100644 --- a/src/DrawingProgram/Tools/EditTools/BrushEditTool.hpp +++ b/src/DrawingProgram/Tools/EditTools/BrushEditTool.hpp @@ -12,7 +12,7 @@ class BrushEditTool : public DrawingProgramEditToolBase { virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override; - virtual bool edit_gui(CanvasComponentContainer::ObjInfo* comp) override; + virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override; private: Vector4f oldColor; }; diff --git a/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.cpp b/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.cpp index 77c5ada..e4416e6 100644 --- a/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.cpp +++ b/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.cpp @@ -5,10 +5,9 @@ DrawingProgramEditToolBase::DrawingProgramEditToolBase(DrawingProgram& initDrawP drawP(initDrawP) {} -bool DrawingProgramEditToolBase::right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) { +void DrawingProgramEditToolBase::right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) { Toolbar& t = drawP.world.main.toolbar; t.paint_popup(popupPos); - return true; } void DrawingProgramEditToolBase::input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key) {} diff --git a/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.hpp b/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.hpp index b996721..3186ee6 100644 --- a/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.hpp +++ b/src/DrawingProgram/Tools/EditTools/DrawingProgramEditToolBase.hpp @@ -12,8 +12,8 @@ class DrawingProgramEditToolBase { virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* compContainer, std::any& prevData) = 0; virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* compContainer, std::any& prevData) = 0; virtual bool edit_update(CanvasComponentContainer::ObjInfo* compContainer) = 0; - virtual bool edit_gui(CanvasComponentContainer::ObjInfo* compContainer) = 0; - virtual bool right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos); + virtual void edit_gui(CanvasComponentContainer::ObjInfo* compContainer) = 0; + virtual void right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos); virtual void input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key); virtual void input_mouse_button_on_canvas_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint); virtual void input_mouse_motion_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseMotionCallbackArgs& motion, bool isDraggingPoint); diff --git a/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.cpp b/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.cpp index 24de66f..f80ec97 100644 --- a/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.cpp +++ b/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.cpp @@ -7,39 +7,45 @@ #include #include "../EditTool.hpp" +#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/RadioButtonHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/LayoutHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/NumberSliderHelpers.hpp" + EllipseDrawEditTool::EllipseDrawEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -bool EllipseDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { +void EllipseDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { + using namespace GUIStuff; + using namespace ElementHelpers; + auto& a = static_cast(comp->obj->get_comp()); Toolbar& t = drawP.world.main.toolbar; t.gui.push_id("edit tool ellipse"); - t.gui.text_label_centered("Edit Ellipse"); - if(t.gui.radio_button_field("fillonly", "Fill only", a.d.fillStrokeMode == 0)) a.d.fillStrokeMode = 0; - if(t.gui.radio_button_field("outlineonly", "Outline only", a.d.fillStrokeMode == 1)) a.d.fillStrokeMode = 1; - if(t.gui.radio_button_field("filloutline", "Fill and Outline", a.d.fillStrokeMode == 2)) a.d.fillStrokeMode = 2; + text_label_centered(t.gui, "Edit Ellipse"); + radio_button_selector(t.gui, "Fill selector", &a.d.fillStrokeMode, { + {"Fill only", 0}, + {"Outline only", 1}, + {"Fill and outline", 2} + }); if(a.d.fillStrokeMode == 0 || a.d.fillStrokeMode == 2) { - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Fill Color", &a.d.fillColor, &a.d.fillColor == t.colorRight)) - t.color_selector_right(&a.d.fillColor == t.colorRight ? nullptr : &a.d.fillColor); - t.gui.text_label("Fill Color"); + left_to_right_line_layout(t.gui, [&] { + //if(t.gui.color_button_big("Fill Color", &a.d.fillColor, &a.d.fillColor == t.colorRight)) + // t.color_selector_right(&a.d.fillColor == t.colorRight ? nullptr : &a.d.fillColor); + text_label(t.gui, "Fill Color"); }); } if(a.d.fillStrokeMode == 1 || a.d.fillStrokeMode == 2) { - t.gui.slider_scalar_field("relstrokewidth", "Outline Size", &a.d.strokeWidth, 3.0f, 40.0f); - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Outline Color", &a.d.strokeColor, &a.d.strokeColor == t.colorRight)) - t.color_selector_right(&a.d.strokeColor == t.colorRight ? nullptr : &a.d.strokeColor); - t.gui.text_label("Outline Color"); + slider_scalar_field(t.gui, "relstrokewidth", "Outline Size", &a.d.strokeWidth, 3.0f, 40.0f); + left_to_right_line_layout(t.gui, [&] { + //if(t.gui.color_button_big("Outline Color", &a.d.strokeColor, &a.d.strokeColor == t.colorRight)) + // t.color_selector_right(&a.d.strokeColor == t.colorRight ? nullptr : &a.d.strokeColor); + text_label(t.gui, "Outline Color"); }); } t.gui.pop_id(); - - bool editHappened = (!oldData.has_value()) || (a.d != oldData); - oldData = a.d; - return editHappened; } void EllipseDrawEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) { diff --git a/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.hpp b/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.hpp index 9b0bff3..c640803 100644 --- a/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.hpp +++ b/src/DrawingProgram/Tools/EditTools/EllipseDrawEditTool.hpp @@ -13,7 +13,7 @@ class EllipseDrawEditTool : public DrawingProgramEditToolBase { virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override; - virtual bool edit_gui(CanvasComponentContainer::ObjInfo* comp) override; + virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override; private: void commit(); diff --git a/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp b/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp index 9d4829f..0b94062 100644 --- a/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp +++ b/src/DrawingProgram/Tools/EditTools/ImageEditTool.cpp @@ -10,6 +10,9 @@ #include "Eigen/Geometry" #include +#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/ButtonHelpers.hpp" + #ifdef __EMSCRIPTEN__ #include #endif @@ -42,30 +45,35 @@ bool ImageEditTool::edit_update(CanvasComponentContainer::ObjInfo* comp) { return true; } -bool ImageEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { +void ImageEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { + using namespace GUIStuff; + using namespace ElementHelpers; + ImageCanvasComponent& a = static_cast(comp->obj->get_comp()); Toolbar& t = drawP.world.main.toolbar; t.gui.push_id("edit tool image"); - t.gui.text_label_centered("File Properties"); + text_label_centered(t.gui, "File Properties"); auto resourceData = drawP.world.netObjMan.get_obj_temporary_ref_from_id(a.d.imageID); if(resourceData) { - t.gui.text_label("Name: " + resourceData->name); - if(t.gui.text_button_wide("file download", "Download file")) { - #ifdef __EMSCRIPTEN__ - emscripten_browser_file::download( - resourceData->name, - "application/octet-binary", - *resourceData->data - ); - #endif - t.open_file_selector("Download File", {{"Any File", "*"}}, [resourceData](const std::filesystem::path& p, const auto& e) { - SDL_SaveFile(p.c_str(), resourceData->data->c_str(), resourceData->data->size()); - }, resourceData->name, true); - } + text_label(t.gui, "Name: " + resourceData->name); + text_button(t.gui, "file download", "Download file", { + .wide = true, + .onClick = [&] { + #ifdef __EMSCRIPTEN__ + emscripten_browser_file::download( + resourceData->name, + "application/octet-binary", + *resourceData->data + ); + #endif + t.open_file_selector("Download File", {{"Any File", "*"}}, [resourceData](const std::filesystem::path& p, const auto& e) { + SDL_SaveFile(p.c_str(), resourceData->data->c_str(), resourceData->data->size()); + }, resourceData->name, true); + } + }); } else - t.gui.text_label_centered("Loading resource..."); + text_label_centered(t.gui, "Loading resource..."); t.gui.pop_id(); - return false; } diff --git a/src/DrawingProgram/Tools/EditTools/ImageEditTool.hpp b/src/DrawingProgram/Tools/EditTools/ImageEditTool.hpp index 0f7985f..53ce119 100644 --- a/src/DrawingProgram/Tools/EditTools/ImageEditTool.hpp +++ b/src/DrawingProgram/Tools/EditTools/ImageEditTool.hpp @@ -10,5 +10,5 @@ class ImageEditTool : public DrawingProgramEditToolBase { virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override; - virtual bool edit_gui(CanvasComponentContainer::ObjInfo* comp) override; + virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override; }; diff --git a/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.cpp b/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.cpp index af180de..4e67545 100644 --- a/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.cpp +++ b/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.cpp @@ -5,39 +5,44 @@ #include #include "../EditTool.hpp" +#include "../../../GUIStuff/ElementHelpers/NumberSliderHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/RadioButtonHelpers.hpp" + RectDrawEditTool::RectDrawEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -bool RectDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { +void RectDrawEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { + using namespace GUIStuff; + using namespace ElementHelpers; + auto& a = static_cast(comp->obj->get_comp()); Toolbar& t = drawP.world.main.toolbar; t.gui.push_id("edit tool rectangle"); - t.gui.text_label_centered("Edit Rectangle"); - t.gui.slider_scalar_field("relradiuswidth", "Corner Radius", &a.d.cornerRadius, 0.0f, 40.0f); - if(t.gui.radio_button_field("fillonly", "Fill only", a.d.fillStrokeMode == 0)) a.d.fillStrokeMode = 0; - if(t.gui.radio_button_field("outlineonly", "Outline only", a.d.fillStrokeMode == 1)) a.d.fillStrokeMode = 1; - if(t.gui.radio_button_field("filloutline", "Fill and Outline", a.d.fillStrokeMode == 2)) a.d.fillStrokeMode = 2; + text_label_centered(t.gui, "Edit Rectangle"); + slider_scalar_field(t.gui, "relradiuswidth", "Corner Radius", &a.d.cornerRadius, 0.0f, 40.0f); + radio_button_selector(t.gui, "Fill selector", &a.d.fillStrokeMode, { + {"Fill only", 0}, + {"Outline only", 1}, + {"Fill and outline", 2} + }); if(a.d.fillStrokeMode == 0 || a.d.fillStrokeMode == 2) { - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Fill Color", &a.d.fillColor, &a.d.fillColor == t.colorRight)) - t.color_selector_right(&a.d.fillColor == t.colorRight ? nullptr : &a.d.fillColor); - t.gui.text_label("Fill Color"); + left_to_right_line_layout(t.gui, [&] { + //if(t.gui.color_button_big("Fill Color", &a.d.fillColor, &a.d.fillColor == t.colorRight)) + // t.color_selector_right(&a.d.fillColor == t.colorRight ? nullptr : &a.d.fillColor); + text_label(t.gui, "Fill Color"); }); } if(a.d.fillStrokeMode == 1 || a.d.fillStrokeMode == 2) { - t.gui.slider_scalar_field("relstrokewidth", "Outline Size", &a.d.strokeWidth, 3.0f, 40.0f); - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Outline Color", &a.d.strokeColor, &a.d.strokeColor == t.colorRight)) - t.color_selector_right(&a.d.strokeColor == t.colorRight ? nullptr : &a.d.strokeColor); - t.gui.text_label("Outline Color"); + slider_scalar_field(t.gui, "relstrokewidth", "Outline Size", &a.d.strokeWidth, 3.0f, 40.0f); + left_to_right_line_layout(t.gui, [&] { + //if(t.gui.color_button_big("Outline Color", &a.d.strokeColor, &a.d.strokeColor == t.colorRight)) + // t.color_selector_right(&a.d.strokeColor == t.colorRight ? nullptr : &a.d.strokeColor); + text_label(t.gui, "Outline Color"); }); } t.gui.pop_id(); - - bool editHappened = (!oldData.has_value()) || (a.d != oldData); - oldData = a.d; - return editHappened; } void RectDrawEditTool::edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) { diff --git a/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.hpp b/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.hpp index 6e81f8f..5a2f2e2 100644 --- a/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.hpp +++ b/src/DrawingProgram/Tools/EditTools/RectDrawEditTool.hpp @@ -12,7 +12,7 @@ class RectDrawEditTool : public DrawingProgramEditToolBase { virtual void edit_start(EditTool& editTool, CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override; - virtual bool edit_gui(CanvasComponentContainer::ObjInfo* comp) override; + virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override; private: std::optional oldData; }; diff --git a/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.cpp b/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.cpp index edc45a5..8ee6129 100644 --- a/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.cpp +++ b/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.cpp @@ -14,142 +14,149 @@ #include #include "../EditTool.hpp" +#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp" +#include "../../../GUIStuff/ElementHelpers/LayoutHelpers.hpp" +#include "../../../GUIStuff/Elements/PositionAdjustingPopupMenu.hpp" + using namespace RichText; TextBoxEditTool::TextBoxEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -bool TextBoxEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { +void TextBoxEditTool::edit_gui(CanvasComponentContainer::ObjInfo* comp) { + using namespace GUIStuff; + using namespace ElementHelpers; + auto& a = static_cast(comp->obj->get_comp()); Toolbar& t = drawP.world.main.toolbar; auto& currentMods = *currentModsPtr; t.gui.push_id("edit tool text"); - t.gui.text_label_centered("Edit Text"); + text_label_centered(t.gui, "Edit Text"); - t.gui.left_to_right_line_layout([&]() { - t.gui.text_label("Font"); - if(t.gui.font_picker("font picker", &newFontName)) { - currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES] = std::make_shared(std::vector{SkString{newFontName.c_str(), newFontName.size()}}); - add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES]);}); - } + left_to_right_line_layout(t.gui, [&] { + text_label(t.gui, "Font"); + //if(t.gui.font_picker("font picker", &newFontName)) { + // currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES] = std::make_shared(std::vector{SkString{newFontName.c_str(), newFontName.size()}}); + // add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES]);}); + //} }); - t.gui.left_to_right_line_centered_layout([&]() { - if(t.gui.svg_icon_button("Bold button", "data/icons/RemixIcon/bold.svg", newIsBold)) { - newIsBold = !newIsBold; - currentMods[TextStyleModifier::ModifierType::WEIGHT] = std::make_shared(newIsBold ? SkFontStyle::Weight::kBold_Weight : SkFontStyle::Weight::kNormal_Weight); - add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::WEIGHT]);}); - } + //left_to_right_line_centered_layout(t.gui, [&] { + // if(svg_icon_button("Bold button", "data/icons/RemixIcon/bold.svg", newIsBold)) { + // newIsBold = !newIsBold; + // currentMods[TextStyleModifier::ModifierType::WEIGHT] = std::make_shared(newIsBold ? SkFontStyle::Weight::kBold_Weight : SkFontStyle::Weight::kNormal_Weight); + // add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::WEIGHT]);}); + // } - if(t.gui.svg_icon_button("Italic button", "data/icons/RemixIcon/italic.svg", newIsItalic)) { - newIsItalic = !newIsItalic; - currentMods[TextStyleModifier::ModifierType::SLANT] = std::make_shared(newIsItalic ? SkFontStyle::Slant::kItalic_Slant : SkFontStyle::Slant::kUpright_Slant); - add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SLANT]);}); - } + // if(t.gui.svg_icon_button("Italic button", "data/icons/RemixIcon/italic.svg", newIsItalic)) { + // newIsItalic = !newIsItalic; + // currentMods[TextStyleModifier::ModifierType::SLANT] = std::make_shared(newIsItalic ? SkFontStyle::Slant::kItalic_Slant : SkFontStyle::Slant::kUpright_Slant); + // add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SLANT]);}); + // } - bool decorationEdited = false; - if(t.gui.svg_icon_button("Underline button", "data/icons/RemixIcon/underline.svg", newIsUnderlined)) { - newIsUnderlined = !newIsUnderlined; - decorationEdited = true; - } - if(t.gui.svg_icon_button("Strikethrough button", "data/icons/RemixIcon/strikethrough.svg", newIsLinethrough)) { - newIsLinethrough = !newIsLinethrough; - decorationEdited = true; - } - if(t.gui.svg_icon_button("Overline button", "data/icons/RemixIcon/overline.svg", newIsOverline)) { - newIsOverline = !newIsOverline; - decorationEdited = true; - } - if(decorationEdited) { - currentMods[TextStyleModifier::ModifierType::DECORATION] = std::make_shared(get_new_decoration_value()); - add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::DECORATION]);}); - } - }); + // bool decorationEdited = false; + // if(t.gui.svg_icon_button("Underline button", "data/icons/RemixIcon/underline.svg", newIsUnderlined)) { + // newIsUnderlined = !newIsUnderlined; + // decorationEdited = true; + // } + // if(t.gui.svg_icon_button("Strikethrough button", "data/icons/RemixIcon/strikethrough.svg", newIsLinethrough)) { + // newIsLinethrough = !newIsLinethrough; + // decorationEdited = true; + // } + // if(t.gui.svg_icon_button("Overline button", "data/icons/RemixIcon/overline.svg", newIsOverline)) { + // newIsOverline = !newIsOverline; + // decorationEdited = true; + // } + // if(decorationEdited) { + // currentMods[TextStyleModifier::ModifierType::DECORATION] = std::make_shared(get_new_decoration_value()); + // add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::DECORATION]);}); + // } + //}); - t.gui.left_to_right_line_centered_layout([&]() { - if(t.gui.svg_icon_button("Align left button", "data/icons/RemixIcon/align-left.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kLeft)) - add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kLeft);}); - if(t.gui.svg_icon_button("Align center button", "data/icons/RemixIcon/align-center.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kCenter)) - add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kCenter);}); - if(t.gui.svg_icon_button("Align right button", "data/icons/RemixIcon/align-right.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kRight)) - add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kRight);}); - if(t.gui.svg_icon_button("Align justify button", "data/icons/RemixIcon/align-justify.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kJustify)) - add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kJustify);}); - if(t.gui.svg_icon_button("Text direction left", "data/icons/RemixIcon/text-direction-l.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kLtr)) - add_undo([&](){a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kLtr);}); - if(t.gui.svg_icon_button("Text direction right", "data/icons/RemixIcon/text-direction-r.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kRtl)) - add_undo([&](){a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kRtl);}); - }); + //t.gui.left_to_right_line_centered_layout([&]() { + // if(t.gui.svg_icon_button("Align left button", "data/icons/RemixIcon/align-left.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kLeft)) + // add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kLeft);}); + // if(t.gui.svg_icon_button("Align center button", "data/icons/RemixIcon/align-center.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kCenter)) + // add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kCenter);}); + // if(t.gui.svg_icon_button("Align right button", "data/icons/RemixIcon/align-right.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kRight)) + // add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kRight);}); + // if(t.gui.svg_icon_button("Align justify button", "data/icons/RemixIcon/align-justify.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kJustify)) + // add_undo([&](){a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kJustify);}); + // if(t.gui.svg_icon_button("Text direction left", "data/icons/RemixIcon/text-direction-l.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kLtr)) + // add_undo([&](){a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kLtr);}); + // if(t.gui.svg_icon_button("Text direction right", "data/icons/RemixIcon/text-direction-r.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kRtl)) + // add_undo([&](){a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kRtl);}); + //}); - if(t.gui.slider_scalar_field("Font Size Slider", "Font Size", &newFontSize, 3, 100)) { - hold_undo_data("Font Size", a); - currentMods[TextStyleModifier::ModifierType::SIZE] = std::make_shared(newFontSize); - a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SIZE]); - } - else - release_undo_data("Font Size"); + //if(t.gui.slider_scalar_field("Font Size Slider", "Font Size", &newFontSize, 3, 100)) { + // hold_undo_data("Font Size", a); + // currentMods[TextStyleModifier::ModifierType::SIZE] = std::make_shared(newFontSize); + // a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SIZE]); + //} + //else + // release_undo_data("Font Size"); - // Text color - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Text Color", &newTextColor, &newTextColor == t.colorRight)) - t.color_selector_right(&newTextColor == t.colorRight ? nullptr : &newTextColor); - t.gui.text_label("Text Color"); - }); + //// Text color + //t.gui.left_to_right_line_layout([&]() { + // if(t.gui.color_button_big("Text Color", &newTextColor, &newTextColor == t.colorRight)) + // t.color_selector_right(&newTextColor == t.colorRight ? nullptr : &newTextColor); + // t.gui.text_label("Text Color"); + //}); - if(&newTextColor == t.colorRight) - hold_undo_data("Text Color", a); - else - release_undo_data("Text Color"); + //if(&newTextColor == t.colorRight) + // hold_undo_data("Text Color", a); + //else + // release_undo_data("Text Color"); - if((&newTextColor == t.colorRight) && t.isUpdatingColorRight) { - currentMods[TextStyleModifier::ModifierType::COLOR] = std::make_shared(newTextColor); - a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::COLOR]); - } + //if((&newTextColor == t.colorRight) && t.isUpdatingColorRight) { + // currentMods[TextStyleModifier::ModifierType::COLOR] = std::make_shared(newTextColor); + // a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::COLOR]); + //} - // Highlight color - t.gui.left_to_right_line_layout([&]() { - if(t.gui.color_button_big("Highlight Color", &newHighlightColor, &newHighlightColor == t.colorRight)) { - if(newHighlightColor.w() == 0.0f) { // Make highlight appear when the button is pressed - newHighlightColor.w() = 1.0f; - currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR] = std::make_shared(newHighlightColor); - add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR]);}); - } - t.color_selector_right(&newHighlightColor == t.colorRight ? nullptr : &newHighlightColor); - } - if(newHighlightColor.w() != 0.0f) { - if(t.gui.svg_icon_button("Remove Highlight Color", "data/icons/close.svg")) { - newHighlightColor = {0.0f, 0.0f, 0.0f, 0.0f}; - currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR] = std::make_shared(newHighlightColor); - add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR]);}); - } - } - t.gui.text_label("Highlight Color"); - }); + //// Highlight color + //t.gui.left_to_right_line_layout([&]() { + // if(t.gui.color_button_big("Highlight Color", &newHighlightColor, &newHighlightColor == t.colorRight)) { + // if(newHighlightColor.w() == 0.0f) { // Make highlight appear when the button is pressed + // newHighlightColor.w() = 1.0f; + // currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR] = std::make_shared(newHighlightColor); + // add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR]);}); + // } + // t.color_selector_right(&newHighlightColor == t.colorRight ? nullptr : &newHighlightColor); + // } + // if(newHighlightColor.w() != 0.0f) { + // if(t.gui.svg_icon_button("Remove Highlight Color", "data/icons/close.svg")) { + // newHighlightColor = {0.0f, 0.0f, 0.0f, 0.0f}; + // currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR] = std::make_shared(newHighlightColor); + // add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR]);}); + // } + // } + // t.gui.text_label("Highlight Color"); + //}); - if(&newHighlightColor == t.colorRight) - hold_undo_data("Highlight Color", a); - else - release_undo_data("Highlight Color"); + //if(&newHighlightColor == t.colorRight) + // hold_undo_data("Highlight Color", a); + //else + // release_undo_data("Highlight Color"); - if((&newHighlightColor == t.colorRight) && t.isUpdatingColorRight) { - currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR] = std::make_shared(newHighlightColor); - a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR]); - } + //if((&newHighlightColor == t.colorRight) && t.isUpdatingColorRight) { + // currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR] = std::make_shared(newHighlightColor); + // a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR]); + //} - t.gui.pop_id(); + //t.gui.pop_id(); - if(a.textBox->inputChangedTextBox) - set_styles_at_selection(a); + //if(a.textBox->inputChangedTextBox) + // set_styles_at_selection(a); - // NOTE: There should be a system that periodically sends updates even if no changes are made, since unreliable channels can drop update data - bool oldInputChangedTextBox = a.textBox->inputChangedTextBox; - a.textBox->inputChangedTextBox = false; - return oldInputChangedTextBox; + //// NOTE: There should be a system that periodically sends updates even if no changes are made, since unreliable channels can drop update data + //bool oldInputChangedTextBox = a.textBox->inputChangedTextBox; + //a.textBox->inputChangedTextBox = false; + //return oldInputChangedTextBox; } void TextBoxEditTool::input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key) { @@ -188,35 +195,33 @@ void TextBoxEditTool::input_mouse_motion_callback(CanvasComponentContainer::ObjI } } -bool TextBoxEditTool::right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) { +void TextBoxEditTool::right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) { + using namespace GUIStuff; + using namespace ElementHelpers; + Toolbar& t = drawP.world.main.toolbar; - bool shouldClose = false; auto& a = static_cast(comp->obj->get_comp()); - t.gui.list_popup_menu("Text popup menu", popupPos, [&]() { - t.gui.text_label_light("Text menu"); + + t.gui.element("Text popup menu", popupPos, [&, popupPos] { + text_label_light(t.gui, "Text menu"); InputManager& input = drawP.world.main.input; - if(t.gui.text_button_left_transparent("Paste", "Paste")) { + drawP.popup_menu_action_button("Paste", "Paste", [&] { input.call_text_paste(true); - shouldClose = true; - } - if(t.gui.text_button_left_transparent("Paste without formatting", "Paste without formatting")) { + }); + drawP.popup_menu_action_button("Paste without formatting", "Paste without formatting", [&] { input.call_text_paste(false); - shouldClose = true; - } + }); if(a.cursor->selectionBeginPos != a.cursor->selectionEndPos) { - if(t.gui.text_button_left_transparent("Copy", "Copy")) { + drawP.popup_menu_action_button("Copy", "Copy", [&] { input.set_clipboard_plain_and_richtext_pair(a.textBox->process_copy(*a.cursor)); - shouldClose = true; - } - if(t.gui.text_button_left_transparent("Cut", "Cut")) { + }); + drawP.popup_menu_action_button("Cut", "Cut", [&] { input.text.do_textbox_operation_with_undo([&]() { input.set_clipboard_plain_and_richtext_pair(a.textBox->process_cut(*a.cursor)); }); - shouldClose = true; - } + }); } }); - return !shouldClose; } void TextBoxEditTool::hold_undo_data(const std::string& undoName, TextBoxCanvasComponent& a) { diff --git a/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.hpp b/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.hpp index f211733..57d9a77 100644 --- a/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.hpp +++ b/src/DrawingProgram/Tools/EditTools/TextBoxEditTool.hpp @@ -13,8 +13,8 @@ class TextBoxEditTool : public DrawingProgramEditToolBase { virtual void edit_start(EditTool& editTool,CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual void commit_edit_updates(CanvasComponentContainer::ObjInfo* comp, std::any& prevData) override; virtual bool edit_update(CanvasComponentContainer::ObjInfo* comp) override; - virtual bool edit_gui(CanvasComponentContainer::ObjInfo* comp) override; - virtual bool right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) override; + virtual void edit_gui(CanvasComponentContainer::ObjInfo* comp) override; + virtual void right_click_popup_gui(CanvasComponentContainer::ObjInfo* comp, Vector2f popupPos) override; virtual void input_key_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::KeyCallbackArgs& key) override; virtual void input_mouse_button_on_canvas_callback(CanvasComponentContainer::ObjInfo* comp, const InputManager::MouseButtonCallbackArgs& button, bool isDraggingPoint) override; diff --git a/src/DrawingProgram/Tools/GridModifyTool.cpp b/src/DrawingProgram/Tools/GridModifyTool.cpp index 66a4314..93b4804 100644 --- a/src/DrawingProgram/Tools/GridModifyTool.cpp +++ b/src/DrawingProgram/Tools/GridModifyTool.cpp @@ -135,7 +135,7 @@ void GridModifyTool::gui_toolbox() { }; left_to_right_line_layout(t.gui, [&]() { text_label(t.gui, "Type"); - t.gui.element>("filepicker select type", &typeSelected, listOfGridTypes, 200.0f); + t.gui.element>("filepicker select type", &typeSelected, listOfGridTypes); }); g.gridType = static_cast(typeSelected); uint32_t sDiv = g.subdivisions; diff --git a/src/DrawingProgram/Tools/LineDrawTool.cpp b/src/DrawingProgram/Tools/LineDrawTool.cpp index 9c03dd4..6b36dea 100644 --- a/src/DrawingProgram/Tools/LineDrawTool.cpp +++ b/src/DrawingProgram/Tools/LineDrawTool.cpp @@ -9,7 +9,7 @@ #include #include "../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp" -#include "../../GUIStuff/ElementHelpers/CheckBoxHelpers.cpp" +#include "../../GUIStuff/ElementHelpers/CheckBoxHelpers.hpp" LineDrawTool::LineDrawTool(DrawingProgram& initDrawP): DrawingProgramToolBase(initDrawP) diff --git a/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp b/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp index 4bb696d..b41f7d1 100644 --- a/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp +++ b/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp @@ -15,7 +15,7 @@ void text_button(GUIManager& gui, const char* id, std::string_view text, const T .childAlignment = {.x = options.centered ? CLAY_ALIGN_X_CENTER : CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} } }) { - gui.element(id, options); + gui.element(id, d); } } @@ -30,7 +30,7 @@ void text_button_sized(GUIManager& gui, const char* id, std::string_view text, C .childAlignment = {.x = options.centered ? CLAY_ALIGN_X_CENTER : CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} } }) { - gui.element(id, options); + gui.element(id, d); } } @@ -40,7 +40,7 @@ void svg_icon_button(GUIManager& gui, const char* id, const std::string& svgPath gui.element("icon", svgPath, p.isSelected || p.isHovering || p.isHeld); }; CLAY_AUTO_ID({.layout = {.sizing = {.width = CLAY_SIZING_FIXED(options.size), .height = CLAY_SIZING_FIXED(options.size) } } }) { - gui.element(id, options); + gui.element(id, d); } } diff --git a/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp b/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp index c92b91f..f79dfe8 100644 --- a/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp +++ b/src/GUIStuff/ElementHelpers/ButtonHelpers.hpp @@ -47,9 +47,10 @@ void text_button_sized(GUIManager& gui, const char* id, std::string_view text, C void svg_icon_button(GUIManager& gui, const char* id, const std::string& svgPath, const SVGButtonOptions& options = {}); template void color_button(GUIManager& gui, const char* id, T* val, const FixedSizeColorButtonOptions& options = {}) { + gui.push_id(id); SelectableButton::Data d = selectable_button_options_to_data(options); d.innerContent = [&] (const SelectableButton::InnerContentCallbackParameters&) { - gui.element([val, hasAlpha = options.hasAlpha] { + gui.element("color display", [val, hasAlpha = options.hasAlpha] { if(hasAlpha) return SkColor4f{(*val)[0], (*val)[1], (*val)[2], 1.0f}; else @@ -57,8 +58,9 @@ template void color_button(GUIManager& gui, const char* id, T* val, }); }; CLAY_AUTO_ID({.layout = {.sizing = {.width = CLAY_SIZING_FIXED(options.size), .height = CLAY_SIZING_FIXED(options.size) } } }) { - gui.element(id, options); + gui.element("button", d); } + gui.pop_id(); } }} diff --git a/src/GUIStuff/ElementHelpers/ColorPickerHelpers.hpp b/src/GUIStuff/ElementHelpers/ColorPickerHelpers.hpp index a9d4d4d..f152d6d 100644 --- a/src/GUIStuff/ElementHelpers/ColorPickerHelpers.hpp +++ b/src/GUIStuff/ElementHelpers/ColorPickerHelpers.hpp @@ -1,44 +1,11 @@ #pragma once -#include "../GUIManager.hpp" -#include "TextBoxHelpers.hpp" -#include "../Elements/ColorPicker.hpp" -#include "../Elements/ColorPickerButton.decl.hpp" +#include "ColorPickerItemsHelpers.hpp" +#include "../Elements/ColorPickerButton.hpp" namespace GUIStuff { namespace ElementHelpers { -struct ColorPickerItemsOptions { - bool hasAlpha = true; - std::function onEdit; -}; - -template void color_picker_items(GUIManager& gui, const char* id, T* val, const ColorPickerItemsOptions& options = {}) { - gui.push_id(id); - auto fullOnEdit = [&gui, oE = options.onEdit, val]() { - oE(); - gui.set_to_layout(); - }; - gui.element("c", val, options.hasAlpha, fullOnEdit); - left_to_right_line_layout([&]() { - text_label(gui, "R"); - input_color_component_255("r", &(*val)[0], { .onEdit = fullOnEdit }); - text_label(gui, "G"); - input_color_component_255("g", &(*val)[1], { .onEdit = fullOnEdit }); - text_label(gui, "B"); - input_color_component_255("b", &(*val)[2], { .onEdit = fullOnEdit }); - if(options.hasAlpha) { - text_label(gui, "A"); - input_color_component_255("a", &(*val)[3], { .onEdit = fullOnEdit }); - } - }); - left_to_right_line_layout([&]() { - text_label(gui, "Hex"); - input_color_hex("h", val, { .onEdit = fullOnEdit, .hasAlpha = options.hasAlpha }); - }); - gui.pop_id(); -} - template void color_picker_button_field(GUIManager& gui, const char* id, std::string_view name, T* val, const ColorPickerButtonData& options = {}) { - left_to_right_line_layout([&]() { + left_to_right_line_layout(gui, [&]() { gui.element>(id, val, options); text_label(gui, name); }); diff --git a/src/GUIStuff/ElementHelpers/ColorPickerItemsHelpers.hpp b/src/GUIStuff/ElementHelpers/ColorPickerItemsHelpers.hpp new file mode 100644 index 0000000..bb27f6a --- /dev/null +++ b/src/GUIStuff/ElementHelpers/ColorPickerItemsHelpers.hpp @@ -0,0 +1,39 @@ +#pragma once +#include "../GUIManager.hpp" +#include "TextBoxHelpers.hpp" +#include "../Elements/ColorPicker.hpp" + +namespace GUIStuff { namespace ElementHelpers { + +struct ColorPickerItemsOptions { + bool hasAlpha = true; + std::function onEdit; +}; + +template void color_picker_items(GUIManager& gui, const char* id, T* val, const ColorPickerItemsOptions& options = {}) { + gui.push_id(id); + auto fullOnEdit = [&gui, oE = options.onEdit, val]() { + oE(); + gui.set_to_layout(); + }; + gui.element>("c", val, options.hasAlpha, fullOnEdit); + left_to_right_line_layout(gui, [&]() { + text_label(gui, "R"); + input_color_component_255(gui, "r", &(*val)[0], { .onEdit = fullOnEdit }); + text_label(gui, "G"); + input_color_component_255(gui, "g", &(*val)[1], { .onEdit = fullOnEdit }); + text_label(gui, "B"); + input_color_component_255(gui, "b", &(*val)[2], { .onEdit = fullOnEdit }); + if(options.hasAlpha) { + text_label(gui, "A"); + input_color_component_255(gui, "a", &(*val)[3], { .onEdit = fullOnEdit }); + } + }); + left_to_right_line_layout(gui, [&]() { + text_label(gui, "Hex"); + input_color_hex(gui, "h", val, { .hasAlpha = options.hasAlpha, .onEdit = fullOnEdit }); + }); + gui.pop_id(); +} + +} } diff --git a/src/GUIStuff/ElementHelpers/NumberSliderHelpers.hpp b/src/GUIStuff/ElementHelpers/NumberSliderHelpers.hpp index 5451847..1a6e5f2 100644 --- a/src/GUIStuff/ElementHelpers/NumberSliderHelpers.hpp +++ b/src/GUIStuff/ElementHelpers/NumberSliderHelpers.hpp @@ -4,15 +4,15 @@ #include "../Elements/NumberSlider.hpp" namespace GUIStuff { namespace ElementHelpers { - template bool slider_scalar_field(GUIManager& gui, const char* id, std::string_view name, T* val, T min, T max, TextBoxScalarOptions options = {}) { + template void slider_scalar_field(GUIManager& gui, const char* id, std::string_view name, T* val, T min, T max, TextBoxScalarOptions options = {}) { gui.push_id(id); options.onEdit = [&, oE = options.onEdit] { oE(); gui.set_to_layout(); }; - left_to_right_line_layout([&]() { + left_to_right_line_layout(gui, [&]() { text_label(gui, name); - input_scalar("textbox", val, min, max, options); + input_scalar(gui, "textbox", val, min, max, options); }); gui.element>("slider", val, min, max, options.onEdit); gui.pop_id(); diff --git a/src/GUIStuff/ElementHelpers/TextBoxHelpers.cpp b/src/GUIStuff/ElementHelpers/TextBoxHelpers.cpp index 81abf6b..60d9730 100644 --- a/src/GUIStuff/ElementHelpers/TextBoxHelpers.cpp +++ b/src/GUIStuff/ElementHelpers/TextBoxHelpers.cpp @@ -1,5 +1,4 @@ #include "TextBoxHelpers.hpp" -#include "../Elements/TextBox.impl.hpp" #include "LayoutHelpers.hpp" namespace GUIStuff { namespace ElementHelpers { @@ -29,7 +28,7 @@ void input_color_component_255(GUIManager& gui, const char* id, float* val, cons return ss.str(); }; - gui.element>(id, d); + gui.element>(id, d); } void input_text(GUIManager& gui, const char* id, std::string* val, const TextBoxOptions& options) { diff --git a/src/GUIStuff/ElementHelpers/TextBoxHelpers.hpp b/src/GUIStuff/ElementHelpers/TextBoxHelpers.hpp index 9000bcd..9c1ef0c 100644 --- a/src/GUIStuff/ElementHelpers/TextBoxHelpers.hpp +++ b/src/GUIStuff/ElementHelpers/TextBoxHelpers.hpp @@ -1,6 +1,6 @@ #pragma once #include "../GUIManager.hpp" -#include "../Elements/TextBox.decl.hpp" +#include "../Elements/TextBox.hpp" #include "TextLabelHelpers.hpp" #include "LayoutHelpers.hpp" @@ -83,10 +83,10 @@ template void input_scalar(GUIManager& gui, const char* id, T* val, std::stringstream ss; if(std::is_floating_point()) { ss.precision(decimalPrecision); - ss << std::fixed << *a; + ss << std::fixed << a; } else - ss << *a; + ss << a; return ss.str(); }; @@ -95,7 +95,7 @@ template void input_scalar(GUIManager& gui, const char* id, T* val, template void input_scalars_field(GUIManager& gui, const char* id, std::string_view name, TContainer* val, size_t elemCount, T minVal, T maxVal, const TextBoxScalarOptions& options = {}) { gui.push_id(id); - left_to_right_line_layout([&]() { + left_to_right_line_layout(gui, [&]() { text_label(gui, name); for(size_t i = 0; i < elemCount; i++) { gui.push_id(i); @@ -107,7 +107,7 @@ template void input_scalars_field(GUIManager& } template void input_scalar_field(GUIManager& gui, const char* id, std::string_view name, T* val, T minVal, T maxVal, const TextBoxScalarOptions& options = {}) { - left_to_right_line_layout([&]() { + left_to_right_line_layout(gui, [&]() { text_label(gui, name); input_scalar(gui, id, val, minVal, maxVal, options); }); @@ -125,7 +125,12 @@ template void input_color_hex(GUIManager& gui, const char* id, T* v TextBoxData d = textbox_options_to_data(options); d.textInputProps = textInputProps; d.fromStr = [hasAlpha = options.hasAlpha](const std::string& a) { - T def = {0.0f, 0.0f, 0.0f, 1.0f}; + T def; + def[0] = 0.0f; + def[1] = 0.0f; + def[2] = 0.0f; + if(hasAlpha) + def[3] = 1.0f; unsigned startIndex = 0; if(a.empty()) return def; diff --git a/src/GUIStuff/Elements/ColorPicker.decl.hpp b/src/GUIStuff/Elements/ColorPicker.decl.hpp index 25d1c54..8dbcb56 100644 --- a/src/GUIStuff/Elements/ColorPicker.decl.hpp +++ b/src/GUIStuff/Elements/ColorPicker.decl.hpp @@ -77,15 +77,6 @@ template class ColorPicker : public Element { static constexpr float BAR_WIDTH = 30.0; static constexpr float BAR_GAP = 5.0; - - static sk_sp hueBarShader; - static sk_sp svSelectionAreaEffect; - static sk_sp alphaBarEffect; - - static sk_sp get_hue_shader(); - static sk_sp get_sv_selection_shader(float hue); - static sk_sp get_alpha_bar_shader(const Vector3f& mainColor, float horizontalResolution); - T* data; Vector3f savedHsv; // We save the HSV so that conversion doesnt ruin the UI std::function onChange; diff --git a/src/GUIStuff/Elements/ColorPicker.impl.hpp b/src/GUIStuff/Elements/ColorPicker.impl.hpp index c728df3..f7f2804 100644 --- a/src/GUIStuff/Elements/ColorPicker.impl.hpp +++ b/src/GUIStuff/Elements/ColorPicker.impl.hpp @@ -4,9 +4,11 @@ namespace GUIStuff { +template ColorPicker::ColorPicker(GUIManager& gui): Element(gui) {} + template void ColorPicker::layout(T* data, bool selectAlpha, const std::function& onChange) { this->data = data; - savedHsv = rgb_to_hsv(*data); + savedHsv = rgb_to_hsv(*data); this->selectAlpha = selectAlpha; this->onChange = onChange; @@ -29,7 +31,7 @@ template void ColorPicker::clay_draw(SkCanvas* canvas, UpdateInp canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, 1.0f, 1.0f), skiaAA); SkPaint svSelectionAreaPaint; - svSelectionAreaPaint.setShader(get_sv_selection_shader(savedHsv.x() / 360.0f)); + svSelectionAreaPaint.setShader(ColorPickerShaders::get_sv_selection_shader(savedHsv.x() / 360.0f)); canvas->drawPaint(svSelectionAreaPaint); SkPaint selectionLinePaint({1.0f, 1.0f, 1.0f, 1.0f}); @@ -50,7 +52,7 @@ template void ColorPicker::clay_draw(SkCanvas* canvas, UpdateInp canvas->clipRect(SkRect::MakeXYWH(0.0f, 0.0f, 1.0f, 1.0f), skiaAA); SkPaint hueBarPaint; - hueBarPaint.setShader(get_hue_shader()); + hueBarPaint.setShader(ColorPickerShaders::get_hue_shader()); canvas->drawPaint(hueBarPaint); canvas->drawLine(0.0f, 1.0f - normalizedHue, 1.0f, 1.0f - normalizedHue, selectionLinePaint); @@ -64,7 +66,7 @@ template void ColorPicker::clay_draw(SkCanvas* canvas, UpdateInp SkPaint alphaBarPaint; if(selectAlpha) - alphaBarPaint.setShader(get_alpha_bar_shader({(*data)[0], (*data)[1], (*data)[2]}, alphaBarDim.x())); + alphaBarPaint.setShader(ColorPickerShaders::get_alpha_bar_shader({(*data)[0], (*data)[1], (*data)[2]}, alphaBarDim.x())); else alphaBarPaint.setColor4f(SkColor4f{(*data)[0], (*data)[1], (*data)[2], 1.0f}); canvas->drawPaint(alphaBarPaint); @@ -103,7 +105,7 @@ template bool ColorPicker::input_mouse_button_callback(const Inp template bool ColorPicker::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) { update_color_picker_pos(motion.pos); - return Element::input_mouse_button_callback(motion, mouseHovering); + return Element::input_mouse_motion_callback(motion, mouseHovering); } template void ColorPicker::update_color_picker_pos(const Vector2f& p) { @@ -111,6 +113,8 @@ template void ColorPicker::update_color_picker_pos(const Vector2 gui.set_post_callback_func([&, p]() { auto& bb = boundingBox.value(); switch(held) { + case HeldBar::NONE: + break; case HeldBar::SV_HELD: { float svSelectionAreaSize = bb.width() - (BAR_GAP + BAR_WIDTH); Vector2f newSv = cwise_vec_clamp((p - bb.min) / svSelectionAreaSize, Vector2f{0.0f, 0.0f}, Vector2f{1.0f, 1.0f}); diff --git a/src/GUIStuff/Elements/ColorPickerButton.decl.hpp b/src/GUIStuff/Elements/ColorPickerButton.decl.hpp index de921de..f7bf85c 100644 --- a/src/GUIStuff/Elements/ColorPickerButton.decl.hpp +++ b/src/GUIStuff/Elements/ColorPickerButton.decl.hpp @@ -4,14 +4,14 @@ namespace GUIStuff { struct ColorPickerButtonData { - bool hasAlpha = false; + bool hasAlpha = true; std::function onEdit; }; template class ColorPickerButton : public Element { public: ColorPickerButton(GUIManager& gui); - void layout(T* val, ColorPickerButtonData& d); + void layout(T* val, const ColorPickerButtonData& d); private: ColorPickerButtonData data; bool isOpen = false; diff --git a/src/GUIStuff/Elements/ColorPickerButton.impl.hpp b/src/GUIStuff/Elements/ColorPickerButton.impl.hpp index cfae679..4407bac 100644 --- a/src/GUIStuff/Elements/ColorPickerButton.impl.hpp +++ b/src/GUIStuff/Elements/ColorPickerButton.impl.hpp @@ -1,12 +1,13 @@ #include "ColorPickerButton.decl.hpp" -#include "../ElementHelpers/ColorPickerHelpers.hpp" +#include "../ElementHelpers/ColorPickerItemsHelpers.hpp" #include "../ElementHelpers/ButtonHelpers.hpp" +#include "../ElementHelpers/LayoutHelpers.hpp" namespace GUIStuff { template ColorPickerButton::ColorPickerButton(GUIManager& gui): Element(gui) {} -template void ColorPickerButton::layout(T* val, ColorPickerButtonData& d) { +template void ColorPickerButton::layout(T* val, const ColorPickerButtonData& d) { this->data = d; GUIStuff::ElementHelpers::color_button(gui, "Color Picker Button", val, { @@ -17,7 +18,7 @@ template void ColorPickerButton::layout(T* val, ColorPickerButto } }); if(isOpen) { - top_to_bottom_window_popup_layout("Color Picker", CLAY_SIZING_FIT(300), CLAY_SIZING_FIT(0), [&, val, data = data]() { + ElementHelpers::top_to_bottom_window_popup_layout(gui, "Color Picker", CLAY_SIZING_FIT(300), CLAY_SIZING_FIT(0), [&, val, data = data]() { ElementHelpers::color_picker_items(gui, "c", val, { .hasAlpha = data.hasAlpha, .onEdit = data.onEdit diff --git a/src/GUIStuff/Elements/ColorRectangleDisplay.cpp b/src/GUIStuff/Elements/ColorRectangleDisplay.cpp index be78ba7..1a5bf10 100644 --- a/src/GUIStuff/Elements/ColorRectangleDisplay.cpp +++ b/src/GUIStuff/Elements/ColorRectangleDisplay.cpp @@ -2,6 +2,8 @@ namespace GUIStuff { +sk_sp ColorRectangleDisplay::alphaBackgroundEffect; + ColorRectangleDisplay::ColorRectangleDisplay(GUIManager& gui): Element(gui) {} void ColorRectangleDisplay::layout(const std::function& colorFunc) { diff --git a/src/GUIStuff/Elements/PaintCircleMenu.cpp b/src/GUIStuff/Elements/PaintCircleMenu.cpp index 5ad8e77..5bb190e 100644 --- a/src/GUIStuff/Elements/PaintCircleMenu.cpp +++ b/src/GUIStuff/Elements/PaintCircleMenu.cpp @@ -14,9 +14,8 @@ constexpr double ROTATE_BAR_SNAP_DISTRIBUTION = std::numbers::pi * 0.25; PaintCircleMenu::PaintCircleMenu(GUIManager& gui): Element(gui) {} -void PaintCircleMenu::layout(const Data& data, const std::function& onChange) { +void PaintCircleMenu::layout(const Data& data) { d = data; - this->onChange = onChange; CLAY_AUTO_ID({ .layout = { diff --git a/src/GUIStuff/Elements/PaintCircleMenu.hpp b/src/GUIStuff/Elements/PaintCircleMenu.hpp index c90d066..0e7e948 100644 --- a/src/GUIStuff/Elements/PaintCircleMenu.hpp +++ b/src/GUIStuff/Elements/PaintCircleMenu.hpp @@ -13,7 +13,7 @@ class PaintCircleMenu : public Element { std::function onRotate; std::function onPaletteClick; }; - void layout(const Data& data, const std::function& onChange); + void layout(const Data& data); virtual bool collides_with_point(const Vector2f& p) const override; virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override; virtual bool input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override; @@ -22,7 +22,6 @@ class PaintCircleMenu : public Element { void draw_rotate_bar(SkCanvas* canvas, UpdateInputData& io, bool skiaAA); void draw_palette_bar(SkCanvas* canvas, UpdateInputData& io, bool skiaAA); Data d; - std::function onChange; unsigned colorSelectionIndex = 0; bool isHovering = false; bool isRotateBarHeld = false; diff --git a/src/GUIStuff/Elements/TextBox.impl.hpp b/src/GUIStuff/Elements/TextBox.impl.hpp index 9e53ddd..ec9ba6a 100644 --- a/src/GUIStuff/Elements/TextBox.impl.hpp +++ b/src/GUIStuff/Elements/TextBox.impl.hpp @@ -3,12 +3,14 @@ namespace GUIStuff { +template TextBox::TextBox(GUIManager& gui): Element(gui) {} + template void TextBox::layout(const TextBoxData& userInfo) { auto& io = *gui.io; this->userInfo = userInfo; textbox->onUserTextEdit = [&] { if(userInfo.immutable) - cur->pos = cur->selectionBeginPos = cur->selectionEndPos = textbox->insert({0, 0}, toStr(*userInfo.data)); + cur->pos = cur->selectionBeginPos = cur->selectionEndPos = textbox->insert({0, 0}, userInfo.toStr(*userInfo.data)); else { if(update_data() && userInfo.onEdit) gui.set_post_callback_func(userInfo.onEdit); @@ -79,7 +81,7 @@ template bool TextBox::input_mouse_button_callback(const InputMa gui.io->input->remove_rich_text_box_input(textbox); if(update_data()) gui.set_post_callback_func(userInfo.onEdit); - update_textbox(io); + init_textbox(*gui.io); isSelected = false; } } @@ -115,7 +117,7 @@ template void TextBox::init_textbox(UpdateInputData& io) { cur = std::make_shared(); rect = std::make_shared>(); - cur->pos = cur->selectionBeginPos = cur->selectionEndPos = textbox->insert({0, 0}, toStr(*userInfo.data)); + cur->pos = cur->selectionBeginPos = cur->selectionEndPos = textbox->insert({0, 0}, userInfo.toStr(*userInfo.data)); } template bool TextBox::update_data() { diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index 943cd9c..f3f4225 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -999,7 +999,6 @@ void Toolbar::update_notification_gui() { void Toolbar::grid_menu(bool justOpened) { if(main.world->gridMan.grids) { gui.push_id("grid menu"); - Clay_ElementId localId = CLAY_ID_LOCAL("INFINIPAINT GRID MENU"); //CLAY(localId, { // .layout = { // .sizing = {.width = CLAY_SIZING_FIT(300), .height = CLAY_SIZING_FIT(0, 600) }, @@ -1763,7 +1762,7 @@ void Toolbar::options_menu() { color_picker_button_field(gui, "canvasColor", "Canvas Color", newColorToSet.get(), { .hasAlpha = false, .onEdit = [&, newColorToSet] { - main.world->canvasTheme.set_back_color(convert_vec3(newColorToSet)); + main.world->canvasTheme.set_back_color(convert_vec3(*newColorToSet)); } }); text_button_wide("done", "Done", [&] { @@ -2211,7 +2210,6 @@ void Toolbar::file_picker_gui_done() { } void Toolbar::file_picker_gui() { - bool isDoneByDoubleClick = false; center_obstructing_window_gui("file picker gui window", CLAY_SIZING_FIXED(700), CLAY_SIZING_FIXED(500), [&] { text_label_centered(gui, filePicker.filePickerWindowName); left_to_right_line_layout(gui, [&]() { diff --git a/src/Toolbar.hpp b/src/Toolbar.hpp index 7af2cbb..db3b29e 100644 --- a/src/Toolbar.hpp +++ b/src/Toolbar.hpp @@ -96,7 +96,6 @@ class Toolbar { bool flipZoomToolDirection = false; float final_gui_scale(); - bool check_if_position_isnt_obstructed(const Vector2f& pos); bool app_close_requested(); private: