diff options
author | rtk0c <[email protected]> | 2021-05-14 20:52:00 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2021-05-14 20:52:00 -0700 |
commit | fa13cad2bf12d8f7f63f7ff6aab07dd2eaf6ec6d (patch) | |
tree | 994198f3636030b3974f73170fc59b04a794681d /core/src/Model | |
parent | 765df313e065f8401319c68ba70cd41b0bc34c9d (diff) |
Node graph editor basic functionality
Diffstat (limited to 'core/src/Model')
-rw-r--r-- | core/src/Model/Workflow/Nodes/DocumentNodes.cpp | 2 | ||||
-rw-r--r-- | core/src/Model/Workflow/Nodes/NumericNodes.cpp | 4 | ||||
-rw-r--r-- | core/src/Model/Workflow/Nodes/TextNodes.cpp | 2 | ||||
-rw-r--r-- | core/src/Model/Workflow/Nodes/UserInputNodes.cpp | 4 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow.hpp | 29 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow_Main.cpp | 57 |
6 files changed, 68 insertions, 30 deletions
diff --git a/core/src/Model/Workflow/Nodes/DocumentNodes.cpp b/core/src/Model/Workflow/Nodes/DocumentNodes.cpp index b858b49..3925dec 100644 --- a/core/src/Model/Workflow/Nodes/DocumentNodes.cpp +++ b/core/src/Model/Workflow/Nodes/DocumentNodes.cpp @@ -9,7 +9,7 @@ bool DocumentTemplateExpansionNode::IsInstance(const WorkflowNode* node) } DocumentTemplateExpansionNode::DocumentTemplateExpansionNode() - : WorkflowNode(KD_DocumentTemplateExpansion) + : WorkflowNode(KD_DocumentTemplateExpansion, false) { } diff --git a/core/src/Model/Workflow/Nodes/NumericNodes.cpp b/core/src/Model/Workflow/Nodes/NumericNodes.cpp index 083172e..ad51fb4 100644 --- a/core/src/Model/Workflow/Nodes/NumericNodes.cpp +++ b/core/src/Model/Workflow/Nodes/NumericNodes.cpp @@ -36,7 +36,7 @@ bool NumericOperationNode::IsInstance(const WorkflowNode* node) } NumericOperationNode::NumericOperationNode(OperationType type) - : WorkflowNode(OperationTypeToNodeKind(type)) + : WorkflowNode(OperationTypeToNodeKind(type), false) , mType{ type } { mInputs.resize(2); @@ -85,7 +85,7 @@ bool NumericExpressionNode::IsInstance(const WorkflowNode* node) } NumericExpressionNode::NumericExpressionNode() - : WorkflowNode(KD_NumericExpression) + : WorkflowNode(KD_NumericExpression, false) { } diff --git a/core/src/Model/Workflow/Nodes/TextNodes.cpp b/core/src/Model/Workflow/Nodes/TextNodes.cpp index b70290d..6c71309 100644 --- a/core/src/Model/Workflow/Nodes/TextNodes.cpp +++ b/core/src/Model/Workflow/Nodes/TextNodes.cpp @@ -53,7 +53,7 @@ bool TextFormatterNode::IsInstance(const WorkflowNode* node) } TextFormatterNode::TextFormatterNode() - : WorkflowNode(KD_TextFormatting) + : WorkflowNode(KD_TextFormatting, false) { } diff --git a/core/src/Model/Workflow/Nodes/UserInputNodes.cpp b/core/src/Model/Workflow/Nodes/UserInputNodes.cpp index 3a30631..f8d3e01 100644 --- a/core/src/Model/Workflow/Nodes/UserInputNodes.cpp +++ b/core/src/Model/Workflow/Nodes/UserInputNodes.cpp @@ -9,7 +9,7 @@ bool FormInputNode::IsInstance(const WorkflowNode* node) } FormInputNode::FormInputNode() - : WorkflowNode(KD_FormInput) + : WorkflowNode(KD_FormInput, false) { } @@ -23,7 +23,7 @@ bool DatabaseRowsInputNode::IsInstance(const WorkflowNode* node) } DatabaseRowsInputNode::DatabaseRowsInputNode() - : WorkflowNode(KD_DatabaseRowsInput) + : WorkflowNode(KD_DatabaseRowsInput, false) { } diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp index 79c2b2f..847aa72 100644 --- a/core/src/Model/Workflow/Workflow.hpp +++ b/core/src/Model/Workflow/Workflow.hpp @@ -4,6 +4,7 @@ #include "Utils/Vector.hpp" #include "cplt_fwd.hpp" +#include <imgui_node_editor.h> #include <cstddef> #include <cstdint> #include <iosfwd> @@ -14,6 +15,8 @@ #include <variant> #include <vector> +namespace ImNodes = ax::NodeEditor; + class WorkflowConnection { public: @@ -31,7 +34,7 @@ public: bool IsValid() const; /// Used for `LinkId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading). - size_t GetLinkId() const; + ImNodes::LinkId GetLinkId() const; void DrawDebugInfo() const; void ReadFrom(std::istream& stream); @@ -99,13 +102,14 @@ protected: uint32_t mId; Kind mKind; int mDepth; + bool mLocked; public: static const char* FormatKind(Kind kind); static const char* FormatType(Type type); static std::unique_ptr<WorkflowNode> CreateByKind(Kind kind); - WorkflowNode(Kind kind); + WorkflowNode(Kind kind, bool locked); virtual ~WorkflowNode() = default; WorkflowNode(const WorkflowNode&) = delete; @@ -118,23 +122,28 @@ public: uint32_t GetId() const; /// Used for `NodeId` when interfacing with imgui node editor. Runtime only (not saved to disk and generated when loading). - size_t GetNodeId() const; + ImNodes::NodeId GetNodeId() const; Kind GetKind() const; int GetDepth() const; + bool IsLocked() const; Type GetType() const; bool IsInputNode() const; bool IsOutputNode() const; - void ConnectInput(uint32_t pinId, WorkflowNode& output, uint32_t outputNodeId); + void ConnectInput(uint32_t pinId, WorkflowNode& srcNode, uint32_t srcPinId); void DisconnectInput(uint32_t pinId); + + void DrawInputPinDebugInfo(uint32_t pinId) const; const InputPin& GetInputPin(uint32_t pinId)const ; - size_t GetInputPinUniqueId(uint32_t pinId) const; + ImNodes::PinId GetInputPinUniqueId(uint32_t pinId) const; - void ConnectOutput(uint32_t pinId, WorkflowNode& input, uint32_t inputNodeId); + void ConnectOutput(uint32_t pinId, WorkflowNode& dstNode, uint32_t dstPinId); void DisconnectOutput(uint32_t pinId); + + void DrawOutputPinDebugInfo(uint32_t pinId)const; const OutputPin& GetOutputPin(uint32_t pinId)const ; - size_t GetOutputPinUniqueId(uint32_t pinId) const; + ImNodes::PinId GetOutputPinUniqueId(uint32_t pinId) const; virtual void Evaluate(WorkflowEvaluationContext& ctx) = 0; @@ -187,7 +196,9 @@ public: std::vector<std::unique_ptr<BaseValue>>& GetConstants(); WorkflowConnection* GetConnectionById(uint32_t id); + WorkflowConnection* GetConnectionByLinkId(ImNodes::LinkId linkId); WorkflowNode* GetNodeById(uint32_t id); + WorkflowNode* GetNodeByNodeId(ImNodes::NodeId nodeId); BaseValue* GetConstantById(uint32_t id); struct GlobalPinId @@ -200,8 +211,8 @@ public: }; /// `pinId` should be the `UniqueId` of a pin from a node that's within this workflow. - GlobalPinId DisassembleGlobalPinId(size_t id); - size_t FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const; + GlobalPinId DisassembleGlobalPinId(ImNodes::PinId id); + ImNodes::PinId FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const; const std::vector<std::vector<uint32_t>>& GetDepthGroups() const; bool DoesDepthNeedsUpdate() const; diff --git a/core/src/Model/Workflow/Workflow_Main.cpp b/core/src/Model/Workflow/Workflow_Main.cpp index 678b4b8..1b50064 100644 --- a/core/src/Model/Workflow/Workflow_Main.cpp +++ b/core/src/Model/Workflow/Workflow_Main.cpp @@ -24,7 +24,7 @@ bool WorkflowConnection::IsValid() const return Id != 0; } -size_t WorkflowConnection::GetLinkId() const +ImNodes::LinkId WorkflowConnection::GetLinkId() const { // Our id is 0-based (represents an index directly) // but imgui-node-editor uses the value 0 to represent a null id, so we need to offset by 1 @@ -33,12 +33,10 @@ size_t WorkflowConnection::GetLinkId() const void WorkflowConnection::DrawDebugInfo() const { - ImGui::BeginTooltip(); ImGui::Text("Source (node with output pin):"); ImGui::Text("{ Node = %u, Pin = %u }", SourceNode, SourcePin); ImGui::Text("Destination (node with input pin):"); ImGui::Text("{ Node = %u, Pin = %u }", DestinationNode, DestinationPin); - ImGui::EndTooltip(); } void WorkflowConnection::ReadFrom(std::istream& stream) @@ -78,9 +76,10 @@ BaseValue::Kind WorkflowNode::OutputPin::GetMatchingType() const return MatchingType; } -WorkflowNode::WorkflowNode(Kind kind) +WorkflowNode::WorkflowNode(Kind kind, bool locked) : mKind{ kind } , mDepth{ -1 } + , mLocked(locked) { } @@ -99,7 +98,7 @@ uint32_t WorkflowNode::GetId() const return mId; } -size_t WorkflowNode::GetNodeId() const +ImNodes::NodeId WorkflowNode::GetNodeId() const { // See WorkflowConnection::GetLinkId for the rationale return mId + 1; @@ -115,6 +114,11 @@ int WorkflowNode::GetDepth() const return mDepth; } +bool WorkflowNode::IsLocked() const +{ + return mLocked; +} + WorkflowNode::Type WorkflowNode::GetType() const { if (IsInputNode()) { @@ -136,9 +140,9 @@ bool WorkflowNode::IsOutputNode() const return mOutputs.size() == 0; } -void WorkflowNode::ConnectInput(uint32_t pinId, WorkflowNode& output, uint32_t outputNodeId) +void WorkflowNode::ConnectInput(uint32_t pinId, WorkflowNode& srcNode, uint32_t srcPinId) { - mWorkflow->Connect(*this, pinId, output, outputNodeId); + mWorkflow->Connect(*this, pinId, srcNode, srcPinId); } void WorkflowNode::DisconnectInput(uint32_t pinId) @@ -146,19 +150,25 @@ void WorkflowNode::DisconnectInput(uint32_t pinId) mWorkflow->DisconnectByDestination(*this, pinId); } +void WorkflowNode::DrawInputPinDebugInfo(uint32_t pinId) const +{ + ImGui::Text("Node ID: %d", mId); + ImGui::Text("Pin ID: (input) %d", pinId); +} + const WorkflowNode::InputPin& WorkflowNode::GetInputPin(uint32_t pinId) const { return mInputs[pinId]; } -size_t WorkflowNode::GetInputPinUniqueId(uint32_t pinId) const +ImNodes::PinId WorkflowNode::GetInputPinUniqueId(uint32_t pinId) const { return mWorkflow->FabricateGlobalPinId(*this, pinId, false); } -void WorkflowNode::ConnectOutput(uint32_t pinId, WorkflowNode& input, uint32_t inputNodeId) +void WorkflowNode::ConnectOutput(uint32_t pinId, WorkflowNode& dstNode, uint32_t dstPinId) { - mWorkflow->Connect(input, inputNodeId, *this, pinId); + mWorkflow->Connect(dstNode, dstPinId, *this, pinId); } void WorkflowNode::DisconnectOutput(uint32_t pinId) @@ -166,12 +176,18 @@ void WorkflowNode::DisconnectOutput(uint32_t pinId) mWorkflow->DisconnectBySource(*this, pinId); } +void WorkflowNode::DrawOutputPinDebugInfo(uint32_t pinId) const +{ + ImGui::Text("Node ID: %d", mId); + ImGui::Text("Pin ID: (output) %d", pinId); +} + const WorkflowNode::OutputPin& WorkflowNode::GetOutputPin(uint32_t pinId) const { return mOutputs[pinId]; } -size_t WorkflowNode::GetOutputPinUniqueId(uint32_t pinId) const +ImNodes::PinId WorkflowNode::GetOutputPinUniqueId(uint32_t pinId) const { return mWorkflow->FabricateGlobalPinId(*this, pinId, true); } @@ -180,12 +196,14 @@ void WorkflowNode::Draw() { for (uint32_t i = 0; i < mInputs.size(); ++i) { auto& pin = mInputs[i]; + auto& typeInfo = BaseValue::QueryInfo(pin.MatchingType); ImNodes::BeginPin(GetInputPinUniqueId(i), ImNodes::PinKind::Input); // TODO ImNodes::EndPin(); } for (uint32_t i = 0; i < mOutputs.size(); ++i) { auto& pin = mOutputs[i]; + auto& typeInfo = BaseValue::QueryInfo(pin.MatchingType); ImNodes::BeginPin(GetOutputPinUniqueId(i), ImNodes::PinKind::Output); // TODO ImNodes::EndPin(); @@ -194,13 +212,11 @@ void WorkflowNode::Draw() void WorkflowNode::DrawDebugInfo() const { - ImGui::BeginTooltip(); ImGui::Text("Node kind: %s", FormatKind(mKind)); ImGui::Text("Node type: %s", FormatType(GetType())); ImGui::Text("Node ID: %u", mId); ImGui::Text("Depth: %d", mDepth); DrawExtraDebugInfo(); - ImGui::EndTooltip(); } void WorkflowNode::ReadFrom(std::istream& stream) @@ -338,17 +354,27 @@ WorkflowConnection* Workflow::GetConnectionById(uint32_t id) return &mConnections[id]; } +WorkflowConnection* Workflow::GetConnectionByLinkId(ImNodes::LinkId id) +{ + return &mConnections[(uint32_t)(size_t)id - 1]; +} + WorkflowNode* Workflow::GetNodeById(uint32_t id) { return mNodes[id].get(); } +WorkflowNode* Workflow::GetNodeByNodeId(ImNodes::NodeId id) +{ + return mNodes[(uint32_t)(size_t)id - 1].get(); +} + BaseValue* Workflow::GetConstantById(uint32_t id) { return mConstants[id].get(); } -Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(size_t id) +Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(ImNodes::PinId pinId) { // imgui-node-editor requires all pins to have a global, unique id // but in our model the pin are typed (input vs output) and associated with a node: there is no built-in global id @@ -362,6 +388,7 @@ Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(size_t id) // 1 is added to pin id to prevent the 0th node's 0th input pin resulting in a 0 global pin id // (this is problematic because imgui-node-editor use 0 to represent null) + auto id = static_cast<uint64_t>(pinId); GlobalPinId result; result.Node = mNodes[id >> 32].get(); @@ -371,7 +398,7 @@ Workflow::GlobalPinId Workflow::DisassembleGlobalPinId(size_t id) return result; } -size_t Workflow::FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const +ImNodes::PinId Workflow::FabricateGlobalPinId(const WorkflowNode& node, uint32_t pinId, bool isOutput) const { // See this->DisassembleGlobalPinId for format details and rationale |