aboutsummaryrefslogtreecommitdiff
path: root/core/src/UI/UI_Workflows.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-05-12 13:23:56 -0700
committerrtk0c <[email protected]>2021-05-12 13:34:43 -0700
commit765df313e065f8401319c68ba70cd41b0bc34c9d (patch)
tree44e0c781ed9f5ea0f98ac906e96c677d04befa27 /core/src/UI/UI_Workflows.cpp
parent6ec8cc216282396ece535941ea6ca4a63d924e8f (diff)
Start to work on actually rendering the node graph
Diffstat (limited to 'core/src/UI/UI_Workflows.cpp')
-rw-r--r--core/src/UI/UI_Workflows.cpp122
1 files changed, 113 insertions, 9 deletions
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<WorkflowNode> (*)();
enum Category
@@ -39,6 +39,7 @@ private:
Category Category;
};
+private:
std::vector<Candidate> 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<const WorkflowDatabase::Candidate> 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();
}