diff options
-rw-r--r-- | core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | core/src/Model/Assets.cpp | 126 | ||||
-rw-r--r-- | core/src/Model/Assets.hpp | 104 | ||||
-rw-r--r-- | core/src/Model/Project.cpp | 139 | ||||
-rw-r--r-- | core/src/Model/Project.hpp | 17 | ||||
-rw-r--r-- | core/src/Model/Template/Template.hpp | 22 | ||||
-rw-r--r-- | core/src/Model/Template/Template_Main.cpp | 66 | ||||
-rw-r--r-- | core/src/Model/Template/fwd.hpp | 2 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow.hpp | 25 | ||||
-rw-r--r-- | core/src/Model/Workflow/Workflow_Main.cpp | 56 | ||||
-rw-r--r-- | core/src/Model/Workflow/fwd.hpp | 2 | ||||
-rw-r--r-- | core/src/Model/fwd.hpp | 6 | ||||
-rw-r--r-- | core/src/UI/UI_Templates.cpp | 44 |
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"); } |