diff options
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/Model/Workflow/Workflow.hpp | 17 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow_RTTI.cpp | 83 | ||||
-rw-r--r-- | core/src/UI/UI_Workflows.cpp | 143 |
3 files changed, 108 insertions, 135 deletions
diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp index 9c809bf..cba0d72 100644 --- a/core/src/Model/Workflow/Workflow.hpp +++ b/core/src/Model/Workflow/Workflow.hpp @@ -7,6 +7,7 @@ #include <imgui_node_editor.h> #include <cstddef> +#include <span> #include <cstdint> #include <filesystem> #include <functional> @@ -72,6 +73,19 @@ public: KindCount = InvalidKind, }; + enum Category + { + CG_Numeric, + CG_Text, + CG_Document, + CG_UserInput, + CG_SystemInput, + CG_Output, + + InvalidCategory, + CategoryCount = InvalidCategory, + }; + struct InputPin { uint32_t Connection = WorkflowConnection::kInvalidId; @@ -108,7 +122,10 @@ protected: public: static const char* FormatKind(Kind kind); + static const char* FormatCategory(Category category); static const char* FormatType(Type type); + static Category QueryCategory(Kind kind); + static std::span<const Kind> QueryCategoryMembers(Category category); static std::unique_ptr<WorkflowNode> CreateByKind(Kind kind); static bool IsInstance(const WorkflowNode* node); diff --git a/core/src/Model/Workflow/Workflow_RTTI.cpp b/core/src/Model/Workflow/Workflow_RTTI.cpp index 579fb3b..cb66c69 100644 --- a/core/src/Model/Workflow/Workflow_RTTI.cpp +++ b/core/src/Model/Workflow/Workflow_RTTI.cpp @@ -27,6 +27,21 @@ const char* WorkflowNode::FormatKind(Kind kind) return ""; } +const char* WorkflowNode::FormatCategory(WorkflowNode::Category category) +{ + switch (category) { + case CG_Numeric: return I18N_TEXT("Numeric", L10N_WORKFLOW_CATEGORY_NUMERIC); + case CG_Text: return I18N_TEXT("Text", L10N_WORKFLOW_CATEGORY_TEXT); + case CG_Document: return I18N_TEXT("Document", L10N_WORKFLOW_CATEGORY_DOCUMENT); + case CG_UserInput: return I18N_TEXT("User input", L10N_WORKFLOW_CATEGORY_USER_INPUT); + case CG_SystemInput: return I18N_TEXT("System input", L10N_WORKFLOW_CATEGORY_SYS_INPUT); + case CG_Output: return I18N_TEXT("Output", L10N_WORKFLOW_CATEGORY_OUTPUT); + + case InvalidCategory: break; + } + return ""; +} + const char* WorkflowNode::FormatType(Type type) { switch (type) { @@ -37,6 +52,73 @@ const char* WorkflowNode::FormatType(Type type) return ""; } +WorkflowNode::Category WorkflowNode::QueryCategory(Kind kind) +{ + switch (kind) { + case KD_NumericAddition: + case KD_NumericSubtraction: + case KD_NumericMultiplication: + case KD_NumericDivision: + case KD_NumericExpression: + return CG_Numeric; + case KD_TextFormatting: + return CG_Text; + case KD_DocumentTemplateExpansion: + return CG_Document; + case KD_FormInput: + case KD_DatabaseRowsInput: + return CG_UserInput; + + case InvalidKind: break; + } + return InvalidCategory; +} + +std::span<const WorkflowNode::Kind> WorkflowNode::QueryCategoryMembers(Category category) +{ + constexpr WorkflowNode::Kind kNumeric[] = { + KD_NumericAddition, + KD_NumericSubtraction, + KD_NumericMultiplication, + KD_NumericDivision, + KD_NumericExpression, + }; + + constexpr WorkflowNode::Kind kText[] = { + KD_TextFormatting, + }; + + constexpr WorkflowNode::Kind kDocument[] = { + KD_DocumentTemplateExpansion, + }; + + constexpr WorkflowNode::Kind kUserInput[] = { + KD_FormInput, + KD_DatabaseRowsInput, + }; + + // TODO remove invalid kinds after we have nodes of these categories + constexpr WorkflowNode::Kind kSystemInput[] = { + InvalidKind, + }; + + constexpr WorkflowNode::Kind kOutput[] = { + InvalidKind, + }; + + switch (category) { + case CG_Numeric: return kNumeric; + case CG_Text: return kText; + case CG_Document: return kDocument; + case CG_UserInput: return kUserInput; + case CG_SystemInput: return kSystemInput; + case CG_Output: return kOutput; + + case InvalidCategory: break; + } + return {}; +} + std::unique_ptr<WorkflowNode> WorkflowNode::CreateByKind(WorkflowNode::Kind kind) { switch (kind) { @@ -44,7 +126,6 @@ std::unique_ptr<WorkflowNode> WorkflowNode::CreateByKind(WorkflowNode::Kind kind case KD_NumericSubtraction: return std::make_unique<NumericOperationNode>(NumericOperationNode::Subtraction); case KD_NumericMultiplication: return std::make_unique<NumericOperationNode>(NumericOperationNode::Multiplication); case KD_NumericDivision: return std::make_unique<NumericOperationNode>(NumericOperationNode::Division); - case KD_NumericExpression: return std::make_unique<NumericExpressionNode>(); case KD_TextFormatting: return std::make_unique<TextFormatterNode>(); case KD_DocumentTemplateExpansion: return std::make_unique<DocumentTemplateExpansionNode>(); diff --git a/core/src/UI/UI_Workflows.cpp b/core/src/UI/UI_Workflows.cpp index 68fd3ee..e61e934 100644 --- a/core/src/UI/UI_Workflows.cpp +++ b/core/src/UI/UI_Workflows.cpp @@ -21,126 +21,10 @@ namespace ImNodes = ax::NodeEditor; namespace { -enum class WorkflowCategory -{ - Numeric, - Text, - Documents, - UserInput, - SystemInput, - Output, -}; - -class WorkflowDatabase -{ -public: - using WorkflowNodeConstructor = std::unique_ptr<WorkflowNode> (*)(); - - struct Candidate - { - WorkflowNodeConstructor Constructor; - std::string Name; - WorkflowCategory Category; - }; - -private: - std::vector<Candidate> mCandidates; - - int mTextOffset; - int mDocumentOffset; - int mUserInputOffset; - int mSystemInputNodes; - int mOutputOffset; - -public: - // clang-format off - std::span<Candidate> GetNumericNodes() { return { &mCandidates[0], (size_t)(mTextOffset - 0) }; }; - std::span<Candidate> GetTextNodes() { return { &mCandidates[mTextOffset], (size_t)(mDocumentOffset - mTextOffset) }; }; - std::span<Candidate> GetDocumentNodes() { return { &mCandidates[mDocumentOffset], (size_t)(mUserInputOffset - mDocumentOffset) }; }; - std::span<Candidate> GetUserInputNodes() { return { &mCandidates[mUserInputOffset], (size_t)(mSystemInputNodes - mUserInputOffset) }; }; - std::span<Candidate> GetSystemInputNodes() { return { &mCandidates[mSystemInputNodes], (size_t)(mOutputOffset - mSystemInputNodes) }; }; - std::span<Candidate> GetOutputNodes() { return { &mCandidates[mOutputOffset], (size_t)(mCandidates.size() - mOutputOffset) }; }; - // clang-format on - -public: - static WorkflowDatabase& GetInstance() - { - static WorkflowDatabase database; - return database; - } - -public: - WorkflowDatabase() - { - // Numeric nodes offset start at 0 - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<NumericOperationNode>(NumericOperationNode::Addition); }, - .Name = I18N_TEXT("Add", L10N_WORKFLOW_ADD), - .Category = WorkflowCategory::Numeric, - }); - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<NumericOperationNode>(NumericOperationNode::Subtraction); }, - .Name = I18N_TEXT("Subtract", L10N_WORKFLOW_SUB), - .Category = WorkflowCategory::Numeric, - }); - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<NumericOperationNode>(NumericOperationNode::Multiplication); }, - .Name = I18N_TEXT("Multiply", L10N_WORKFLOW_MUL), - .Category = WorkflowCategory::Numeric, - }); - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<NumericOperationNode>(NumericOperationNode::Division); }, - .Name = I18N_TEXT("Divide", L10N_WORKFLOW_DIV), - .Category = WorkflowCategory::Numeric, - }); - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<NumericExpressionNode>(); }, - .Name = I18N_TEXT("Evaluate expression", L10N_WORKFLOW_EVAL), - .Category = WorkflowCategory::Numeric, - }); - - mTextOffset = mCandidates.size(); - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<TextFormatterNode>(); }, - .Name = I18N_TEXT("Format text", L10N_WORKFLOW_FMT), - .Category = WorkflowCategory::Text, - }); - - mDocumentOffset = mCandidates.size(); - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<DocumentTemplateExpansionNode>(); }, - .Name = I18N_TEXT("Expand template", L10N_WORKFLOW_INSTANTIATE_TEMPLATE), - .Category = WorkflowCategory::Documents, - }); - - /* Inputs */ - - mUserInputOffset = mCandidates.size(); - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<FormInputNode>(); }, - .Name = I18N_TEXT("Form input", L10N_WORKFLOW_FORM_INPUT), - .Category = WorkflowCategory::UserInput, - }); - - mCandidates.push_back(Candidate{ - .Constructor = []() -> std::unique_ptr<WorkflowNode> { return std::make_unique<DatabaseRowsInputNode>(); }, - .Name = I18N_TEXT("Database input", L10N_WORKFLOW_DB_INPUT), - .Category = WorkflowCategory::UserInput, - }); - - mSystemInputNodes = mCandidates.size(); - - /* Outputs */ - - mOutputOffset = mCandidates.size(); - } -}; - class WorkflowUI { private: std::unique_ptr<Workflow> mWorkflow; - WorkflowDatabase* mWorkflowDb; ImNodes::EditorContext* mContext; @@ -152,7 +36,6 @@ public: WorkflowUI(std::unique_ptr<Workflow> workflow) : mWorkflow{ std::move(workflow) } { - mWorkflowDb = &WorkflowDatabase::GetInstance(); mContext = ImNodes::CreateEditor(); } @@ -325,25 +208,21 @@ public: } if (ImGui::BeginPopup("CreateNodeCtxMenu")) { - auto DisplayCandidatesCategory = [&](const char* name, std::span<const WorkflowDatabase::Candidate> candidates) { - if (ImGui::BeginMenu(name)) { - for (auto& candidate : candidates) { - if (ImGui::MenuItem(candidate.Name.c_str())) { + for (int i = WorkflowNode::CG_Numeric; i < WorkflowNode::InvalidCategory; ++i) { + auto category = (WorkflowNode::Category)i; + auto members = WorkflowNode::QueryCategoryMembers(category); + + if (ImGui::BeginMenu(WorkflowNode::FormatCategory(category))) { + for (auto member : members) { + if (ImGui::MenuItem(WorkflowNode::FormatKind(member))) { // Create node - auto uptr = candidate.Constructor(); + auto uptr = WorkflowNode::CreateByKind(member); mWorkflow->AddNode(std::move(uptr)); } } ImGui::EndMenu(); } - }; - - DisplayCandidatesCategory(I18N_TEXT("Numeric", L10N_WORKFLOW_CATEGORY_NUMERIC), mWorkflowDb->GetNumericNodes()); - DisplayCandidatesCategory(I18N_TEXT("Text", L10N_WORKFLOW_CATEGORY_TEXT), mWorkflowDb->GetTextNodes()); - DisplayCandidatesCategory(I18N_TEXT("Document", L10N_WORKFLOW_CATEGORY_DOCUMENT), mWorkflowDb->GetDocumentNodes()); - DisplayCandidatesCategory(I18N_TEXT("User input", L10N_WORKFLOW_CATEGORY_USER_INPUT), mWorkflowDb->GetUserInputNodes()); - DisplayCandidatesCategory(I18N_TEXT("System input", L10N_WORKFLOW_CATEGORY_SYS_INPUT), mWorkflowDb->GetSystemInputNodes()); - DisplayCandidatesCategory(I18N_TEXT("Output", L10N_WORKFLOW_CATEGORY_OUTPUT), mWorkflowDb->GetOutputNodes()); + } ImGui::EndPopup(); } @@ -356,10 +235,6 @@ public: ImNodes::End(); } - - void DisplayNodeList() - { - } }; } // namespace |