aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-06-05 19:44:54 -0700
committerrtk0c <[email protected]>2021-06-05 19:44:54 -0700
commita180e1b56025c6b7d81d2e587ad90531d29de44c (patch)
tree1c88361320371b508c81b52a28ae0579fcdd1fd7 /core
parentd3fa128d5408673b0ea8d3ba3435c38b258a5e7a (diff)
Initial work on asset system (does not compile)
Diffstat (limited to 'core')
-rw-r--r--core/CMakeLists.txt1
-rw-r--r--core/src/Model/Assets.cpp126
-rw-r--r--core/src/Model/Assets.hpp104
-rw-r--r--core/src/Model/Project.cpp139
-rw-r--r--core/src/Model/Project.hpp17
-rw-r--r--core/src/Model/Template/Template.hpp22
-rw-r--r--core/src/Model/Template/Template_Main.cpp66
-rw-r--r--core/src/Model/Template/fwd.hpp2
-rw-r--r--core/src/Model/Workflow/Workflow.hpp25
-rw-r--r--core/src/Model/Workflow/Workflow_Main.cpp56
-rw-r--r--core/src/Model/Workflow/fwd.hpp2
-rw-r--r--core/src/Model/fwd.hpp6
-rw-r--r--core/src/UI/UI_Templates.cpp44
13 files changed, 396 insertions, 214 deletions
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 8483981..64a31d7 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -33,6 +33,7 @@ set(ENTRYPOINT_MODULE_SOURCES
)
add_source_group(MODEL_MODULE_SOURCES
+ src/Model/Assets.cpp
src/Model/Database.cpp
src/Model/Filter.cpp
src/Model/GlobalStates.cpp
diff --git a/core/src/Model/Assets.cpp b/core/src/Model/Assets.cpp
new file mode 100644
index 0000000..e4eee54
--- /dev/null
+++ b/core/src/Model/Assets.cpp
@@ -0,0 +1,126 @@
+#include "Assets.hpp"
+
+#include <imgui.h>
+#include <fstream>
+#include <utility>
+
+namespace fs = std::filesystem;
+
+Asset::Asset()
+{
+}
+
+std::unique_ptr<Asset> AssetCategory::CreateEmptyUnique(const SavedAsset& diskForm) const
+{
+ return std::unique_ptr<Asset>(CreateEmpty(diskForm));
+}
+
+std::unique_ptr<Asset> AssetCategory::LoadUnique(const SavedAsset& diskForm) const
+{
+ return std::unique_ptr<Asset>(Load(diskForm));
+}
+
+void AssetCategory::DiscoverFilesByExtension(const std::function<void(SavedAsset)>& callback, const std::filesystem::path& containerDir, std::string_view extension)
+{
+ for (auto entry : fs::directory_iterator(containerDir)) {
+ if (!entry.is_regular_file()) continue;
+
+ // If the caller provided an extension to match against, and it doesn't equal to current file extension, skip
+ if (!extension.empty() &&
+ entry.path().extension() != extension)
+ {
+ continue;
+ }
+
+ callback(SavedAsset{
+ .Path = entry.path(),
+ .Name = entry.path().stem().string(),
+ });
+ }
+}
+
+void AssetCategory::DiscoverFilesByHeader(const std::function<void(SavedAsset)>& callback, const std::filesystem::__cxx11::path& containerDir, const std::function<bool(std::istream&)>& validater)
+{
+ // TODO
+}
+
+AssetList::AssetList(const AssetCategory& loader)
+ : mLoader{ &loader }
+{
+}
+
+void AssetList::Reload()
+{
+ mLoader->DiscoverFiles([this](SavedAsset asset) -> void {
+ Create(std::move(asset));
+ });
+}
+
+const SavedAsset* AssetList::FindByName(std::string_view name) const
+{
+ auto iter = mAssets.find(name);
+ if (iter != mAssets.end()) {
+ return &iter.value();
+ } else {
+ return nullptr;
+ }
+}
+
+const SavedAsset& AssetList::Create(SavedAsset asset)
+{
+ auto [iter, DISCARD] = mAssets.insert(asset.Name, SavedAsset{});
+ auto& savedAsset = iter.value();
+
+ mLoader->CreateEmpty(asset);
+ savedAsset = std::move(asset);
+
+ return savedAsset;
+}
+
+std::unique_ptr<Asset> AssetList::CreateAndLoad(SavedAsset assetIn)
+{
+ auto& savedAsset = Create(std::move(assetIn));
+ auto asset = std::unique_ptr<Asset>(mLoader->CreateEmpty(savedAsset));
+ return asset;
+}
+
+std::unique_ptr<Asset> AssetList::LoadFromDisk(std::string_view name) const
+{
+ if (auto savedAsset = FindByName(name)) {
+ auto asset = mLoader->LoadUnique(*savedAsset);
+ return asset;
+ }
+}
+
+bool AssetList::Rename(std::string_view oldName, std::string_view newName)
+{
+}
+
+bool AssetList::Remove(std::string_view name)
+{
+}
+
+int AssetList::GetCacheSizeLimit() const
+{
+ return mCacheSizeLimit;
+}
+
+void AssetList::SetCacheSizeLimit(int limit)
+{
+ mCacheSizeLimit = limit;
+}
+
+void AssetList::DrawBigIcons(DrawState& state)
+{
+ // TODO
+}
+
+void AssetList::DrawDetails(DrawState& state)
+{
+ mLoader->SetupDetailsTable("AssetDetailsTable");
+ for (auto& asset : mAssets) {
+ mLoader->DrawDetailsTableRow(asset);
+ ImGui::TableNextRow();
+ }
+ ImGui::EndTable();
+}
diff --git a/core/src/Model/Assets.hpp b/core/src/Model/Assets.hpp
new file mode 100644
index 0000000..bc5219d
--- /dev/null
+++ b/core/src/Model/Assets.hpp
@@ -0,0 +1,104 @@
+#pragma once
+
+#include <tsl/array_map.h>
+#include <filesystem>
+#include <iosfwd>
+#include <memory>
+#include <string_view>
+
+/// A structure representing a ready-to-be-loaded asset, locating on the disk.
+struct SavedAsset
+{
+ std::filesystem::path Path;
+ std::string Name;
+ /// `Path`'s string form, encoded in UTF-8.
+ std::string PathString = Path.string();
+};
+
+class Asset
+{
+public:
+ Asset();
+ virtual ~Asset() = default;
+};
+
+class AssetCategory
+{
+public:
+ virtual ~AssetCategory() = default;
+
+ virtual void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const = 0;
+
+ virtual Asset* CreateEmpty(const SavedAsset& diskForm) const = 0;
+ std::unique_ptr<Asset> CreateEmptyUnique(const SavedAsset& diskForm) const;
+ virtual Asset* Load(const SavedAsset& diskForm) const = 0;
+ std::unique_ptr<Asset> LoadUnique(const SavedAsset& diskForm) const;
+
+ /// This should call ImGui::BeginTable() along with other accessories such as setting up the header row.
+ virtual void SetupDetailsTable(const char* tableId) const = 0;
+ virtual void DrawBigIcon(const SavedAsset& asset) const = 0;
+ virtual void DrawDetailsTableRow(const SavedAsset& asset) const = 0;
+
+protected:
+ /* Helper loader functions */
+
+ static void DiscoverFilesByExtension(const std::function<void(SavedAsset)>& callback, const std::filesystem::path& containerDir, std::string_view extension);
+ static void DiscoverFilesByHeader(const std::function<void(SavedAsset)>& callback, const std::filesystem::path& containerDir, const std::function<bool(std::istream&)>& validater);
+};
+
+class AssetList
+{
+private:
+ const AssetCategory* mLoader;
+ tsl::array_map<char, SavedAsset> mAssets;
+ tsl::array_map<char, std::unique_ptr<Asset>> mCache;
+ int mCacheSizeLimit = 0;
+
+public:
+ AssetList(const AssetCategory& loader);
+
+ // TODO support file watches
+ void Reload();
+
+ const SavedAsset* FindByName(std::string_view name) const;
+ const SavedAsset& Create(SavedAsset asset);
+ std::unique_ptr<Asset> CreateAndLoad(SavedAsset asset);
+ std::unique_ptr<Asset> LoadFromDisk(std::string_view name) const;
+ bool Rename(std::string_view oldName, std::string_view newName);
+ bool Remove(std::string_view name);
+
+ int GetCacheSizeLimit() const;
+ void SetCacheSizeLimit(int limit);
+
+ struct DrawState
+ {
+ const SavedAsset* SelectedAsset = nullptr;
+ };
+ void DrawBigIcons(DrawState& state);
+ void DrawDetails(DrawState& state);
+};
+
+template <class TAsset>
+class TypedAssetList : public AssetList
+{
+public:
+ using Asset = TAsset;
+ using AssetType = typename TAsset::CategoryType;
+
+public:
+ // Import constructor
+ using AssetList::AssetList;
+
+ Asset* FindByName(std::string_view name) const
+ {
+ return static_cast<TAsset*>(AssetList::FindByName(name));
+ }
+ std::unique_ptr<Asset> Create(std::string_view name)
+ {
+ return std::unique_ptr<TAsset>(static_cast<TAsset*>(AssetList::Create(name).release()));
+ }
+ std::unique_ptr<Asset> LoadFromDisk(std::string_view name) const
+ {
+ return std::unique_ptr<TAsset>(static_cast<TAsset>(AssetList::LoadFromDisk(name)));
+ }
+};
diff --git a/core/src/Model/Project.cpp b/core/src/Model/Project.cpp
index 3cb3cb4..9f41d3a 100644
--- a/core/src/Model/Project.cpp
+++ b/core/src/Model/Project.cpp
@@ -62,23 +62,6 @@ Project::Project(fs::path rootPath)
ReadItemList(Products, itemsDir / "products.json");
ReadItemList(Factories, itemsDir / "factories.json");
ReadItemList(Customers, itemsDir / "customers.json");
-
- auto workflowsDir = mRootPath / "workflows";
- fs::create_directories(workflowsDir);
-
- for (auto& entry : fs::directory_iterator(workflowsDir)) {
- if (!entry.is_regular_file()) continue;
- auto& path = entry.path();
- if (path.extension() != ".cplt-workflow") continue;
-
- auto name = path.stem().string();
- auto [it, DISCARD] = mWorkflows.insert(name, WorkflowInfo{});
- auto& info = it.value();
-
- info.Name = std::move(name);
- info.PathStringCache = path.string();
- info.Path = path;
- }
}
Project::Project(fs::path rootPath, std::string name)
@@ -139,128 +122,6 @@ void Project::SetName(std::string name)
mName = std::move(name);
}
-const tsl::array_map<char, WorkflowInfo>& Project::GetWorkflows() const
-{
- return mWorkflows;
-}
-
-std::unique_ptr<Workflow> Project::LoadWorkflow(std::string_view name)
-{
- auto iter = mWorkflows.find(name);
- if (iter == mWorkflows.end()) {
- return iter.value().LoadFromDisk();
- } else {
- return nullptr;
- }
-}
-
-std::unique_ptr<Workflow> Project::CreateWorkflow(std::string_view name)
-{
- if (mWorkflows.find(name) != mWorkflows.end()) {
- // Workflow with name already exists
- return nullptr;
- }
-
- auto workflow = std::make_unique<Workflow>();
- auto [it, DISCARD] = mWorkflows.insert(
- name,
- WorkflowInfo{
- .Path = GetWorkflowPath(name),
- .Name = std::string(name),
- });
-
- return workflow;
-}
-
-bool Project::RemoveWorkflow(std::string_view name)
-{
- auto iter = mWorkflows.find(name);
- if (iter == mWorkflows.end()) {
- return false;
- }
- auto& info = iter.value();
-
- fs::remove(info.Path);
- mWorkflows.erase(iter);
-
- return true;
-}
-
-bool Project::RenameWorkflow(std::string_view oldName, std::string_view newName)
-{
- auto iter = mWorkflows.find(oldName);
- if (iter == mWorkflows.end()) return false;
-
- auto info = std::move(iter.value());
-
- auto& oldPath = info.Path;
- auto newPath = GetWorkflowPath(newName);
- fs::rename(oldPath, newPath);
- info.Path = std::move(newPath);
-
- mWorkflows.insert(newName, std::move(info));
- mWorkflows.erase(iter);
-
- return true;
-}
-
-const tsl::array_map<char, TemplateInfo>& Project::GetTemplates() const
-{
- return mTemplates;
-}
-
-std::unique_ptr<Template> Project::LoadTemplate(std::string_view name)
-{
- auto iter = mTemplates.find(name);
- if (iter == mTemplates.end()) {
- return iter.value().LoadFromDisk();
- } else {
- return nullptr;
- }
-}
-
-TemplateInfo* Project::InsertTemplate(std::string_view name, TemplateInfo info)
-{
- auto [it, inserted] = mTemplates.insert(name, info);
- if (inserted) {
- return &it.value();
- } else {
- return nullptr;
- }
-}
-
-bool Project::RemoveTemplate(std::string_view name)
-{
- auto iter = mTemplates.find(name);
- if (iter == mTemplates.end()) {
- return false;
- }
- auto& info = iter.value();
-
- fs::remove(info.Path);
- mTemplates.erase(iter);
-
- return true;
-}
-
-bool Project::RenameTemplate(std::string_view oldName, std::string_view newName)
-{
- auto iter = mTemplates.find(oldName);
- if (iter == mTemplates.end()) return false;
-
- auto info = std::move(iter.value());
-
- auto& oldPath = info.Path;
- auto newPath = GetTemplatePath(newName);
- fs::rename(oldPath, newPath);
- info.Path = std::move(newPath);
-
- mTemplates.insert(newName, std::move(info));
- mTemplates.erase(iter);
-
- return true;
-}
-
Json::Value Project::Serialize()
{
Json::Value root(Json::objectValue);
diff --git a/core/src/Model/Project.hpp b/core/src/Model/Project.hpp
index c971445..fea148d 100644
--- a/core/src/Model/Project.hpp
+++ b/core/src/Model/Project.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "Model/Assets.hpp"
#include "Model/Database.hpp"
#include "Model/Items.hpp"
#include "Model/Template/Template.hpp"
@@ -14,13 +15,13 @@
class Project
{
public:
+ TypedAssetList<Workflow> Workflows;
+ TypedAssetList<Template> Templates;
ItemList<ProductItem> Products;
ItemList<FactoryItem> Factories;
ItemList<CustomerItem> Customers;
private:
- tsl::array_map<char, WorkflowInfo> mWorkflows;
- tsl::array_map<char, TemplateInfo> mTemplates;
std::filesystem::path mRootPath;
std::string mRootPathString;
std::string mName;
@@ -51,18 +52,6 @@ public:
const std::string& GetName() const;
void SetName(std::string name);
- const tsl::array_map<char, WorkflowInfo>& GetWorkflows() const;
- std::unique_ptr<Workflow> LoadWorkflow(std::string_view name);
- std::unique_ptr<Workflow> CreateWorkflow(std::string_view name);
- bool RemoveWorkflow(std::string_view name);
- bool RenameWorkflow(std::string_view oldName, std::string_view newName);
-
- const tsl::array_map<char, TemplateInfo>& GetTemplates() const;
- std::unique_ptr<Template> LoadTemplate(std::string_view name);
- TemplateInfo* InsertTemplate(std::string_view name, TemplateInfo info);
- bool RemoveTemplate(std::string_view name);
- bool RenameTemplate(std::string_view oldName, std::string_view newName);
-
Json::Value Serialize();
void WriteToDisk();
};
diff --git a/core/src/Model/Template/Template.hpp b/core/src/Model/Template/Template.hpp
index 131a6ac..d876650 100644
--- a/core/src/Model/Template/Template.hpp
+++ b/core/src/Model/Template/Template.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "Model/Assets.hpp"
#include "cplt_fwd.hpp"
#include <filesystem>
@@ -7,7 +8,7 @@
#include <memory>
#include <string>
-class Template
+class Template : public Asset
{
public:
enum Kind
@@ -18,6 +19,9 @@ public:
KindCount = InvalidKind,
};
+ using CategoryType = TemplateAssetCategory;
+ static constinit const TemplateAssetCategory Category;
+
private:
Kind mKind;
@@ -32,7 +36,7 @@ public:
Kind GetKind() const;
- enum class ReadResult
+ enum ReadResult
{
RR_Success,
RR_InvalidFormat,
@@ -41,13 +45,13 @@ public:
virtual void WriteTo(std::ostream& stream) const = 0;
};
-class TemplateInfo
+class TemplateAssetCategory : public AssetCategory
{
public:
- std::filesystem::path Path;
- std::string Name;
- std::string PathStringCache = Path.string();
- Template::Kind Kind;
-
- std::unique_ptr<Template> LoadFromDisk() const;
+ virtual void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const override;
+ virtual Template* CreateEmpty(const SavedAsset& diskForm) const override;
+ virtual Template* Load(const SavedAsset& diskForm) const override;
+ virtual void SetupDetailsTable(const char* tableId) const override;
+ virtual void DrawBigIcon(const SavedAsset& asset) const override;
+ virtual void DrawDetailsTableRow(const SavedAsset& asset) const override;
};
diff --git a/core/src/Model/Template/Template_Main.cpp b/core/src/Model/Template/Template_Main.cpp
index 35da52b..9efbeae 100644
--- a/core/src/Model/Template/Template_Main.cpp
+++ b/core/src/Model/Template/Template_Main.cpp
@@ -1,5 +1,15 @@
#include "Template.hpp"
+#include "Model/GlobalStates.hpp"
+#include "Model/Project.hpp"
+
+#include <imgui.h>
+#include <fstream>
+
+using namespace std::literals::string_view_literals;
+
+constinit const TemplateAssetCategory Template::Category{};
+
Template::Template(Kind kind)
: mKind{ kind }
{
@@ -10,8 +20,60 @@ Template::Kind Template::GetKind() const
return mKind;
}
-std::unique_ptr<Template> TemplateInfo::LoadFromDisk() const
+void TemplateAssetCategory::DiscoverFiles(const std::function<void(SavedAsset)>& callback) const
{
+ auto& gs = GlobalStates::GetInstance();
+ DiscoverFilesByExtension(callback, gs.GetCurrentProject()->GetTemplatesDirectory(), ".cplt-template"sv);
+}
+
+Template* TemplateAssetCategory::CreateEmpty(const SavedAsset& diskForm) const
+{
+ // TODO
+}
+
+Template* TemplateAssetCategory::Load(const SavedAsset& diskForm) const
+{
+ std::ifstream ifs(diskForm.Path);
+ if (!ifs) return nullptr;
+
+ uint32_t iKind;
+ ifs >> iKind;
+
+ auto kind = (Template::Kind)iKind;
+ auto tmpl = Template::CreateByKind(kind);
+
+ auto res = tmpl->ReadFrom(ifs);
+ if (res != Template::RR_Success) {
+ return nullptr;
+ }
+
+ return tmpl.release();
+}
+
+void TemplateAssetCategory::SetupDetailsTable(const char* tableId) const
+{
+ ImGui::BeginTable(tableId, 3);
+
+ ImGui::TableSetupColumn("Name");
+ ImGui::TableSetupColumn("Type");
+ ImGui::TableSetupColumn("Modified time");
+ ImGui::TableHeadersRow();
+}
+
+void TemplateAssetCategory::DrawBigIcon(const SavedAsset& asset) const
+{
+ // TODO
+}
+
+void TemplateAssetCategory::DrawDetailsTableRow(const SavedAsset& asset) const
+{
+ ImGui::TableNextColumn();
+ ImGui::TextUnformatted(asset.Name.c_str());
+
+ ImGui::TableNextColumn();
+ // TODO
+ //ImGui::TextUnformatted(Template::FormatKind(asset.));
+
+ ImGui::TableNextColumn();
// TODO
- return nullptr;
}
diff --git a/core/src/Model/Template/fwd.hpp b/core/src/Model/Template/fwd.hpp
index 6bc7349..aad9f14 100644
--- a/core/src/Model/Template/fwd.hpp
+++ b/core/src/Model/Template/fwd.hpp
@@ -8,4 +8,4 @@ class TableTemplate;
// Template.hpp
class Template;
-class TemplateInfo;
+class TemplateAssetCategory;
diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp
index c57ac31..51596e5 100644
--- a/core/src/Model/Workflow/Workflow.hpp
+++ b/core/src/Model/Workflow/Workflow.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "Model/Assets.hpp"
#include "Model/Workflow/Value.hpp"
#include "Utils/Vector.hpp"
#include "cplt_fwd.hpp"
@@ -174,17 +175,12 @@ protected:
void OnDetach();
};
-struct WorkflowInfo
+class Workflow : public Asset
{
- std::filesystem::path Path;
- std::string Name;
- std::string PathStringCache = Path.string();
-
- std::unique_ptr<Workflow> LoadFromDisk() const;
-};
+public:
+ using CategoryType = WorkflowAssetCategory;
+ static constinit const WorkflowAssetCategory Category;
-class Workflow
-{
private:
friend class WorkflowNode;
friend class WorkflowEvaluationContext;
@@ -279,3 +275,14 @@ private:
std::pair<WorkflowConnection&, size_t> AllocWorkflowConnection();
std::pair<std::unique_ptr<WorkflowNode>&, size_t> AllocWorkflowStep();
};
+
+class WorkflowAssetCategory : public AssetCategory
+{
+public:
+ virtual void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const override;
+ virtual Workflow* CreateEmpty(const SavedAsset& diskForm) const override;
+ virtual Workflow* Load(const SavedAsset& diskForm) const override;
+ virtual void SetupDetailsTable(const char* tableId) const override;
+ virtual void DrawBigIcon(const SavedAsset& asset) const override;
+ virtual void DrawDetailsTableRow(const SavedAsset& asset) const override;
+};
diff --git a/core/src/Model/Workflow/Workflow_Main.cpp b/core/src/Model/Workflow/Workflow_Main.cpp
index 61cd510..0875f11 100644
--- a/core/src/Model/Workflow/Workflow_Main.cpp
+++ b/core/src/Model/Workflow/Workflow_Main.cpp
@@ -1,5 +1,8 @@
#include "Workflow.hpp"
+#include "Model/GlobalStates.hpp"
+#include "Model/Project.hpp"
+
#include <imgui.h>
#include <imgui_node_editor.h>
#include <tsl/robin_set.h>
@@ -9,6 +12,7 @@
#include <queue>
#include <utility>
+using namespace std::literals::string_view_literals;
namespace ImNodes = ax::NodeEditor;
WorkflowConnection::WorkflowConnection()
@@ -320,17 +324,49 @@ void WorkflowNode::OnDetach()
{
}
-std::unique_ptr<Workflow> WorkflowInfo::LoadFromDisk() const
+constinit const WorkflowAssetCategory Workflow::Category{};
+
+void WorkflowAssetCategory::DiscoverFiles(const std::function<void(SavedAsset)>& callback) const
+{
+ auto& gs = GlobalStates::GetInstance();
+ DiscoverFilesByExtension(callback, gs.GetCurrentProject()->GetWorkflowsDirectory(), ".cplt-workflow"sv);
+}
+
+Workflow* WorkflowAssetCategory::CreateEmpty(const SavedAsset& diskForm) const
+{
+ // TODO
+}
+
+Workflow* WorkflowAssetCategory::Load(const SavedAsset& diskForm) const
{
- std::ifstream ifs(this->Path);
+ std::ifstream ifs(diskForm.Path);
if (!ifs) return nullptr;
auto workflow = std::make_unique<Workflow>();
- if (workflow->ReadFrom(ifs) == Workflow::RR_Success) {
- return workflow;
+ if (workflow->ReadFrom(ifs) != Workflow::RR_Success) {
+ return nullptr;
}
- return nullptr;
+ return workflow.release();
+}
+
+void WorkflowAssetCategory::SetupDetailsTable(const char* tableId) const
+{
+ ImGui::BeginTable(tableId, 2);
+
+ ImGui::TableSetupColumn("Name");
+ ImGui::TableSetupColumn("Modified time");
+ ImGui::TableHeadersRow();
+}
+
+void WorkflowAssetCategory::DrawBigIcon(const SavedAsset& asset) const
+{
+ // TODO
+}
+
+void WorkflowAssetCategory::DrawDetailsTableRow(const SavedAsset& asset) const
+{
+ // TODO
}
const std::vector<WorkflowConnection>& Workflow::GetConnections() const
@@ -717,6 +753,16 @@ void Workflow::WriteTo(std::ostream& stream)
}
}
+void Workflow::DrawBigIcon() const
+{
+ // TODO
+}
+
+void Workflow::DrawDetailTableRow() const
+{
+ // TODO
+}
+
std::pair<WorkflowConnection&, size_t> Workflow::AllocWorkflowConnection()
{
for (size_t idx = 0; idx < mConnections.size(); ++idx) {
diff --git a/core/src/Model/Workflow/fwd.hpp b/core/src/Model/Workflow/fwd.hpp
index d118fe8..8f0263d 100644
--- a/core/src/Model/Workflow/fwd.hpp
+++ b/core/src/Model/Workflow/fwd.hpp
@@ -18,5 +18,5 @@ class BaseObjectValue;
// Workflow.hpp
class WorkflowConnection;
class WorkflowNode;
-struct WorkflowInfo;
class Workflow;
+class WorkflowAssetCategory;
diff --git a/core/src/Model/fwd.hpp b/core/src/Model/fwd.hpp
index cb7c7dd..ba7b156 100644
--- a/core/src/Model/fwd.hpp
+++ b/core/src/Model/fwd.hpp
@@ -11,6 +11,12 @@ class DeliveryTable;
class MainDatabase;
// Assets.hpp
+struct SavedAsset;
+class Asset;
+class AssetCategory;
+class AssetList;
+template <class T>
+class TypedAssetList;
// Filter.hpp
class TableRowsFilter;
diff --git a/core/src/UI/UI_Templates.cpp b/core/src/UI/UI_Templates.cpp
index 4f6e69e..7ebb9e1 100644
--- a/core/src/UI/UI_Templates.cpp
+++ b/core/src/UI/UI_Templates.cpp
@@ -130,41 +130,17 @@ std::unique_ptr<TemplateUI> TemplateUI::CreateByKind(Template::Kind kind)
case Template::InvalidKind: return nullptr;
}
}
-
-struct DrawTemplateList_State
-{
- // Internal data
-
- // Items that are intended for user usage
- const TemplateInfo* SelectedTemplate = nullptr;
-};
-
-void DrawTemplateList(DrawTemplateList_State& state)
-{
- auto& gs = GlobalStates::GetInstance();
- auto& templates = gs.GetCurrentProject()->GetTemplates();
-
- for (auto& info : templates) {
- if (ImGui::Selectable(info.Name.c_str(), state.SelectedTemplate == &info)) {
- state.SelectedTemplate = &info;
- }
- if (ImGui::IsItemHovered()) {
- ImGui::BeginTooltip();
- ImGui::Text("Path: %s", info.PathStringCache.c_str());
- ImGui::EndTooltip();
- }
- }
-}
} // namespace
void UI::TemplatesTab()
{
auto ls = LocaleStrings::Instance.get();
auto& gs = GlobalStates::GetInstance();
+ auto& project = *gs.GetCurrentProject();
bool openedDummy = true;
static std::unique_ptr<TemplateUI> openTemplate;
- static DrawTemplateList_State state;
+ static AssetList::DrawState state;
// Toolbar item: close
if (ImGui::Button(ls->Close.Get(), openTemplate == nullptr)) {
@@ -177,11 +153,11 @@ void UI::TemplatesTab()
ImGui::OpenPopup("Open template");
}
if (ImGui::BeginPopupModal("Open template", &openedDummy, ImGuiWindowFlags_AlwaysAutoResize)) {
- DrawTemplateList(state);
+ project.Templates.DrawDetails(state);
- if (state.SelectedTemplate) {
- auto kind = state.SelectedTemplate->Kind;
- auto tmpl = state.SelectedTemplate->LoadFromDisk();
+ if (state.SelectedAsset) {
+ auto kind = state.SelectedAsset->Kind;
+ auto tmpl = state.SelectedAsset->LoadFromDisk();
openTemplate = TemplateUI::CreateByKind(kind, std::move(tmpl));
}
@@ -194,7 +170,7 @@ void UI::TemplatesTab()
ImGui::OpenPopup("Manage templates");
}
if (ImGui::BeginPopupModal("Manage templates", &openedDummy, ImGuiWindowFlags_AlwaysAutoResize)) {
- DrawTemplateList(state);
+ project.Templates.DrawDetails(state);
enum class NameSelectionError
{
@@ -257,8 +233,6 @@ void UI::TemplatesTab()
}
if (ImGui::Button(ls->DialogConfirm.Get(), IsInputValid())) {
- auto& project = *gs.GetCurrentProject();
-
project.InsertTemplate(
newName,
TemplateInfo{
@@ -280,6 +254,7 @@ void UI::TemplatesTab()
ImGui::EndPopup();
}
+ ImGui::SameLine();
if (ImGui::Button(ls->Rename.Get(), state.SelectedTemplate == nullptr)) {
ImGui::OpenPopup("Rename template");
newName.clear();
@@ -292,7 +267,7 @@ void UI::TemplatesTab()
if (ImGui::Button(ls->DialogConfirm.Get(), IsInputValid())) {
auto& project = *gs.GetCurrentProject();
- project.RenameTemplate(
+ project.Templates.Rename(
state.SelectedTemplate->Name,
newName);
@@ -309,6 +284,7 @@ void UI::TemplatesTab()
ImGui::EndPopup();
}
+ ImGui::SameLine();
if (ImGui::Button(ls->Delete.Get(), state.SelectedTemplate == nullptr)) {
ImGui::OpenPopup("Delete confirmation");
}