From 37dfdb700cb78cffd53a8b7cf1e9cc51051d1456 Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Wed, 22 Jun 2022 17:38:31 +0200 Subject: [PATCH 01/10] GUI alignment improvements --- .../GUI/CircuitEditor/CircuitEditor.cpp | 3 +++ .../GUI/ComponentEditor/ComponentEditor.cpp | 26 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ElecDev_Graphics_Application/Source/GUI/CircuitEditor/CircuitEditor.cpp b/ElecDev_Graphics_Application/Source/GUI/CircuitEditor/CircuitEditor.cpp index 5b9d8158e..157f9d495 100644 --- a/ElecDev_Graphics_Application/Source/GUI/CircuitEditor/CircuitEditor.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/CircuitEditor/CircuitEditor.cpp @@ -40,6 +40,7 @@ void CircuitEditor::onImGuiRender() if(engine) { // Circuit name. + ImGui::AlignTextToFramePadding(); ImGui::Text("Circuit Name: "); ImGui::SameLine(); if (ImGui::InputText("##circuitName", &engine->m_circuit->m_label)) @@ -60,6 +61,7 @@ void CircuitEditor::onImGuiRender() if (ImGui::CollapsingHeader("Components", NULL, ImGuiTreeNodeFlags_SpanFullWidth)) { // Filter. + ImGui::AlignTextToFramePadding(); ImGui::Text("Search: "); ImGui::SameLine(); ImGui::PushItemWidth(-1); @@ -126,6 +128,7 @@ void CircuitEditor::onImGuiRender() { // Filter. + ImGui::AlignTextToFramePadding(); ImGui::Text("Search: "); ImGui::SameLine(); ImGui::PushItemWidth(-1); diff --git a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp index 7ae70ebc5..719e5aca4 100644 --- a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp @@ -374,17 +374,20 @@ void ComponentEditor::onImGuiRender() ImGui::PushID("CompGeneral"); if (activeComponent) { + ImGui::AlignTextToFramePadding(); ImGui::Text(" Designator Index:\t"); ImGui::SameLine(); //ImGui::Text(activeComponent->designatorSym.c_str()); activeTitleString = activeComponent->m_tag; - + ImGui::PushItemWidth(-1); int designatorIdx = activeComponent->getDesignatorIdx(); if (ImGui::InputInt("##designatorIdx", &designatorIdx)) { activeComponent->setDesignatorIdx(designatorIdx); } + ImGui::PopItemWidth(); + ImGui::AlignTextToFramePadding(); ImGui::Text((std::string(" Description:\t ") + activeComponent->equipType).c_str()); } @@ -576,21 +579,33 @@ void ComponentEditor::onImGuiRender() if (activeComponent) { // Display tag number. + ImGui::BeginTable("##tagTable", 3, ImGuiTableFlags_SizingStretchProp); + ImGui::TableSetupColumn("1", ImGuiTableColumnFlags_::ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("2", ImGuiTableColumnFlags_::ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("3", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); ImGui::Text("Tag: "); - ImGui::SameLine(); - //ImGui::PushItemWidth(-1); + ImGui::TableNextColumn(); + ImGui::PushItemWidth(-1); if (ImGui::InputText("##tag", &activeComponent->m_tag)) { activeComponent->updateText(); } + ImGui::PopItemWidth(); + + ImGui::TableNextColumn(); - ImGui::SameLine(); ImGui::BeginDisabled(activeComponent->m_tag == activeComponent->designatorSym + std::to_string(activeComponent->getDesignatorIdx())); + //ImGui::PushItemWidth(-1); if (ImGui::Button("Reset Default")) { activeComponent->setTag(); } + //ImGui::PopItemWidth(); ImGui::EndDisabled(); - ImGui::SetNextItemOpen(false, ImGuiCond_Once); + ImGui::EndTable(); + + ImGui::SetNextItemOpen(true, ImGuiCond_Once); if (ImGui::CollapsingHeader("Ports")) { // Setup table. @@ -739,6 +754,7 @@ void ComponentEditor::onImGuiRender() // Dict data. ImGui::TableSetColumnIndex(0); ImGui::PushItemWidth(-1); + ImGui::AlignTextToFramePadding(); ImGui::Text(key.c_str()); ImGui::PopItemWidth(); ImGui::TableSetColumnIndex(1); From 39cde63ccdd8b5860d3efac1fbbeaaa82b514636 Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Thu, 23 Jun 2022 03:30:44 +0200 Subject: [PATCH 02/10] Framework for undo/redo system Changes to primitive colours can be undone/redone. --- .../ElecDev_Graphics_Application.vcxproj | 2 + ...ecDev_Graphics_Application.vcxproj.filters | 2 + .../Source/Application/Events/Events.h | 2 + .../CircuitDesigner_Events.cpp | 6 +- .../CircuitDesigner_Utilities.cpp | 6 +- .../GUI/ComponentDesignerColorEditor.cpp | 65 ++++---- .../GUI/ComponentDesignerColorEditor.h | 2 + .../CircuitDesigner/Peripherals/Circuit.cpp | 2 +- .../Peripherals/Component2D.cpp | 35 +++-- .../CircuitDesigner/Peripherals/Component2D.h | 8 +- .../CircuitDesigner/Peripherals/Port.cpp | 2 +- .../Source/Engines/CommandSystem/Command.h | 148 ++++++++++++++++++ .../Source/Engines/EngineCore/EngineCore.h | 6 + .../Engines/EngineCore/EngineCore_Events.cpp | 8 + .../Source/Engines/EntityComponents/Mutable.h | 37 +++++ .../GUI/ComponentEditor/ComponentEditor.cpp | 6 +- .../GUI/RendererStats/RendererStats.cpp | 4 +- .../GUI/SettingsWidget/SettingsWidget.cpp | 2 +- .../Graphics/OpenGL/Primitives/Grid.cpp | 2 +- .../Graphics/OpenGL/Primitives/Primitive.h | 21 +-- .../Graphics/OpenGL/Primitives/Text.cpp | 2 +- 21 files changed, 292 insertions(+), 76 deletions(-) create mode 100644 ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h create mode 100644 ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h diff --git a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj index 54f7826e0..7eeccc706 100644 --- a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj +++ b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj @@ -318,6 +318,7 @@ + @@ -782,6 +783,7 @@ + diff --git a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters index bd59180f9..1e4e4a14f 100644 --- a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters +++ b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters @@ -625,6 +625,8 @@ + + diff --git a/ElecDev_Graphics_Application/Source/Application/Events/Events.h b/ElecDev_Graphics_Application/Source/Application/Events/Events.h index f369aaf00..746f35639 100644 --- a/ElecDev_Graphics_Application/Source/Application/Events/Events.h +++ b/ElecDev_Graphics_Application/Source/Application/Events/Events.h @@ -73,6 +73,8 @@ enum EventType : LumenEventID EventType_Dehover = (LumenEventID) 1 << 31, EventType_MouseDragStart = (LumenEventID) 1 << 32, EventType_MouseDragStop = (LumenEventID) 1 << 33, + EventType_Undo = (LumenEventID) 1 << 34, + EventType_Redo = (LumenEventID) 1 << 35, }; //==============================================================================================================================================// diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp index 66aeb390a..ef91ee3b7 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp @@ -150,7 +150,7 @@ void CircuitDesigner::onMouseMoveEvent(const MouseMoveEvent& event) if (designerState == COMPONENT_PLACE) { // Move the component. - m_activeComponent->moveTo(getNearestGridVertex(screenCoords)); + m_activeComponent->translateTo(getNearestGridVertex(screenCoords)); } else { @@ -238,7 +238,7 @@ void CircuitDesigner::onMouseDragEvent(const MouseDragEvent& event) { if (m_activeComponent.get()) { - m_activeComponent->move(translation); + m_activeComponent->translate(translation); } if (m_activeVertexIdx != -1) { @@ -260,7 +260,7 @@ void CircuitDesigner::onNotifyEvent(const NotifyEvent& event) { glm::vec2 vert = getNearestGridVertex(m_activeComponent->centre); LUMEN_LOG_DEBUG(std::to_string(vert.x), "Component Designer Notify"); - m_activeComponent->moveTo(getNearestGridVertex(m_activeComponent->centre)); + m_activeComponent->translateTo(getNearestGridVertex(m_activeComponent->centre)); } if (m_activeVertexIdx != -1) { diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp index 81940d194..b69fa8474 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp @@ -163,7 +163,7 @@ void CircuitDesigner::loadAndPlaceComponent(const std::filesystem::path& path, c if (m_activeComponent) m_activeComponent->disableOutline(); m_circuit->m_components.push_back(std::make_shared(path, m_circuit.get())); - m_circuit->m_components.back()->move(getNearestGridVertex(pixelToWorldCoords(mousePos))); + m_circuit->m_components.back()->translate(getNearestGridVertex(pixelToWorldCoords(mousePos))); m_activeComponent = m_circuit->m_components.back(); m_activeComponent->setTag(); designerState = ENTITY_SELECT; @@ -175,7 +175,7 @@ void CircuitDesigner::loadAndPlaceComponent(const YAML::Node& node, const glm::v if(m_activeComponent) m_activeComponent->disableOutline(); m_circuit->m_components.push_back(std::make_shared(node, m_circuit.get())); - m_circuit->m_components.back()->move(getNearestGridVertex(pixelToWorldCoords(mousePos))); + m_circuit->m_components.back()->translate(getNearestGridVertex(pixelToWorldCoords(mousePos))); m_activeComponent = m_circuit->m_components.back(); m_activeComponent->setTag(); designerState = ENTITY_SELECT; @@ -595,7 +595,7 @@ void CircuitDesigner::reloadComponent(Component2D* component, const YAML::Node& portsVector = std::move(newPorts); // Update component. - component->move(componentCentre); + component->translate(componentCentre); component->rotate(componentRotation); } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp index 5c0839813..b3318f1e7 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp @@ -14,13 +14,14 @@ #include "Graphics/OpenGL/Primitives/PolyLine.h" #include "Graphics/OpenGL/Primitives/Polygon.h" #include "Graphics/OpenGL/Primitives/Text.h" +#include "Engines/CommandSystem/Command.h" //==============================================================================================================================================// // Popup menu. // //==============================================================================================================================================// ComponentDesignerColorEditor::ComponentDesignerColorEditor(std::string name, int imguiWindowFlags, glm::vec4* const target) - : LumenWindow(name, imguiWindowFlags), m_target(target) + : LumenWindow(name, imguiWindowFlags), m_target(target), color(*target) { addImGuiWindowFlags(ImGuiWindowFlags_AlwaysAutoResize); } @@ -71,44 +72,44 @@ void ComponentDesignerColorEditor::onImGuiRender() } // Set the color to be edited. - glm::vec4* color = m_target; - if (activePrimitive) - { - color = &activePrimitive->m_colour; - } - else if (activePort) - { - color = &activePort->body->m_colour; - } - else if (activeCable) - { - color = &activeCable->m_colour; + + if (activePrimitive != lastActivePrimitive) { + if (!activePrimitive) glm::vec4 color = *m_target; + else { + if (activePrimitive) + { + color = activePrimitive->m_colour; + } + } + lastActivePrimitive = activePrimitive; } + // Open color editor. - if (color) + ImGui::SameLine(); + if (ImGui::ColorPicker4("##ColorEditor", &color.r, ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf)) { - ImGui::SameLine(); - if (ImGui::ColorPicker4("##ColorEditor", &color->r, ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf)) + + //No longer supported. To remove. + /* + else if (activeCable) { - if (activePrimitive) - { - activePrimitive->setColor(*color); - } - else if (activeCable) - { - activeCable->m_colour = *color; - activeCable->setColour(*color); - } - else if (activePort) - { - activePort->body->setColor(*color); - } + activeCable->m_colour = *color; + activeCable->setColour(*color); } + else if (activePort) + { + activePort->body->setColor(*color); + }*/ + + if(!activePrimitive) *m_target = color; } - else - { - ImGui::Text("No active element."); + if (ImGui::Button("Apply")) { + if (activePrimitive) + { + engine->commandLog.execute(color, activePrimitive); + //activePrimitive->setColor(*color); + } } } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h index 1260bf702..1ebff24fd 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h @@ -48,6 +48,8 @@ class ComponentDesignerColorEditor : public LumenWindow // The position that the window starts up at. glm::vec2 m_initialPosition; glm::vec4* const m_target; + IPrimitive* lastActivePrimitive; + glm::vec4 color; }; //==============================================================================================================================================// diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Circuit.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Circuit.cpp index 61c9d5847..b62366535 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Circuit.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Circuit.cpp @@ -53,7 +53,7 @@ Circuit::Circuit(const YAML::Node& node) // Update component. auto& currentComponent = m_components.back(); currentComponent->disableOutline(); - currentComponent->moveTo({ componentNode["Position"][0].as(), componentNode["Position"][1].as() }); + currentComponent->translateTo({ componentNode["Position"][0].as(), componentNode["Position"][1].as() }); currentComponent->dataDict.clear(); YAML::Node dictNode = component.second["Dictionary"]; for (const auto& node : dictNode) diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp index ea9980d63..fec0fc47f 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp @@ -83,7 +83,7 @@ Component2D::Component2D(Circuit* parent) Component2D::Component2D(const glm::vec2& centreCoords, Circuit* parent) : Component2D(parent) { - moveTo(centreCoords); + translateTo(centreCoords); } Component2D::Component2D(const YAML::Node& node, Circuit* parent) @@ -200,13 +200,13 @@ Component2D::~Component2D() // Constructor & Destructor. // //=============================================================================================================================================// -void Component2D::moveTo(const glm::vec2& pointerPos) +void Component2D::translateTo(const glm::vec2& pointerPos) { glm::vec2 translation = pointerPos - centre; - move(translation); + translate(translation); } -void Component2D::move(const glm::vec2& translation) +void Component2D::translate(const glm::vec2& translation) { title->translate(translation); designator->translate(translation); @@ -221,7 +221,7 @@ void Component2D::move(const glm::vec2& translation) void Component2D::place(const glm::vec2& pos) { // Ensure the component is at the desired position. - moveTo(pos); + translateTo(pos); setLayer(0.0f); title->setColor(titleColour); for (auto poly : m_polygons) poly->setColor(shapeColour); @@ -434,16 +434,8 @@ void Component2D::setDesignatorIdx(const int& idx) void Component2D::rotate(float degrees) { - m_rotation += degrees; - glm::vec3 rotationPoint = { centre.x, centre.y, 0.f }; - glm::vec3 rotateNormal = {0.f, 0.f, 1.f}; - title->rotate(degrees, rotationPoint, rotateNormal); - designator->rotate(degrees, rotationPoint, rotateNormal); - for (auto poly : m_polygons) poly->rotate(degrees, rotationPoint, rotateNormal); - for (auto line : m_lines) line->rotate(degrees, rotationPoint, rotateNormal); - for (auto circ : m_circles) circ->rotate(degrees, rotationPoint, rotateNormal); - for (auto text : m_text) text->rotate(degrees, rotationPoint, rotateNormal); - for (auto& port : ports) port->rotate(degrees, rotationPoint, rotateNormal); + glm::vec3 rotateNormal = { 0.f, 0.f, 1.f }; + rotate(degrees, rotateNormal); } //=============================================================================================================================================// @@ -457,6 +449,19 @@ PortType Component2D::getPortType(YAML::Node node) else if (node["Type"].as() == "PORT_INOUT") { return PortType::PORT_INOUT; } } +void Component2D::rotate(float degrees, const glm::vec3& rotateNormal) +{ + m_rotation += degrees; + glm::vec3 rotationPoint = { centre.x, centre.y, 0.f }; + title->rotate(degrees, rotationPoint, rotateNormal); + designator->rotate(degrees, rotationPoint, rotateNormal); + for (auto poly : m_polygons) poly->rotate(degrees, rotationPoint, rotateNormal); + for (auto line : m_lines) line->rotate(degrees, rotationPoint, rotateNormal); + for (auto circ : m_circles) circ->rotate(degrees, rotationPoint, rotateNormal); + for (auto text : m_text) text->rotate(degrees, rotationPoint, rotateNormal); + for (auto& port : ports) port->rotate(degrees, rotationPoint, rotateNormal); +} + //=============================================================================================================================================// // EOF. // //=============================================================================================================================================// \ No newline at end of file diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h index 8bfb2bc88..fbce9d085 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h @@ -12,6 +12,7 @@ #include "Graphics/Entities/Entity.h" #include "External/YAML-CPP/Includes/yaml-cpp/yaml.h" #include +#include "Engines/EntityComponents/Mutable.h" //=============================================================================================================================================// // Forward declerations. // @@ -37,7 +38,7 @@ enum class PortType; // Class. // //=============================================================================================================================================// -class Component2D : public Entity +class Component2D : public Entity, public Translatable2D, public Rotatable { public: @@ -110,9 +111,9 @@ class Component2D : public Entity // Deconstructor.s ~Component2D(); //Move the component to a new positioned centred at the given coordinates - void moveTo(const glm::vec2& pointerPos); + void translateTo(const glm::vec2& pointerPos); //Move the component by the given vector - void move(const glm::vec2& translation); + void translate(const glm::vec2& translation); //Place the component. void place(const glm::vec2& pos); //Move the component to a new layer. @@ -155,4 +156,5 @@ class Component2D : public Entity private: PortType getPortType(YAML::Node node); + void rotate(float degrees, const glm::vec3& rotateNormal); }; diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp index d967a03cc..ac09b0ed9 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp @@ -61,7 +61,7 @@ Port::Port(const glm::vec2& centre, PortType type, Component2D* parent, const st labelLocal = "Port " + std::to_string(parent->numPorts++); //else m_label = label; - float textMargin = 0.0015; + float textMargin = 0.0015f; //OLD DEPRECATED CODE //infer the port position from the offset, and set the title /*if (m_offset.y > 0.078) diff --git a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h new file mode 100644 index 000000000..06f0ea8b4 --- /dev/null +++ b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h @@ -0,0 +1,148 @@ +#pragma once +#include "Engines/EntityComponents/Mutable.h" +#include "Graphics/OpenGL/Primitives/Primitive.h" +#include "OpenGL/Renderer/RendererGL.h" +#include +#include + +class Command +{ +public: + inline virtual void execute() = 0; + inline virtual void undo() = 0;//consider making access to this protected (only for use through CommandLog as a Friend class) + +protected: + // We do no want instances of Command. + inline Command() = default; + +private: + // Children will have data here required for the command. + +}; + +class TranslateCommand:public Command { +private: + glm::vec3 translation; + Translatable* target; +public: + inline TranslateCommand(const glm::vec2& translation, Translatable* target) : translation({ translation, 0.f }), target(target) {}; + void execute() { + if (target) + target->translate(translation); + } + void undo() { + target->translate(-translation); + } +}; + +class SetColourCommand:public Command { +private: + glm::vec4 old_colour; + glm::vec4 new_colour; + IPrimitive* target; +public: + inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target):new_colour(new_colour),old_colour(target->m_colour), target(target) {}; + void execute() { + if (target) + target->setColor(new_colour); + } + void undo() { + target->setColor(old_colour); + } +}; + +class RemoveCommand:public Command { +private: + Removable* target; +public: + inline RemoveCommand(Removable* target):target(target) {} + void execute() { + if (target) + target->remove(); + } + void undo() { + target->restore(); + } +}; + +class RemovePrimitveCommand:public Command { +private: + IPrimitive* target; +public: + inline RemovePrimitveCommand(IPrimitive* target):target(target) {} + void execute() { + if (target) + Renderer::remove(target); + } + void undo() { + //add primitive back to renderer. + } +}; + + +class CommandLog +{ +private: + // Probably want to put a max size on this in future. + std::vector> m_commandHistory; + //std::vector>::iterator next_command_it = m_commandHistory.end(); + unsigned next_command_ixd = 0; + +public: + void undo() + { + if (next_command_ixd == 0) return; + + //std::advance(next_command_it, -1); + next_command_ixd--; + m_commandHistory.at(next_command_ixd)->undo(); + + }; + + void redo() + { + if (next_command_ixd == m_commandHistory.size()) return; + + m_commandHistory.at(next_command_ixd)->execute(); + next_command_ixd++; + + }; + template + void log(const Args&... args) + { + if (next_command_ixd == m_commandHistory.size()) { + m_commandHistory.emplace_back(std::make_unique(args...)); + /*if (m_commandHistory.size() == 1) { + next_command_it = m_commandHistory.begin(); + }*/ + } + else m_commandHistory[next_command_ixd] = std::make_unique(args...); + m_commandHistory[next_command_ixd]->execute(); + next_command_ixd++; + }; + /* + template + void log(std::unique_ptr currentCommand) + { + std::advance(next_command_it, 1); + if (next_command_it >= m_commandHistory.end()) { + m_commandHistory.push_back(currentCommand); + } + else m_commandHistory.insert(next_command_it, currentCommand); + + execute(std::prev(next_command_it)->get()); + };*/ + + template + void execute(const Args&... args) + { + //std::unique_ptr currentCommand(std::make_unique(args...); + //command->execute(); + log(args...); + } + + const auto& getHistory() + { + return m_commandHistory; + } +}; diff --git a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h index 2a1479769..0f83a9821 100644 --- a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h +++ b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h @@ -8,6 +8,7 @@ #include #include #include +#include "Engines/CommandSystem/Command.h" //=============================================================================================================================================// // Forward declerations. // @@ -93,6 +94,9 @@ class EngineCore // E V E N T S // // ------------- // + + CommandLog commandLog; + virtual void onEvent(const Event& event); inline virtual void onMouseButtonEvent(const MouseButtonEvent& event) {} inline virtual void onMouseMoveEvent(const MouseMoveEvent& event) {} @@ -108,6 +112,8 @@ class EngineCore inline virtual void onFileDropEvent(const FileDropEvent& event) {} inline virtual void onYamlNodeDropEvent(const YamlNodeDropEvent& event) {} inline virtual void onFileSaveEvent(const FileSaveEvent& event) {} + inline virtual void onUndoEvent(const NotifyEvent& event) { commandLog.undo(); } + inline virtual void onRedoEvent(const NotifyEvent& event) { commandLog.redo(); } // ----------------------- // // C O O R D I N A T E S // diff --git a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp index 76eceff86..93c92fb91 100644 --- a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp @@ -153,6 +153,14 @@ void EngineCore::onKeyEventForce(const KeyEvent& event) onFileSaveEvent(FileSaveEvent()); return; } + if (event.isType(EventType_LeftCtrl | EventType_KeyPress) && event.key == GLFW_KEY_Z) { + onUndoEvent(NotifyEvent(EventType::EventType_Undo)); + return; + } + if (event.isType(EventType_LeftCtrl | EventType_KeyPress) && event.key == GLFW_KEY_Y) { + onRedoEvent(NotifyEvent(EventType::EventType_Redo)); + return; + } onKeyEvent(event); } diff --git a/ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h b/ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h new file mode 100644 index 000000000..9147d547b --- /dev/null +++ b/ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h @@ -0,0 +1,37 @@ +#pragma once +#include "glm/glm.hpp" +class Translatable2D +{ +public: + virtual void translate(const glm::vec2& translation) = 0; + virtual void translateTo(const glm::vec2& position) = 0; +}; + +class Translatable:public Translatable2D +{ +public: + virtual void translate(const glm::vec3& translation) = 0; + virtual void translateTo(const glm::vec3& position) = 0; +}; + +class Rotatable { +public: + //virtual void rotate(float degrees, const glm::vec3& rotatePoint, const glm::vec3& rotateNormal) = 0; + virtual void rotate(float degrees, const glm::vec3& rotateNormal = { 0.f, 0.f, 1.f }) = 0; +}; + +class Transformable { +public: + virtual void transform(const glm::mat4& transform) = 0; +}; + +class Scalable{ +public: + virtual void scale(const glm::vec3& scaleFactor) = 0; +}; + +class Removable {//Are all entities removable? +public: + virtual void remove() = 0; + virtual void restore() = 0; +}; \ No newline at end of file diff --git a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp index 719e5aca4..967a01e82 100644 --- a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp @@ -171,7 +171,7 @@ void ComponentEditor::onImGuiRender() { std::unordered_map& dataDict = activeComponent->dataDict; - const char* buffer[100]; + const char* buffer[100]{}; int numKeys = 0; if (activeComponent) @@ -470,7 +470,7 @@ void ComponentEditor::onImGuiRender() } } - const char* possibleInformation[100]; + const char* possibleInformation[100]{}; int posKeys = 0; @@ -679,7 +679,7 @@ void ComponentEditor::onImGuiRender() if (activeComponent) dataDict = &activeComponent->dataDict; else if (activeCable) dataDict = &activeCable->cableDict; - const char* buffer[100]; + const char* buffer[100]{}; int numKeys = 0; if (activeComponent) diff --git a/ElecDev_Graphics_Application/Source/GUI/RendererStats/RendererStats.cpp b/ElecDev_Graphics_Application/Source/GUI/RendererStats/RendererStats.cpp index ea797a84b..550f58b67 100644 --- a/ElecDev_Graphics_Application/Source/GUI/RendererStats/RendererStats.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/RendererStats/RendererStats.cpp @@ -101,11 +101,11 @@ void RendererStats::onImGuiRender() } else if (name == "Frametime (CPU)") { - fpsCPU = 1.f / (time * 1e-3); + fpsCPU = 1.f / (time * 1e-3f); } else if (name == "Frametime (App)") { - fpsApp = 1.f / (time * 1e-3); + fpsApp = 1.f / (time * 1e-3f); } #ifdef PROFILE_IMGUI_OVERHEAD diff --git a/ElecDev_Graphics_Application/Source/GUI/SettingsWidget/SettingsWidget.cpp b/ElecDev_Graphics_Application/Source/GUI/SettingsWidget/SettingsWidget.cpp index a618a6291..18456a506 100644 --- a/ElecDev_Graphics_Application/Source/GUI/SettingsWidget/SettingsWidget.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/SettingsWidget/SettingsWidget.cpp @@ -67,7 +67,7 @@ void SettingsWidget::onImGuiRender() // Reduce timeout fps if larger than target. if (timeoutFPS > fps) - timeoutFPS == fps; + timeoutFPS = fps; } ImGui::Separator(); diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Grid.cpp b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Grid.cpp index 52ee09ee2..0ef791af0 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Grid.cpp +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Grid.cpp @@ -50,7 +50,7 @@ Grid& Grid::createGrid() float maxVertexCoord = (float)m_totalCoarseLines * (float)m_coarseIncrementSize; int totalCoarseVerts = m_totalCoarseLines * 2 * 4; int totalFineVerts = (int)std::floor(maxVertexCoord / m_fineIncrementSize) * 2 * 8; - float z = -0.99; + float z = -0.99f; // Setup the Buffer's. m_fineBuffer->setCapacityIncrements(totalFineVerts); m_fineBuffer->setCapacityIncrements(totalFineVerts); diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h index ad98789e8..0d320dbdc 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h @@ -18,13 +18,14 @@ for a VAO to be able to render the entity to the screen. #include #include +#include "Engines/EntityComponents/Mutable.h" //=============================================================================================================================================// // Primitive Class. // //=============================================================================================================================================// template -class Primitive: public IPrimitive +class Primitive: public IPrimitive, public Translatable, public Rotatable, public Transformable, public Scalable { protected: @@ -44,7 +45,7 @@ class Primitive: public IPrimitive if (m_onGPU) removeFromGraphicsBuffer(); } - virtual void translate(const glm::vec3& translation) + virtual void translate(const glm::vec3& translation) override { for (int i = 0; i < m_vertexCount; i++) getVertex(i).position += translation; @@ -53,22 +54,22 @@ class Primitive: public IPrimitive syncWithGPU(); } - virtual void translate(const glm::vec2& translation) + virtual void translate(const glm::vec2& translation) override { This::translate(glm::vec3{ translation, 0.f }); } - virtual void translateTo(const glm::vec3& position) + virtual void translateTo(const glm::vec3& position) override { This::translate(position - m_trackedCenter); } - virtual void translateTo(const glm::vec2& position) + virtual void translateTo(const glm::vec2& position) override { This::translateTo(glm::vec3{ position, m_trackedCenter.z }); } - virtual void rotate(float degrees, const glm::vec3& rotatePoint, const glm::vec3& rotateNormal) + virtual void rotate(float degrees, const glm::vec3& rotatePoint, const glm::vec3& rotateNormal) { // Rather call transform if a lot of these are going to be called sequentially. glm::mat4 transform = glm::translate(glm::mat4(1.f), rotatePoint); @@ -81,12 +82,12 @@ class Primitive: public IPrimitive syncWithGPU(); } - virtual void rotate(float degrees, const glm::vec3& rotateNormal = { 0.f, 0.f, 1. }) + virtual void rotate(float degrees, const glm::vec3& rotateNormal = { 0.f, 0.f, 1. }) override { This::rotate(degrees, m_trackedCenter, rotateNormal); } - virtual void transform(const glm::mat4& transform) + virtual void transform(const glm::mat4& transform) override { for (int i = 0; i < m_vertexCount; i++) getVertex(i).position = glm::vec3(transform * glm::vec4(getVertex(i).position, 1.f)); @@ -97,14 +98,14 @@ class Primitive: public IPrimitive syncWithGPU(); } - virtual void scale(const glm::vec3& scaling) + virtual void scale(const glm::vec3& scaling) override { // ... syncWithGPU(); } - virtual void enableOutline(float value = 1.f) + virtual void enableOutline(float value = 1.f) { if (m_outlineEnabled) return; m_outlineEnabled = true; diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Text.cpp b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Text.cpp index 0190c0b77..5c63b391e 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Text.cpp +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Text.cpp @@ -381,7 +381,7 @@ void Text::setLayer(float layer) { // Text box. for (int i = 0; i < 4; i++) - getVertex(i).position.z = layer - 0.001; + getVertex(i).position.z = layer - 0.001f; // Text. for (int i = 4; i < m_vertexCount; i++) From c48138fc0821e65a6275db294220e69423ef2252 Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Thu, 23 Jun 2022 04:42:44 +0200 Subject: [PATCH 03/10] Dragging is undoable --- .../CircuitDesigner/ComponentDesigner.h | 1 + .../ComponentDesigner_Events.cpp | 57 ++++++++++++++++--- .../Peripherals/Component2D.cpp | 2 +- .../CircuitDesigner/Peripherals/Port.cpp | 6 +- .../CircuitDesigner/Peripherals/Port.h | 7 ++- .../Source/Engines/CommandSystem/Command.h | 44 +++++++------- 6 files changed, 80 insertions(+), 37 deletions(-) diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.h index 53d85dc07..17faf941d 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.h @@ -42,6 +42,7 @@ class ComponentDesigner : public Base2DEngine glm::vec4 helperColour = { 0.18f, 0.30f, 0.67f, 0.85f }; //PortType next_port_type = PortType::PORT_INOUT; + glm::vec2 m_dragStart; glm::vec2 m_lastDragPos = { 0.f, 0.f }; unsigned int m_currentEntityID = 0; float clickTol = 15.0f; diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp index 705138413..a73b9e953 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp @@ -179,7 +179,7 @@ void ComponentDesigner::onMouseMoveEvent(const MouseMoveEvent& event) m_activePort->title->updateAlignment("L"); } //update port location - m_activePort->moveTo(getNearestGridVertex(screenCoords)); + m_activePort->translateTo(getNearestGridVertex(screenCoords)); } } @@ -356,7 +356,7 @@ void ComponentDesigner::onMouseDragEvent(const MouseDragEvent& event) } if (m_activePort.get()) { - m_activePort->move(translation); + m_activePort->translate(translation); m_lastDragPos = getNearestGridVertex(screenCoords); } } @@ -366,11 +366,51 @@ void ComponentDesigner::onMouseDragEvent(const MouseDragEvent& event) void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) { - if (event.isType(EventType_MouseDragStop | EventType_MouseButtonLeft)) + if (event.isType(EventType_MouseDragStart | EventType_MouseButtonLeft)) { - if (m_activePoly) m_activePoly->translateTo(getNearestGridVertex(m_activePoly->m_trackedCenter)); - if (m_activeLine) m_activeLine->translateTo(getNearestGridVertex(m_activeLine->m_trackedCenter)); - if (m_activeCircle) m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); + if (m_activePoly) { + m_dragStart = m_activePoly->m_trackedCenter; + } + if (m_activeLine) { + m_dragStart = m_activeLine->m_trackedCenter; + } + if (m_activeCircle) { + m_dragStart = m_activeCircle->m_trackedCenter; + } + if (m_activePort) { + m_dragStart = m_activePort->centre; + } + if (m_activeVertexIdx != -1) { + if (m_activeLine) m_activeLine->m_vertices.at(m_activeVertexIdx); + else if (m_activePoly) + { + PolyLine* polyline = dynamic_cast(m_activePoly); + if (polyline) + { + // Polygon is clear, so we index with m_vertices (nodes). + m_dragStart = polyline->m_vertices.at(m_activeVertexIdx); + } + else + { + m_dragStart = m_activePoly->getVertex(m_activeVertexIdx).position; + } + } + } + } + else if (event.isType(EventType_MouseDragStop | EventType_MouseButtonLeft)) + { + if (m_activePoly) { + m_activePoly->translateTo(getNearestGridVertex(m_activePoly->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activePoly->m_trackedCenter) - m_dragStart, m_activePoly); + } + if (m_activeLine) { + m_activeLine->translateTo(getNearestGridVertex(m_activeLine->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeLine->m_trackedCenter) - m_dragStart, m_activeLine); + } + if (m_activeCircle) { + m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeCircle->m_trackedCenter) - m_dragStart, m_activeCircle); + } if (m_activeVertexIdx != -1) { if (m_activeLine) m_activeLine->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx))); @@ -388,7 +428,10 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) } } } - if (m_activePort) m_activePort->moveTo(getNearestGridVertex(m_activePort->centre)); + if (m_activePort) { + m_activePort->translateTo(getNearestGridVertex(m_activePort->centre)); + commandLog.log(getNearestGridVertex(m_activePort->centre) - m_dragStart, m_activePort.get()); + } } } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp index fec0fc47f..db891495f 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp @@ -214,7 +214,7 @@ void Component2D::translate(const glm::vec2& translation) for (auto line : m_lines) line->translate(translation); for (auto circ : m_circles) circ->translate(translation); for (auto text : m_text) text->translate(translation); - for (auto& port : ports) port->move(translation); + for (auto& port : ports) port->translate(translation); centre += translation; } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp index ac09b0ed9..29bf0ad2b 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp @@ -192,7 +192,7 @@ Port::~Port() Renderer::remove(title); } -void Port::moveTo(const glm::vec2& destination) +void Port::translateTo(const glm::vec2& destination) { //update the port centre title->translate(destination - centre); @@ -207,7 +207,7 @@ void Port::moveTo(const glm::vec2& destination) cable->followPort(this); } -void Port::move(const glm::vec2& translation) +void Port::translate(const glm::vec2& translation) { //update the port centre centre += translation; @@ -251,7 +251,7 @@ void Port::disableOutline() void Port::setOffset(const glm::vec2& offset) { // Move port to new offset (trust the math). - moveTo(centre - m_offset - m_offset + offset); + translateTo(centre - m_offset - m_offset + offset); // Update internal offset. m_offset = offset; } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h index d30aef9ae..3bb114592 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h @@ -10,6 +10,7 @@ #include "yaml-cpp/yaml.h" #include "Graphics/Entities/Entity.h" #include "OpenGL/Buffers/VertexArrayObjectGL.h" +#include "Engines/EntityComponents/Mutable.h" //==============================================================================================================================================// // Forward declerations. // @@ -44,7 +45,7 @@ enum class PortPosition // Port class. // //==============================================================================================================================================// -class Port: public Entity +class Port: public Entity, public Translatable2D { public: @@ -85,8 +86,8 @@ class Port: public Entity Port& operator = (const Port &t); // Helper methods. - void moveTo(const glm::vec2& destination); - void move(const glm::vec2& translation); + void translateTo(const glm::vec2& destination); + void translate(const glm::vec2& translation); void setLayer(float layer); void enableOutline(); void disableOutline(); diff --git a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h index 06f0ea8b4..b448714cf 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h +++ b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h @@ -26,6 +26,22 @@ class TranslateCommand:public Command { Translatable* target; public: inline TranslateCommand(const glm::vec2& translation, Translatable* target) : translation({ translation, 0.f }), target(target) {}; + inline TranslateCommand(const glm::vec3& translation, Translatable* target) : translation(translation), target(target) {}; + void execute() { + if (target) + target->translate(translation); + } + void undo() { + target->translate(-translation); + } +}; + +class Translate2DCommand :public Command { +private: + glm::vec2 translation; + Translatable2D* target; +public: + inline Translate2DCommand(const glm::vec2& translation, Translatable2D* target) : translation(translation), target(target) {}; void execute() { if (target) target->translate(translation); @@ -85,7 +101,6 @@ class CommandLog private: // Probably want to put a max size on this in future. std::vector> m_commandHistory; - //std::vector>::iterator next_command_it = m_commandHistory.end(); unsigned next_command_ixd = 0; public: @@ -93,7 +108,6 @@ class CommandLog { if (next_command_ixd == 0) return; - //std::advance(next_command_it, -1); next_command_ixd--; m_commandHistory.at(next_command_ixd)->undo(); @@ -110,35 +124,19 @@ class CommandLog template void log(const Args&... args) { - if (next_command_ixd == m_commandHistory.size()) { - m_commandHistory.emplace_back(std::make_unique(args...)); - /*if (m_commandHistory.size() == 1) { - next_command_it = m_commandHistory.begin(); - }*/ + if (next_command_ixd != m_commandHistory.size()) { + //subsequent entries become invalid at this point + m_commandHistory.resize(next_command_ixd); } - else m_commandHistory[next_command_ixd] = std::make_unique(args...); - m_commandHistory[next_command_ixd]->execute(); + m_commandHistory.emplace_back(std::make_unique(args...)); next_command_ixd++; }; - /* - template - void log(std::unique_ptr currentCommand) - { - std::advance(next_command_it, 1); - if (next_command_it >= m_commandHistory.end()) { - m_commandHistory.push_back(currentCommand); - } - else m_commandHistory.insert(next_command_it, currentCommand); - - execute(std::prev(next_command_it)->get()); - };*/ template void execute(const Args&... args) { - //std::unique_ptr currentCommand(std::make_unique(args...); - //command->execute(); log(args...); + m_commandHistory[next_command_ixd-1]->execute(); } const auto& getHistory() From cf16a6e448f2aaefef59d8ab9eaeb7c515f1745a Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Thu, 23 Jun 2022 16:20:47 +0200 Subject: [PATCH 04/10] Colour editor improvements --- .../ComponentDesigner_Events.cpp | 7 ++++++ .../GUI/ComponentDesignerColorEditor.cpp | 22 ++++++++++++++++--- .../GUI/ComponentDesignerColorEditor.h | 1 + .../Source/Engines/CommandSystem/Command.h | 7 +++++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp index a73b9e953..d69d9ae3d 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp @@ -377,6 +377,9 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) if (m_activeCircle) { m_dragStart = m_activeCircle->m_trackedCenter; } + if (m_activeText) { + m_dragStart = m_activeText->m_trackedCenter; + } if (m_activePort) { m_dragStart = m_activePort->centre; } @@ -411,6 +414,10 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); commandLog.log(getNearestGridVertex(m_activeCircle->m_trackedCenter) - m_dragStart, m_activeCircle); } + if (m_activeText) { + m_activeText->translateTo(getNearestGridVertex(m_activeText->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeText->m_trackedCenter) - m_dragStart, m_activeText); + } if (m_activeVertexIdx != -1) { if (m_activeLine) m_activeLine->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx))); diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp index b3318f1e7..e7ccce316 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.cpp @@ -82,12 +82,13 @@ void ComponentDesignerColorEditor::onImGuiRender() } } lastActivePrimitive = activePrimitive; + oldColor = color; } // Open color editor. ImGui::SameLine(); - if (ImGui::ColorPicker4("##ColorEditor", &color.r, ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf)) + if (ImGui::ColorPicker4("##ColorEditor", &color.r, ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf, &oldColor.r)) { //No longer supported. To remove. @@ -102,15 +103,30 @@ void ComponentDesignerColorEditor::onImGuiRender() activePort->body->setColor(*color); }*/ + if(!activePrimitive) *m_target = color; } - if (ImGui::Button("Apply")) { + + if (ImGui::IsMouseDown(ImGuiMouseButton_::ImGuiMouseButton_Left)) { + + } + else { if (activePrimitive) { - engine->commandLog.execute(color, activePrimitive); + if (oldColor != color) + engine->commandLog.execute(color, activePrimitive, oldColor); //activePrimitive->setColor(*color); } + oldColor = color; } + /*if (ImGui::IsMouseReleased(ImGuiMouseButton_::ImGuiMouseButton_Left)) { + if (activePrimitive) + { + if(oldColor != color) + engine->commandLog.execute(color, activePrimitive, oldColor); + //activePrimitive->setColor(*color); + } + }*/ } void ComponentDesignerColorEditor::onImGuiEnd() diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h index 1ebff24fd..fc24eb3b4 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/GUI/ComponentDesignerColorEditor.h @@ -50,6 +50,7 @@ class ComponentDesignerColorEditor : public LumenWindow glm::vec4* const m_target; IPrimitive* lastActivePrimitive; glm::vec4 color; + glm::vec4 oldColor; }; //==============================================================================================================================================// diff --git a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h index b448714cf..d52e634e8 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h +++ b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h @@ -4,6 +4,7 @@ #include "OpenGL/Renderer/RendererGL.h" #include #include +#include "Utilities/Logger/Logger.h" class Command { @@ -30,9 +31,12 @@ class TranslateCommand:public Command { void execute() { if (target) target->translate(translation); + else LUMEN_LOG_WARN("Tried to execute a translation on an invlaid target.", "Command"); } void undo() { + if (target) target->translate(-translation); + else LUMEN_LOG_WARN("Tried to undo a translation on an invlaid target.", "Command"); } }; @@ -57,7 +61,8 @@ class SetColourCommand:public Command { glm::vec4 new_colour; IPrimitive* target; public: - inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target):new_colour(new_colour),old_colour(target->m_colour), target(target) {}; + inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target) :new_colour(new_colour), old_colour(target->m_colour), target(target) {}; + inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target, const glm::vec4& old_colour) :new_colour(new_colour), old_colour(old_colour), target(target) {}; void execute() { if (target) target->setColor(new_colour); From e836ce13ce4f8c6e01b4a3d8d56166c26aee878a Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Fri, 24 Jun 2022 20:50:17 +0200 Subject: [PATCH 05/10] Add vertex translations to command system --- .../CircuitDesigner/ComponentDesigner.cpp | 1 + .../ComponentDesigner_Events.cpp | 51 ++-- .../Source/Engines/CommandSystem/Command.h | 225 +++++++++++++++--- .../Source/Engines/EntityComponents/Mutable.h | 6 + .../OpenGL/Primitives/LineSegment.cpp | 4 +- .../Graphics/OpenGL/Primitives/LineSegment.h | 4 +- .../Graphics/OpenGL/Primitives/PolyLine.cpp | 8 +- .../Graphics/OpenGL/Primitives/PolyLine.h | 8 +- .../Graphics/OpenGL/Primitives/Polygon.cpp | 8 +- .../Graphics/OpenGL/Primitives/Polygon.h | 8 +- .../Graphics/OpenGL/Primitives/Primitive.h | 12 +- 11 files changed, 259 insertions(+), 76 deletions(-) diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp index 1f5a99845..5b8ea1f3a 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp @@ -101,6 +101,7 @@ void ComponentDesigner::switchState(CompDesignState state) m_activePoly = nullptr; m_activeCircle = nullptr; m_activePort = nullptr; + m_activeVertexIdx = -1; designerState = CompDesignState::SELECT; break; } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp index d69d9ae3d..0202e81e8 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp @@ -402,25 +402,34 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) } else if (event.isType(EventType_MouseDragStop | EventType_MouseButtonLeft)) { - if (m_activePoly) { - m_activePoly->translateTo(getNearestGridVertex(m_activePoly->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activePoly->m_trackedCenter) - m_dragStart, m_activePoly); - } - if (m_activeLine) { - m_activeLine->translateTo(getNearestGridVertex(m_activeLine->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeLine->m_trackedCenter) - m_dragStart, m_activeLine); - } - if (m_activeCircle) { - m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeCircle->m_trackedCenter) - m_dragStart, m_activeCircle); - } - if (m_activeText) { - m_activeText->translateTo(getNearestGridVertex(m_activeText->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeText->m_trackedCenter) - m_dragStart, m_activeText); + + if (m_activeVertexIdx == -1) {//move primitives + if (m_activePoly) { + m_activePoly->translateTo(getNearestGridVertex(m_activePoly->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activePoly->m_trackedCenter) - m_dragStart, m_activePoly); + } + if (m_activeLine) { + m_activeLine->translateTo(getNearestGridVertex(m_activeLine->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeLine->m_trackedCenter) - m_dragStart, m_activeLine); + } + if (m_activeCircle) { + m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeCircle->m_trackedCenter) - m_dragStart, m_activeCircle); + } + if (m_activeText) { + m_activeText->translateTo(getNearestGridVertex(m_activeText->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeText->m_trackedCenter) - m_dragStart, m_activeText); + } + if (m_activePort) { + m_activePort->translateTo(getNearestGridVertex(m_activePort->centre)); + commandLog.log(getNearestGridVertex(m_activePort->centre) - m_dragStart, m_activePort.get()); + } } - if (m_activeVertexIdx != -1) - { - if (m_activeLine) m_activeLine->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx))); + else{//move vertices + if (m_activeLine) { + m_activeLine->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx))); + commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx)) - m_dragStart, m_activeLine); + } else if (m_activePoly) { PolyLine* polyline = dynamic_cast(m_activePoly); @@ -428,17 +437,15 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) { // Polygon is clear, so we index with m_vertices (nodes). polyline->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx))); + commandLog.log(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx)) - m_dragStart, polyline); } else { m_activePoly->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position)); + commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position) - m_dragStart, m_activePoly); } } } - if (m_activePort) { - m_activePort->translateTo(getNearestGridVertex(m_activePort->centre)); - commandLog.log(getNearestGridVertex(m_activePort->centre) - m_dragStart, m_activePort.get()); - } } } diff --git a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h index d52e634e8..1e2bfeb42 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h +++ b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h @@ -5,10 +5,29 @@ #include #include #include "Utilities/Logger/Logger.h" +#include "Application/Application.h" +#include "Lumen/Lumen.h" +#include "Engines\EngineCore\EngineCore.h" + +//typedef uint64_t LumenCommandID; +enum class CommandType +{ + CommandType_None,//This should never be seen in practice + CommandType_Translate, + CommandType_Translate2D, + CommandType_SetColour, + CommandType_Remove, + CommandType_RemovePrimitive, + CommandType_ChangeValue, + CommandType_TranslateVertex +}; + + class Command { public: + CommandType commandType = CommandType::CommandType_None; inline virtual void execute() = 0; inline virtual void undo() = 0;//consider making access to this protected (only for use through CommandLog as a Friend class) @@ -23,83 +42,178 @@ class Command class TranslateCommand:public Command { private: - glm::vec3 translation; - Translatable* target; + const glm::vec3 translation; + Translatable* const target; public: - inline TranslateCommand(const glm::vec2& translation, Translatable* target) : translation({ translation, 0.f }), target(target) {}; - inline TranslateCommand(const glm::vec3& translation, Translatable* target) : translation(translation), target(target) {}; + inline TranslateCommand(const glm::vec2& translation, Translatable* target) : translation({ translation, 0.f }), target(target) { commandType = CommandType::CommandType_Translate; }; + inline TranslateCommand(const glm::vec3& translation, Translatable* target) : translation(translation), target(target) { commandType = CommandType::CommandType_Translate; }; void execute() { - if (target) + try { target->translate(translation); - else LUMEN_LOG_WARN("Tried to execute a translation on an invlaid target.", "Command"); + } + catch (...) { + LUMEN_LOG_WARN("Tried to execute a translation on an invlaid target.", "Command"); + } } void undo() { - if (target) - target->translate(-translation); - else LUMEN_LOG_WARN("Tried to undo a translation on an invlaid target.", "Command"); + try { + target->translate(-translation); + } + catch (...) { + LUMEN_LOG_WARN("Tried to undo a translation on an invlaid target.", "Command"); + } } }; class Translate2DCommand :public Command { private: - glm::vec2 translation; - Translatable2D* target; + const glm::vec2 translation; + Translatable2D* const target; public: - inline Translate2DCommand(const glm::vec2& translation, Translatable2D* target) : translation(translation), target(target) {}; + inline Translate2DCommand(const glm::vec2& translation, Translatable2D* target) : translation(translation), target(target) { commandType = CommandType::CommandType_Translate2D; }; void execute() { - if (target) + try { target->translate(translation); + } + catch (...) { + LUMEN_LOG_WARN("Tried to execute a translation on an invlaid target.", "Command"); + } } void undo() { - target->translate(-translation); + try { + target->translate(-translation); + } + catch (...) { + LUMEN_LOG_WARN("Tried to undo a translation on an invlaid target.", "Command"); + } + } +}; + + +class TranslateVertexCommand :public Command { +private: + const glm::vec2 translation; + const unsigned index; + Reshapable* const target; +public: + inline TranslateVertexCommand(const unsigned& localIndex, const glm::vec2& translation, Reshapable* target) : index(localIndex), translation(translation), target(target) { commandType = CommandType::CommandType_TranslateVertex; }; + void execute() { + try { + target->translateVertexAtIndex(index, translation); + } + catch (...) { + LUMEN_LOG_WARN("Tried to execute a vertex translation on an invlaid target.", "Command"); + } + } + void undo() { + try { + target->translateVertexAtIndex(index, -translation); + } + catch (...) { + LUMEN_LOG_WARN("Tried to undo a vertex translation on an invlaid target.", "Command"); + } } }; class SetColourCommand:public Command { private: - glm::vec4 old_colour; - glm::vec4 new_colour; - IPrimitive* target; + const glm::vec4 old_colour; + const glm::vec4 new_colour; + IPrimitive* const target; public: - inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target) :new_colour(new_colour), old_colour(target->m_colour), target(target) {}; - inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target, const glm::vec4& old_colour) :new_colour(new_colour), old_colour(old_colour), target(target) {}; + inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target) :new_colour(new_colour), old_colour(target->m_colour), target(target) { commandType = CommandType::CommandType_SetColour; }; + inline SetColourCommand(const glm::vec4& new_colour, IPrimitive* target, const glm::vec4& old_colour) :new_colour(new_colour), old_colour(old_colour), target(target) { commandType = CommandType::CommandType_SetColour; }; void execute() { - if (target) + try { target->setColor(new_colour); + } + catch (...) { + LUMEN_LOG_WARN("Tried to execute a colour change on an invlaid target.", "Command"); + } + } void undo() { - target->setColor(old_colour); + try { + target->setColor(old_colour); + } + catch (...) { + LUMEN_LOG_WARN("Tried to undo a colour change on an invlaid target.", "Command"); + } } }; class RemoveCommand:public Command { private: - Removable* target; + Removable* const target; public: - inline RemoveCommand(Removable* target):target(target) {} + inline RemoveCommand(Removable* target):target(target) { commandType = CommandType::CommandType_Remove; } void execute() { - if (target) + try { target->remove(); + } + catch (...) { + LUMEN_LOG_WARN("Tried to remove an invlaid target.", "Command"); + } } void undo() { - target->restore(); + try { + target->restore(); + } + catch (...) { + LUMEN_LOG_WARN("Tried to restore an invlaid target.", "Command"); + } } }; class RemovePrimitveCommand:public Command { private: - IPrimitive* target; + IPrimitive* const target; public: - inline RemovePrimitveCommand(IPrimitive* target):target(target) {} + inline RemovePrimitveCommand(IPrimitive* target):target(target) { commandType = CommandType::CommandType_RemovePrimitive; } void execute() { - if (target) + try { Renderer::remove(target); + } + catch (...) { + LUMEN_LOG_WARN("Tried to remove an invlaid primitive.", "Command"); + } } void undo() { //add primitive back to renderer. + try { + + } + catch (...) { + LUMEN_LOG_WARN("Tried to remove an invlaid primitive.", "Command"); + } } }; +template +class ChangeValueCommand: Command{ +private: + const T oldVal; + const T newVal; + T* const target; +public: + inline ChangeValueCommand(const T& newValue, T* target) : oldVal(*target), newVal(newValue), target(target) { commandType = CommandType::CommandType_ChangeValue; }; + inline void execute() { + try { + *target = newVal; + } + catch (...) { + LUMEN_LOG_WARN("Tried to change the value of an invlaid target.", "Command"); + } + } + inline void undo() { + try { + *target = oldVal; + } + catch (...) { + LUMEN_LOG_WARN("Tried to change the value of an invlaid target.", "Command"); + } + } +}; class CommandLog { @@ -107,6 +221,7 @@ class CommandLog // Probably want to put a max size on this in future. std::vector> m_commandHistory; unsigned next_command_ixd = 0; + EngineCore* parent;//Primarily used to notify the engine when a command is logged public: void undo() @@ -115,6 +230,33 @@ class CommandLog next_command_ixd--; m_commandHistory.at(next_command_ixd)->undo(); + + switch (m_commandHistory.at(next_command_ixd)->commandType) { + case CommandType::CommandType_Remove: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo delete"); + break; + case CommandType::CommandType_RemovePrimitive: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo delete"); + break; + case CommandType::CommandType_SetColour: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo colour change"); + break; + case CommandType::CommandType_Translate: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo translation"); + break; + case CommandType::CommandType_Translate2D: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo translation"); + break; + case CommandType::CommandType_ChangeValue: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo edit"); + break; + case CommandType::CommandType_TranslateVertex: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo edit"); + break; + default: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo action"); + break; + } }; @@ -125,6 +267,30 @@ class CommandLog m_commandHistory.at(next_command_ixd)->execute(); next_command_ixd++; + switch (m_commandHistory.at(next_command_ixd)->commandType) { + case CommandType::CommandType_Remove: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo delete"); + break; + case CommandType::CommandType_RemovePrimitive: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo delete"); + break; + case CommandType::CommandType_SetColour: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo colour change"); + break; + case CommandType::CommandType_Translate: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo translation"); + break; + case CommandType::CommandType_Translate2D: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo translation"); + break; + case CommandType::CommandType_ChangeValue: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo edit"); + break; + default: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo action"); + break; + } + }; template void log(const Args&... args) @@ -135,6 +301,9 @@ class CommandLog } m_commandHistory.emplace_back(std::make_unique(args...)); next_command_ixd++; + + //Notify engine of change + parent->unsavedDocument(); }; template diff --git a/ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h b/ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h index 9147d547b..ec0e90e03 100644 --- a/ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h +++ b/ElecDev_Graphics_Application/Source/Engines/EntityComponents/Mutable.h @@ -34,4 +34,10 @@ class Removable {//Are all entities removable? public: virtual void remove() = 0; virtual void restore() = 0; +}; + +class Reshapable { +public: + virtual void translateVertexAtIndex(const unsigned& localIndex, const glm::vec2& translation) = 0; + virtual void translateVertexAtIndexTo(const unsigned& localIndex, const glm::vec2& position) = 0; }; \ No newline at end of file diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.cpp b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.cpp index 6775e1bdd..c9a42040e 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.cpp +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.cpp @@ -90,7 +90,7 @@ void LineSegment::translateVertex(VertexData* vertex, const glm::vec2 translatio } } -void LineSegment::translateVertexAtIndex(unsigned index, const glm::vec2& translation) +void LineSegment::translateVertexAtIndex(const unsigned& index, const glm::vec2& translation) { // Check if we should move the end or the start of the line. if (glm::length(glm::vec2(getVertex(index).position) - m_end) < @@ -106,7 +106,7 @@ void LineSegment::translateVertexAtIndex(unsigned index, const glm::vec2& transl } } -void LineSegment::translateVertexAtIndexTo(unsigned index, const glm::vec2& position) +void LineSegment::translateVertexAtIndexTo(const unsigned& index, const glm::vec2& position) { // Check if we should move the end or the start of the line. if (glm::length(glm::vec2(getVertex(index).position) - m_end) < diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.h b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.h index dd9401e34..056cdbade 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.h +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/LineSegment.h @@ -42,8 +42,8 @@ class LineSegment : protected boost::base_from_member< glm::vec2, 1>, void translateVertexTo(VertexData* vertex, const glm::vec2 position) override; void translateVertex(VertexData* vertex, const glm::vec2 translation) override; - void translateVertexAtIndexTo(unsigned index, const glm::vec2& position) override; - void translateVertexAtIndex(unsigned index, const glm::vec2& translation) override; + void translateVertexAtIndexTo(const unsigned& index, const glm::vec2& position) override; + void translateVertexAtIndex(const unsigned& index, const glm::vec2& translation) override; }; //==============================================================================================================================================// diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.cpp b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.cpp index 792036edb..9b67f2a94 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.cpp +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.cpp @@ -91,23 +91,23 @@ void PolyLine::pushVertex(const glm::vec2& vertex) update(); } -void PolyLine::translateVertexAtIndex(unsigned index, const glm::vec3& translation) +void PolyLine::translateVertexAtIndex(const unsigned& index, const glm::vec3& translation) { translateVertexAtIndex(index, glm::vec2{ translation }); } -void PolyLine::translateVertexAtIndex(unsigned index, const glm::vec2& translation) +void PolyLine::translateVertexAtIndex(const unsigned& index, const glm::vec2& translation) { m_vertices.at(index) += translation; update(); } -void PolyLine::translateVertexAtIndexTo(unsigned index, const glm::vec3& position) +void PolyLine::translateVertexAtIndexTo(const unsigned& index, const glm::vec3& position) { translateVertexAtIndexTo(index, glm::vec2{ position }); } -void PolyLine::translateVertexAtIndexTo(unsigned index, const glm::vec2& position) +void PolyLine::translateVertexAtIndexTo(const unsigned& index, const glm::vec2& position) { glm::vec2 translation = position - m_vertices.at(index); translateVertexAtIndex(index, translation); diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.h b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.h index 4c5ed48ef..98eea50d1 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.h +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/PolyLine.h @@ -25,11 +25,11 @@ class PolyLine : public Polygon2D //Calculates the offset and runs the triangulation function virtual void pushVertex(const glm::vec3& vertex) override; virtual void pushVertex(const glm::vec2& vertex); - virtual void translateVertexAtIndex(unsigned index, const glm::vec3& translation) override; - virtual void translateVertexAtIndex(unsigned index, const glm::vec2& translation) override; + virtual void translateVertexAtIndex(const unsigned& index, const glm::vec3& translation) override; + virtual void translateVertexAtIndex(const unsigned& index, const glm::vec2& translation) override; // Translate to. - virtual void translateVertexAtIndexTo(unsigned index, const glm::vec3& position) override; - virtual void translateVertexAtIndexTo(unsigned index, const glm::vec2& position) override; + virtual void translateVertexAtIndexTo(const unsigned& index, const glm::vec3& position) override; + virtual void translateVertexAtIndexTo(const unsigned& index, const glm::vec2& position) override; // Move a vertex virtual void translateVertexTo(VertexData* vertex, const glm::vec3 position) override; // Move a vertex diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.cpp b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.cpp index 11dd60330..5b1e13936 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.cpp +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.cpp @@ -101,19 +101,19 @@ void Polygon2D::pushVertex(const glm::vec3& vertex) }*/ } -void Polygon2D::translateVertexAtIndex(unsigned index, const glm::vec3& translation) +void Polygon2D::translateVertexAtIndex(const unsigned& index, const glm::vec3& translation) { getVertex(index).position += translation; updateIndices(); syncWithGPU(); } -void Polygon2D::translateVertexAtIndex(unsigned index, const glm::vec2& translation) +void Polygon2D::translateVertexAtIndex(const unsigned& index, const glm::vec2& translation) { translateVertexAtIndex(index, { translation.x, translation.y, 0.f }); } -void Polygon2D::translateVertexAtIndexTo(unsigned index, const glm::vec3& position) +void Polygon2D::translateVertexAtIndexTo(const unsigned& index, const glm::vec3& position) { glm::vec3* currentPosition = &getVertex(index).position; *currentPosition += (position - *currentPosition); @@ -121,7 +121,7 @@ void Polygon2D::translateVertexAtIndexTo(unsigned index, const glm::vec3& positi syncWithGPU(); } -void Polygon2D::translateVertexAtIndexTo(unsigned index, const glm::vec2& position) +void Polygon2D::translateVertexAtIndexTo(const unsigned& index, const glm::vec2& position) { translateVertexAtIndexTo(index, { position.x, position.y, 0.f }); } diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.h b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.h index af8d7ba29..e1dd0418f 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.h +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Polygon.h @@ -31,11 +31,11 @@ class Polygon2D : public Primitive> // Adds a new vertex and handles the required manipulation of data. virtual void pushVertex(const glm::vec3& vertex); - virtual void translateVertexAtIndex(unsigned index, const glm::vec3& translation) override; - virtual void translateVertexAtIndex(unsigned index, const glm::vec2& translation) override; + virtual void translateVertexAtIndex(const unsigned& index, const glm::vec3& translation) override; + virtual void translateVertexAtIndex(const unsigned& index, const glm::vec2& translation) override; // Translate to. - virtual void translateVertexAtIndexTo(unsigned index, const glm::vec3& position) override; - virtual void translateVertexAtIndexTo(unsigned index, const glm::vec2& position) override; + virtual void translateVertexAtIndexTo(const unsigned& index, const glm::vec3& position) override; + virtual void translateVertexAtIndexTo(const unsigned& index, const glm::vec2& position) override; virtual void updateIndices(); // Move a vertex virtual void translateVertexTo(VertexData* vertex, const glm::vec3 position) override; diff --git a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h index 0d320dbdc..d0b0577df 100644 --- a/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h +++ b/ElecDev_Graphics_Application/Source/Graphics/OpenGL/Primitives/Primitive.h @@ -25,7 +25,7 @@ for a VAO to be able to render the entity to the screen. //=============================================================================================================================================// template -class Primitive: public IPrimitive, public Translatable, public Rotatable, public Transformable, public Scalable +class Primitive: public IPrimitive, public Translatable, public Rotatable, public Transformable, public Scalable, public Reshapable { protected: @@ -162,27 +162,27 @@ class Primitive: public IPrimitive, public Translatable, public Rotatable, publi This::translateVertex(vertex, glm::vec3{ translation, 0.f }); } - inline virtual void translateVertexAtIndex(unsigned index, const glm::vec3& translation) + inline virtual void translateVertexAtIndex(const unsigned& const index, const glm::vec3& translation) { This::translateVertex(&getVertex(index), translation); } - inline virtual void translateVertexAtIndex(unsigned index, const glm::vec2& translation) + inline virtual void translateVertexAtIndex(const unsigned& index, const glm::vec2& translation) { This::translateVertexAtIndex(index, glm::vec3{ translation, 0.f }); } - inline virtual void translateVertexAtIndexTo(unsigned index, const glm::vec3& position) + inline virtual void translateVertexAtIndexTo(const unsigned& index, const glm::vec3& position) { This::translateVertexTo(&getVertex(index), position); } - inline virtual void translateVertexAtIndexTo(unsigned index, const glm::vec2& position) + inline virtual void translateVertexAtIndexTo(const unsigned& index, const glm::vec2& position) { This::translateVertexAtIndexTo(index, glm::vec3{ position, 0.f }); } - inline virtual void setVertexAtIndexColor(unsigned index, const glm::vec4& color) + inline virtual void setVertexAtIndexColor(const unsigned& index, const glm::vec4& color) { getVertex(index).color = color; syncWithGPU(); From c23937e1b03f0913ac80b6b8b52b90a041c8f385 Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Fri, 24 Jun 2022 21:50:31 +0200 Subject: [PATCH 06/10] Engines are notified of commands Engines are now marked as 'unsaved' when a command is logged/undone/redone --- .../ElecDev_Graphics_Application.vcxproj | 1 + ...ecDev_Graphics_Application.vcxproj.filters | 1 + .../ComponentDesigner_Events.cpp | 221 +++++++++--------- .../Source/Engines/CommandSystem/Command.h | 79 +------ .../Engines/CommandSystem/CommandLog.cpp | 77 ++++++ .../Source/Engines/EngineCore/EngineCore.h | 2 +- 6 files changed, 200 insertions(+), 181 deletions(-) create mode 100644 ElecDev_Graphics_Application/Source/Engines/CommandSystem/CommandLog.cpp diff --git a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj index 6f6aed843..34f950071 100644 --- a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj +++ b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj @@ -199,6 +199,7 @@ + diff --git a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters index c85e64e1b..2fac49e5e 100644 --- a/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters +++ b/ElecDev_Graphics_Application/ElecDev_Graphics_Application.vcxproj.filters @@ -148,6 +148,7 @@ + diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp index 0202e81e8..19a5a2f63 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp @@ -307,57 +307,58 @@ void ComponentDesigner::onKeyEvent(const KeyEvent& event) void ComponentDesigner::onMouseDragEvent(const MouseDragEvent& event) { Base2DEngine::onMouseDragEvent(event); - - if (event.isType(EventType_MouseButtonLeft) && event.isNotType(EventType_MouseButtonLeft | EventType_SpaceBar)) - { - glm::vec2 pixelCoords = event.mousePosition; - glm::vec3 WorldCoords = pixelToWorldCoords(pixelCoords); - glm::vec2 screenCoords = { WorldCoords.x, WorldCoords.y }; - if (designerState == CompDesignState::SELECT) + if (designerState == CompDesignState::SELECT) { + if (event.isType(EventType_MouseButtonLeft) && event.isNotType(EventType_MouseButtonLeft | EventType_SpaceBar)) { - // User is dragging a component. - glm::vec2 translation = pixelToWorldDistance(event.currentFrameDelta); - if (m_activeVertexIdx != -1) - { - // First check if we should move a vertex - // We need to move a vertex - if (m_activePoly) - { - m_activePoly->translateVertexAtIndex(m_activeVertexIdx, translation); - } - else if (m_activeLine) - { - m_activeLine->translateVertexAtIndex(m_activeVertexIdx, translation); - } - } - else + glm::vec2 pixelCoords = event.mousePosition; + glm::vec3 WorldCoords = pixelToWorldCoords(pixelCoords); + glm::vec2 screenCoords = { WorldCoords.x, WorldCoords.y }; + if (designerState == CompDesignState::SELECT) { - // If we are not moving a vertex, then check to move primitives - if (m_activePoly) + // User is dragging a component. + glm::vec2 translation = pixelToWorldDistance(event.currentFrameDelta); + if (m_activeVertexIdx != -1) { - m_activePoly->translate(translation); - m_lastDragPos = screenCoords; + // First check if we should move a vertex + // We need to move a vertex + if (m_activePoly) + { + m_activePoly->translateVertexAtIndex(m_activeVertexIdx, translation); + } + else if (m_activeLine) + { + m_activeLine->translateVertexAtIndex(m_activeVertexIdx, translation); + } } - if (m_activeLine) - { - m_activeLine->translate(translation); - m_lastDragPos = getNearestGridVertex(screenCoords); - } - if (m_activeCircle) - { - m_activeCircle->translate(translation); - m_lastDragPos = getNearestGridVertex(screenCoords); - } - if (m_activeText) - { - // Consideration: Should we keep track of the text position in the parent port/component? If so, this should be updated here. - m_activeText->translate(translation); - m_lastDragPos = getNearestGridVertex(screenCoords); - } - if (m_activePort.get()) + else { - m_activePort->translate(translation); - m_lastDragPos = getNearestGridVertex(screenCoords); + // If we are not moving a vertex, then check to move primitives + if (m_activePoly) + { + m_activePoly->translate(translation); + m_lastDragPos = screenCoords; + } + if (m_activeLine) + { + m_activeLine->translate(translation); + m_lastDragPos = getNearestGridVertex(screenCoords); + } + if (m_activeCircle) + { + m_activeCircle->translate(translation); + m_lastDragPos = getNearestGridVertex(screenCoords); + } + if (m_activeText) + { + // Consideration: Should we keep track of the text position in the parent port/component? If so, this should be updated here. + m_activeText->translate(translation); + m_lastDragPos = getNearestGridVertex(screenCoords); + } + if (m_activePort.get()) + { + m_activePort->translate(translation); + m_lastDragPos = getNearestGridVertex(screenCoords); + } } } } @@ -366,83 +367,85 @@ void ComponentDesigner::onMouseDragEvent(const MouseDragEvent& event) void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) { - if (event.isType(EventType_MouseDragStart | EventType_MouseButtonLeft)) - { - if (m_activePoly) { - m_dragStart = m_activePoly->m_trackedCenter; - } - if (m_activeLine) { - m_dragStart = m_activeLine->m_trackedCenter; - } - if (m_activeCircle) { - m_dragStart = m_activeCircle->m_trackedCenter; - } - if (m_activeText) { - m_dragStart = m_activeText->m_trackedCenter; - } - if (m_activePort) { - m_dragStart = m_activePort->centre; - } - if (m_activeVertexIdx != -1) { - if (m_activeLine) m_activeLine->m_vertices.at(m_activeVertexIdx); - else if (m_activePoly) - { - PolyLine* polyline = dynamic_cast(m_activePoly); - if (polyline) - { - // Polygon is clear, so we index with m_vertices (nodes). - m_dragStart = polyline->m_vertices.at(m_activeVertexIdx); - } - else - { - m_dragStart = m_activePoly->getVertex(m_activeVertexIdx).position; - } - } - } - } - else if (event.isType(EventType_MouseDragStop | EventType_MouseButtonLeft)) - { - - if (m_activeVertexIdx == -1) {//move primitives + if (designerState == CompDesignState::SELECT) { + if (event.isType(EventType_MouseDragStart | EventType_MouseButtonLeft)) + { if (m_activePoly) { - m_activePoly->translateTo(getNearestGridVertex(m_activePoly->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activePoly->m_trackedCenter) - m_dragStart, m_activePoly); + m_dragStart = m_activePoly->m_trackedCenter; } if (m_activeLine) { - m_activeLine->translateTo(getNearestGridVertex(m_activeLine->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeLine->m_trackedCenter) - m_dragStart, m_activeLine); + m_dragStart = m_activeLine->m_trackedCenter; } if (m_activeCircle) { - m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeCircle->m_trackedCenter) - m_dragStart, m_activeCircle); + m_dragStart = m_activeCircle->m_trackedCenter; } if (m_activeText) { - m_activeText->translateTo(getNearestGridVertex(m_activeText->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeText->m_trackedCenter) - m_dragStart, m_activeText); + m_dragStart = m_activeText->m_trackedCenter; } if (m_activePort) { - m_activePort->translateTo(getNearestGridVertex(m_activePort->centre)); - commandLog.log(getNearestGridVertex(m_activePort->centre) - m_dragStart, m_activePort.get()); + m_dragStart = m_activePort->centre; + } + if (m_activeVertexIdx != -1) { + if (m_activeLine) m_activeLine->m_vertices.at(m_activeVertexIdx); + else if (m_activePoly) + { + PolyLine* polyline = dynamic_cast(m_activePoly); + if (polyline) + { + // Polygon is clear, so we index with m_vertices (nodes). + m_dragStart = polyline->m_vertices.at(m_activeVertexIdx); + } + else + { + m_dragStart = m_activePoly->getVertex(m_activeVertexIdx).position; + } + } } } - else{//move vertices - if (m_activeLine) { - m_activeLine->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx))); - commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx)) - m_dragStart, m_activeLine); + else if (event.isType(EventType_MouseDragStop | EventType_MouseButtonLeft)) + { + + if (m_activeVertexIdx == -1) {//move primitives + if (m_activePoly) { + m_activePoly->translateTo(getNearestGridVertex(m_activePoly->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activePoly->m_trackedCenter) - m_dragStart, m_activePoly); + } + if (m_activeLine) { + m_activeLine->translateTo(getNearestGridVertex(m_activeLine->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeLine->m_trackedCenter) - m_dragStart, m_activeLine); + } + if (m_activeCircle) { + m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeCircle->m_trackedCenter) - m_dragStart, m_activeCircle); + } + if (m_activeText) { + m_activeText->translateTo(getNearestGridVertex(m_activeText->m_trackedCenter)); + commandLog.log(getNearestGridVertex(m_activeText->m_trackedCenter) - m_dragStart, m_activeText); + } + if (m_activePort) { + m_activePort->translateTo(getNearestGridVertex(m_activePort->centre)); + commandLog.log(getNearestGridVertex(m_activePort->centre) - m_dragStart, m_activePort.get()); + } } - else if (m_activePoly) - { - PolyLine* polyline = dynamic_cast(m_activePoly); - if (polyline) - { - // Polygon is clear, so we index with m_vertices (nodes). - polyline->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx))); - commandLog.log(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx)) - m_dragStart, polyline); + else {//move vertices + if (m_activeLine) { + m_activeLine->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx))); + commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx)) - m_dragStart, m_activeLine); } - else + else if (m_activePoly) { - m_activePoly->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position)); - commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position) - m_dragStart, m_activePoly); + PolyLine* polyline = dynamic_cast(m_activePoly); + if (polyline) + { + // Polygon is clear, so we index with m_vertices (nodes). + polyline->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx))); + commandLog.log(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx)) - m_dragStart, polyline); + } + else + { + m_activePoly->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position)); + commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position) - m_dragStart, m_activePoly); + } } } } diff --git a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h index 1e2bfeb42..74057281d 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h +++ b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h @@ -7,7 +7,6 @@ #include "Utilities/Logger/Logger.h" #include "Application/Application.h" #include "Lumen/Lumen.h" -#include "Engines\EngineCore\EngineCore.h" //typedef uint64_t LumenCommandID; enum class CommandType @@ -215,6 +214,7 @@ class ChangeValueCommand: Command{ } }; +class EngineCore; class CommandLog { private: @@ -223,75 +223,12 @@ class CommandLog unsigned next_command_ixd = 0; EngineCore* parent;//Primarily used to notify the engine when a command is logged -public: - void undo() - { - if (next_command_ixd == 0) return; - - next_command_ixd--; - m_commandHistory.at(next_command_ixd)->undo(); - - switch (m_commandHistory.at(next_command_ixd)->commandType) { - case CommandType::CommandType_Remove: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo delete"); - break; - case CommandType::CommandType_RemovePrimitive: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo delete"); - break; - case CommandType::CommandType_SetColour: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo colour change"); - break; - case CommandType::CommandType_Translate: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo translation"); - break; - case CommandType::CommandType_Translate2D: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo translation"); - break; - case CommandType::CommandType_ChangeValue: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo edit"); - break; - case CommandType::CommandType_TranslateVertex: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo edit"); - break; - default: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo action"); - break; - } - - }; + void notifyParent(); - void redo() - { - if (next_command_ixd == m_commandHistory.size()) return; - - m_commandHistory.at(next_command_ixd)->execute(); - next_command_ixd++; - - switch (m_commandHistory.at(next_command_ixd)->commandType) { - case CommandType::CommandType_Remove: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo delete"); - break; - case CommandType::CommandType_RemovePrimitive: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo delete"); - break; - case CommandType::CommandType_SetColour: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo colour change"); - break; - case CommandType::CommandType_Translate: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo translation"); - break; - case CommandType::CommandType_Translate2D: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo translation"); - break; - case CommandType::CommandType_ChangeValue: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo edit"); - break; - default: - Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo action"); - break; - } - - }; +public: + inline CommandLog(EngineCore* parent) :parent(parent) {}; + void undo(); + void redo(); template void log(const Args&... args) { @@ -302,8 +239,8 @@ class CommandLog m_commandHistory.emplace_back(std::make_unique(args...)); next_command_ixd++; - //Notify engine of change - parent->unsavedDocument(); + //Notify engine of logged change + notifyParent(); }; template diff --git a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/CommandLog.cpp b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/CommandLog.cpp new file mode 100644 index 000000000..f4b0c5148 --- /dev/null +++ b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/CommandLog.cpp @@ -0,0 +1,77 @@ +#include "Command.h" +#include "Engines/EngineCore/EngineCore.h" + +void CommandLog::undo() +{ + if (next_command_ixd == 0) return; + + next_command_ixd--; + m_commandHistory.at(next_command_ixd)->undo(); + + switch (m_commandHistory.at(next_command_ixd)->commandType) { + case CommandType::CommandType_Remove: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo delete"); + break; + case CommandType::CommandType_RemovePrimitive: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo delete"); + break; + case CommandType::CommandType_SetColour: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo colour change"); + break; + case CommandType::CommandType_Translate: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo translation"); + break; + case CommandType::CommandType_Translate2D: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo translation"); + break; + case CommandType::CommandType_ChangeValue: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo edit"); + break; + case CommandType::CommandType_TranslateVertex: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo edit"); + break; + default: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Undo action"); + break; + } + notifyParent(); +}; + +void CommandLog::redo() +{ + if (next_command_ixd == m_commandHistory.size()) return; + + m_commandHistory.at(next_command_ixd)->execute(); + + switch (m_commandHistory.at(next_command_ixd)->commandType) { + case CommandType::CommandType_Remove: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo delete"); + break; + case CommandType::CommandType_RemovePrimitive: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo delete"); + break; + case CommandType::CommandType_SetColour: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo colour change"); + break; + case CommandType::CommandType_Translate: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo translation"); + break; + case CommandType::CommandType_Translate2D: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo translation"); + break; + case CommandType::CommandType_ChangeValue: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo edit"); + break; + default: + Lumen::getApp().pushNotification(NotificationType::Success, 500, "Redo action"); + break; + } + next_command_ixd++; + notifyParent(); +} +void CommandLog::notifyParent() +{ + parent->unsavedDocument(); +} +; + diff --git a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h index 0f83a9821..9f1dd0770 100644 --- a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h +++ b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h @@ -95,7 +95,7 @@ class EngineCore // ------------- // - CommandLog commandLog; + CommandLog commandLog = this; virtual void onEvent(const Event& event); inline virtual void onMouseButtonEvent(const MouseButtonEvent& event) {} From 91854c1b7bb917b7b889e79f0d0969e16f3e3343 Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Fri, 24 Jun 2022 23:11:43 +0200 Subject: [PATCH 07/10] Added undo system to circuit designer --- .../Engines/CircuitDesigner/CircuitDesigner.h | 3 +- .../CircuitDesigner_Events.cpp | 34 ++++++++++++++----- .../ComponentDesigner_Events.cpp | 18 +++++----- .../CircuitDesigner/Peripherals/Cable.cpp | 4 +-- .../CircuitDesigner/Peripherals/Cable.h | 7 ++-- .../Source/Engines/EngineCore/EngineCore.cpp | 1 + .../Source/Engines/EngineCore/EngineCore.h | 4 +++ .../Engines/EngineCore/EngineCore_Events.cpp | 11 +++++- 8 files changed, 57 insertions(+), 25 deletions(-) diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner.h index 8984a894d..f5c4d23b8 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner.h @@ -30,7 +30,7 @@ enum designState { COMPONENT_PLACE, ENTITY_SELECT, - COMPONENT_MOVE, + //COMPONENT_MOVE, CABLE_PLACE }; @@ -57,6 +57,7 @@ class CircuitDesigner : public Base2DEngine glm::vec4 helperColour = { 0.18f, 0.30f, 0.67f, 0.85f }; std::shared_ptr m_circuit; glm::vec2 m_lastDragPos = {0.f, 0.f}; + glm::vec2 m_dragStart; unsigned int m_currentEntityID = 0; Port* m_hoveredPort = nullptr; unsigned m_hoveredID; diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp index ef91ee3b7..3c951d038 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Events.cpp @@ -17,6 +17,7 @@ #include "Utilities/Logger/Logger.h" #include "glm/glm.hpp" #include "OpenGL/Primitives/Grid.h" +#include "OpenGL/Primitives/PolyLine.h" #include "GUI/LumenGizmo/LumenGizmo.h" #include "Utilities/Serialisation/Serialiser.h" #include "Utilities/Windows/WindowsUtilities.h" @@ -254,18 +255,33 @@ void CircuitDesigner::onMouseDragEvent(const MouseDragEvent& event) void CircuitDesigner::onNotifyEvent(const NotifyEvent& event) { - if (event.isType(EventType_MouseDragStop | EventType_MouseButtonLeft)) - { - if (m_activeComponent.get()) + + glm::vec2 worldCoords = pixelToWorldCoords(getMouseLocalPosition()); + if (designerState == designState::ENTITY_SELECT) { + if (event.isType(EventType_MouseDragStart | EventType_MouseButtonLeft)) { - glm::vec2 vert = getNearestGridVertex(m_activeComponent->centre); - LUMEN_LOG_DEBUG(std::to_string(vert.x), "Component Designer Notify"); - m_activeComponent->translateTo(getNearestGridVertex(m_activeComponent->centre)); + if (m_activeComponent.get()) + { + m_dragStart = m_activeComponent->centre; + } + if (m_activeVertexIdx != -1) { + m_dragStart = m_activeCable->m_polyLine->m_vertices.at(m_activeVertexIdx); + } } - if (m_activeVertexIdx != -1) + if (event.isType(EventType_MouseDragStop | EventType_MouseButtonLeft)) { - glm::vec2 worldCoords = pixelToWorldCoords(getMouseLocalPosition()); - m_activeCable->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(worldCoords)); + if (m_activeComponent.get()) + { + glm::vec2 vert = getNearestGridVertex(m_activeComponent->centre); + LUMEN_LOG_DEBUG(std::to_string(vert.x), "Component Designer Notify"); + m_activeComponent->translateTo(getNearestGridVertex(m_activeComponent->centre)); + commandLog.log(glm::vec2{ m_activeComponent->centre } - m_dragStart, m_activeComponent.get()); + } + if (m_activeVertexIdx != -1) + { + m_activeCable->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(worldCoords)); + commandLog.log(m_activeVertexIdx, m_activeCable->m_polyLine->m_vertices.at(m_activeVertexIdx) - m_dragStart, m_activeCable.get()); + } } } } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp index 19a5a2f63..8fdea0735 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp @@ -386,7 +386,7 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) m_dragStart = m_activePort->centre; } if (m_activeVertexIdx != -1) { - if (m_activeLine) m_activeLine->m_vertices.at(m_activeVertexIdx); + if (m_activeLine) m_dragStart = m_activeLine->m_vertices.at(m_activeVertexIdx); else if (m_activePoly) { PolyLine* polyline = dynamic_cast(m_activePoly); @@ -408,29 +408,29 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) if (m_activeVertexIdx == -1) {//move primitives if (m_activePoly) { m_activePoly->translateTo(getNearestGridVertex(m_activePoly->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activePoly->m_trackedCenter) - m_dragStart, m_activePoly); + commandLog.log(glm::vec2{ m_activePoly->m_trackedCenter } - m_dragStart, m_activePoly); } if (m_activeLine) { m_activeLine->translateTo(getNearestGridVertex(m_activeLine->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeLine->m_trackedCenter) - m_dragStart, m_activeLine); + commandLog.log(glm::vec2{ m_activeLine->m_trackedCenter } - m_dragStart, m_activeLine); } if (m_activeCircle) { m_activeCircle->translateTo(getNearestGridVertex(m_activeCircle->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeCircle->m_trackedCenter) - m_dragStart, m_activeCircle); + commandLog.log(glm::vec2{ m_activeCircle->m_trackedCenter } - m_dragStart, m_activeCircle); } if (m_activeText) { m_activeText->translateTo(getNearestGridVertex(m_activeText->m_trackedCenter)); - commandLog.log(getNearestGridVertex(m_activeText->m_trackedCenter) - m_dragStart, m_activeText); + commandLog.log(glm::vec2{ m_activeText->m_trackedCenter } - m_dragStart, m_activeText); } if (m_activePort) { m_activePort->translateTo(getNearestGridVertex(m_activePort->centre)); - commandLog.log(getNearestGridVertex(m_activePort->centre) - m_dragStart, m_activePort.get()); + commandLog.log(glm::vec2{ m_activePort->centre } - m_dragStart, m_activePort.get()); } } else {//move vertices if (m_activeLine) { m_activeLine->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx))); - commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activeLine->m_vertices.at(m_activeVertexIdx)) - m_dragStart, m_activeLine); + commandLog.log(m_activeVertexIdx, m_activeLine->m_vertices.at(m_activeVertexIdx) - m_dragStart, m_activeLine); } else if (m_activePoly) { @@ -439,12 +439,12 @@ void ComponentDesigner::onNotifyEvent(const NotifyEvent& event) { // Polygon is clear, so we index with m_vertices (nodes). polyline->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx))); - commandLog.log(m_activeVertexIdx, getNearestGridVertex(polyline->m_vertices.at(m_activeVertexIdx)) - m_dragStart, polyline); + commandLog.log(m_activeVertexIdx, polyline->m_vertices.at(m_activeVertexIdx) - m_dragStart, polyline); } else { m_activePoly->translateVertexAtIndexTo(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position)); - commandLog.log(m_activeVertexIdx, getNearestGridVertex(m_activePoly->getVertex(m_activeVertexIdx).position) - m_dragStart, m_activePoly); + commandLog.log(m_activeVertexIdx, glm::vec2{ m_activePoly->getVertex(m_activeVertexIdx).position } - m_dragStart, m_activePoly); } } } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.cpp index b2075e842..560414bd1 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.cpp @@ -281,7 +281,7 @@ void Cable::setColour(glm::vec4 colour, bool save) m_polyLine->setColor(colour); } -void Cable::translateVertexAtIndex(unsigned vertexIdx, glm::vec2 translation) +void Cable::translateVertexAtIndex(const unsigned& vertexIdx, const glm::vec2& translation) { if (vertexIdx == 0 || vertexIdx == m_polyLine->m_vertices.size() - 1) { //Don't allow the ends to be moved off the port @@ -290,7 +290,7 @@ void Cable::translateVertexAtIndex(unsigned vertexIdx, glm::vec2 translation) m_polyLine->translateVertexAtIndex(vertexIdx, translation); } -void Cable::translateVertexAtIndexTo(unsigned vertexIdx, glm::vec2 position) +void Cable::translateVertexAtIndexTo(const unsigned& vertexIdx, const glm::vec2& position) { if (vertexIdx == 0 || vertexIdx == m_polyLine->m_vertices.size() - 1) { //Don't allow the ends to be moved off the port diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.h index e684098ad..a9e84e855 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Cable.h @@ -8,6 +8,7 @@ #include #include "yaml-cpp/yaml.h" #include +#include "Engines/EntityComponents/Mutable.h" //==============================================================================================================================================// // Forward declerations. // @@ -32,7 +33,7 @@ enum class LineOrientation // Cable class. // //==============================================================================================================================================// -class Cable : public Entity +class Cable : public Entity, public Reshapable { public: @@ -82,8 +83,8 @@ class Cable : public Entity bool attach(Port* endPort); void followPort(Port* movedPort); void setColour(glm::vec4 colour, bool save = true); - void translateVertexAtIndex(unsigned vertexIdx, glm::vec2 translation); - void translateVertexAtIndexTo(unsigned vertexIdx, glm::vec2 position); + void translateVertexAtIndex(const unsigned& vertexIdx, const glm::vec2& translation) override; + void translateVertexAtIndexTo(const unsigned& vertexIdx, const glm::vec2& position) override; void enableOutline(); void disableOutline(); std::tuple getNearestVertexIdx(glm::vec2 pos); diff --git a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.cpp b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.cpp index f3f66840d..6362ec20c 100644 --- a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.cpp @@ -132,6 +132,7 @@ glm::vec2 EngineCore::getMouseGlobalPosition() void EngineCore::unsavedDocument() { + engineLastModified = std::time(nullptr); m_parentWindow->unsavedDocument(); } diff --git a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h index 9f1dd0770..bcaaf4556 100644 --- a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h +++ b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore.h @@ -62,6 +62,9 @@ class EngineCore // The window the engine is displayed in. LumenWindow* m_parentWindow = nullptr; + + std::time_t engineLastModified = 0; + std::time_t lastSaved = 0; // Display window as a saved document. void unsavedDocument(); // Display window as an unsaved document. @@ -208,6 +211,7 @@ class EngineCore virtual void onMouseButtonEventForce(const MouseButtonEvent& event); virtual void onMouseScrollEventForce(const MouseScrollEvent& event); virtual void onKeyEventForce(const KeyEvent& event); + virtual void onFileSaveEventForce(const FileSaveEvent& event); }; //=============================================================================================================================================// diff --git a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp index a2b14adb3..c875d4900 100644 --- a/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/EngineCore/EngineCore_Events.cpp @@ -151,7 +151,7 @@ void EngineCore::onKeyEventForce(const KeyEvent& event) { // Do not pass event if ImGui is using the keyboard. if (event.isType(EventType_LeftCtrl | EventType_KeyPress) && event.key == GLFW_KEY_S) { - onFileSaveEvent(FileSaveEvent()); + onFileSaveEventForce(FileSaveEvent()); return; } if (event.isType(EventType_LeftCtrl | EventType_KeyPress) && event.key == GLFW_KEY_Z) { @@ -165,6 +165,15 @@ void EngineCore::onKeyEventForce(const KeyEvent& event) onKeyEvent(event); } +void EngineCore::onFileSaveEventForce(const FileSaveEvent& event) +{ + if (lastSaved < engineLastModified) {//only save if design has been modified. + onFileSaveEvent(event); + lastSaved = std::time(nullptr);//Consider setting = engineLastModified. + } + m_parentWindow->savedDocument();//we can remove unsaved tag regardless +} + //==============================================================================================================================================// // EOF. // //==============================================================================================================================================// \ No newline at end of file From 363949a4fbaf3c26a2b52968e46750e3946dfa5f Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Fri, 24 Jun 2022 23:25:59 +0200 Subject: [PATCH 08/10] Update ComponentDesigner_Events.cpp --- .../Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp index 8fdea0735..9af8fbda2 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp @@ -244,6 +244,7 @@ void ComponentDesigner::onKeyEvent(const KeyEvent& event) case GLFW_KEY_P: //Add new polygon switchState(CompDesignState::DRAW_POLY); + drawFilled = !drawFilled; break; case GLFW_KEY_L: @@ -254,6 +255,7 @@ void ComponentDesigner::onKeyEvent(const KeyEvent& event) case GLFW_KEY_C: //Add new circle switchState(CompDesignState::DRAW_CIRCLE); + drawFilled = !drawFilled; break; case GLFW_KEY_O: From 2d85a175988000cdbfc796d8256b0a3d13a7e8e4 Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Sat, 25 Jun 2022 19:01:28 +0200 Subject: [PATCH 09/10] Undo system expansion --- .../Engines/AssetViewer/AssetViewer.cpp | 2 +- .../CircuitDesigner_Utilities.cpp | 10 +-- .../CircuitDesigner/ComponentDesigner.cpp | 2 +- .../ComponentDesigner_Events.cpp | 4 +- .../Peripherals/Component2D.cpp | 12 ++-- .../CircuitDesigner/Peripherals/Component2D.h | 2 +- .../CircuitDesigner/Peripherals/Port.cpp | 5 +- .../CircuitDesigner/Peripherals/Port.h | 2 +- .../Source/Engines/CommandSystem/Command.h | 69 +++++++++++++++--- .../GUI/ComponentEditor/ComponentEditor.cpp | 72 +++++++++++++++---- .../GUI/ComponentEditor/ComponentEditor.h | 8 +++ .../Source/GUI/TextEntryGUI/TextEntryGUI.cpp | 20 ++++-- .../Source/GUI/TextEntryGUI/TextEntryGUI.h | 7 +- .../Entities/CircuitSerialiser.cpp | 2 +- .../Entities/Component2DSerialiser.cpp | 3 +- .../Serialisation/SerialiserYAML.cpp | 4 +- 16 files changed, 173 insertions(+), 51 deletions(-) diff --git a/ElecDev_Graphics_Application/Source/Engines/AssetViewer/AssetViewer.cpp b/ElecDev_Graphics_Application/Source/Engines/AssetViewer/AssetViewer.cpp index dc79705d6..f2b09a78c 100644 --- a/ElecDev_Graphics_Application/Source/Engines/AssetViewer/AssetViewer.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/AssetViewer/AssetViewer.cpp @@ -107,7 +107,7 @@ void AssetViewer::viewComponent(const YAML::Node& node) clearAssets(); m_component = std::make_unique(node); m_component->disableOutline(); - m_currentAsset = m_component->equipType + ".lmcp"; + m_currentAsset = m_component->title->m_string + ".lmcp"; Renderer::restoreAndUnbindScene(); } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp index 2fa938456..7f1022cd5 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/CircuitDesigner_Utilities.cpp @@ -352,7 +352,7 @@ int CircuitDesigner::getComponentCount(const std::string& type) int count = 0; for (auto& component : m_circuit->m_components) { - if (component->equipType == componentType) + if (component->title->m_string == componentType) count++; } return count; @@ -400,7 +400,7 @@ void CircuitDesigner::removeImportedComponent(const std::string& name, bool chec while (count < componentsVector.size()) { Component2D* component = componentsVector[count].get(); - if (component->equipType == componentType) + if (component->title->m_string == componentType) { if (m_activeComponent.get() == component) m_activeComponent = nullptr; componentsVector.erase(componentsVector.begin() + count); @@ -446,7 +446,7 @@ void CircuitDesigner::overwriteComponents(const std::string& type, const YAML::N int overwriteCount = 0; for (auto& component : m_circuit->m_components) { - if (component->equipType == componentType) + if (component->title->m_string == componentType) { reloadComponent(component.get(), node); overwriteCount++; @@ -482,13 +482,13 @@ void CircuitDesigner::reloadComponent(Component2D* component, const YAML::Node& { Renderer::remove(component->title); component->title = Renderer::addText2D(node["Title"], component); - component->equipType = component->title->m_string; + component->title->m_string = component->title->m_string; } else if (node["Equipment Type"].IsDefined()) { Renderer::remove(component->title); component->title = Renderer::addText2D(node["Equipment Type"], component); - component->equipType = component->title->m_string; + component->title->m_string = component->title->m_string; } // Designator. diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp index 5b8ea1f3a..82fca3dd8 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner.cpp @@ -29,7 +29,7 @@ ComponentDesigner::ComponentDesigner() // Create default component. m_activeComponent = std::make_shared(nullptr); - m_activeComponent->title->updateText(m_activeComponent->equipType); + m_activeComponent->title->updateText(m_activeComponent->title->m_string); m_activeComponent->place(glm::vec2(0.f)); m_activeComponent->disableOutline(); diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp index 9af8fbda2..a3fc3d6dd 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/ComponentDesigner_Events.cpp @@ -108,7 +108,7 @@ void ComponentDesigner::onMouseButtonEvent(const MouseButtonEvent& event) m_activeText = Renderer::addText2D(" ", screenCoords, textColour, textSize, "C", "B", m_activeComponent.get()); m_activeComponent->m_text.push_back(m_activeText); - TextEntryGUI* menu = Lumen::getApp().pushWindow(LumenDockPanel::Floating, "Text Entry", m_activeText); + TextEntryGUI* menu = Lumen::getApp().pushWindow(LumenDockPanel::Floating, "Text Entry", m_activeText, &commandLog); switchState(CompDesignState::SELECT); } } @@ -124,7 +124,7 @@ void ComponentDesigner::onMouseButtonEvent(const MouseButtonEvent& event) { if (designerState == CompDesignState::SELECT) { - if (m_activeText) Lumen::getApp().pushWindow(LumenDockPanel::Floating, "Text Entry", m_activeText); + if (m_activeText) Lumen::getApp().pushWindow(LumenDockPanel::Floating, "Text Entry", m_activeText, &commandLog); } } } diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp index db891495f..2f6a3dd12 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.cpp @@ -115,12 +115,12 @@ Component2D::Component2D(const YAML::Node& node, Circuit* parent) if (componentNode["Title"].IsDefined()) { title = Renderer::addText2D(componentNode["Title"], this); - equipType = title->m_string; + //equipType = title->m_string; } else if (componentNode["Equipment Type"].IsDefined()) { title = Renderer::addText2D(componentNode["Equipment Type"], this); - equipType = title->m_string; + //equipType = title->m_string; } // Default title. else @@ -305,8 +305,8 @@ void Component2D::translateTitle(glm::vec2 translation) void Component2D::updateText() { //std::string textString = designatorSym + std::to_string(designatorIdx); - if (title->updateText(equipType)) - title->rotate(m_rotation, glm::vec3(centre, 0.f), { 0.f, 0.f, 1.f }); + title->update(); + title->rotate(m_rotation, glm::vec3(centre, 0.f), { 0.f, 0.f, 1.f }); if (designator->updateText(m_tag)) designator->rotate(m_rotation, glm::vec3(centre, 0.f), {0.f, 0.f, 1.f}); @@ -314,8 +314,8 @@ void Component2D::updateText() void Component2D::updateTextWithoutLabel() { - if (title->updateText(equipType)) - title->rotate(m_rotation, glm::vec3(centre, 0.f), { 0.f, 0.f, 1.f }); + title->update(); + title->rotate(m_rotation, glm::vec3(centre, 0.f), { 0.f, 0.f, 1.f }); if (designator->updateText(designatorSym)) designator->rotate(m_rotation, glm::vec3(centre, 0.f), { 0.f, 0.f, 1.f }); diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h index fbce9d085..1d4147270 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Component2D.h @@ -63,7 +63,7 @@ class Component2D : public Entity, public Translatable2D, public Rotatable static unsigned componentID; // Specify the type of the equipment - std::string equipType = "Block"; + //std::string equipType = "Block"; std::string type = "Unspecified"; std::string designatorSym = "?"; int designatorIdx = -1; diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp index 29bf0ad2b..a732a6d9c 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.cpp @@ -315,8 +315,11 @@ void Port::detachCable(Cable* cable) } } -void Port::updateType() +void Port::updateType(PortType type) { + if (type != (PortType)( - 1)) { + m_type = type; + } //assumes no hovered/attached ports (port types should only change in component designer) switch (m_type) { case PortType::PORT_IN: diff --git a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h index 3bb114592..02f7c93a3 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h +++ b/ElecDev_Graphics_Application/Source/Engines/CircuitDesigner/Peripherals/Port.h @@ -94,7 +94,7 @@ class Port: public Entity, public Translatable2D void setOffset(const glm::vec2& offset); void attachCable(Cable* cable); void detachCable(Cable* cable); - void updateType(); + void updateType(PortType type = (PortType) (- 1)); void showAttachIndicator(); void hideAttachIndicator(); void updateDesctiption(std::string newDescription = ""); diff --git a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h index 74057281d..e78e717e8 100644 --- a/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h +++ b/ElecDev_Graphics_Application/Source/Engines/CommandSystem/Command.h @@ -1,12 +1,14 @@ #pragma once #include "Engines/EntityComponents/Mutable.h" #include "Graphics/OpenGL/Primitives/Primitive.h" +#include "Graphics/OpenGL/Primitives/Text.h" #include "OpenGL/Renderer/RendererGL.h" #include #include #include "Utilities/Logger/Logger.h" #include "Application/Application.h" #include "Lumen/Lumen.h" +#include //typedef uint64_t LumenCommandID; enum class CommandType @@ -164,6 +166,21 @@ class RemoveCommand:public Command { } }; +class EditTextCommand :public Command { + const std::string oldString; + const std::string newString; + Text* const target; +public: + inline EditTextCommand(Text* target, const std::string& newString, const std::string& oldString) :target(target), oldString(oldString), newString(newString) { commandType = CommandType::CommandType_ChangeValue; }; + inline EditTextCommand(Text* target, const std::string& newString) : EditTextCommand(target, newString, target->m_string) {}; + void execute() { + target->updateText(newString); + } + void undo() { + target->updateText(oldString); + } +}; + class RemovePrimitveCommand:public Command { private: IPrimitive* const target; @@ -188,14 +205,16 @@ class RemovePrimitveCommand:public Command { } }; -template -class ChangeValueCommand: Command{ +template +class ChangeValueCommand: public Command{ private: const T oldVal; const T newVal; T* const target; public: inline ChangeValueCommand(const T& newValue, T* target) : oldVal(*target), newVal(newValue), target(target) { commandType = CommandType::CommandType_ChangeValue; }; + template + inline ChangeValueCommand(const T& newValue, T* target, const T& oldValue) : oldVal(oldValue), newVal(newValue), target(target) { commandType = CommandType::CommandType_ChangeValue; }; inline void execute() { try { *target = newVal; @@ -214,6 +233,38 @@ class ChangeValueCommand: Command{ } }; +template +class ChangeValueWithSetterCommand : public Command { +private: + const T oldVal; + const T newVal; + C* const target; + + std::function setter; + +public: + inline ChangeValueWithSetterCommand(const T& newValue, C* target, const T& oldValue, std::function setter) : + oldVal(oldValue), newVal(newValue), target(target), setter(setter) { commandType = CommandType::CommandType_ChangeValue; }; + inline void execute() { + try { + setter(target, newVal); + } + catch (...) { + LUMEN_LOG_WARN("Tried to change the value of an invlaid target.", "Command"); + } + } + inline void undo() { + try { + setter(target, oldVal); + } + catch (...) { + LUMEN_LOG_WARN("Tried to change the value of an invlaid target.", "Command"); + } + } +}; + + + class EngineCore; class CommandLog { @@ -229,29 +280,29 @@ class CommandLog inline CommandLog(EngineCore* parent) :parent(parent) {}; void undo(); void redo(); - template + template void log(const Args&... args) { if (next_command_ixd != m_commandHistory.size()) { //subsequent entries become invalid at this point m_commandHistory.resize(next_command_ixd); } - m_commandHistory.emplace_back(std::make_unique(args...)); + m_commandHistory.emplace_back(std::make_unique(args...)); next_command_ixd++; //Notify engine of logged change notifyParent(); }; - template + template void execute(const Args&... args) { - log(args...); - m_commandHistory[next_command_ixd-1]->execute(); - } + log(args...); + m_commandHistory[next_command_ixd - 1]->execute(); + }; const auto& getHistory() { return m_commandHistory; - } + }; }; diff --git a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp index 17367beed..8ffc2ae3d 100644 --- a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp @@ -19,6 +19,7 @@ #include "GUI/LumenPayload/LumenPayload.h" #include "imgui/misc/cpp/imgui_stdlib.h" #include "Graphics/OpenGL/Primitives/Text.h" +#include "Engines/CommandSystem/Command.h" /*=======================================================================================================================================*/ /* Component Editor. */ @@ -56,13 +57,15 @@ void ComponentEditor::onImGuiRender() { ImGui::Text(" Designator:\t "); ImGui::SameLine(); - ImGui::InputText("##Designator", &activeComponent->designatorSym); + inputTextWithLog("##Designator Prefix", activeComponent->designatorSym, &component_designer->commandLog); + //ImGui::InputText("##Designator Prefix", &activeComponent->designatorSym); ImGui::Text(" Name:\t "); ImGui::SameLine(); - ImGui::InputText("##Equipment Type", &activeComponent->equipType); + //ImGui::InputText("##Equipment Type", &activeComponent->equipType); + inputTextWithLog("##description", activeComponent->title, &component_designer->commandLog); ImGui::Text("Type: \t"); ImGui::SameLine(); - static std::string types[] = { "Unspecified", + std::string types[] = { "Unspecified", "Substation", "Distribution Transformer", "Mini Substation", @@ -85,7 +88,8 @@ void ComponentEditor::onImGuiRender() for (size_t i = 0; i < IM_ARRAYSIZE(types); i++) { if (ImGui::Selectable(types[i].c_str())) { - activeComponent->type = types[i]; + component_designer->commandLog.execute>(types[i], &(activeComponent->type)); + //activeComponent->type = types[i]; } } ImGui::EndCombo(); @@ -128,22 +132,23 @@ void ComponentEditor::onImGuiRender() // Name. ImGui::PushItemWidth(-1); - if (ImGui::InputText(labelName, &port->title->m_string)) - port->title->update(); + inputTextWithLog(labelName, port->title, &component_designer->commandLog); ImGui::PopItemWidth(); ImGui::TableNextColumn(); // Description ImGui::PushItemWidth(-1); - ImGui::InputText(labelDesc, &port->description); + inputTextWithLog(labelDesc, port->description, &component_designer->commandLog); + //ImGui::InputText(labelDesc, &port->description); ImGui::PopItemWidth(); ImGui::TableNextColumn(); // Type. ImGui::PushItemWidth(-1); - int* typeval = (int*)&port->m_type; - if (ImGui::Combo(labelType, typeval, "IN\0OUT\0IN/OUT")) { - port->updateType(); + PortType* typeval = &port->m_type; + PortType oldtype = port->m_type; + if (ImGui::Combo(labelType, (int*)typeval, "IN\0OUT\0IN/OUT")) { + component_designer->commandLog.log>(*typeval, port.get(), oldtype, &Port::updateType); } ImGui::PopItemWidth(); ImGui::TableNextColumn(); @@ -383,12 +388,13 @@ void ComponentEditor::onImGuiRender() ImGui::PushItemWidth(-1); int designatorIdx = activeComponent->getDesignatorIdx(); if (ImGui::InputInt("##designatorIdx", &designatorIdx)) { - activeComponent->setDesignatorIdx(designatorIdx); + //activeComponent->setDesignatorIdx(designatorIdx); + design_engine->commandLog.execute>(designatorIdx, activeComponent, activeComponent->getDesignatorIdx(), &Component2D::setDesignatorIdx); } ImGui::PopItemWidth(); ImGui::AlignTextToFramePadding(); - ImGui::Text((std::string(" Description:\t ") + activeComponent->equipType).c_str()); + ImGui::Text((std::string(" Description:\t ") + activeComponent->title->m_string).c_str()); } // ------------------------------- // @@ -588,9 +594,19 @@ void ComponentEditor::onImGuiRender() ImGui::Text("Tag: "); ImGui::TableNextColumn(); ImGui::PushItemWidth(-1); - if (ImGui::InputText("##tag", &activeComponent->m_tag)) { + ImGui::InputText("##tag", &activeComponent->m_tag); + if (ImGui::IsItemEdited()) { activeComponent->updateText(); } + if (ImGui::IsItemActivated()) { + //save original data + strBeforeEdit = activeComponent->m_tag; + } + if (ImGui::IsItemDeactivatedAfterEdit()) { + //log change + design_engine->commandLog.log>(activeComponent->m_tag, activeComponent, strBeforeEdit, &Component2D::setTag); + + } ImGui::PopItemWidth(); ImGui::TableNextColumn(); @@ -934,6 +950,36 @@ void ComponentEditor::onImGuiEnd() ImGui::End(); } +void ComponentEditor::inputTextWithLog(const char* label, Text* textToUpdate, CommandLog* log) +{ + ImGui::InputText(label, &textToUpdate->m_string); + if (ImGui::IsItemEdited()) { + textToUpdate->update(); + } + if (ImGui::IsItemActivated()) { + //save original data + strBeforeEdit = textToUpdate->m_string; + } + if (ImGui::IsItemDeactivatedAfterEdit()) { + //log change + log->log(textToUpdate, textToUpdate->m_string, strBeforeEdit); + } +} + +void ComponentEditor::inputTextWithLog(const char* label, std::string& stringToUpdate, CommandLog* log) +{ + ImGui::InputText(label, &stringToUpdate); + if (ImGui::IsItemActivated()) { + //save original data + strBeforeEdit = stringToUpdate; + } + if (ImGui::IsItemDeactivatedAfterEdit()) { + //log change + log->log>(stringToUpdate, &stringToUpdate, strBeforeEdit); + + } +} + /*=======================================================================================================================================*/ /* EOF. */ /*=======================================================================================================================================*/ \ No newline at end of file diff --git a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.h b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.h index 834e112d6..f1bee6c0d 100644 --- a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.h +++ b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.h @@ -13,6 +13,8 @@ //=======================================================================================================================================// class Cable; +class Text; +class CommandLog; class ComponentEditor : public LumenWindow { @@ -27,6 +29,9 @@ class ComponentEditor : public LumenWindow virtual void onImGuiEnd() override; private: + //Vars saving original data while edit is in progress + //We can reuse these, as we can only have one active edit at a time. + std::string strBeforeEdit; int fromSelector = 0; int databaseSelector = 0; @@ -57,6 +62,9 @@ class ComponentEditor : public LumenWindow inline static bool m_copiedDictCable = false; inline static bool m_copiedDictComponent = false; inline static std::string m_copiedDictFrom = ""; + + void inputTextWithLog(const char* label, Text* textToUpdate, CommandLog* log); + void inputTextWithLog(const char* label, std::string& stringToUpdate, CommandLog* log); }; //=======================================================================================================================================// diff --git a/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.cpp b/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.cpp index 2354979c5..4b1027584 100644 --- a/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.cpp @@ -1,6 +1,7 @@ #include "TextEntryGUI.h" +#include "Engines/CommandSystem/Command.h" -TextEntryGUI::TextEntryGUI(const std::string& name, Text* text, int imguiWindowFlags) : LumenPopupWindow(name, imguiWindowFlags), m_text(text), m_textToEdit(text->m_string) +TextEntryGUI::TextEntryGUI(const std::string& name, Text* text, CommandLog* log, int imguiWindowFlags) : LumenPopupWindow(name, imguiWindowFlags), m_text(text), m_log(log) { removeImGuiWindowFlags(ImGuiWindowFlags_NoResize); addImGuiWindowFlags(ImGuiWindowFlags_AlwaysAutoResize); @@ -8,13 +9,22 @@ TextEntryGUI::TextEntryGUI(const std::string& name, Text* text, int imguiWindowF void TextEntryGUI::onImGuiRender() { - ImGui::SetKeyboardFocusHere(); - if (ImGui::InputText("##Text", &m_textToEdit, ImGuiInputTextFlags_AlwaysOverwrite)) { - m_text->updateText(m_textToEdit); + ImGui::SetKeyboardFocusHere(); + ImGui::InputText("##text", &m_text->m_string); + if (ImGui::IsItemEdited()) { + m_text->update(); + } + if (ImGui::IsItemActivated()) { + //save original data + strBeforeEdit = m_text->m_string; + } + if (ImGui::IsItemDeactivatedAfterEdit()) { + //log change + m_log->log(m_text, m_text->m_string, strBeforeEdit); } if (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_Escape)) { //TODO: check for whitespace, and remove text if blank - + //Perform special checks if Text field is a port name. closeWindow(); } diff --git a/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.h b/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.h index 4f2f1a465..da98f379c 100644 --- a/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.h +++ b/ElecDev_Graphics_Application/Source/GUI/TextEntryGUI/TextEntryGUI.h @@ -3,13 +3,15 @@ #include "Application/Windows/LumenPopupWindow.h" #include "Graphics/OpenGL/Primitives/Text.h" +class CommandLog; + class TextEntryGUI : public LumenPopupWindow { public: // Constructor. - TextEntryGUI(const std::string& name, Text* text, int imguiWindowFlags = 0); + TextEntryGUI(const std::string& name, Text* text, CommandLog* log, int imguiWindowFlags = 0); // Rendering. virtual void onImGuiRender() override; @@ -17,6 +19,7 @@ class TextEntryGUI : public LumenPopupWindow private: Text* m_text; - std::string m_textToEdit; + CommandLog* m_log; + std::string strBeforeEdit; }; diff --git a/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/CircuitSerialiser.cpp b/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/CircuitSerialiser.cpp index e6c9cdad9..a2da2f5e5 100644 --- a/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/CircuitSerialiser.cpp +++ b/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/CircuitSerialiser.cpp @@ -41,7 +41,7 @@ YAML::Emitter& operator<<(YAML::Emitter& emitter, Circuit* circuit) { emitter << YAML::Key << "Component " + std::to_string(index) << YAML::Value; emitter << YAML::BeginMap; - emitter << YAML::Key << "Filename" << YAML::Value << comp->equipType + ".lmcp"; + emitter << YAML::Key << "Filename" << YAML::Value << comp->title->m_string + ".lmcp"; emitter << YAML::Key << "Designator Index" << YAML::Value << comp->designatorIdx; emitter << YAML::Key << "Position" << YAML::Value << comp->centre; emitter << YAML::Key << "Rotation" << YAML::Value << comp->m_rotation; diff --git a/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/Component2DSerialiser.cpp b/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/Component2DSerialiser.cpp index 2eb2765f4..2ded2d767 100644 --- a/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/Component2DSerialiser.cpp +++ b/ElecDev_Graphics_Application/Source/Utilities/Serialisation/Entities/Component2DSerialiser.cpp @@ -6,6 +6,7 @@ #include "Engines/CircuitDesigner/Peripherals/Component2D.h" #include "Graphics/Fonts/FontLoader.h" #include "OpenGL/Primitives/PolyLine.h" +#include "OpenGL/Primitives/Text.h" //=============================================================================================================================================// // Component 2D serialiser. // @@ -17,7 +18,7 @@ YAML::Emitter& operator<<(YAML::Emitter& emitter, Component2D* comp) emitter << YAML::BeginMap; // Component data. - emitter << YAML::Key << "Filename" << YAML::Value << comp->equipType + ".lmcp"; + emitter << YAML::Key << "Filename" << YAML::Value << comp->title->m_string + ".lmcp"; emitter << YAML::Key << "Internal Circuit" << YAML::Value << "Test_AE_234.lmct"; emitter << YAML::Key << "Equipment Type" << YAML::Value << comp->title; emitter << YAML::Key << "Designator" << YAML::Value << comp->designator; diff --git a/ElecDev_Graphics_Application/Source/Utilities/Serialisation/SerialiserYAML.cpp b/ElecDev_Graphics_Application/Source/Utilities/Serialisation/SerialiserYAML.cpp index eba3e145a..bd1495674 100644 --- a/ElecDev_Graphics_Application/Source/Utilities/Serialisation/SerialiserYAML.cpp +++ b/ElecDev_Graphics_Application/Source/Utilities/Serialisation/SerialiserYAML.cpp @@ -68,7 +68,7 @@ void saveToYAML(Component2D* component, const std::filesystem::path& path) if (path.filename().string().size()) { std::string newName = path.filename().stem().string(); - component->equipType = newName; + component->title->m_string = newName; component->title->updateText(newName); } @@ -87,7 +87,7 @@ void saveToYAML(Component2D* component, const std::filesystem::path& path) std::string saveLocation = path.string(); if (!path.filename().string().size()) { - saveLocation += component->equipType + ".lmcp"; + saveLocation += component->title->m_string + ".lmcp"; } // Check if a file extension was supplied. else if (path.extension().string() != ".lmcp") From 6337339709519477d4811c46220ba6fe77d66c6d Mon Sep 17 00:00:00 2001 From: Cullen Stewart-Burger Date: Sat, 25 Jun 2022 22:10:55 +0200 Subject: [PATCH 10/10] Update ComponentEditor.cpp --- .../Source/GUI/ComponentEditor/ComponentEditor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp index 8ffc2ae3d..4ca559822 100644 --- a/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp +++ b/ElecDev_Graphics_Application/Source/GUI/ComponentEditor/ComponentEditor.cpp @@ -604,7 +604,8 @@ void ComponentEditor::onImGuiRender() } if (ImGui::IsItemDeactivatedAfterEdit()) { //log change - design_engine->commandLog.log>(activeComponent->m_tag, activeComponent, strBeforeEdit, &Component2D::setTag); + design_engine->commandLog.log> + (activeComponent->m_tag, activeComponent, strBeforeEdit, &Component2D::setTag); } ImGui::PopItemWidth(); @@ -614,7 +615,8 @@ void ComponentEditor::onImGuiRender() ImGui::BeginDisabled(activeComponent->m_tag == activeComponent->designatorSym + std::to_string(activeComponent->getDesignatorIdx())); //ImGui::PushItemWidth(-1); if (ImGui::Button("Reset Default")) { - activeComponent->setTag(); + design_engine->commandLog.log> + ("None", activeComponent, activeComponent->m_tag, &Component2D::setTag); } //ImGui::PopItemWidth(); ImGui::EndDisabled();