From 765df313e065f8401319c68ba70cd41b0bc34c9d Mon Sep 17 00:00:00 2001 From: rtk0c Date: Wed, 12 May 2021 13:23:56 -0700 Subject: Start to work on actually rendering the node graph --- core/src/UI/UI_Workflows.cpp | 122 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 9 deletions(-) (limited to 'core/src/UI/UI_Workflows.cpp') diff --git a/core/src/UI/UI_Workflows.cpp b/core/src/UI/UI_Workflows.cpp index f9857a1..7aefeab 100644 --- a/core/src/UI/UI_Workflows.cpp +++ b/core/src/UI/UI_Workflows.cpp @@ -17,9 +17,9 @@ namespace ImNodes = ax::NodeEditor; namespace { -class WorkflowCreationMenu +class WorkflowDatabase { -private: +public: using WorkflowNodeConstructor = std::unique_ptr (*)(); enum Category @@ -39,6 +39,7 @@ private: Category Category; }; +private: std::vector mCandidates; #define SUB_RANGE_ACCESS(Type, AccessorName, storage, begin, nextBegin) \ @@ -53,6 +54,7 @@ private: int mSystemInputNodes; int mOutputOffset; +public: SUB_RANGE_ACCESS(Candidate, GetNumericNodes, mCandidates, 0, mTextOffset); SUB_RANGE_ACCESS(Candidate, GetTextNodes, mCandidates, mTextOffset, mDocumentOffset); SUB_RANGE_ACCESS(Candidate, GetDocumentNodes, mCandidates, mDocumentOffset, mUserInputOffset); @@ -63,12 +65,6 @@ private: #undef SUB_RANGE_ACCESS public: - WorkflowCreationMenu() - { - SetupCandidates(); - } - -private: void SetupCandidates() { // Numeric nodes offset start at 0 @@ -140,11 +136,13 @@ class WorkflowUI private: Workflow* mWorkflow; ImNodes::EditorContext* mContext; + WorkflowDatabase mWorkflowDatabase; public: WorkflowUI() { mContext = ImNodes::CreateEditor(); + mWorkflowDatabase.SetupCandidates(); } ~WorkflowUI() @@ -157,6 +155,8 @@ public: ImNodes::SetCurrentEditor(mContext); ImNodes::Begin(""); + const char* tooltipMessage = nullptr; + for (auto& node : mWorkflow->GetNodes()) { if (!node) continue; @@ -168,8 +168,112 @@ public: for (auto& conn : mWorkflow->GetConnections()) { if (!conn.IsValid()) continue; - // TODO create link + auto srcId = mWorkflow->GetNodes()[conn.SourceNode]->GetOutputPinUniqueId(conn.SourcePin); + auto dstId = mWorkflow->GetNodes()[conn.DestinationNode]->GetInputPinUniqueId(conn.DestinationPin); + ImNodes::Link(conn.GetLinkId(), srcId, dstId); + } + + if (ImNodes::BeginCreate()) { + ImNodes::PinId src = 0, dst = 0; + if (ImNodes::QueryNewLink(&src, &dst)) { + if (!src || !dst) { + goto createError; + } + + auto [srcNode, srcPinId, srcIsOutput] = mWorkflow->DisassembleGlobalPinId((size_t)src); + auto [dstNode, dstPinId, dstIsOutput] = mWorkflow->DisassembleGlobalPinId((size_t)dst); + + if (srcNode == dstNode) { + ImNodes::RejectNewItem(); + goto createError; + } + + if (srcIsOutput == dstIsOutput) { + ImNodes::RejectNewItem(); + goto createError; + } + + auto srcPin = srcNode->GetOutputPin(srcPinId); + auto dstPin = dstNode->GetOutputPin(dstPinId); + + if (srcPin.MatchingType != dstPin.MatchingType) { + ImNodes::RejectNewItem(); + goto createError; + } + + if (ImNodes::AcceptNewItem()) { + mWorkflow->Connect(*srcNode, srcPinId, *dstNode, dstPinId); + } + } + + ImNodes::PinId newNodePin = 0; + if (ImNodes::QueryNewNode(&newNodePin)) { + auto [node, pinId, isOutput] = mWorkflow->DisassembleGlobalPinId((size_t)newNodePin); + + if ((isOutput && node->GetOutputPin(pinId).IsConnected()) || + (!isOutput && node->GetInputPin(pinId).IsConnected())) + { + ImNodes::RejectNewItem(); + goto createError; + } + + if (ImNodes::AcceptNewItem()) { + ImNodes::Suspend(); + ImGui::BeginPopup("Create Node"); + ImNodes::Resume(); + } + } + } + createError: + ImNodes::EndCreate(); + + if (ImNodes::BeginDelete()) { + ImNodes::LinkId deletedLinkId; + if (ImNodes::QueryDeletedLink(&deletedLinkId)) { + // Link id is the same as our connection id + auto& conn = *mWorkflow->GetConnectionById((size_t)deletedLinkId); + + // TODO + } + } + deleteError: + ImNodes::EndDelete(); + + // Popups + ImNodes::Suspend(); + if (ImGui::BeginPopup("Node Context Menu")) { + // TODO + ImGui::EndPopup(); + } + if (ImGui::BeginPopup("Link Context Menu")) { + // TODO + ImGui::EndPopup(); + } + if (ImGui::BeginPopup("Create Node")) { + auto DisplayCandidatesCategory = [&](const char* name, std::span candidates) { + ImGui::TreeNode(name); + for (auto& candidate : candidates) { + if (ImGui::MenuItem(candidate.Name.c_str())) { + // TODO + } + } + ImGui::TreePop(); + }; + + DisplayCandidatesCategory("Numeric nodes", mWorkflowDatabase.GetNumericNodes()); + DisplayCandidatesCategory("Text nodes", mWorkflowDatabase.GetTextNodes()); + DisplayCandidatesCategory("Document nodes", mWorkflowDatabase.GetDocumentNodes()); + DisplayCandidatesCategory("User input nodes", mWorkflowDatabase.GetUserInputNodes()); + DisplayCandidatesCategory("System input nodes", mWorkflowDatabase.GetSystemInputNodes()); + DisplayCandidatesCategory("Output nodes", mWorkflowDatabase.GetOutputNodes()); + ImGui::EndPopup(); + } + if (tooltipMessage) { + ImGui::BeginTooltip(); + ImGui::TextUnformatted(tooltipMessage); + ImGui::EndTooltip(); } + ImNodes::Resume(); ImNodes::End(); } -- cgit v1.2.3-70-g09d2