From 7d1671229b71c40a5fecf39ddb6bab80ed4ecd28 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Mon, 15 Dec 2025 15:36:42 +0300 Subject: [PATCH] All tools now converted to use new net objects --- .../DelayUpdateSerializedClassManager.hpp | 21 +-- .../NetworkingObjects/NetObjManager.hpp | 2 +- .../NetworkingObjects/NetObjOrderedList.hpp | 6 +- .../BrushStrokeCanvasComponent.cpp | 9 +- .../BrushStrokeCanvasComponent.hpp | 3 +- src/CanvasComponents/CanvasComponent.cpp | 12 +- src/CanvasComponents/CanvasComponent.hpp | 16 +- .../CanvasComponentAllocator.cpp | 19 ++- .../CanvasComponentAllocator.hpp | 9 +- .../CanvasComponentContainer.cpp | 3 +- .../CanvasComponentContainer.hpp | 8 +- src/CanvasComponents/CanvasComponentType.hpp | 10 ++ .../EllipseCanvasComponent.cpp | 10 +- .../EllipseCanvasComponent.hpp | 3 +- src/CanvasComponents/ImageCanvasComponent.cpp | 9 +- src/CanvasComponents/ImageCanvasComponent.hpp | 3 +- .../RectangleCanvasComponent.cpp | 9 +- .../RectangleCanvasComponent.hpp | 3 +- .../TextBoxCanvasComponent.cpp | 11 +- .../TextBoxCanvasComponent.hpp | 5 +- src/DrawData.cpp | 8 +- src/DrawingProgram/BrushTool.cpp | 34 ++-- src/DrawingProgram/BrushTool.hpp | 3 +- src/DrawingProgram/DrawingProgram.cpp | 6 +- .../DrawingProgramEditToolBase.cpp | 2 +- .../DrawingProgramEditToolBase.hpp | 12 +- src/DrawingProgram/DrawingProgramToolBase.hpp | 2 + src/DrawingProgram/EditTool.cpp | 161 +++++++++--------- src/DrawingProgram/EditTool.hpp | 20 +-- src/DrawingProgram/EllipseDrawEditTool.cpp | 60 +++---- src/DrawingProgram/EllipseDrawEditTool.hpp | 13 +- src/DrawingProgram/EllipseDrawTool.cpp | 28 +-- src/DrawingProgram/EllipseDrawTool.hpp | 3 +- src/DrawingProgram/EraserTool.cpp | 4 + src/DrawingProgram/EraserTool.hpp | 1 + src/DrawingProgram/EyeDropperTool.cpp | 3 + src/DrawingProgram/EyeDropperTool.hpp | 1 + src/DrawingProgram/GridModifyTool.cpp | 3 + src/DrawingProgram/GridModifyTool.hpp | 1 + src/DrawingProgram/ImageEditTool.cpp | 15 +- src/DrawingProgram/ImageEditTool.hpp | 8 +- src/DrawingProgram/LassoSelectTool.cpp | 3 + src/DrawingProgram/LassoSelectTool.hpp | 2 +- src/DrawingProgram/PanCanvasTool.cpp | 3 + src/DrawingProgram/PanCanvasTool.hpp | 1 + src/DrawingProgram/RectDrawEditTool.cpp | 62 +++---- src/DrawingProgram/RectDrawEditTool.hpp | 12 +- src/DrawingProgram/RectDrawTool.cpp | 34 ++-- src/DrawingProgram/RectDrawTool.hpp | 5 +- src/DrawingProgram/RectSelectTool.cpp | 3 + src/DrawingProgram/RectSelectTool.hpp | 2 +- src/DrawingProgram/ScreenshotTool.cpp | 3 + src/DrawingProgram/ScreenshotTool.hpp | 1 + src/DrawingProgram/TextBoxEditTool.cpp | 142 +++++++-------- src/DrawingProgram/TextBoxEditTool.hpp | 22 +-- src/DrawingProgram/TextBoxTool.cpp | 74 ++++---- src/DrawingProgram/TextBoxTool.hpp | 16 +- src/DrawingProgram/ZoomCanvasTool.cpp | 3 + src/DrawingProgram/ZoomCanvasTool.hpp | 1 + src/Server/ServerData.cpp | 16 -- src/Toolbar.cpp | 7 +- src/World.cpp | 2 +- 62 files changed, 492 insertions(+), 481 deletions(-) create mode 100644 src/CanvasComponents/CanvasComponentType.hpp diff --git a/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp b/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp index 753cbca..91432a2 100644 --- a/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp +++ b/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp @@ -11,13 +11,13 @@ namespace NetworkingObjects { std::function writeConstructor = [](const T& o, cereal::PortableBinaryOutputArchive& a) { a(o); }; - std::function readConstructor = [](T& o, cereal::PortableBinaryOutputArchive& a) { + std::function readConstructor = [](T& o, cereal::PortableBinaryInputArchive& a) { a(o); }; std::function writeUpdate = [](const T& o, cereal::PortableBinaryOutputArchive& a) { a(o); }; - std::function readUpdate = [](T& o, cereal::PortableBinaryOutputArchive& a) { + std::function readUpdate = [](T& o, cereal::PortableBinaryInputArchive& a) { a(o); }; std::function(const T& o)> allocateCopy = [](const T& o) { @@ -34,11 +34,11 @@ namespace NetworkingObjects { }; template void register_class(NetObjManager& objMan, const CustomConstructors& t = CustomConstructors()) { objMan.register_class({ - .writeConstructorFuncClient = t.writeConstructor, - .readConstructorFuncClient = t.readConstructor, + .writeConstructorFuncClient = [writeConstructor = t.writeConstructor](const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) {writeConstructor(*o, a);}, + .readConstructorFuncClient = [readConstructor = t.readConstructor](const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) {readConstructor(*o, a);}, .readUpdateFuncClient = [&, readUpdate = t.readUpdate](const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&){client_read_update_func(o, a, readUpdate);}, - .writeConstructorFuncServer = t.writeConstructor, - .readConstructorFuncServer = t.readConstructor, + .writeConstructorFuncServer = [writeConstructor = t.writeConstructor](const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) {writeConstructor(*o, a);}, + .readConstructorFuncServer = [readConstructor = t.readConstructor](const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&) {readConstructor(*o, a);}, .readUpdateFuncServer = [&, readUpdate = t.readUpdate](const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr&){server_read_update_func(o, a, readUpdate);} }); typeIndexFuncs[std::type_index(typeid(T))] = { @@ -57,6 +57,7 @@ namespace NetworkingObjects { }; } template void send_update_to_all(const NetworkingObjects::NetObjTemporaryPtr& o, bool finalUpdate) { + // TODO: When finalUpdate = false, maybe add a small delay between updates instead of sending them every frame? o.send_update_to_all(finalUpdate ? RELIABLE_COMMAND_CHANNEL : UNRELIABLE_COMMAND_CHANNEL, [&](const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) { if(o.get_obj_man()->is_server()) server_write_func(o, a); @@ -91,7 +92,7 @@ namespace NetworkingObjects { } } - template void client_read_update_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::function& readUpdate) { + template void client_read_update_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::function& readUpdate) { auto it = updatingObjs.find(o.get_net_id()); if(it == updatingObjs.end()) { readUpdate(*o, a); @@ -104,7 +105,7 @@ namespace NetworkingObjects { } } - template void server_write_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a, const std::function& postAssignmentFunc) { + template void server_write_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) { typeIndexFuncs[std::type_index(typeid(T))].writeUpdateFunc(static_cast(o.get()), a); auto it = updatingObjs.find(o.get_net_id()); @@ -113,7 +114,7 @@ namespace NetworkingObjects { toAdd.objToUpdateCurrentData = typeIndexFuncs[std::type_index(typeid(T))].allocateCopyFunc(static_cast(o.get())); toAdd.lastUpdateTimePoint = std::chrono::steady_clock::now(); toAdd.doLastAssignment = std::make_shared(false); - toAdd.setDataAfterTimeout = [&typeIndexFuncs = typeIndexFuncs, postAssignmentFunc, oWeak = NetObjWeakPtr(o), currentData = toAdd.objToUpdateCurrentData, doLastAssignment = toAdd.doLastAssignment]() { + toAdd.setDataAfterTimeout = [&typeIndexFuncs = typeIndexFuncs, oWeak = NetObjWeakPtr(o), currentData = toAdd.objToUpdateCurrentData, doLastAssignment = toAdd.doLastAssignment]() { NetObjTemporaryPtr oLock = oWeak.lock(); if(oLock && *doLastAssignment) { typeIndexFuncs[std::type_index(typeid(T))].assignmentFunc(static_cast(oLock.get()), static_cast(currentData.get())); @@ -133,7 +134,7 @@ namespace NetworkingObjects { } } - template void server_read_update_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::function& readUpdate) { + template void server_read_update_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryInputArchive& a, const std::function& readUpdate) { auto it = updatingObjs.find(o.get_net_id()); bool finalUpdate; if(it == updatingObjs.end()) { diff --git a/include/Helpers/NetworkingObjects/NetObjManager.hpp b/include/Helpers/NetworkingObjects/NetObjManager.hpp index 516fd86..34db568 100644 --- a/include/Helpers/NetworkingObjects/NetObjManager.hpp +++ b/include/Helpers/NetworkingObjects/NetObjManager.hpp @@ -49,7 +49,7 @@ namespace NetworkingObjects { template NetObjOwnerPtr make_obj_direct(Args&&... items) { return emplace_raw_ptr(NetObjID::random_gen(), new T(items...)); } - template NetObjOwnerPtr obj_from_ptr(T* p) { + template NetObjOwnerPtr make_obj_from_ptr(T* p) { return emplace_raw_ptr(NetObjID::random_gen(), p); } template NetObjOwnerPtr get_obj_ref_from_id(NetObjID id) { diff --git a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp index 0879e4c..cddf0c7 100644 --- a/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp +++ b/include/Helpers/NetworkingObjects/NetObjOrderedList.hpp @@ -53,11 +53,11 @@ namespace NetworkingObjects { return l->insert(l, nullptr, l->size(), std::move(newObj)); } static NetObjOrderedListObjectInfoPtr push_back_and_send_create(const NetObjTemporaryPtr>& l, T* newObj) { - NetObjOwnerPtr newObjOwner = l.get_obj_man()->template make_obj(newObj); + NetObjOwnerPtr newObjOwner = l.get_obj_man()->template make_obj_from_ptr(newObj); return l->insert(l, nullptr, l->size(), std::move(newObjOwner)); } static NetObjOrderedListObjectInfoPtr insert_and_send_create(const NetObjTemporaryPtr>& l, uint32_t posToInsertAt, T* newObj) { - NetObjOwnerPtr newObjOwner = l.get_obj_man()->template make_obj(newObj); + NetObjOwnerPtr newObjOwner = l.get_obj_man()->template make_obj_from_ptr(newObj); return l->insert(l, nullptr, posToInsertAt, std::move(newObjOwner)); } static std::vector> insert_ordered_list_and_send_create(const NetObjTemporaryPtr>& l, const std::vector>& newObjs) { @@ -65,7 +65,7 @@ namespace NetworkingObjects { return {}; std::vector>> ownerPtrOrderedList; for(uint32_t i = 0; i < static_cast(newObjs.size()); i++) - ownerPtrOrderedList.emplace_back(newObjs[i].first, std::move(l.get_obj_man()->template make_obj(newObjs[i].second))); + ownerPtrOrderedList.emplace_back(newObjs[i].first, std::move(l.get_obj_man()->template make_obj_from_ptr(newObjs[i].second))); return l->insert_ordered_list(l, nullptr, ownerPtrOrderedList); } static void erase_unordered_set(const NetObjTemporaryPtr>& l, const std::unordered_set& ids) { diff --git a/src/CanvasComponents/BrushStrokeCanvasComponent.cpp b/src/CanvasComponents/BrushStrokeCanvasComponent.cpp index 863752d..cfbddd8 100644 --- a/src/CanvasComponents/BrushStrokeCanvasComponent.cpp +++ b/src/CanvasComponents/BrushStrokeCanvasComponent.cpp @@ -29,8 +29,8 @@ void BrushStrokeCanvasComponent::load_file(cereal::PortableBinaryInputArchive& a a(d->points, d->color, d->hasRoundCaps); } -CanvasComponent::CompType BrushStrokeCanvasComponent::get_type() const { - return CompType::BRUSHSTROKE; +CanvasComponentType BrushStrokeCanvasComponent::get_type() const { + return CanvasComponentType::BRUSHSTROKE; } void BrushStrokeCanvasComponent::draw(SkCanvas* canvas, const DrawData& drawData) const { @@ -46,6 +46,11 @@ void BrushStrokeCanvasComponent::draw(SkCanvas* canvas, const DrawData& drawData canvas->restore(); } +void BrushStrokeCanvasComponent::set_data_from(const CanvasComponent& other) { + auto& otherStroke = static_cast(other); + d = otherStroke.d; +} + void BrushStrokeCanvasComponent::initialize_draw_data(DrawingProgram& drawP) { if(!d->points.empty()) { std::vector points = smooth_points(0, d->points.size() - 1, DEFAULT_SMOOTHNESS); diff --git a/src/CanvasComponents/BrushStrokeCanvasComponent.hpp b/src/CanvasComponents/BrushStrokeCanvasComponent.hpp index f2bbf10..123a5c0 100644 --- a/src/CanvasComponents/BrushStrokeCanvasComponent.hpp +++ b/src/CanvasComponents/BrushStrokeCanvasComponent.hpp @@ -17,7 +17,7 @@ class BrushStrokeCanvasComponent : public CanvasComponent { public: constexpr static float DRAW_MINIMUM_LIMIT = 0.3; - virtual CompType get_type() const override; + virtual CanvasComponentType get_type() const override; virtual void save(cereal::PortableBinaryOutputArchive& a) const override; virtual void load(cereal::PortableBinaryInputArchive& a) override; virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override; @@ -30,6 +30,7 @@ class BrushStrokeCanvasComponent : public CanvasComponent { }; std::shared_ptr d = std::make_shared(); // It's a pointer here since brush strokes cant be edited + virtual void set_data_from(const CanvasComponent& other) override; private: virtual void draw(SkCanvas* canvas, const DrawData& drawData) const override; virtual void initialize_draw_data(DrawingProgram& drawP) override; diff --git a/src/CanvasComponents/CanvasComponent.cpp b/src/CanvasComponents/CanvasComponent.cpp index b1fd319..ab3ffe6 100644 --- a/src/CanvasComponents/CanvasComponent.cpp +++ b/src/CanvasComponents/CanvasComponent.cpp @@ -8,17 +8,17 @@ void CanvasComponent::update(DrawingProgram& drawP) { } -CanvasComponent* CanvasComponent::allocate_comp(CanvasComponent::CompType type) { +CanvasComponent* CanvasComponent::allocate_comp(CanvasComponentType type) { switch(type) { - case CanvasComponent::CompType::BRUSHSTROKE: + case CanvasComponentType::BRUSHSTROKE: return new BrushStrokeCanvasComponent; - case CanvasComponent::CompType::RECTANGLE: + case CanvasComponentType::RECTANGLE: return new RectangleCanvasComponent; - case CanvasComponent::CompType::ELLIPSE: + case CanvasComponentType::ELLIPSE: return new EllipseCanvasComponent; - case CanvasComponent::CompType::TEXTBOX: + case CanvasComponentType::TEXTBOX: return new TextBoxCanvasComponent; - case CanvasComponent::CompType::IMAGE: + case CanvasComponentType::IMAGE: return new ImageCanvasComponent; } return nullptr; diff --git a/src/CanvasComponents/CanvasComponent.hpp b/src/CanvasComponents/CanvasComponent.hpp index 619f1dc..1412e8f 100644 --- a/src/CanvasComponents/CanvasComponent.hpp +++ b/src/CanvasComponents/CanvasComponent.hpp @@ -4,28 +4,22 @@ #include #include #include +#include "CanvasComponentType.hpp" +#include "CanvasComponentContainer.hpp" class DrawingProgram; -class DrawData; -class CanvasComponentContainer; class CanvasComponent { public: - enum class CompType : uint8_t { - BRUSHSTROKE = 0, - RECTANGLE, - ELLIPSE, - TEXTBOX, - IMAGE - }; - virtual CompType get_type() const = 0; + virtual CanvasComponentType get_type() const = 0; virtual ~CanvasComponent(); - static CanvasComponent* allocate_comp(CanvasComponent::CompType type); + static CanvasComponent* allocate_comp(CanvasComponentType type); virtual void save(cereal::PortableBinaryOutputArchive& a) const = 0; virtual void load(cereal::PortableBinaryInputArchive& a) = 0; virtual void save_file(cereal::PortableBinaryOutputArchive& a) const = 0; virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) = 0; + virtual void set_data_from(const CanvasComponent& other) = 0; protected: friend class CanvasComponentContainer; friend class CanvasComponentAllocator; diff --git a/src/CanvasComponents/CanvasComponentAllocator.cpp b/src/CanvasComponents/CanvasComponentAllocator.cpp index 6bae126..b4925b3 100644 --- a/src/CanvasComponents/CanvasComponentAllocator.cpp +++ b/src/CanvasComponents/CanvasComponentAllocator.cpp @@ -1,21 +1,24 @@ #include "CanvasComponentAllocator.hpp" #include "CanvasComponentContainer.hpp" #include "../DrawingProgram/DrawingProgram.hpp" +#include "../World.hpp" +#include +#include "CanvasComponent.hpp" CanvasComponentAllocator::CanvasComponentAllocator() {} -CanvasComponentAllocator::CanvasComponentAllocator(CanvasComponent::CompType typeToAllocate) { +CanvasComponentAllocator::CanvasComponentAllocator(CanvasComponentType typeToAllocate) { comp = std::unique_ptr(CanvasComponent::allocate_comp(typeToAllocate)); } -void CanvasComponentAllocator::register_class(DrawingProgram& drawP, NetworkingObjects::DelayUpdateSerializedClassManager& delayUpdateMan, NetworkingObjects::NetObjManager& objMan) { - delayUpdateMan.register_class(objMan, NetworkingObjects::DelayUpdateSerializedClassManager::CustomConstructors{ +void CanvasComponentAllocator::register_class(World& world, NetworkingObjects::NetObjManager& objMan) { + world.delayedUpdateObjectManager.register_class(objMan, NetworkingObjects::DelayUpdateSerializedClassManager::CustomConstructors{ .writeConstructor = [](const CanvasComponentAllocator& o, cereal::PortableBinaryOutputArchive& a) { a(o.comp->get_type()); a(*o.comp); }, - .readConstructor = [](CanvasComponentAllocator& o, cereal::PortableBinaryOutputArchive& a) { - CanvasComponent::CompType typeToAllocate; + .readConstructor = [](CanvasComponentAllocator& o, cereal::PortableBinaryInputArchive& a) { + CanvasComponentType typeToAllocate; a(typeToAllocate); o.comp = std::unique_ptr(CanvasComponent::allocate_comp(typeToAllocate)); a(*o.comp); @@ -23,7 +26,7 @@ void CanvasComponentAllocator::register_class(DrawingProgram& drawP, NetworkingO .writeUpdate = [](const CanvasComponentAllocator& o, cereal::PortableBinaryOutputArchive& a) { a(*o.comp); }, - .readUpdate = [](CanvasComponentAllocator& o, cereal::PortableBinaryOutputArchive& a) { + .readUpdate = [](CanvasComponentAllocator& o, cereal::PortableBinaryInputArchive& a) { a(*o.comp); }, .allocateCopy = [](const CanvasComponentAllocator& o) { @@ -33,9 +36,9 @@ void CanvasComponentAllocator::register_class(DrawingProgram& drawP, NetworkingO return theCopy; }, .assignmentFunc = [](CanvasComponentAllocator& o, const CanvasComponentAllocator& o2) { - // Assignment still needs to be implemented + o.comp->set_data_from(*o2.comp); }, - .postUpdateFunc = [&drawP](CanvasComponentAllocator& o) { + .postUpdateFunc = [&drawP = world.drawProg](CanvasComponentAllocator& o) { o.comp->compContainer->commit_update(drawP); } }); diff --git a/src/CanvasComponents/CanvasComponentAllocator.hpp b/src/CanvasComponents/CanvasComponentAllocator.hpp index 654ff1b..030803b 100644 --- a/src/CanvasComponents/CanvasComponentAllocator.hpp +++ b/src/CanvasComponents/CanvasComponentAllocator.hpp @@ -1,15 +1,16 @@ #pragma once #include -#include "CanvasComponent.hpp" +#include "CanvasComponentType.hpp" #include #include -class DrawingProgram; +class World; +class CanvasComponent; class CanvasComponentAllocator { public: CanvasComponentAllocator(); - CanvasComponentAllocator(CanvasComponent::CompType typeToAllocate); + CanvasComponentAllocator(CanvasComponentType typeToAllocate); std::unique_ptr comp; - static void register_class(DrawingProgram& drawP, NetworkingObjects::DelayUpdateSerializedClassManager& delayUpdateMan, NetworkingObjects::NetObjManager& objMan); + static void register_class(World& world, NetworkingObjects::NetObjManager& objMan); }; diff --git a/src/CanvasComponents/CanvasComponentContainer.cpp b/src/CanvasComponents/CanvasComponentContainer.cpp index 8ce9b81..4de70e1 100644 --- a/src/CanvasComponents/CanvasComponentContainer.cpp +++ b/src/CanvasComponents/CanvasComponentContainer.cpp @@ -3,13 +3,14 @@ #include "../DrawData.hpp" #include "../DrawingProgram/DrawingProgram.hpp" #include "../World.hpp" +#include "CanvasComponent.hpp" #include using namespace NetworkingObjects; CanvasComponentContainer::CanvasComponentContainer() { } -CanvasComponentContainer::CanvasComponentContainer(NetworkingObjects::NetObjManager& objMan, CanvasComponent::CompType type) { +CanvasComponentContainer::CanvasComponentContainer(NetworkingObjects::NetObjManager& objMan, CanvasComponentType type) { compAllocator = objMan.make_obj_direct(type); } diff --git a/src/CanvasComponents/CanvasComponentContainer.hpp b/src/CanvasComponents/CanvasComponentContainer.hpp index 5d58eae..a32ecdb 100644 --- a/src/CanvasComponents/CanvasComponentContainer.hpp +++ b/src/CanvasComponents/CanvasComponentContainer.hpp @@ -1,13 +1,13 @@ #pragma once #include "../CoordSpaceHelper.hpp" -#include "CanvasComponent.hpp" #include +#include "CanvasComponentType.hpp" #include "../VersionConstants.hpp" #include #include +#include "CanvasComponentAllocator.hpp" class DrawingProgram; -class CanvasComponentAllocator; class DrawingProgramCacheBVHNode; class CanvasComponentContainer { @@ -26,7 +26,7 @@ class CanvasComponentContainer { constexpr static int COMP_MIPMAP_LEVEL_TWO = 5; CanvasComponentContainer(); - CanvasComponentContainer(NetworkingObjects::NetObjManager& objMan, CanvasComponent::CompType type); + CanvasComponentContainer(NetworkingObjects::NetObjManager& objMan, CanvasComponentType type); static void register_class(NetworkingObjects::NetObjManager& t); static void delay_post_assignment_update(DrawingProgram& drawP, CanvasComponent& comp); void save_file(cereal::PortableBinaryOutputArchive& a) const; @@ -61,7 +61,7 @@ class CanvasComponentContainer { }; unsigned get_mipmap_level(const DrawData& drawData) const; - CanvasComponent* allocate_comp(CanvasComponent::CompType type); + CanvasComponent* allocate_comp(CanvasComponentType type); void canvas_do_transform(SkCanvas* canvas, const TransformDrawData& transformData) const; TransformDrawData calculate_draw_transform(const DrawData& drawData) const; void calculate_world_bounds(); diff --git a/src/CanvasComponents/CanvasComponentType.hpp b/src/CanvasComponents/CanvasComponentType.hpp new file mode 100644 index 0000000..9dac1e6 --- /dev/null +++ b/src/CanvasComponents/CanvasComponentType.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +enum class CanvasComponentType : uint8_t { + BRUSHSTROKE = 0, + RECTANGLE, + ELLIPSE, + TEXTBOX, + IMAGE +}; diff --git a/src/CanvasComponents/EllipseCanvasComponent.cpp b/src/CanvasComponents/EllipseCanvasComponent.cpp index 2f3a68f..df7c47a 100644 --- a/src/CanvasComponents/EllipseCanvasComponent.cpp +++ b/src/CanvasComponents/EllipseCanvasComponent.cpp @@ -1,11 +1,12 @@ #include "EllipseCanvasComponent.hpp" +#include "CanvasComponent.hpp" #include "Helpers/ConvertVec.hpp" #include "Helpers/SCollision.hpp" #include #include "../DrawCollision.hpp" -CanvasComponent::CompType EllipseCanvasComponent::get_type() const { - return CompType::ELLIPSE; +CanvasComponentType EllipseCanvasComponent::get_type() const { + return CanvasComponentType::ELLIPSE; } void EllipseCanvasComponent::save(cereal::PortableBinaryOutputArchive& a) const { @@ -51,6 +52,11 @@ void EllipseCanvasComponent::initialize_draw_data(DrawingProgram& drawP) { create_collider(); } +void EllipseCanvasComponent::set_data_from(const CanvasComponent& other) { + auto& otherEllipse = static_cast(other); + d = otherEllipse.d; +} + bool EllipseCanvasComponent::collides_within_coords(const SCollision::ColliderCollection& checkAgainst) const { return collisionTree.is_collide(checkAgainst); } diff --git a/src/CanvasComponents/EllipseCanvasComponent.hpp b/src/CanvasComponents/EllipseCanvasComponent.hpp index ba36fa8..55d986d 100644 --- a/src/CanvasComponents/EllipseCanvasComponent.hpp +++ b/src/CanvasComponents/EllipseCanvasComponent.hpp @@ -5,11 +5,12 @@ class EllipseCanvasComponent : public CanvasComponent { public: - virtual CompType get_type() const override; + virtual CanvasComponentType get_type() const override; virtual void save(cereal::PortableBinaryOutputArchive& a) const override; virtual void load(cereal::PortableBinaryInputArchive& a) override; virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override; virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override; + virtual void set_data_from(const CanvasComponent& other) override; // User input data struct Data { diff --git a/src/CanvasComponents/ImageCanvasComponent.cpp b/src/CanvasComponents/ImageCanvasComponent.cpp index b7bc691..886f9db 100644 --- a/src/CanvasComponents/ImageCanvasComponent.cpp +++ b/src/CanvasComponents/ImageCanvasComponent.cpp @@ -9,8 +9,8 @@ #include "../DrawCollision.hpp" #include "CanvasComponentContainer.hpp" -CanvasComponent::CompType ImageCanvasComponent::get_type() const { - return CompType::IMAGE; +CanvasComponentType ImageCanvasComponent::get_type() const { + return CanvasComponentType::IMAGE; } void ImageCanvasComponent::save(cereal::PortableBinaryOutputArchive& a) const { @@ -48,6 +48,11 @@ void ImageCanvasComponent::draw_download_progress_bar(SkCanvas* canvas, const Dr } } +void ImageCanvasComponent::set_data_from(const CanvasComponent& other) { + auto& otherImage = static_cast(other); + d = otherImage.d; +} + void ImageCanvasComponent::draw(SkCanvas* canvas, const DrawData& drawData) const { ResourceDisplay* display = drawData.rMan->get_display_data(d.imageID); if(display) diff --git a/src/CanvasComponents/ImageCanvasComponent.hpp b/src/CanvasComponents/ImageCanvasComponent.hpp index 85ecdb2..bb53901 100644 --- a/src/CanvasComponents/ImageCanvasComponent.hpp +++ b/src/CanvasComponents/ImageCanvasComponent.hpp @@ -10,7 +10,8 @@ class ImageCanvasComponent : public CanvasComponent { virtual void load(cereal::PortableBinaryInputArchive& a) override; virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override; virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override; - virtual CompType get_type() const override; + virtual CanvasComponentType get_type() const override; + virtual void set_data_from(const CanvasComponent& other) override; void draw_download_progress_bar(SkCanvas* canvas, const DrawData& drawData, float progress) const; diff --git a/src/CanvasComponents/RectangleCanvasComponent.cpp b/src/CanvasComponents/RectangleCanvasComponent.cpp index de95446..f8be515 100644 --- a/src/CanvasComponents/RectangleCanvasComponent.cpp +++ b/src/CanvasComponents/RectangleCanvasComponent.cpp @@ -7,8 +7,8 @@ #include "../SharedTypes.hpp" #include "../DrawCollision.hpp" -CanvasComponent::CompType RectangleCanvasComponent::get_type() const { - return CompType::RECTANGLE; +CanvasComponentType RectangleCanvasComponent::get_type() const { + return CanvasComponentType::RECTANGLE; } void RectangleCanvasComponent::save(cereal::PortableBinaryOutputArchive& a) const { @@ -45,6 +45,11 @@ void RectangleCanvasComponent::draw(SkCanvas* canvas, const DrawData& drawData) } } +void RectangleCanvasComponent::set_data_from(const CanvasComponent& other) { + auto& otherRect = static_cast(other); + d = otherRect.d; +} + void RectangleCanvasComponent::initialize_draw_data(DrawingProgram& drawP) { create_draw_data(); create_collider(); diff --git a/src/CanvasComponents/RectangleCanvasComponent.hpp b/src/CanvasComponents/RectangleCanvasComponent.hpp index 9ebd503..69e40ed 100644 --- a/src/CanvasComponents/RectangleCanvasComponent.hpp +++ b/src/CanvasComponents/RectangleCanvasComponent.hpp @@ -10,7 +10,8 @@ class RectangleCanvasComponent : public CanvasComponent { virtual void load(cereal::PortableBinaryInputArchive& a) override; virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override; virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override; - virtual CompType get_type() const override; + virtual CanvasComponentType get_type() const override; + virtual void set_data_from(const CanvasComponent& other) override; // User input data struct Data { diff --git a/src/CanvasComponents/TextBoxCanvasComponent.cpp b/src/CanvasComponents/TextBoxCanvasComponent.cpp index 5519768..f6a21cb 100644 --- a/src/CanvasComponents/TextBoxCanvasComponent.cpp +++ b/src/CanvasComponents/TextBoxCanvasComponent.cpp @@ -21,8 +21,8 @@ TextBoxCanvasComponent::TextBoxCanvasComponent(): textBox->set_initial_text_style_modifier(std::make_shared(std::vector{SkString{"Roboto"}})); } -CanvasComponent::CompType TextBoxCanvasComponent::get_type() const { - return CompType::TEXTBOX; +CanvasComponentType TextBoxCanvasComponent::get_type() const { + return CanvasComponentType::TEXTBOX; } void TextBoxCanvasComponent::save(cereal::PortableBinaryOutputArchive& a) const { @@ -58,6 +58,13 @@ void TextBoxCanvasComponent::load_file(cereal::PortableBinaryInputArchive& a, Ve } } +void TextBoxCanvasComponent::set_data_from(const CanvasComponent& other) { + auto& otherTextBox = static_cast(other); + d = otherTextBox.d; + *cursor = *otherTextBox.cursor; + textBox->set_rich_text_data(otherTextBox.textBox->get_rich_text_data()); +} + void TextBoxCanvasComponent::init_text_box(DrawingProgram& drawP) { textBox->set_font_data(drawP.world.main.fonts); // Getting a segfault relating to the paragraph cache means that the font collection hasn't been set yet textBox->set_width(d.p2.x() - d.p1.x() - TEXTBOX_PADDING * 2.0f); diff --git a/src/CanvasComponents/TextBoxCanvasComponent.hpp b/src/CanvasComponents/TextBoxCanvasComponent.hpp index 47b7725..7ab31bc 100644 --- a/src/CanvasComponents/TextBoxCanvasComponent.hpp +++ b/src/CanvasComponents/TextBoxCanvasComponent.hpp @@ -10,11 +10,12 @@ class TextBoxCanvasComponent : public CanvasComponent { constexpr static float TEXTBOX_PADDING = 5.0f; TextBoxCanvasComponent(); - virtual CompType get_type() const override; + virtual CanvasComponentType get_type() const override; virtual void save(cereal::PortableBinaryOutputArchive& a) const override; virtual void load(cereal::PortableBinaryInputArchive& a) override; virtual void save_file(cereal::PortableBinaryOutputArchive& a) const override; virtual void load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version) override; + virtual void set_data_from(const CanvasComponent& other) override; // User input data struct Data { @@ -26,6 +27,8 @@ class TextBoxCanvasComponent : public CanvasComponent { } d; private: + friend class TextBoxEditTool; + virtual void draw(SkCanvas* canvas, const DrawData& drawData) const override; virtual void initialize_draw_data(DrawingProgram& drawP) override; virtual bool collides_within_coords(const SCollision::ColliderCollection& checkAgainst) const override; diff --git a/src/DrawData.cpp b/src/DrawData.cpp index 10e4980..c9e197d 100644 --- a/src/DrawData.cpp +++ b/src/DrawData.cpp @@ -1,9 +1,9 @@ #include "DrawData.hpp" -#include "DrawComponents/DrawComponent.hpp" +#include "CanvasComponents/CanvasComponentContainer.hpp" void DrawData::refresh_draw_optimizing_values() { clampDrawBetween = true; - clampDrawMinimum = cam.c.inverseScale >> DRAWCOMP_MIN_SHIFT_BEFORE_DISAPPEAR; - mipMapLevelOne = cam.c.inverseScale >> DRAWCOMP_MIPMAP_LEVEL_ONE; - mipMapLevelTwo = cam.c.inverseScale >> DRAWCOMP_MIPMAP_LEVEL_TWO; + clampDrawMinimum = cam.c.inverseScale >> CanvasComponentContainer::COMP_MIN_SHIFT_BEFORE_DISAPPEAR; + mipMapLevelOne = cam.c.inverseScale >> CanvasComponentContainer::COMP_MIPMAP_LEVEL_ONE; + mipMapLevelTwo = cam.c.inverseScale >> CanvasComponentContainer::COMP_MIPMAP_LEVEL_TWO; } diff --git a/src/DrawingProgram/BrushTool.cpp b/src/DrawingProgram/BrushTool.cpp index 36cb448..e4638ce 100644 --- a/src/DrawingProgram/BrushTool.cpp +++ b/src/DrawingProgram/BrushTool.cpp @@ -7,6 +7,7 @@ #include "../CanvasComponents/BrushStrokeCanvasComponent.hpp" #include "Helpers/NetworkingObjects/NetObjTemporaryPtr.decl.hpp" #include "Helpers/NetworkingObjects/NetObjWeakPtr.hpp" +#include "../CanvasComponents/CanvasComponentContainer.hpp" #include #define VEL_SMOOTH_MIN 0.6 @@ -25,6 +26,13 @@ void BrushTool::switch_tool(DrawingProgramToolType newTool) { commit_stroke(); } +void BrushTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { + if(objInfoBeingEdited == erasedComp) { + isDrawing = false; + objInfoBeingEdited = nullptr; + } +} + bool BrushTool::extensive_point_checking(const BrushStrokeCanvasComponent& brushStroke, const Vector2f& newPoint) { auto& points = brushStroke.d->points; if(points.size() >= 1 && (newPoint - points[points.size() - 1].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT) @@ -83,7 +91,7 @@ void BrushTool::tool_update() { if(isPenDown) { if(!isDrawing) { isDrawing = true; - CanvasComponentContainer* newBrushStrokeContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponent::CompType::BRUSHSTROKE); + CanvasComponentContainer* newBrushStrokeContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::BRUSHSTROKE); BrushStrokeCanvasComponent& newBrushStroke = static_cast(newBrushStrokeContainer->get_comp()); BrushStrokeCanvasComponentPoint p; @@ -94,16 +102,11 @@ void BrushTool::tool_update() { newBrushStroke.d->color = drawP.controls.foregroundColor; newBrushStroke.d->hasRoundCaps = hasRoundCaps; newBrushStrokeContainer->coords = drawP.world.drawData.cam.c; - intermediateContainer = drawP.components->push_back_and_send_create(drawP.components, newBrushStrokeContainer)->obj; + objInfoBeingEdited = drawP.components->push_back_and_send_create(drawP.components, newBrushStrokeContainer); addedTemporaryPoint = false; } else { - NetworkingObjects::NetObjTemporaryPtr containerPtr = intermediateContainer.lock(); - if(!containerPtr) { - isDrawing = false; - intermediateContainer.reset(); - return; - } + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; BrushStrokeCanvasComponent& brushStroke = static_cast(containerPtr->get_comp()); BrushStrokeCanvasComponentPoint p; @@ -130,7 +133,6 @@ void BrushTool::tool_update() { if((!drawingMinimumRelativeToSize && distToPrev >= 10.0) || (drawingMinimumRelativeToSize && distToPrev >= drawP.controls.relativeWidth * BrushStrokeCanvasComponent::DRAW_MINIMUM_LIMIT)) { brushStroke.d->points.back() = p; addedTemporaryPoint = false; - containerPtr->send_comp_update(drawP, true); if(midwayInterpolation) { if(brushStroke.d->points.size() != 2) // Don't interpolate the first point @@ -138,8 +140,10 @@ void BrushTool::tool_update() { prevPointUnaltered = p.pos; } } - containerPtr->commit_update(drawP); } + + containerPtr->send_comp_update(drawP, false); + containerPtr->commit_update(drawP); } } else if(isDrawing) { @@ -149,12 +153,10 @@ void BrushTool::tool_update() { } void BrushTool::commit_stroke() { - NetworkingObjects::NetObjTemporaryPtr lockedPtr = intermediateContainer.lock(); - if(lockedPtr) { - lockedPtr->commit_update(drawP); - lockedPtr->send_comp_update(drawP, true); - } - intermediateContainer.reset(); + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; + containerPtr->commit_update(drawP); + containerPtr->send_comp_update(drawP, true); + objInfoBeingEdited = nullptr; } void BrushTool::gui_toolbox() { diff --git a/src/DrawingProgram/BrushTool.hpp b/src/DrawingProgram/BrushTool.hpp index 38502b0..30a1fc0 100644 --- a/src/DrawingProgram/BrushTool.hpp +++ b/src/DrawingProgram/BrushTool.hpp @@ -20,6 +20,7 @@ class BrushTool : public DrawingProgramToolBase { virtual void gui_toolbox() override; virtual void tool_update() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void switch_tool(DrawingProgramToolType newTool) override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual bool prevent_undo_or_redo() override; @@ -36,7 +37,7 @@ class BrushTool : public DrawingProgramToolBase { }; std::deque penSmoothingData; - NetworkingObjects::NetObjWeakPtr intermediateContainer; + CanvasComponentContainer::ObjInfoSharedPtr objInfoBeingEdited; bool isDrawing = false; bool hasRoundCaps = true; bool drawingMinimumRelativeToSize = true; diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 8ecabb9..2db8601 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -50,14 +50,11 @@ void DrawingProgram::set_component_list_callbacks() { c->obj->set_owner_obj_info(c); c->obj->commit_update(*this); // Run commit update on insert so that world bounds are calculated compCache.add_component(c); - if(drawTool->get_type() == DrawingProgramToolType::ERASER) { - EraserTool* eraserTool = static_cast(drawTool.get()); - eraserTool->erasedComponents.erase(c); - } }); components->set_erase_callback([&](const CanvasComponentContainer::ObjInfoSharedPtr& c) { compCache.erase_component(c); selection.erase_component(c); + drawTool->erase_component(c); }); components->set_post_sync_callback([&]() { clear_draw_cache(); @@ -303,6 +300,7 @@ void DrawingProgram::update() { selection.update(); drawTool->tool_update(); + // Switch tools after the tool update, not before, so that we dont have to call erase_component on the toolToSwitchToAfterUpdate as well (components will not be erased in this time period) if(toolToSwitchToAfterUpdate) { switch_to_tool_ptr(std::move(toolToSwitchToAfterUpdate)); toolToSwitchToAfterUpdate = nullptr; diff --git a/src/DrawingProgram/DrawingProgramEditToolBase.cpp b/src/DrawingProgram/DrawingProgramEditToolBase.cpp index 24ecefa..208af3f 100644 --- a/src/DrawingProgram/DrawingProgramEditToolBase.cpp +++ b/src/DrawingProgram/DrawingProgramEditToolBase.cpp @@ -5,7 +5,7 @@ DrawingProgramEditToolBase::DrawingProgramEditToolBase(DrawingProgram& initDrawP drawP(initDrawP) {} -bool DrawingProgramEditToolBase::right_click_popup_gui(const std::shared_ptr& comp, Vector2f popupPos) { +bool DrawingProgramEditToolBase::right_click_popup_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp, Vector2f popupPos) { Toolbar& t = drawP.world.main.toolbar; t.paint_popup(popupPos); return true; diff --git a/src/DrawingProgram/DrawingProgramEditToolBase.hpp b/src/DrawingProgram/DrawingProgramEditToolBase.hpp index 379a8fa..1ea66b5 100644 --- a/src/DrawingProgram/DrawingProgramEditToolBase.hpp +++ b/src/DrawingProgram/DrawingProgramEditToolBase.hpp @@ -1,7 +1,7 @@ #pragma once #include #include "../DrawData.hpp" -#include "../DrawComponents/DrawComponent.hpp" +#include "../CanvasComponents/CanvasComponentContainer.hpp" class DrawingProgram; class EditTool; @@ -9,11 +9,11 @@ class EditTool; class DrawingProgramEditToolBase { public: DrawingProgramEditToolBase(DrawingProgram& initDrawP); - virtual void edit_start(EditTool& editTool, const std::shared_ptr& a, std::any& prevData) = 0; - virtual void commit_edit_updates(const std::shared_ptr& a, std::any& prevData) = 0; - virtual bool edit_update(const std::shared_ptr& a) = 0; - virtual bool edit_gui(const std::shared_ptr& a) = 0; - virtual bool right_click_popup_gui(const std::shared_ptr& comp, Vector2f popupPos); + virtual void edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& compContainer, std::any& prevData) = 0; + virtual void commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& compContainer, std::any& prevData) = 0; + virtual bool edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& compContainer) = 0; + virtual bool edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& compContainer) = 0; + virtual bool right_click_popup_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp, Vector2f popupPos); virtual ~DrawingProgramEditToolBase(); protected: DrawingProgram& drawP; diff --git a/src/DrawingProgram/DrawingProgramToolBase.hpp b/src/DrawingProgram/DrawingProgramToolBase.hpp index beec85d..7d899be 100644 --- a/src/DrawingProgram/DrawingProgramToolBase.hpp +++ b/src/DrawingProgram/DrawingProgramToolBase.hpp @@ -1,6 +1,7 @@ #pragma once #include #include "../DrawData.hpp" +#include "../CanvasComponents/CanvasComponentContainer.hpp" class DrawingProgram; @@ -27,6 +28,7 @@ class DrawingProgramToolBase { DrawingProgramToolBase(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() = 0; virtual void gui_toolbox() = 0; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) = 0; virtual bool right_click_popup_gui(Vector2f popupPos) = 0; virtual void tool_update() = 0; virtual void draw(SkCanvas* canvas, const DrawData& drawData) = 0; diff --git a/src/DrawingProgram/EditTool.cpp b/src/DrawingProgram/EditTool.cpp index 96989f9..056b776 100644 --- a/src/DrawingProgram/EditTool.cpp +++ b/src/DrawingProgram/EditTool.cpp @@ -24,15 +24,10 @@ DrawingProgramToolType EditTool::get_type() { void EditTool::gui_toolbox() { Toolbar& t = drawP.world.main.toolbar; - if(controls.isEditing) { - std::shared_ptr a = controls.compToEdit.lock(); - if(a) { - bool editHappened = controls.compEditTool->edit_gui(a); - if(editHappened) { - a->commit_update(drawP); - a->client_send_update(drawP, true); - } - } + if(isEditing) { + bool editHappened = compEditTool->edit_gui(objInfoBeingEdited); + if(editHappened) + objInfoBeingEdited->obj->commit_update(drawP); } else { t.gui.push_id("edit tool"); @@ -41,70 +36,73 @@ void EditTool::gui_toolbox() { } } +void EditTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { + if(erasedComp == objInfoBeingEdited) + switch_tool(get_type()); +} + bool EditTool::right_click_popup_gui(Vector2f popupPos) { - if(controls.isEditing) - return controls.compEditTool->right_click_popup_gui(controls.compToEdit.lock(), popupPos); + if(isEditing) + return compEditTool->right_click_popup_gui(objInfoBeingEdited, popupPos); else return drawP.selection_action_menu(popupPos); } void EditTool::add_point_handle(const HandleData& handle) { - controls.pointHandles.emplace_back(handle); + pointHandles.emplace_back(handle); } void EditTool::switch_tool(DrawingProgramToolType newTool) { - auto a = controls.compToEdit.lock(); - if(a && a->collabListInfo.lock()) { - controls.compEditTool->commit_edit_updates(a, controls.prevData); - a->commit_update(drawP); - a->client_send_update(drawP, true); + if(objInfoBeingEdited) { + compEditTool->commit_edit_updates(objInfoBeingEdited, prevData); + objInfoBeingEdited->obj->commit_update(drawP); + objInfoBeingEdited->obj->send_comp_update(drawP, true); } - controls.compToEdit.reset(); - controls.pointHandles.clear(); - controls.pointDragging = nullptr; - controls.isEditing = false; + objInfoBeingEdited = nullptr; + pointHandles.clear(); + pointDragging = nullptr; + isEditing = false; if(!drawP.is_selection_allowing_tool(newTool)) drawP.selection.deselect_all(); } -void EditTool::edit_start(const std::shared_ptr& comp) { - controls.isEditing = true; - switch(comp->get_type()) { - case DRAWCOMPONENT_TEXTBOX: { - controls.compEditTool = std::make_unique(drawP); +void EditTool::edit_start(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { + isEditing = true; + switch(comp->obj->get_comp().get_type()) { + case CanvasComponentType::TEXTBOX: { + compEditTool = std::make_unique(drawP); break; } - case DRAWCOMPONENT_ELLIPSE: { - controls.compEditTool = std::make_unique(drawP); + case CanvasComponentType::ELLIPSE: { + compEditTool = std::make_unique(drawP); break; } - case DRAWCOMPONENT_RECTANGLE: { - controls.compEditTool = std::make_unique(drawP); + case CanvasComponentType::RECTANGLE: { + compEditTool = std::make_unique(drawP); break; } - case DRAWCOMPONENT_IMAGE: { - controls.compEditTool = std::make_unique(drawP); + case CanvasComponentType::IMAGE: { + compEditTool = std::make_unique(drawP); break; } default: { - controls.isEditing = false; + isEditing = false; break; } } - if(controls.isEditing) { - controls.compToEdit = comp; - controls.compEditTool->edit_start(*this, comp, controls.prevData); - comp->lastUpdateTime = std::chrono::steady_clock::now(); + if(isEditing) { + objInfoBeingEdited = comp; + compEditTool->edit_start(*this, objInfoBeingEdited, prevData); } } -bool EditTool::is_editable(const std::shared_ptr& comp) { - return comp->get_type() != DRAWCOMPONENT_BRUSHSTROKE; +bool EditTool::is_editable(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { + return comp->obj->get_comp().get_type() != CanvasComponentType::BRUSHSTROKE; } void EditTool::tool_update() { - if(!controls.isEditing) { + if(!isEditing) { SCollision::AABB mouseAABB{drawP.world.get_mouse_world_pos() - WorldVec{0.5f, 0.5f}, drawP.world.get_mouse_world_pos() + WorldVec{0.5f, 0.5f}}; SCollision::ColliderCollection cMouseAABB; cMouseAABB.aabb.emplace_back(mouseAABB); @@ -118,11 +116,11 @@ void EditTool::tool_update() { if(drawP.controls.leftClick) { bool modifySelection = !drawP.selection.is_being_transformed(); if(drawP.world.main.input.mouse.leftClicks >= 2 && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) { - CollabListType::ObjectInfoPtr selectedObjectToEdit = drawP.selection.get_front_object_colliding_with(camCMouseAABB); + CanvasComponentContainer::ObjInfoSharedPtr selectedObjectToEdit = drawP.selection.get_front_object_colliding_with(camCMouseAABB); - if(selectedObjectToEdit && is_editable(selectedObjectToEdit->obj)) { + if(selectedObjectToEdit && is_editable(selectedObjectToEdit)) { drawP.selection.deselect_all(); - edit_start(selectedObjectToEdit->obj); + edit_start(selectedObjectToEdit); modifySelection = false; } } @@ -144,60 +142,53 @@ void EditTool::tool_update() { cMouseCircle.circle.emplace_back(mouseCircle); cMouseCircle.recalculate_bounds(); - std::shared_ptr a = controls.compToEdit.lock(); - if(a) { - bool isMovingPoint = false; - bool clickedAway = false; - if(!controls.pointDragging && drawP.controls.leftClick) { - for(HandleData& h : controls.pointHandles) { - if(SCollision::collide(mouseCircle, SCollision::Circle(drawP.world.drawData.cam.c.to_space(a->coords.from_space(*h.p)), drawP.drag_point_radius()))) { - controls.pointDragging = &h; - isMovingPoint = true; - break; - } - } - if(!isMovingPoint && !a->collides_with_cam_coords(drawP.world.drawData.cam.c, cMouseCircle)) - clickedAway = true; - } - else if(controls.pointDragging) { - if(drawP.controls.leftClickHeld) { - Vector2f newPos = a->coords.get_mouse_pos(drawP.world); - if(newPos != *controls.pointDragging->p) { - if(controls.pointDragging->min) - newPos = cwise_vec_max((*controls.pointDragging->min + Vector2f{controls.pointDragging->minimumDistanceBetweenBoundsAndPoint, controls.pointDragging->minimumDistanceBetweenBoundsAndPoint}).eval(), newPos); - if(controls.pointDragging->max) - newPos = cwise_vec_min((*controls.pointDragging->max - Vector2f{controls.pointDragging->minimumDistanceBetweenBoundsAndPoint, controls.pointDragging->minimumDistanceBetweenBoundsAndPoint}).eval(), newPos); - *controls.pointDragging->p = newPos; - a->commit_update(drawP); - a->client_send_update(drawP, false); - } + bool isMovingPoint = false; + bool clickedAway = false; + if(!pointDragging && drawP.controls.leftClick) { + for(HandleData& h : pointHandles) { + if(SCollision::collide(mouseCircle, SCollision::Circle(drawP.world.drawData.cam.c.to_space(objInfoBeingEdited->obj->coords.from_space(*h.p)), drawP.drag_point_radius()))) { + pointDragging = &h; isMovingPoint = true; + break; } - else - controls.pointDragging = nullptr; } - - a->lastUpdateTime = std::chrono::steady_clock::now(); - - bool shouldNotReset = controls.compEditTool->edit_update(a); - if(!shouldNotReset || clickedAway) - switch_tool(get_type()); + if(!isMovingPoint && !objInfoBeingEdited->obj->collides_with_cam_coords(drawP.world.drawData.cam.c, cMouseCircle)) + clickedAway = true; } - else + else if(pointDragging) { + if(drawP.controls.leftClickHeld) { + Vector2f newPos = objInfoBeingEdited->obj->coords.get_mouse_pos(drawP.world); + if(newPos != *pointDragging->p) { + if(pointDragging->min) + newPos = cwise_vec_max((*pointDragging->min + Vector2f{pointDragging->minimumDistanceBetweenBoundsAndPoint, pointDragging->minimumDistanceBetweenBoundsAndPoint}).eval(), newPos); + if(pointDragging->max) + newPos = cwise_vec_min((*pointDragging->max - Vector2f{pointDragging->minimumDistanceBetweenBoundsAndPoint, pointDragging->minimumDistanceBetweenBoundsAndPoint}).eval(), newPos); + *pointDragging->p = newPos; + objInfoBeingEdited->obj->commit_update(drawP); + } + isMovingPoint = true; + } + else + pointDragging = nullptr; + } + + objInfoBeingEdited->obj->send_comp_update(drawP, false); + + bool shouldNotReset = compEditTool->edit_update(objInfoBeingEdited); + if(!shouldNotReset || clickedAway) switch_tool(get_type()); } } bool EditTool::prevent_undo_or_redo() { - return controls.isEditing; + return isEditing; } void EditTool::draw(SkCanvas* canvas, const DrawData& drawData) { - if(controls.isEditing) { - std::shared_ptr a = controls.compToEdit.lock(); - if(a) { - for(HandleData& h : controls.pointHandles) - drawP.draw_drag_circle(canvas, drawData.cam.c.to_space((a->coords.from_space(*h.p))), {0.1f, 0.9f, 0.9f, 1.0f}, drawData); + if(isEditing) { + if(objInfoBeingEdited) { + for(HandleData& h : pointHandles) + drawP.draw_drag_circle(canvas, drawData.cam.c.to_space((objInfoBeingEdited->obj->coords.from_space(*h.p))), {0.1f, 0.9f, 0.9f, 1.0f}, drawData); } } } diff --git a/src/DrawingProgram/EditTool.hpp b/src/DrawingProgram/EditTool.hpp index 25c6351..44d5bae 100644 --- a/src/DrawingProgram/EditTool.hpp +++ b/src/DrawingProgram/EditTool.hpp @@ -1,6 +1,5 @@ #pragma once #include "DrawingProgramToolBase.hpp" -#include "../DrawComponents/DrawEllipse.hpp" #include #include #include "DrawingProgramEditToolBase.hpp" @@ -22,20 +21,19 @@ class EditTool : public DrawingProgramToolBase { virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; virtual void tool_update() override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void switch_tool(DrawingProgramToolType newTool) override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual bool prevent_undo_or_redo() override; void add_point_handle(const HandleData& handle); - void edit_start(const std::shared_ptr& comp); - bool is_editable(const std::shared_ptr& comp); + void edit_start(const CanvasComponentContainer::ObjInfoSharedPtr& comp); + bool is_editable(const CanvasComponentContainer::ObjInfoSharedPtr& comp); - struct EditControls { - std::unique_ptr compEditTool; - std::vector pointHandles; - std::weak_ptr compToEdit; - bool isEditing = false; - HandleData* pointDragging = nullptr; - std::any prevData; - } controls; + std::unique_ptr compEditTool; + std::vector pointHandles; + CanvasComponentContainer::ObjInfoSharedPtr objInfoBeingEdited; + bool isEditing = false; + HandleData* pointDragging = nullptr; + std::any prevData; }; diff --git a/src/DrawingProgram/EllipseDrawEditTool.cpp b/src/DrawingProgram/EllipseDrawEditTool.cpp index f720b76..fddeb05 100644 --- a/src/DrawingProgram/EllipseDrawEditTool.cpp +++ b/src/DrawingProgram/EllipseDrawEditTool.cpp @@ -11,66 +11,48 @@ EllipseDrawEditTool::EllipseDrawEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -bool EllipseDrawEditTool::edit_gui(const std::shared_ptr& comp) { - auto a = std::static_pointer_cast(comp); +bool EllipseDrawEditTool::edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { + 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; - if(a->d.fillStrokeMode == 0 || a->d.fillStrokeMode == 2) { + 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; + 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); + 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"); }); } - if(a->d.fillStrokeMode == 1 || a->d.fillStrokeMode == 2) { - t.gui.slider_scalar_field("relstrokewidth", "Outline Size", &a->d.strokeWidth, 3.0f, 40.0f); + 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); + 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"); }); } t.gui.pop_id(); - bool editHappened = (!oldData.has_value()) || (a->d != oldData); - oldData = a->d; + bool editHappened = (!oldData.has_value()) || (a.d != oldData); + oldData = a.d; return editHappened; } -void EllipseDrawEditTool::edit_start(EditTool& editTool, const std::shared_ptr& comp, std::any& prevData) { - auto a = std::static_pointer_cast(comp); +void EllipseDrawEditTool::edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { + auto& a = static_cast(comp->obj->get_comp()); - prevData = a->d; - editTool.add_point_handle({&a->d.p1, nullptr, &a->d.p2}); - editTool.add_point_handle({&a->d.p2, &a->d.p1, nullptr}); + prevData = a.d; + editTool.add_point_handle({&a.d.p1, nullptr, &a.d.p2}); + editTool.add_point_handle({&a.d.p2, &a.d.p1, nullptr}); } -void EllipseDrawEditTool::commit_edit_updates(const std::shared_ptr& comp, std::any& prevData) { - auto a = std::static_pointer_cast(comp); - - DrawEllipse::Data pData = std::any_cast(prevData); - DrawEllipse::Data cData = a->d; - drawP.world.undo.push(UndoManager::UndoRedoPair{ - [&drawP = drawP, a, pData]() { - a->d = pData; - a->client_send_update(drawP, true); - a->commit_update(drawP); - return true; - }, - [&drawP = drawP, a, cData]() { - a->d = cData; - a->client_send_update(drawP, true); - a->commit_update(drawP); - return true; - } - }); +void EllipseDrawEditTool::commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { } -bool EllipseDrawEditTool::edit_update(const std::shared_ptr& comp) { +bool EllipseDrawEditTool::edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { return true; } diff --git a/src/DrawingProgram/EllipseDrawEditTool.hpp b/src/DrawingProgram/EllipseDrawEditTool.hpp index 833b1ae..f682f11 100644 --- a/src/DrawingProgram/EllipseDrawEditTool.hpp +++ b/src/DrawingProgram/EllipseDrawEditTool.hpp @@ -1,6 +1,7 @@ #pragma once #include "DrawingProgramEditToolBase.hpp" -#include "../DrawComponents/DrawEllipse.hpp" +#include "../CanvasComponents/CanvasComponentContainer.hpp" +#include "../CanvasComponents//EllipseCanvasComponent.hpp" #include #include @@ -9,12 +10,12 @@ class DrawingProgram; class EllipseDrawEditTool : public DrawingProgramEditToolBase { public: EllipseDrawEditTool(DrawingProgram& initDrawP); - virtual void edit_start(EditTool& editTool, const std::shared_ptr& comp, std::any& prevData) override; - virtual void commit_edit_updates(const std::shared_ptr& comp, std::any& prevData) override; - virtual bool edit_update(const std::shared_ptr& comp) override; - virtual bool edit_gui(const std::shared_ptr& comp) override; + virtual void edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual void commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual bool edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; + virtual bool edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; private: void commit(); - std::optional oldData; + std::optional oldData; }; diff --git a/src/DrawingProgram/EllipseDrawTool.cpp b/src/DrawingProgram/EllipseDrawTool.cpp index 3d8bdfc..5bcd612 100644 --- a/src/DrawingProgram/EllipseDrawTool.cpp +++ b/src/DrawingProgram/EllipseDrawTool.cpp @@ -7,6 +7,7 @@ #include "../InputManager.hpp" #include #include "../CanvasComponents/EllipseCanvasComponent.hpp" +#include "../CanvasComponents/CanvasComponentContainer.hpp" EllipseDrawTool::EllipseDrawTool(DrawingProgram& initDrawP): DrawingProgramToolBase(initDrawP) @@ -28,6 +29,13 @@ void EllipseDrawTool::gui_toolbox() { t.gui.pop_id(); } +void EllipseDrawTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { + if(objInfoBeingEdited == erasedComp) { + objInfoBeingEdited = nullptr; + drawStage = 0; + } +} + bool EllipseDrawTool::right_click_popup_gui(Vector2f popupPos) { Toolbar& t = drawP.world.main.toolbar; t.paint_popup(popupPos); @@ -42,7 +50,7 @@ void EllipseDrawTool::tool_update() { switch(drawStage) { case 0: { if(drawP.controls.leftClick) { - CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponent::CompType::ELLIPSE); + CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::ELLIPSE); EllipseCanvasComponent& newEllipse = static_cast(newContainer->get_comp()); startAt = drawP.world.main.input.mouse.pos; @@ -55,14 +63,14 @@ void EllipseDrawTool::tool_update() { newEllipse.d.fillStrokeMode = static_cast(fillStrokeMode); newContainer->coords = drawP.world.drawData.cam.c; - intermediateContainer = drawP.components->push_back_and_send_create(drawP.components, newContainer)->obj; + objInfoBeingEdited = drawP.components->push_back_and_send_create(drawP.components, newContainer); drawStage = 1; } break; } case 1: { - NetworkingObjects::NetObjTemporaryPtr containerPtr = intermediateContainer.lock(); - if(drawP.controls.leftClickHeld && containerPtr) { + if(drawP.controls.leftClickHeld) { + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; Vector2f newPos = containerPtr->coords.get_mouse_pos(drawP.world); if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) { float height = std::fabs(startAt.y() - newPos.y()); @@ -72,7 +80,7 @@ void EllipseDrawTool::tool_update() { ellipse.d.p1 = cwise_vec_min(startAt, newPos); ellipse.d.p2 = cwise_vec_max(startAt, newPos); ellipse.d.p2 = ensure_points_have_distance(ellipse.d.p1, ellipse.d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); - containerPtr->send_comp_update(drawP, true); + containerPtr->send_comp_update(drawP, false); containerPtr->commit_update(drawP); } else { @@ -89,12 +97,10 @@ bool EllipseDrawTool::prevent_undo_or_redo() { } void EllipseDrawTool::commit() { - NetworkingObjects::NetObjTemporaryPtr lockedPtr = intermediateContainer.lock(); - if(lockedPtr) { - lockedPtr->commit_update(drawP); - drawP.world.delayedUpdateObjectManager.send_update_to_all(lockedPtr, true); - } - intermediateContainer.reset(); + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; + containerPtr->commit_update(drawP); + containerPtr->send_comp_update(drawP, true); + objInfoBeingEdited = nullptr; } void EllipseDrawTool::draw(SkCanvas* canvas, const DrawData& drawData) { diff --git a/src/DrawingProgram/EllipseDrawTool.hpp b/src/DrawingProgram/EllipseDrawTool.hpp index 93a0a3d..9ba6850 100644 --- a/src/DrawingProgram/EllipseDrawTool.hpp +++ b/src/DrawingProgram/EllipseDrawTool.hpp @@ -12,6 +12,7 @@ class EllipseDrawTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void switch_tool(DrawingProgramToolType newTool) override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; @@ -22,5 +23,5 @@ class EllipseDrawTool : public DrawingProgramToolBase { Vector2f startAt; int fillStrokeMode = 1; int drawStage = 0; - NetworkingObjects::NetObjWeakPtr intermediateContainer; + CanvasComponentContainer::ObjInfoSharedPtr objInfoBeingEdited; }; diff --git a/src/DrawingProgram/EraserTool.cpp b/src/DrawingProgram/EraserTool.cpp index 4b5e8a5..813cad0 100644 --- a/src/DrawingProgram/EraserTool.cpp +++ b/src/DrawingProgram/EraserTool.cpp @@ -26,6 +26,10 @@ bool EraserTool::right_click_popup_gui(Vector2f popupPos) { return true; } +void EraserTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { + erasedComponents.erase(erasedComp); +} + void EraserTool::switch_tool(DrawingProgramToolType newTool) { DrawingProgramCache::move_components_from_bvh_nodes_to_set(erasedComponents, erasedBVHNodes); if(!erasedComponents.empty()) { diff --git a/src/DrawingProgram/EraserTool.hpp b/src/DrawingProgram/EraserTool.hpp index 770b4a4..5e12d35 100644 --- a/src/DrawingProgram/EraserTool.hpp +++ b/src/DrawingProgram/EraserTool.hpp @@ -12,6 +12,7 @@ class EraserTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void switch_tool(DrawingProgramToolType newTool) override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; diff --git a/src/DrawingProgram/EyeDropperTool.cpp b/src/DrawingProgram/EyeDropperTool.cpp index 3fde576..921e40f 100644 --- a/src/DrawingProgram/EyeDropperTool.cpp +++ b/src/DrawingProgram/EyeDropperTool.cpp @@ -45,6 +45,9 @@ bool EyeDropperTool::right_click_popup_gui(Vector2f popupPos) { return true; } +void EyeDropperTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { +} + void EyeDropperTool::tool_update() { if(drawP.controls.leftClick) { SkSurfaceProps props; diff --git a/src/DrawingProgram/EyeDropperTool.hpp b/src/DrawingProgram/EyeDropperTool.hpp index 6dc5913..8c672f8 100644 --- a/src/DrawingProgram/EyeDropperTool.hpp +++ b/src/DrawingProgram/EyeDropperTool.hpp @@ -10,6 +10,7 @@ class EyeDropperTool : public DrawingProgramToolBase { virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; virtual void tool_update() override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual bool prevent_undo_or_redo() override; virtual void switch_tool(DrawingProgramToolType newTool) override; diff --git a/src/DrawingProgram/GridModifyTool.cpp b/src/DrawingProgram/GridModifyTool.cpp index 8f5705a..403222c 100644 --- a/src/DrawingProgram/GridModifyTool.cpp +++ b/src/DrawingProgram/GridModifyTool.cpp @@ -33,6 +33,9 @@ DrawingProgramToolType GridModifyTool::get_type() { return DrawingProgramToolType::GRIDMODIFY; } +void GridModifyTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { +} + void GridModifyTool::gui_toolbox() { Toolbar& t = drawP.world.main.toolbar; t.gui.push_id("Grid modify tool"); diff --git a/src/DrawingProgram/GridModifyTool.hpp b/src/DrawingProgram/GridModifyTool.hpp index 24d8731..5ba0a74 100644 --- a/src/DrawingProgram/GridModifyTool.hpp +++ b/src/DrawingProgram/GridModifyTool.hpp @@ -13,6 +13,7 @@ class GridModifyTool : public DrawingProgramToolBase { virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; virtual void tool_update() override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual bool prevent_undo_or_redo() override; virtual void switch_tool(DrawingProgramToolType newTool) override; diff --git a/src/DrawingProgram/ImageEditTool.cpp b/src/DrawingProgram/ImageEditTool.cpp index 779c20b..bb479a8 100644 --- a/src/DrawingProgram/ImageEditTool.cpp +++ b/src/DrawingProgram/ImageEditTool.cpp @@ -1,6 +1,6 @@ #include "ImageEditTool.hpp" #include "DrawingProgram.hpp" -#include "../DrawComponents/DrawImage.hpp" +#include "../CanvasComponents/ImageCanvasComponent.hpp" #include "../World.hpp" #include "../Toolbar.hpp" #include "../MainProgram.hpp" @@ -16,23 +16,22 @@ ImageEditTool::ImageEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -void ImageEditTool::edit_start(EditTool& editTool, const std::shared_ptr& comp, std::any& prevData) { +void ImageEditTool::edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { } -void ImageEditTool::commit_edit_updates(const std::shared_ptr& comp, std::any& prevData) { +void ImageEditTool::commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { } -bool ImageEditTool::edit_update(const std::shared_ptr& comp) { +bool ImageEditTool::edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { return true; } -bool ImageEditTool::edit_gui(const std::shared_ptr& comp) { - std::shared_ptr a = std::static_pointer_cast(comp); +bool ImageEditTool::edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { + 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"); - std::optional resourceData = drawP.world.rMan.get_resource(a->d.imageID); - + std::optional resourceData = drawP.world.rMan.get_resource(a.d.imageID); if(resourceData) { t.gui.text_label("Name: " + resourceData->name); diff --git a/src/DrawingProgram/ImageEditTool.hpp b/src/DrawingProgram/ImageEditTool.hpp index 008ecfa..fce2ae5 100644 --- a/src/DrawingProgram/ImageEditTool.hpp +++ b/src/DrawingProgram/ImageEditTool.hpp @@ -7,8 +7,8 @@ class DrawingProgram; class ImageEditTool : public DrawingProgramEditToolBase { public: ImageEditTool(DrawingProgram& initDrawP); - virtual void edit_start(EditTool& editTool, const std::shared_ptr& comp, std::any& prevData) override; - virtual void commit_edit_updates(const std::shared_ptr& comp, std::any& prevData) override; - virtual bool edit_update(const std::shared_ptr& comp) override; - virtual bool edit_gui(const std::shared_ptr& comp) override; + virtual void edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual void commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual bool edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; + virtual bool edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; }; diff --git a/src/DrawingProgram/LassoSelectTool.cpp b/src/DrawingProgram/LassoSelectTool.cpp index cbb9ff7..e19dd5d 100644 --- a/src/DrawingProgram/LassoSelectTool.cpp +++ b/src/DrawingProgram/LassoSelectTool.cpp @@ -46,6 +46,9 @@ bool LassoSelectTool::right_click_popup_gui(Vector2f popupPos) { return drawP.selection_action_menu(popupPos); } +void LassoSelectTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { +} + void LassoSelectTool::switch_tool(DrawingProgramToolType newTool) { if(!drawP.is_selection_allowing_tool(newTool)) drawP.selection.deselect_all(); diff --git a/src/DrawingProgram/LassoSelectTool.hpp b/src/DrawingProgram/LassoSelectTool.hpp index 2c975f8..b67d5ca 100644 --- a/src/DrawingProgram/LassoSelectTool.hpp +++ b/src/DrawingProgram/LassoSelectTool.hpp @@ -3,7 +3,6 @@ #include "../DrawData.hpp" #include #include "../CoordSpaceHelper.hpp" -#include "../DrawComponents/DrawComponent.hpp" #include "DrawingProgramToolBase.hpp" class DrawingProgram; @@ -14,6 +13,7 @@ class LassoSelectTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void switch_tool(DrawingProgramToolType newTool) override; diff --git a/src/DrawingProgram/PanCanvasTool.cpp b/src/DrawingProgram/PanCanvasTool.cpp index ca51816..6af1f76 100644 --- a/src/DrawingProgram/PanCanvasTool.cpp +++ b/src/DrawingProgram/PanCanvasTool.cpp @@ -25,6 +25,9 @@ bool PanCanvasTool::right_click_popup_gui(Vector2f popupPos) { return drawP.selection_action_menu(popupPos); } +void PanCanvasTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { +} + void PanCanvasTool::tool_update() { } diff --git a/src/DrawingProgram/PanCanvasTool.hpp b/src/DrawingProgram/PanCanvasTool.hpp index 9848499..f03e87b 100644 --- a/src/DrawingProgram/PanCanvasTool.hpp +++ b/src/DrawingProgram/PanCanvasTool.hpp @@ -9,6 +9,7 @@ class PanCanvasTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual bool prevent_undo_or_redo() override; diff --git a/src/DrawingProgram/RectDrawEditTool.cpp b/src/DrawingProgram/RectDrawEditTool.cpp index c7a4cc8..5931e59 100644 --- a/src/DrawingProgram/RectDrawEditTool.cpp +++ b/src/DrawingProgram/RectDrawEditTool.cpp @@ -9,65 +9,47 @@ RectDrawEditTool::RectDrawEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -bool RectDrawEditTool::edit_gui(const std::shared_ptr& comp) { - std::shared_ptr a = std::static_pointer_cast(comp); +bool RectDrawEditTool::edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { + 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; - if(a->d.fillStrokeMode == 0 || a->d.fillStrokeMode == 2) { + 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; + 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); + 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"); }); } - if(a->d.fillStrokeMode == 1 || a->d.fillStrokeMode == 2) { - t.gui.slider_scalar_field("relstrokewidth", "Outline Size", &a->d.strokeWidth, 3.0f, 40.0f); + 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); + 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"); }); } t.gui.pop_id(); - bool editHappened = (!oldData.has_value()) || (a->d != oldData); - oldData = a->d; + bool editHappened = (!oldData.has_value()) || (a.d != oldData); + oldData = a.d; return editHappened; } -void RectDrawEditTool::edit_start(EditTool& editTool, const std::shared_ptr& comp, std::any& prevData) { - std::shared_ptr a = std::static_pointer_cast(comp); - prevData = a->d; - editTool.add_point_handle({&a->d.p1, nullptr, &a->d.p2}); - editTool.add_point_handle({&a->d.p2, &a->d.p1, nullptr}); +void RectDrawEditTool::edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { + auto& a = static_cast(comp->obj->get_comp()); + prevData = a.d; + editTool.add_point_handle({&a.d.p1, nullptr, &a.d.p2}); + editTool.add_point_handle({&a.d.p2, &a.d.p1, nullptr}); } -void RectDrawEditTool::commit_edit_updates(const std::shared_ptr& comp, std::any& prevData) { - std::shared_ptr a = std::static_pointer_cast(comp); - - DrawRectangle::Data pData = std::any_cast(prevData); - DrawRectangle::Data cData = a->d; - drawP.world.undo.push(UndoManager::UndoRedoPair{ - [&drawP = drawP, a, pData]() { - a->d = pData; - a->client_send_update(drawP, true); - a->commit_update(drawP); - return true; - }, - [&drawP = drawP, a, cData]() { - a->d = cData; - a->client_send_update(drawP, true); - a->commit_update(drawP); - return true; - } - }); +void RectDrawEditTool::commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { } -bool RectDrawEditTool::edit_update(const std::shared_ptr& comp) { +bool RectDrawEditTool::edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { return true; } diff --git a/src/DrawingProgram/RectDrawEditTool.hpp b/src/DrawingProgram/RectDrawEditTool.hpp index 3a86e4d..e36e488 100644 --- a/src/DrawingProgram/RectDrawEditTool.hpp +++ b/src/DrawingProgram/RectDrawEditTool.hpp @@ -1,6 +1,6 @@ #pragma once #include "DrawingProgramEditToolBase.hpp" -#include "../DrawComponents/DrawRectangle.hpp" +#include "../CanvasComponents/RectangleCanvasComponent.hpp" #include #include @@ -9,10 +9,10 @@ class DrawingProgram; class RectDrawEditTool : public DrawingProgramEditToolBase { public: RectDrawEditTool(DrawingProgram& initDrawP); - virtual void edit_start(EditTool& editTool, const std::shared_ptr& comp, std::any& prevData) override; - virtual void commit_edit_updates(const std::shared_ptr& comp, std::any& prevData) override; - virtual bool edit_update(const std::shared_ptr& comp) override; - virtual bool edit_gui(const std::shared_ptr& comp) override; + virtual void edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual void commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual bool edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; + virtual bool edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; private: - std::optional oldData; + std::optional oldData; }; diff --git a/src/DrawingProgram/RectDrawTool.cpp b/src/DrawingProgram/RectDrawTool.cpp index 841abae..2c67b0f 100644 --- a/src/DrawingProgram/RectDrawTool.cpp +++ b/src/DrawingProgram/RectDrawTool.cpp @@ -4,6 +4,7 @@ #include "../DrawData.hpp" #include "DrawingProgramToolBase.hpp" #include "../CanvasComponents/RectangleCanvasComponent.hpp" +#include "../CanvasComponents/CanvasComponentContainer.hpp" RectDrawTool::RectDrawTool(DrawingProgram& initDrawP): DrawingProgramToolBase(initDrawP) @@ -26,6 +27,13 @@ void RectDrawTool::gui_toolbox() { t.gui.pop_id(); } +void RectDrawTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { + if(objInfoBeingEdited == erasedComp) { + objInfoBeingEdited = nullptr; + drawStage = 0; + } +} + bool RectDrawTool::right_click_popup_gui(Vector2f popupPos) { Toolbar& t = drawP.world.main.toolbar; t.paint_popup(popupPos); @@ -33,7 +41,7 @@ bool RectDrawTool::right_click_popup_gui(Vector2f popupPos) { } void RectDrawTool::switch_tool(DrawingProgramToolType newTool) { - commit_rectangle(); + commit(); drawStage = 0; } @@ -41,7 +49,7 @@ void RectDrawTool::tool_update() { switch(drawStage) { case 0: { if(drawP.controls.leftClick) { - CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponent::CompType::RECTANGLE); + CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::RECTANGLE); RectangleCanvasComponent& newRectangle = static_cast(newContainer->get_comp()); startAt = drawP.world.main.input.mouse.pos; @@ -54,14 +62,14 @@ void RectDrawTool::tool_update() { newRectangle.d.p2 = ensure_points_have_distance(newRectangle.d.p1, newRectangle.d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); newRectangle.d.fillStrokeMode = static_cast(fillStrokeMode); newContainer->coords = drawP.world.drawData.cam.c; - intermediateContainer = drawP.components->push_back_and_send_create(drawP.components, newContainer)->obj; + objInfoBeingEdited = drawP.components->push_back_and_send_create(drawP.components, newContainer); drawStage = 1; } break; } case 1: { - NetworkingObjects::NetObjTemporaryPtr containerPtr = intermediateContainer.lock(); - if(drawP.controls.leftClickHeld && containerPtr) { + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; + if(drawP.controls.leftClickHeld) { Vector2f newPos = containerPtr->coords.get_mouse_pos(drawP.world); if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) { float height = std::fabs(startAt.y() - newPos.y()); @@ -71,11 +79,11 @@ void RectDrawTool::tool_update() { rectangle.d.p1 = cwise_vec_min(startAt, newPos); rectangle.d.p2 = cwise_vec_max(startAt, newPos); rectangle.d.p2 = ensure_points_have_distance(rectangle.d.p1, rectangle.d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); - containerPtr->send_comp_update(drawP, true); + containerPtr->send_comp_update(drawP, false); containerPtr->commit_update(drawP); } else { - commit_rectangle(); + commit(); drawStage = 0; } break; @@ -87,13 +95,11 @@ bool RectDrawTool::prevent_undo_or_redo() { return (drawStage == 1); } -void RectDrawTool::commit_rectangle() { - NetworkingObjects::NetObjTemporaryPtr lockedPtr = intermediateContainer.lock(); - if(lockedPtr) { - lockedPtr->commit_update(drawP); - drawP.world.delayedUpdateObjectManager.send_update_to_all(lockedPtr, true); - } - intermediateContainer.reset(); +void RectDrawTool::commit() { + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; + containerPtr->commit_update(drawP); + containerPtr->send_comp_update(drawP, true); + objInfoBeingEdited = nullptr; } void RectDrawTool::draw(SkCanvas* canvas, const DrawData& drawData) { diff --git a/src/DrawingProgram/RectDrawTool.hpp b/src/DrawingProgram/RectDrawTool.hpp index 30f4dab..2131585 100644 --- a/src/DrawingProgram/RectDrawTool.hpp +++ b/src/DrawingProgram/RectDrawTool.hpp @@ -11,16 +11,17 @@ class RectDrawTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void switch_tool(DrawingProgramToolType newTool) override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual bool prevent_undo_or_redo() override; private: - void commit_rectangle(); + void commit(); Vector2f startAt; float relativeRadiusWidth = 10.0f; int fillStrokeMode = 1; int drawStage = 0; - NetworkingObjects::NetObjWeakPtr intermediateContainer; + CanvasComponentContainer::ObjInfoSharedPtr objInfoBeingEdited; }; diff --git a/src/DrawingProgram/RectSelectTool.cpp b/src/DrawingProgram/RectSelectTool.cpp index b5d86b7..237f8bd 100644 --- a/src/DrawingProgram/RectSelectTool.cpp +++ b/src/DrawingProgram/RectSelectTool.cpp @@ -20,6 +20,9 @@ void RectSelectTool::gui_toolbox() { drawP.world.main.toolbar.gui.text_label_centered("Rectangle Select"); } +void RectSelectTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { +} + bool RectSelectTool::right_click_popup_gui(Vector2f popupPos) { return drawP.selection_action_menu(popupPos); } diff --git a/src/DrawingProgram/RectSelectTool.hpp b/src/DrawingProgram/RectSelectTool.hpp index e2bc60f..63bd61e 100644 --- a/src/DrawingProgram/RectSelectTool.hpp +++ b/src/DrawingProgram/RectSelectTool.hpp @@ -2,7 +2,6 @@ #include "DrawingProgramToolBase.hpp" #include #include "../CoordSpaceHelper.hpp" -#include "../DrawComponents/DrawComponent.hpp" class DrawingProgram; @@ -11,6 +10,7 @@ class RectSelectTool : public DrawingProgramToolBase { RectSelectTool(DrawingProgram& initDrawP); virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual bool right_click_popup_gui(Vector2f popupPos) override; virtual void tool_update() override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; diff --git a/src/DrawingProgram/ScreenshotTool.cpp b/src/DrawingProgram/ScreenshotTool.cpp index 1ac43c7..2523f13 100644 --- a/src/DrawingProgram/ScreenshotTool.cpp +++ b/src/DrawingProgram/ScreenshotTool.cpp @@ -117,6 +117,9 @@ bool ScreenshotTool::right_click_popup_gui(Vector2f popupPos) { return true; } +void ScreenshotTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { +} + void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) { if(controls.imageSize.x() <= 0 || controls.imageSize.y() <= 0) { std::cout << "[ScreenshotTool::take_screenshot] Image size is 0 or negative" << std::endl; diff --git a/src/DrawingProgram/ScreenshotTool.hpp b/src/DrawingProgram/ScreenshotTool.hpp index a24cfc9..58b7c0a 100644 --- a/src/DrawingProgram/ScreenshotTool.hpp +++ b/src/DrawingProgram/ScreenshotTool.hpp @@ -13,6 +13,7 @@ class ScreenshotTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void switch_tool(DrawingProgramToolType newTool) override; diff --git a/src/DrawingProgram/TextBoxEditTool.cpp b/src/DrawingProgram/TextBoxEditTool.cpp index 9ac0f73..9099e2a 100644 --- a/src/DrawingProgram/TextBoxEditTool.cpp +++ b/src/DrawingProgram/TextBoxEditTool.cpp @@ -20,8 +20,8 @@ TextBoxEditTool::TextBoxEditTool(DrawingProgram& initDrawP): DrawingProgramEditToolBase(initDrawP) {} -bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { - std::shared_ptr a = std::static_pointer_cast(comp); +bool TextBoxEditTool::edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { + auto& a = static_cast(comp->obj->get_comp()); Toolbar& t = drawP.world.main.toolbar; t.gui.push_id("edit tool text"); @@ -31,7 +31,7 @@ bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { 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]);}); + add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES]);}); } }); @@ -39,13 +39,13 @@ bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { 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]);}); + 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]);}); + 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; @@ -63,29 +63,29 @@ bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { } 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]);}); + 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);}); + 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);}); + 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);}); + 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);}); + 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);}); + 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);}); + 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]); + a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::SIZE]); } else release_undo_data("Font Size"); @@ -104,7 +104,7 @@ bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { 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]); + a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::COLOR]); } @@ -115,7 +115,7 @@ bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { 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]);}); + 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); } @@ -123,7 +123,7 @@ bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { 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]);}); + 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"); @@ -136,26 +136,26 @@ bool TextBoxEditTool::edit_gui(const std::shared_ptr& comp) { 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]); + a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::HIGHLIGHT_COLOR]); } t.gui.pop_id(); - if(a->textBox->inputChangedTextBox) + 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; + bool oldInputChangedTextBox = a.textBox->inputChangedTextBox; + a.textBox->inputChangedTextBox = false; return oldInputChangedTextBox; } -bool TextBoxEditTool::right_click_popup_gui(const std::shared_ptr& comp, Vector2f popupPos) { +bool TextBoxEditTool::right_click_popup_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp, Vector2f popupPos) { Toolbar& t = drawP.world.main.toolbar; bool shouldClose = false; - std::shared_ptr a = std::static_pointer_cast(comp); + auto& a = static_cast(comp->obj->get_comp()); t.gui.list_popup_menu("Text popup menu", popupPos, [&]() { t.gui.text_label_light("Text menu"); InputManager& input = drawP.world.main.input; @@ -167,14 +167,14 @@ bool TextBoxEditTool::right_click_popup_gui(const std::shared_ptr input.call_text_paste(false); shouldClose = true; } - if(a->cursor->selectionBeginPos != a->cursor->selectionEndPos) { + if(a.cursor->selectionBeginPos != a.cursor->selectionEndPos) { if(t.gui.text_button_left_transparent("Copy", "Copy")) { - input.set_clipboard_plain_and_richtext_pair(a->textBox->process_copy(*a->cursor)); + input.set_clipboard_plain_and_richtext_pair(a.textBox->process_copy(*a.cursor)); shouldClose = true; } if(t.gui.text_button_left_transparent("Cut", "Cut")) { input.text.do_textbox_operation_with_undo([&]() { - input.set_clipboard_plain_and_richtext_pair(a->textBox->process_cut(*a->cursor)); + input.set_clipboard_plain_and_richtext_pair(a.textBox->process_cut(*a.cursor)); }); shouldClose = true; } @@ -183,15 +183,15 @@ bool TextBoxEditTool::right_click_popup_gui(const std::shared_ptr return !shouldClose; } -void TextBoxEditTool::hold_undo_data(const std::string& undoName, const std::shared_ptr& a) { +void TextBoxEditTool::hold_undo_data(const std::string& undoName, TextBoxCanvasComponent& a) { auto it = undoHeldData.find(undoName); if(it != undoHeldData.end()) { std::pair& undoData = it->second; - if(undoData.first != *a->cursor) + if(undoData.first != *a.cursor) undoHeldData.erase(it); } - else if(a->cursor->selectionBeginPos != a->cursor->selectionEndPos) - undoHeldData.emplace(undoName, std::pair{*a->cursor, a->textBox->get_rich_text_data()}); + else if(a.cursor->selectionBeginPos != a.cursor->selectionEndPos) + undoHeldData.emplace(undoName, std::pair{*a.cursor, a.textBox->get_rich_text_data()}); } void TextBoxEditTool::release_undo_data(const std::string& undoName) { @@ -204,8 +204,8 @@ void TextBoxEditTool::release_undo_data(const std::string& undoName) { } } -void TextBoxEditTool::add_undo_if_selecting_area(const std::shared_ptr& a, const std::function& func) { - if(a->cursor->selectionBeginPos == a->cursor->selectionEndPos) +void TextBoxEditTool::add_undo_if_selecting_area(TextBoxCanvasComponent& a, const std::function& func) { + if(a.cursor->selectionBeginPos == a.cursor->selectionEndPos) func(); else { InputManager& input = drawP.world.main.input; @@ -229,13 +229,13 @@ uint8_t TextBoxEditTool::get_new_decoration_value() { return toRet; } -void TextBoxEditTool::set_styles_at_selection(const std::shared_ptr& a) { - TextPosition start = std::min(a->cursor->selectionBeginPos, a->cursor->selectionEndPos); - TextPosition end = std::max(a->cursor->selectionBeginPos, a->cursor->selectionEndPos); +void TextBoxEditTool::set_styles_at_selection(TextBoxCanvasComponent& a) { + TextPosition start = std::min(a.cursor->selectionBeginPos, a.cursor->selectionEndPos); + TextPosition end = std::max(a.cursor->selectionBeginPos, a.cursor->selectionEndPos); if(start == end) - currentMods = a->textBox->get_mods_used_at_pos(a->textBox->move(TextBox::Movement::LEFT, start)); + currentMods = a.textBox->get_mods_used_at_pos(a.textBox->move(TextBox::Movement::LEFT, start)); else - currentMods = a->textBox->get_mods_used_at_pos(start); + currentMods = a.textBox->get_mods_used_at_pos(start); newFontName = std::static_pointer_cast(currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES])->get_families().back().c_str(); newFontSize = std::static_pointer_cast(currentMods[TextStyleModifier::ModifierType::SIZE])->get_size(); @@ -247,78 +247,54 @@ void TextBoxEditTool::set_styles_at_selection(const std::shared_ptr newIsLinethrough = std::static_pointer_cast(currentMods[TextStyleModifier::ModifierType::DECORATION])->get_decoration_value() & skia::textlayout::TextDecoration::kLineThrough; newIsOverline = std::static_pointer_cast(currentMods[TextStyleModifier::ModifierType::DECORATION])->get_decoration_value() & skia::textlayout::TextDecoration::kOverline; - currentPStyle = a->textBox->get_paragraph_style_data_at(start.fParagraphIndex); + currentPStyle = a.textBox->get_paragraph_style_data_at(start.fParagraphIndex); } -void TextBoxEditTool::commit_edit_updates(const std::shared_ptr& comp, std::any& prevData) { - std::shared_ptr a = std::static_pointer_cast(comp); - - a->d.editing = false; - auto pData = std::any_cast(prevData); - TextBoxEditToolAllData cData = get_all_data(a); - TextData richText = a->textBox->get_rich_text_data(); - drawP.world.undo.push(UndoManager::UndoRedoPair{ - [&drawP = drawP, a, pData]() { - a->d = pData.textboxData; - a->textBox->set_rich_text_data(pData.richText); - a->d.editing = false; - a->client_send_update(drawP, true); - a->commit_update(drawP); - return true; - }, - [&drawP = drawP, a, cData]() { - a->d = cData.textboxData; - a->textBox->set_rich_text_data(cData.richText); - a->d.editing = false; - a->client_send_update(drawP, true); - a->commit_update(drawP); - return true; - } - }); +void TextBoxEditTool::commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { + auto& a = static_cast(comp->obj->get_comp()); + a.d.editing = false; + comp->obj->commit_update(drawP); } -TextBoxEditTool::TextBoxEditToolAllData TextBoxEditTool::get_all_data(const std::shared_ptr& a) { +TextBoxEditTool::TextBoxEditToolAllData TextBoxEditTool::get_all_data(const TextBoxCanvasComponent& a) { return { - .textboxData = a->d, - .richText = a->textBox->get_rich_text_data() + .textboxData = a.d, + .richText = a.textBox->get_rich_text_data() }; } -void TextBoxEditTool::edit_start(EditTool& editTool, const std::shared_ptr& comp, std::any& prevData) { - std::shared_ptr a = std::static_pointer_cast(comp); - auto& cur = a->cursor; - auto& textbox = a->textBox; +void TextBoxEditTool::edit_start(EditTool& editTool, const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) { + auto& a = static_cast(comp->obj->get_comp()); + auto& cur = a.cursor; + auto& textbox = a.textBox; cur = std::make_shared(); - Vector2f textSelectPos = a->get_mouse_pos(drawP); + Vector2f textSelectPos = a.get_mouse_pos(drawP); textbox->process_mouse_left_button(*cur, textSelectPos, 1, false, false); prevData = get_all_data(a); - a->d.editing = true; - a->textBox->inputChangedTextBox = true; - - a->commit_update(drawP); - a->client_send_update(drawP, false); + a.d.editing = true; + a.textBox->inputChangedTextBox = true; set_styles_at_selection(a); - editTool.add_point_handle({&a->d.p1, nullptr, &a->d.p2}); - editTool.add_point_handle({&a->d.p2, &a->d.p1, nullptr}); + editTool.add_point_handle({&a.d.p1, nullptr, &a.d.p2}); + editTool.add_point_handle({&a.d.p2, &a.d.p1, nullptr}); } -bool TextBoxEditTool::edit_update(const std::shared_ptr& comp) { - std::shared_ptr a = std::static_pointer_cast(comp); +bool TextBoxEditTool::edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) { + auto& a = static_cast(comp->obj->get_comp()); SCollision::ColliderCollection mousePointCollection; mousePointCollection.circle.emplace_back(drawP.world.main.input.mouse.pos, 1.0f); mousePointCollection.recalculate_bounds(); - a->init_text_box(drawP); + a.init_text_box(drawP); InputManager& input = drawP.world.main.input; - bool collidesWithBox = a->collides_with_cam_coords(drawP.world.drawData.cam.c, mousePointCollection); + bool collidesWithBox = comp->obj->collides_with_cam_coords(drawP.world.drawData.cam.c, mousePointCollection); - input.text.set_rich_text_box_input(a->textBox, a->cursor, true, currentMods); - a->textBox->process_mouse_left_button(*a->cursor, a->get_mouse_pos(drawP), (drawP.controls.leftClick && collidesWithBox) ? drawP.world.main.input.mouse.leftClicks : 0, drawP.controls.leftClickHeld, input.key(InputManager::KEY_GENERIC_LSHIFT).held); + input.text.set_rich_text_box_input(a.textBox, a.cursor, true, currentMods); + a.textBox->process_mouse_left_button(*a.cursor, a.get_mouse_pos(drawP), (drawP.controls.leftClick && collidesWithBox) ? drawP.world.main.input.mouse.leftClicks : 0, drawP.controls.leftClickHeld, input.key(InputManager::KEY_GENERIC_LSHIFT).held); return true; } diff --git a/src/DrawingProgram/TextBoxEditTool.hpp b/src/DrawingProgram/TextBoxEditTool.hpp index b5a1c6d..88f66cc 100644 --- a/src/DrawingProgram/TextBoxEditTool.hpp +++ b/src/DrawingProgram/TextBoxEditTool.hpp @@ -1,5 +1,5 @@ #pragma once -#include "../DrawComponents/DrawTextBox.hpp" +#include "../CanvasComponents/TextBoxCanvasComponent.hpp" #include "DrawingProgramEditToolBase.hpp" #include #include @@ -10,14 +10,14 @@ class TextBoxEditTool : public DrawingProgramEditToolBase { public: TextBoxEditTool(DrawingProgram& initDrawP); - virtual void edit_start(EditTool& editTool, const std::shared_ptr& a, std::any& prevData) override; - virtual void commit_edit_updates(const std::shared_ptr& a, std::any& prevData) override; - virtual bool edit_update(const std::shared_ptr& a) override; - virtual bool edit_gui(const std::shared_ptr& a) override; - virtual bool right_click_popup_gui(const std::shared_ptr& comp, Vector2f popupPos) override; + virtual void edit_start(EditTool& editTool,const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual void commit_edit_updates(const CanvasComponentContainer::ObjInfoSharedPtr& comp, std::any& prevData) override; + virtual bool edit_update(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; + virtual bool edit_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp) override; + virtual bool right_click_popup_gui(const CanvasComponentContainer::ObjInfoSharedPtr& comp, Vector2f popupPos) override; private: struct TextBoxEditToolAllData { - DrawTextBox::Data textboxData; + TextBoxCanvasComponent::Data textboxData; RichText::TextData richText; }; @@ -33,11 +33,11 @@ class TextBoxEditTool : public DrawingProgramEditToolBase { RichText::ParagraphStyleData currentPStyle; uint8_t get_new_decoration_value(); - void set_styles_at_selection(const std::shared_ptr& a); - void add_undo_if_selecting_area(const std::shared_ptr& a, const std::function& func); + void set_styles_at_selection(TextBoxCanvasComponent& a); + void add_undo_if_selecting_area(TextBoxCanvasComponent& a, const std::function& func); void add_undo(const std::function& func); - void hold_undo_data(const std::string& undoName, const std::shared_ptr& a); + void hold_undo_data(const std::string& undoName, TextBoxCanvasComponent& a); void release_undo_data(const std::string& undoName); std::unordered_map> undoHeldData; @@ -46,5 +46,5 @@ class TextBoxEditTool : public DrawingProgramEditToolBase { std::vector sortedFontList; - TextBoxEditToolAllData get_all_data(const std::shared_ptr& a); + TextBoxEditToolAllData get_all_data(const TextBoxCanvasComponent& a); }; diff --git a/src/DrawingProgram/TextBoxTool.cpp b/src/DrawingProgram/TextBoxTool.cpp index ad92844..d05498d 100644 --- a/src/DrawingProgram/TextBoxTool.cpp +++ b/src/DrawingProgram/TextBoxTool.cpp @@ -7,6 +7,8 @@ #include "Helpers/SCollision.hpp" #include #include +#include "../CanvasComponents/TextBoxCanvasComponent.hpp" +#include "../CanvasComponents/CanvasComponentContainer.hpp" #include "EditTool.hpp" TextBoxTool::TextBoxTool(DrawingProgram& initDrawP): @@ -24,6 +26,13 @@ void TextBoxTool::gui_toolbox() { t.gui.pop_id(); } +void TextBoxTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { + if(objInfoBeingEdited == erasedComp) { + objInfoBeingEdited = nullptr; + drawStage = 0; + } +} + bool TextBoxTool::right_click_popup_gui(Vector2f popupPos) { Toolbar& t = drawP.world.main.toolbar; t.paint_popup(popupPos); @@ -32,50 +41,50 @@ bool TextBoxTool::right_click_popup_gui(Vector2f popupPos) { void TextBoxTool::switch_tool(DrawingProgramToolType newTool) { commit(); - controls.drawStage = 0; + drawStage = 0; } void TextBoxTool::tool_update() { - switch(controls.drawStage) { + switch(drawStage) { case 0: { if(drawP.controls.leftClick) { - controls.intermediateItem = std::make_shared(); - controls.startAt = drawP.world.main.input.mouse.pos; - controls.endAt = controls.startAt; - controls.intermediateItem->d.p1 = controls.intermediateItem->d.p2 = controls.startAt; - controls.intermediateItem->d.p2 = ensure_points_have_distance(controls.intermediateItem->d.p1, controls.intermediateItem->d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); - controls.intermediateItem->d.editing = true; - controls.intermediateItem->coords = drawP.world.drawData.cam.c; - controls.intermediateItem->lastUpdateTime = std::chrono::steady_clock::now(); - uint64_t placement = drawP.components.client_list().size(); - auto objAdd = drawP.components.client_insert(placement, controls.intermediateItem); - controls.intermediateItem->client_send_place(drawP); - controls.intermediateItem->commit_update(drawP); - drawP.add_undo_place_component(objAdd); - controls.drawStage = 1; + startAt = drawP.world.main.input.mouse.pos; + endAt = startAt; + + CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::TEXTBOX); + TextBoxCanvasComponent& newTextBox = static_cast(newContainer->get_comp()); + + newTextBox.d.p1 = newTextBox.d.p2 = startAt; + newTextBox.d.p2 = ensure_points_have_distance(newTextBox.d.p1, newTextBox.d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); + newTextBox.d.editing = true; + newContainer->coords = drawP.world.drawData.cam.c; + objInfoBeingEdited = drawP.components->push_back_and_send_create(drawP.components, newContainer); + drawStage = 1; } break; } case 1: { - Vector2f newPos = controls.intermediateItem->coords.get_mouse_pos(drawP.world); + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; + TextBoxCanvasComponent& textBox = static_cast(containerPtr->get_comp()); + + Vector2f newPos = containerPtr->coords.get_mouse_pos(drawP.world); if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) { - float height = std::fabs(controls.startAt.y() - newPos.y()); - newPos.x() = controls.startAt.x() + (((newPos.x() - controls.startAt.x()) < 0.0f ? -1.0f : 1.0f) * height); + float height = std::fabs(startAt.y() - newPos.y()); + newPos.x() = startAt.x() + (((newPos.x() - startAt.x()) < 0.0f ? -1.0f : 1.0f) * height); } - controls.endAt = newPos; - controls.intermediateItem->d.p1 = cwise_vec_min(controls.endAt, controls.startAt); - controls.intermediateItem->d.p2 = cwise_vec_max(controls.endAt, controls.startAt); - controls.intermediateItem->d.p2 = ensure_points_have_distance(controls.intermediateItem->d.p1, controls.intermediateItem->d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); - controls.intermediateItem->lastUpdateTime = std::chrono::steady_clock::now(); + endAt = newPos; + textBox.d.p1 = cwise_vec_min(endAt, startAt); + textBox.d.p2 = cwise_vec_max(endAt, startAt); + textBox.d.p2 = ensure_points_have_distance(textBox.d.p1, textBox.d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); if(!drawP.controls.leftClickHeld) { auto editTool = std::make_unique(drawP); - editTool->edit_start(controls.intermediateItem); + editTool->edit_start(objInfoBeingEdited); drawP.toolToSwitchToAfterUpdate = std::move(editTool); return; } else { - controls.intermediateItem->client_send_update(drawP, false); - controls.intermediateItem->commit_update(drawP); + containerPtr->send_comp_update(drawP, false); + containerPtr->commit_update(drawP); } break; } @@ -83,15 +92,14 @@ void TextBoxTool::tool_update() { } bool TextBoxTool::prevent_undo_or_redo() { - return controls.intermediateItem != nullptr; + return (drawStage == 1); } void TextBoxTool::commit() { - if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { - controls.intermediateItem->client_send_update(drawP, true); - controls.intermediateItem->commit_update(drawP); - } - controls.intermediateItem = nullptr; + NetworkingObjects::NetObjOwnerPtr& containerPtr = objInfoBeingEdited->obj; + containerPtr->commit_update(drawP); + containerPtr->send_comp_update(drawP, true); + objInfoBeingEdited = nullptr; } void TextBoxTool::draw(SkCanvas* canvas, const DrawData& drawData) { diff --git a/src/DrawingProgram/TextBoxTool.hpp b/src/DrawingProgram/TextBoxTool.hpp index 7696e1e..8e24b00 100644 --- a/src/DrawingProgram/TextBoxTool.hpp +++ b/src/DrawingProgram/TextBoxTool.hpp @@ -1,8 +1,7 @@ #pragma once -#include "../DrawComponents/DrawTextBox.hpp" #include "DrawingProgramToolBase.hpp" #include -#include +#include "../CanvasComponents/CanvasComponentContainer.hpp" class DrawingProgram; @@ -12,19 +11,16 @@ class TextBoxTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void switch_tool(DrawingProgramToolType newTool) override; virtual bool prevent_undo_or_redo() override; private: - void edit_text(std::function toRun, const std::shared_ptr& textBox); - void update_textbox_network(const std::shared_ptr& textBox); void commit(); - struct TextBoxControls { - Vector2f startAt; - Vector2f endAt; - int drawStage = 0; - std::shared_ptr intermediateItem; - } controls; + Vector2f startAt; + Vector2f endAt; + int drawStage = 0; + CanvasComponentContainer::ObjInfoSharedPtr objInfoBeingEdited; }; diff --git a/src/DrawingProgram/ZoomCanvasTool.cpp b/src/DrawingProgram/ZoomCanvasTool.cpp index af56e08..4e4a355 100644 --- a/src/DrawingProgram/ZoomCanvasTool.cpp +++ b/src/DrawingProgram/ZoomCanvasTool.cpp @@ -25,6 +25,9 @@ bool ZoomCanvasTool::right_click_popup_gui(Vector2f popupPos) { return drawP.selection_action_menu(popupPos); } +void ZoomCanvasTool::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) { +} + void ZoomCanvasTool::tool_update() { } diff --git a/src/DrawingProgram/ZoomCanvasTool.hpp b/src/DrawingProgram/ZoomCanvasTool.hpp index 8545918..ed8520d 100644 --- a/src/DrawingProgram/ZoomCanvasTool.hpp +++ b/src/DrawingProgram/ZoomCanvasTool.hpp @@ -9,6 +9,7 @@ class ZoomCanvasTool : public DrawingProgramToolBase { virtual DrawingProgramToolType get_type() override; virtual void gui_toolbox() override; virtual bool right_click_popup_gui(Vector2f popupPos) override; + virtual void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& erasedComp) override; virtual void tool_update() override; virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual bool prevent_undo_or_redo() override; diff --git a/src/Server/ServerData.cpp b/src/Server/ServerData.cpp index c161de6..18a2aef 100644 --- a/src/Server/ServerData.cpp +++ b/src/Server/ServerData.cpp @@ -1,28 +1,12 @@ #include "ServerData.hpp" -#include "../DrawComponents/DrawComponent.hpp" void ServerData::save(cereal::PortableBinaryOutputArchive& a) const { a(canvasBackColor, canvasScale); - a((uint64_t)components.size()); - for(uint64_t i = 0; i < components.size(); i++) - a(components[i]->get_type(), components[i]->id, components[i]->coords, *components[i]); } void ServerData::load(cereal::PortableBinaryInputArchive& a) { a(canvasBackColor, canvasScale); - uint64_t compCount; - a(compCount); - for(uint64_t i = 0; i < compCount; i++) { - DrawComponentType t; - a(t); - auto newComp = DrawComponent::allocate_comp_type(t); - a(newComp->id, newComp->coords, *newComp); - components.emplace_back(newComp); - idToComponentMap.emplace(newComp->id, newComp); - } } void ServerData::scale_up(const WorldScalar& scaleUpAmount) { - for(auto& c : components) - c->scale_up(scaleUpAmount); } diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index c5642a2..7a3c1ca 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -540,8 +540,9 @@ void Toolbar::top_toolbar() { #else open_file_selector("Open File", {{"Any File", "*"}}, [w = make_weak_ptr(main.world)](const std::filesystem::path& p, const auto& e) { auto wLock = w.lock(); - if(wLock) - wLock->drawProg.add_file_to_canvas_by_path(p.string(), wLock->main.window.size.cast() / 2.0f, false); + // NOTE: Implement again later + //if(wLock) + // wLock->drawProg.add_file_to_canvas_by_path(p.string(), wLock->main.window.size.cast() / 2.0f, false); }); #endif } @@ -1245,7 +1246,7 @@ void Toolbar::performance_metrics() { std::stringstream a; a << "FPS: " << std::fixed << std::setprecision(0) << (1.0 / main.deltaTime); gui.text_label(a.str()); - gui.text_label("Item Count: " + std::to_string(main.world->drawProg.components.client_list().size())); + gui.text_label("Item Count: " + std::to_string(main.world->drawProg.components->size())); std::stringstream b; b << "Coord: " << main.world->drawData.cam.c.pos.x().display_int_str(5) << ", " << main.world->drawData.cam.c.pos.y().display_int_str(5); gui.text_label(b.str()); diff --git a/src/World.cpp b/src/World.cpp index 40f3647..5aa3304 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -84,7 +84,7 @@ void World::init_net_obj_type_list() { NetworkingObjects::register_ordered_list_class(netObjMan); delayedUpdateObjectManager.register_class(netObjMan); NetworkingObjects::register_ordered_list_class(netObjMan); - CanvasComponentAllocator::register_class(delayedUpdateObjectManager, netObjMan); + CanvasComponentAllocator::register_class(*this, netObjMan); CanvasComponentContainer::register_class(netObjMan); }