#include "Template.hpp" #include "Model/GlobalStates.hpp" #include "Model/Project.hpp" #include "Utils/I18n.hpp" #include "UI/UI.hpp" #include "Utils/UUID.hpp" #include #include #include #include #include using namespace std::literals::string_view_literals; namespace fs = std::filesystem; Template::Template(Kind kind) : mKind{ kind } { } Template::Kind Template::GetKind() const { return mKind; } void TemplateAssetList::DiscoverFiles(const std::function& callback) const { auto dir = GetConnectedProject().GetTemplatesDirectory(); DiscoverFilesByExtension(callback, dir, ".cplt-template"sv); } std::string TemplateAssetList::RetrieveNameFromFile(const fs::path& file) const { std::ifstream ifs(file); if (!ifs) return ""; uint64_t len; ifs >> len; std::string name; name.reserve(len); std::copy_n(std::istreambuf_iterator(ifs), len, std::back_inserter(name)); return name; } uuids::uuid TemplateAssetList::RetrieveUuidFromFile(const fs::path& file) const { return uuids::uuid::from_string(file.stem().string()); } fs::path TemplateAssetList::RetrievePathFromAsset(const SavedAsset& asset) const { auto fileName = uuids::to_string(asset.Uuid); return GetConnectedProject().GetTemplatePath(fileName); } void TemplateAssetList::SaveEmptyInstance(const SavedAsset& asset) const { auto path = RetrievePathFromAsset(asset); std::ofstream ofs(path); if (!ofs) return; ofs << (uint64_t)asset.Name.size(); ofs << asset.Name; ofs << static_cast(asset.Payload); } Template* TemplateAssetList::CreateEmptyInstance(const SavedAsset& asset) const { auto kind = static_cast(asset.Payload); return Template::CreateByKind(kind).release(); } Template* TemplateAssetList::LoadImpl(const SavedAsset& asset) const { std::ifstream ifs(RetrievePathFromAsset(asset)); if (!ifs) return nullptr; uint32_t iKind; ifs >> iKind; auto kind = static_cast(iKind); auto tmpl = Template::CreateByKind(kind); auto res = tmpl->ReadFrom(ifs); if (res != Template::RR_Success) { return nullptr; } return tmpl.release(); } void TemplateAssetList::DisplayAssetCreator(ListState& state) { auto ValidateNewName = [&]() -> void { if (mACNewName.empty()) { mACNewNameError = NameSelectionError::Empty; return; } if (FindByName(mACNewName)) { mACNewNameError = NameSelectionError::Duplicated; return; } mACNewNameError = NameSelectionError::None; }; auto ShowNewNameErrors = [&]() -> void { switch (mACNewNameError) { case NameSelectionError::None: break; case NameSelectionError::Duplicated: ImGui::ErrorMessage(I18N_TEXT("Duplicate name", L10N_DUPLICATE_NAME_ERROR)); break; case NameSelectionError::Empty: ImGui::ErrorMessage(I18N_TEXT("Name cannot be empty", L10N_EMPTY_NAME_ERROR)); break; } }; auto ShowNewKindErrors = [&]() -> void { if (mACNewKind == Template::InvalidKind) { ImGui::ErrorMessage(I18N_TEXT("Invalid template type", L10N_TEMPLATE_INVALID_TYPE_ERROR)); } }; auto IsInputValid = [&]() -> bool { return mACNewNameError == NameSelectionError::None && mACNewKind != Template::InvalidKind; }; auto ResetState = [&]() -> void { mACNewName.clear(); mACNewKind = Template::InvalidKind; ValidateNewName(); }; if (ImGui::InputText(I18N_TEXT("Name", L10N_NAME), &mACNewName)) { ValidateNewName(); } if (ImGui::BeginCombo(I18N_TEXT("Type", L10N_TYPE), Template::FormatKind(mACNewKind))) { for (int i = 0; i < Template::KindCount; ++i) { auto kind = static_cast(i); if (ImGui::Selectable(Template::FormatKind(kind), mACNewKind == kind)) { mACNewKind = kind; } } ImGui::EndCombo(); } ShowNewNameErrors(); ShowNewKindErrors(); if (ImGui::Button(I18N_TEXT("OK", L10N_CONFIRM), !IsInputValid())) { ImGui::CloseCurrentPopup(); Create(SavedAsset{ .Name = mACNewName, .Payload = static_cast(mACNewKind), }); ResetState(); } ImGui::SameLine(); if (ImGui::Button(I18N_TEXT("Cancel", L10N_CANCEL))) { ImGui::CloseCurrentPopup(); } } void TemplateAssetList::SetupDetailsTable(const char* tableId) const { ImGui::BeginTable(tableId, 2, ImGuiTableFlags_Borders); ImGui::TableSetupColumn(I18N_TEXT("Name", L10N_NAME)); ImGui::TableSetupColumn(I18N_TEXT("Type", L10N_TYPE)); ImGui::TableHeadersRow(); } void TemplateAssetList::DrawBigIcon(ListState& state, const SavedAsset& asset) const { // TODO } void TemplateAssetList::DrawDetailsTableRow(ListState& state, const SavedAsset& asset) const { ImGui::TableNextColumn(); if (ImGui::Selectable(asset.Name.c_str(), state.SelectedAsset == &asset, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_DontClosePopups)) { state.SelectedAsset = &asset; } ImGui::TableNextColumn(); auto kind = static_cast(asset.Payload); ImGui::TextUnformatted(Template::FormatKind(kind)); }