summaryrefslogtreecommitdiff
path: root/core/src/UI
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-05-14 20:52:00 -0700
committerrtk0c <[email protected]>2021-05-14 20:52:00 -0700
commitfa13cad2bf12d8f7f63f7ff6aab07dd2eaf6ec6d (patch)
tree994198f3636030b3974f73170fc59b04a794681d /core/src/UI
parent765df313e065f8401319c68ba70cd41b0bc34c9d (diff)
Node graph editor basic functionality
Diffstat (limited to 'core/src/UI')
-rw-r--r--core/src/UI/Localization.hpp1
-rw-r--r--core/src/UI/UI_Workflows.cpp100
2 files changed, 88 insertions, 13 deletions
diff --git a/core/src/UI/Localization.hpp b/core/src/UI/Localization.hpp
index 65fcdfd..b421d24 100644
--- a/core/src/UI/Localization.hpp
+++ b/core/src/UI/Localization.hpp
@@ -19,6 +19,7 @@ public:
BasicTranslation Add{ "Generic.Add"sv };
BasicTranslation Edit{ "Generic.Edit"sv };
BasicTranslation Delete{ "Generic.Delete"sv };
+ BasicTranslation Disconnect{ "Generic.Disconnect"sv };
BasicTranslation Close{ "Generic.Close"sv };
BasicTranslation DialogConfirm{ "Generic.Dialog.Confirm"sv };
BasicTranslation DialogCancel{ "Generic.Dialog.Cancel"sv };
diff --git a/core/src/UI/UI_Workflows.cpp b/core/src/UI/UI_Workflows.cpp
index 7aefeab..1a4294f 100644
--- a/core/src/UI/UI_Workflows.cpp
+++ b/core/src/UI/UI_Workflows.cpp
@@ -138,6 +138,10 @@ private:
ImNodes::EditorContext* mContext;
WorkflowDatabase mWorkflowDatabase;
+ ImNodes::NodeId mContextMenuNodeId = 0;
+ ImNodes::PinId mContextMenuPinId = 0;
+ ImNodes::LinkId mContextMenuLinkId = 0;
+
public:
WorkflowUI()
{
@@ -152,9 +156,12 @@ public:
void Draw()
{
+ auto ls = LocaleStrings::Instance.get();
+
ImNodes::SetCurrentEditor(mContext);
ImNodes::Begin("");
+ // Defer creation of tooltip because within the node editor, cursor positioning is going to be off
const char* tooltipMessage = nullptr;
for (auto& node : mWorkflow->GetNodes()) {
@@ -180,8 +187,8 @@ public:
goto createError;
}
- auto [srcNode, srcPinId, srcIsOutput] = mWorkflow->DisassembleGlobalPinId((size_t)src);
- auto [dstNode, dstPinId, dstIsOutput] = mWorkflow->DisassembleGlobalPinId((size_t)dst);
+ auto [srcNode, srcPinId, srcIsOutput] = mWorkflow->DisassembleGlobalPinId(src);
+ auto [dstNode, dstPinId, dstIsOutput] = mWorkflow->DisassembleGlobalPinId(dst);
if (srcNode == dstNode) {
ImNodes::RejectNewItem();
@@ -208,7 +215,7 @@ public:
ImNodes::PinId newNodePin = 0;
if (ImNodes::QueryNewNode(&newNodePin)) {
- auto [node, pinId, isOutput] = mWorkflow->DisassembleGlobalPinId((size_t)newNodePin);
+ auto [node, pinId, isOutput] = mWorkflow->DisassembleGlobalPinId(newNodePin);
if ((isOutput && node->GetOutputPin(pinId).IsConnected()) ||
(!isOutput && node->GetInputPin(pinId).IsConnected()))
@@ -230,10 +237,22 @@ public:
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);
+ auto& conn = *mWorkflow->GetConnectionByLinkId(deletedLinkId);
+ mWorkflow->RemoveConnection(conn.Id);
+ }
+
+ ImNodes::NodeId deletedNodeId;
+ if (ImNodes::QueryDeletedNode(&deletedNodeId)) {
+ auto node = mWorkflow->GetNodeByNodeId(deletedNodeId);
+ if (!node) {
+ ImNodes::RejectDeletedItem();
+ goto deleteError;
+ }
- // TODO
+ if (node->IsLocked()) {
+ ImNodes::RejectDeletedItem();
+ goto deleteError;
+ }
}
}
deleteError:
@@ -241,23 +260,77 @@ public:
// Popups
ImNodes::Suspend();
+ if (ImNodes::ShowNodeContextMenu(&mContextMenuNodeId)) {
+ ImGui::OpenPopup("Node Context Menu");
+ } else if (ImNodes::ShowPinContextMenu(&mContextMenuPinId)) {
+ ImGui::OpenPopup("Pin Context Menu");
+ } else if (ImNodes::ShowLinkContextMenu(&mContextMenuLinkId)) {
+ ImGui::OpenPopup("Link Context Menu");
+ }
+
if (ImGui::BeginPopup("Node Context Menu")) {
- // TODO
+ auto& node = *mWorkflow->GetNodeByNodeId(mContextMenuNodeId);
+ node.DrawDebugInfo();
+
+ if (ImGui::MenuItem(ls->Delete.Get())) {
+ ImNodes::DeleteNode(mContextMenuNodeId);
+ }
+
ImGui::EndPopup();
}
+
+ if (ImGui::BeginPopup("Pin Context Menu")) {
+ auto [node, pinId, isOutput] = mWorkflow->DisassembleGlobalPinId(mContextMenuPinId);
+ if (isOutput) {
+ node->DrawOutputPinDebugInfo(pinId);
+ } else {
+ node->DrawInputPinDebugInfo(pinId);
+ }
+
+ if (ImGui::MenuItem(ls->Disconnect.Get())) {
+ if (isOutput) {
+ auto& pin = node->GetOutputPin(pinId);
+ if (pin.IsConnected()) {
+ auto linkId = mWorkflow->GetConnectionById(pin.Connection)->GetLinkId();
+ ImNodes::DeleteLink(linkId);
+ }
+ } else {
+ auto& pin = node->GetInputPin(pinId);
+ if (pin.IsConstantConnection()) {
+ // TODO
+ } else if (pin.IsConnected()) {
+ auto linkId = mWorkflow->GetConnectionById(pin.Connection)->GetLinkId();
+ ImNodes::DeleteLink(linkId);
+ }
+ }
+ }
+
+ ImGui::EndPopup();
+ }
+
if (ImGui::BeginPopup("Link Context Menu")) {
- // TODO
+ auto& conn = *mWorkflow->GetConnectionByLinkId(mContextMenuLinkId);
+ conn.DrawDebugInfo();
+
+ if (ImGui::MenuItem(ls->Delete.Get())) {
+ ImNodes::DeleteLink(mContextMenuLinkId);
+ }
+
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
+ if (ImGui::BeginMenu(name)) {
+ for (auto& candidate : candidates) {
+ if (ImGui::MenuItem(candidate.Name.c_str())) {
+ // Create node
+ auto uptr = candidate.Constructor();
+ mWorkflow->AddNode(std::move(uptr));
+ }
}
+ ImGui::EndMenu();
}
- ImGui::TreePop();
};
DisplayCandidatesCategory("Numeric nodes", mWorkflowDatabase.GetNumericNodes());
@@ -268,6 +341,7 @@ public:
DisplayCandidatesCategory("Output nodes", mWorkflowDatabase.GetOutputNodes());
ImGui::EndPopup();
}
+
if (tooltipMessage) {
ImGui::BeginTooltip();
ImGui::TextUnformatted(tooltipMessage);