aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/Model/Assets.cpp9
-rw-r--r--core/src/Model/Assets.hpp9
-rw-r--r--core/src/Model/Project.cpp24
-rw-r--r--core/src/Model/Project.hpp14
-rw-r--r--core/src/Model/Template/TableTemplate.cpp10
-rw-r--r--core/src/Model/Template/Template.hpp4
-rw-r--r--core/src/Model/Template/Template_Main.cpp14
-rw-r--r--core/src/Model/Workflow/Workflow.hpp4
-rw-r--r--core/src/Model/Workflow/Workflow_Main.cpp14
-rw-r--r--core/src/UI/UI_DatabaseView.cpp10
-rw-r--r--core/src/UI/UI_Templates.cpp83
-rw-r--r--core/src/Utils/Color.hpp10
12 files changed, 147 insertions, 58 deletions
diff --git a/core/src/Model/Assets.cpp b/core/src/Model/Assets.cpp
index 64e1f22..374995d 100644
--- a/core/src/Model/Assets.cpp
+++ b/core/src/Model/Assets.cpp
@@ -21,6 +21,7 @@ Asset::Asset()
class AssetList::Private
{
public:
+ Project* ConnectedProject;
tsl::array_map<char, SavedAsset> Assets;
tsl::array_map<char, std::unique_ptr<Asset>> Cache;
int CacheSizeLimit = 0;
@@ -65,9 +66,10 @@ public:
} PopupPrivateState;
};
-AssetList::AssetList()
+AssetList::AssetList(Project& project)
: mPrivate{ std::make_unique<Private>() }
{
+ mPrivate->ConnectedProject = &project;
}
// Write an empty destructor here so std::unique_ptr's destructor can see AssetList::Private's implementation
@@ -75,6 +77,11 @@ AssetList::~AssetList()
{
}
+Project& AssetList::GetConnectedProject() const
+{
+ return *mPrivate->ConnectedProject;
+}
+
void AssetList::Reload()
{
DiscoverFiles([this](SavedAsset asset) -> void {
diff --git a/core/src/Model/Assets.hpp b/core/src/Model/Assets.hpp
index adde97b..9fd781f 100644
--- a/core/src/Model/Assets.hpp
+++ b/core/src/Model/Assets.hpp
@@ -1,8 +1,7 @@
#pragma once
#include "Utils/UUID.hpp"
-
-#include "Assets.hpp"
+#include "cplt_fwd.hpp"
#include <filesystem>
#include <iosfwd>
@@ -42,9 +41,11 @@ private:
std::unique_ptr<Private> mPrivate;
public:
- AssetList();
+ AssetList(Project& project);
virtual ~AssetList();
+ Project& GetConnectedProject() const;
+
// TODO support file watches
void Reload();
@@ -99,6 +100,8 @@ template <class T>
class AssetListTyped : public AssetList
{
public:
+ using AssetList::AssetList;
+
std::unique_ptr<T> CreateAndLoad(SavedAsset asset)
{
return std::unique_ptr<T>(static_cast<T*>(AssetList::CreateAndLoad(asset).release()));
diff --git a/core/src/Model/Project.cpp b/core/src/Model/Project.cpp
index 9f41d3a..523ee9b 100644
--- a/core/src/Model/Project.cpp
+++ b/core/src/Model/Project.cpp
@@ -14,7 +14,7 @@
namespace fs = std::filesystem;
template <class T>
-void ReadItemList(ItemList<T>& list, const fs::path& filePath)
+static void ReadItemList(ItemList<T>& list, const fs::path& filePath)
{
std::ifstream ifs(filePath);
if (ifs) {
@@ -25,9 +25,19 @@ void ReadItemList(ItemList<T>& list, const fs::path& filePath)
}
}
+static void CreateProjectSubfolders(const Project& project)
+{
+ fs::create_directory(project.GetDatabasesDirectory());
+ fs::create_directory(project.GetItemsDirectory());
+ fs::create_directory(project.GetWorkflowsDirectory());
+ fs::create_directory(project.GetTemplatesDirectory());
+}
+
Project::Project(fs::path rootPath)
: mRootPath{ std::move(rootPath) }
, mRootPathString{ mRootPath.string() }
+ , Workflows(*this)
+ , Templates(*this)
, Database(*this)
{
// TODO better diagnostic
@@ -58,18 +68,26 @@ Project::Project(fs::path rootPath)
}
}
+ CreateProjectSubfolders(*this);
+
auto itemsDir = mRootPath / "items";
ReadItemList(Products, itemsDir / "products.json");
ReadItemList(Factories, itemsDir / "factories.json");
ReadItemList(Customers, itemsDir / "customers.json");
+
+ Workflows.Reload();
+ Templates.Reload();
}
Project::Project(fs::path rootPath, std::string name)
: mRootPath{ std::move(rootPath) }
, mRootPathString{ mRootPath.string() }
, mName{ std::move(name) }
+ , Workflows(*this)
+ , Templates(*this)
, Database(*this)
{
+ CreateProjectSubfolders(*this);
}
const fs::path& Project::GetPath() const
@@ -143,9 +161,7 @@ void Project::WriteToDisk()
std::ofstream ofs(mRootPath / "cplt_project.json");
ofs << this->Serialize();
- auto itemsDir = mRootPath / "items";
- fs::create_directories(itemsDir);
-
+ auto itemsDir = GetItemsDirectory();
WriteItemList(Products, itemsDir / "products.json");
WriteItemList(Factories, itemsDir / "factories.json");
WriteItemList(Customers, itemsDir / "customers.json");
diff --git a/core/src/Model/Project.hpp b/core/src/Model/Project.hpp
index 8cf3483..17d9acb 100644
--- a/core/src/Model/Project.hpp
+++ b/core/src/Model/Project.hpp
@@ -14,24 +14,24 @@
class Project
{
-public:
- WorkflowAssetList Workflows;
- TemplateAssetList Templates;
- ItemList<ProductItem> Products;
- ItemList<FactoryItem> Factories;
- ItemList<CustomerItem> Customers;
-
private:
std::filesystem::path mRootPath;
std::string mRootPathString;
std::string mName;
+ // (Exception to style guidelines)
// This is put after the private fields, so that when XxxDatabase's constructor runs, all of them will be initialized
public:
+ WorkflowAssetList Workflows;
+ TemplateAssetList Templates;
+ ItemList<ProductItem> Products;
+ ItemList<FactoryItem> Factories;
+ ItemList<CustomerItem> Customers;
MainDatabase Database;
public:
/// Load the project from a directory containing the cplt_project.json file.
+ /// This only loads the main project file, the caller needs to
Project(std::filesystem::path rootPath);
/// Create a project with the given name in the given path. Note that the path should be a directory that will contain the project files once created.
diff --git a/core/src/Model/Template/TableTemplate.cpp b/core/src/Model/Template/TableTemplate.cpp
index 28a4d6e..f2524a0 100644
--- a/core/src/Model/Template/TableTemplate.cpp
+++ b/core/src/Model/Template/TableTemplate.cpp
@@ -88,17 +88,15 @@ void TableTemplate::Resize(int newWidth, int newHeight)
int tableWidth = GetTableWidth();
int tableHeight = GetTableHeight();
- int yEnd = std::min(tableHeight, newHeight);
- int xEnd = std::min(tableWidth, newWidth);
- for (int y = 0; y < yEnd; ++y) {
+ for (int y = 0; y < newHeight; ++y) {
if (y >= tableHeight) {
- for (int x = 0; x < xEnd; ++x) {
+ for (int x = 0; x < newWidth; ++x) {
cells.push_back(TableCell{});
}
continue;
}
- for (int x = 0; x < xEnd; ++x) {
+ for (int x = 0; x < newWidth; ++x) {
if (x >= tableWidth) {
cells.push_back(TableCell{});
} else {
@@ -109,6 +107,8 @@ void TableTemplate::Resize(int newWidth, int newHeight)
}
mCells = std::move(cells);
+ mColumnWidths.resize(newWidth);
+ mRowHeights.resize(newHeight);
}
int TableTemplate::GetRowHeight(int row) const
diff --git a/core/src/Model/Template/Template.hpp b/core/src/Model/Template/Template.hpp
index 7cfbb8b..7d43130 100644
--- a/core/src/Model/Template/Template.hpp
+++ b/core/src/Model/Template/Template.hpp
@@ -52,6 +52,10 @@ private:
NameSelectionError mACNewNameError = NameSelectionError::Empty;
Template::Kind mACNewKind = Template::InvalidKind;
+public:
+ // Inherit constructors
+ using AssetListTyped::AssetListTyped;
+
protected:
virtual void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const override;
diff --git a/core/src/Model/Template/Template_Main.cpp b/core/src/Model/Template/Template_Main.cpp
index 7dd5f87..8b659cf 100644
--- a/core/src/Model/Template/Template_Main.cpp
+++ b/core/src/Model/Template/Template_Main.cpp
@@ -25,8 +25,8 @@ Template::Kind Template::GetKind() const
void TemplateAssetList::DiscoverFiles(const std::function<void(SavedAsset)>& callback) const
{
- auto& gs = GlobalStates::GetInstance();
- DiscoverFilesByExtension(callback, gs.GetCurrentProject()->GetTemplatesDirectory(), ".cplt-template"sv);
+ auto dir = GetConnectedProject().GetTemplatesDirectory();
+ DiscoverFilesByExtension(callback, dir, ".cplt-template"sv);
}
std::string TemplateAssetList::RetrieveNameFromFile(const fs::path& file) const
@@ -46,12 +46,8 @@ uuids::uuid TemplateAssetList::RetrieveUuidFromFile(const fs::path& file) const
fs::path TemplateAssetList::RetrievePathFromAsset(const SavedAsset& asset) const
{
- auto uuid = uuids::uuid_random_generator{}();
- auto fileName = uuids::to_string(uuid);
- fileName.append(".cplt-template");
-
- auto& gs = GlobalStates::GetInstance();
- return gs.GetCurrentProject()->GetTemplatePath(fileName);
+ auto fileName = uuids::to_string(asset.Uuid);
+ return GetConnectedProject().GetTemplatePath(fileName);
}
void TemplateAssetList::SaveEmptyInstance(const SavedAsset& asset) const
@@ -183,7 +179,7 @@ void TemplateAssetList::DrawBigIcon(ListState& state, const SavedAsset& asset) c
void TemplateAssetList::DrawDetailsTableRow(ListState& state, const SavedAsset& asset) const
{
ImGui::TableNextColumn();
- if (ImGui::Selectable(asset.Name.c_str(), state.SelectedAsset == &asset, ImGuiSelectableFlags_SpanAllColumns)) {
+ if (ImGui::Selectable(asset.Name.c_str(), state.SelectedAsset == &asset, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_DontClosePopups)) {
state.SelectedAsset = &asset;
}
diff --git a/core/src/Model/Workflow/Workflow.hpp b/core/src/Model/Workflow/Workflow.hpp
index 3dc6f38..9c809bf 100644
--- a/core/src/Model/Workflow/Workflow.hpp
+++ b/core/src/Model/Workflow/Workflow.hpp
@@ -283,6 +283,10 @@ private:
NameSelectionError mACNewNameError = NameSelectionError::Empty;
public:
+ // Inherit constructors
+ using AssetListTyped::AssetListTyped;
+
+public:
virtual void DiscoverFiles(const std::function<void(SavedAsset)>& callback) const override;
virtual std::string RetrieveNameFromFile(const std::filesystem::path& file) const override;
diff --git a/core/src/Model/Workflow/Workflow_Main.cpp b/core/src/Model/Workflow/Workflow_Main.cpp
index adf944e..77b64d3 100644
--- a/core/src/Model/Workflow/Workflow_Main.cpp
+++ b/core/src/Model/Workflow/Workflow_Main.cpp
@@ -746,8 +746,8 @@ std::pair<std::unique_ptr<WorkflowNode>&, uint32_t> Workflow::AllocWorkflowStep(
void WorkflowAssetList::DiscoverFiles(const std::function<void(SavedAsset)>& callback) const
{
- auto& gs = GlobalStates::GetInstance();
- DiscoverFilesByExtension(callback, gs.GetCurrentProject()->GetWorkflowsDirectory(), ".cplt-workflow"sv);
+ auto dir = GetConnectedProject().GetWorkflowsDirectory();
+ DiscoverFilesByExtension(callback, dir, ".cplt-workflow"sv);
}
std::string WorkflowAssetList::RetrieveNameFromFile(const fs::path& file) const
@@ -767,12 +767,8 @@ uuids::uuid WorkflowAssetList::RetrieveUuidFromFile(const fs::path& file) const
fs::path WorkflowAssetList::RetrievePathFromAsset(const SavedAsset& asset) const
{
- auto uuid = uuids::uuid_random_generator{}();
- auto fileName = uuids::to_string(uuid);
- fileName.append(".cplt-workflow");
-
- auto& gs = GlobalStates::GetInstance();
- return gs.GetCurrentProject()->GetTemplatePath(fileName);
+ auto fileName = uuids::to_string(asset.Uuid);
+ return GetConnectedProject().GetTemplatePath(fileName);
}
void WorkflowAssetList::SaveEmptyInstance(const SavedAsset& asset) const
@@ -875,7 +871,7 @@ void WorkflowAssetList::DrawBigIcon(ListState& state, const SavedAsset& asset) c
void WorkflowAssetList::DrawDetailsTableRow(ListState& state, const SavedAsset& asset) const
{
ImGui::TableNextColumn();
- if (ImGui::Selectable(asset.Name.c_str(), state.SelectedAsset == &asset, ImGuiSelectableFlags_SpanAllColumns)) {
+ if (ImGui::Selectable(asset.Name.c_str(), state.SelectedAsset == &asset, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_DontClosePopups)) {
state.SelectedAsset = &asset;
}
}
diff --git a/core/src/UI/UI_DatabaseView.cpp b/core/src/UI/UI_DatabaseView.cpp
index caf81d8..40f29ca 100644
--- a/core/src/UI/UI_DatabaseView.cpp
+++ b/core/src/UI/UI_DatabaseView.cpp
@@ -225,6 +225,11 @@ public:
}
ImGui::SameLine();
+ if (ImGui::Button(ICON_FA_PLUS " " I18N_TEXT("Add", L10N_ADD))) {
+ // TODO
+ }
+
+ ImGui::SameLine();
if (ImGui::Button(ICON_FA_EDIT " " I18N_TEXT("Edit", L10N_EDIT), mSelectRow == -1)) {
ImGui::OpenPopup(mEditDialogTitle);
}
@@ -236,11 +241,6 @@ public:
}
ImGui::SameLine();
- if (ImGui::Button(ICON_FA_PLUS " " I18N_TEXT("Add", L10N_ADD))) {
- // TODO
- }
-
- ImGui::SameLine();
if (ImGui::Button(ICON_FA_TRASH " " I18N_TEXT("Delete", L10N_DELETE), mSelectRow == -1)) {
// TODO
}
diff --git a/core/src/UI/UI_Templates.cpp b/core/src/UI/UI_Templates.cpp
index e08510a..7d0251a 100644
--- a/core/src/UI/UI_Templates.cpp
+++ b/core/src/UI/UI_Templates.cpp
@@ -30,17 +30,27 @@ class TableTemplateUI : public TemplateUI
private:
std::unique_ptr<TableTemplate> mTable;
- TableCell* mSelectedCell = nullptr;
+ Vec2i mSelectionTL;
+ Vec2i mSelectionBR;
+
+ bool mDirty = false;
+ bool mFirstDraw = true;
public:
TableTemplateUI(std::unique_ptr<TableTemplate> table)
: mTable{ std::move(table) }
{
+ // TODO debug code
+ mTable->Resize(6, 2);
}
virtual void Draw() override
{
ImGui::Columns(2);
+ if (mFirstDraw) {
+ mFirstDraw = false;
+ ImGui::SetColumnWidth(0, ImGui::GetWindowWidth() * 0.15f);
+ }
DrawInspector();
ImGui::NextColumn();
@@ -55,36 +65,43 @@ private:
void DrawInspector()
{
if (ImGui::BeginTabBar("Inspector")) {
- if (ImGui::BeginTabItem("Table")) {
- DrawTableInspector();
- ImGui::EndTabItem();
- }
if (ImGui::BeginTabItem("Cell")) {
DrawCellInspector();
ImGui::EndTabItem();
}
+ if (ImGui::BeginTabItem("Table")) {
+ DrawTableInspector();
+ ImGui::EndTabItem();
+ }
ImGui::EndTabBar();
}
}
- void DrawTableInspector()
- {
- // TODO
- }
-
void DrawCellInspector()
{
- if (mSelectedCell) {
-
+ if (IsSelected()) {
+ if (mSelectionTL == mSelectionBR) {
+ auto& selectCell = mTable->GetCell(mSelectionTL);
+ // TODO
+ } else {
+ // TODO
+ }
} else {
ImGui::Text("Select a cell to edit");
}
}
+ void DrawTableInspector()
+ {
+ // TODO
+ }
+
void DrawTable()
{
constexpr int kCellSpacing = 20;
+ ImGui::BeginChild("TableTemplate");
+
int colCount = mTable->GetTableWidth();
int rowCount = mTable->GetTableHeight();
float x = 0.0f;
@@ -95,12 +112,28 @@ private:
for (int colIdx = 0; colIdx < colCount; ++colIdx) {
int colWidth = mTable->GetColumnWidth(colIdx);
+ int i = rowIdx * colCount + colIdx;
+ ImGuiID id = ImGui::GetCurrentWindow()->GetID(i);
+
+ auto p = ImGui::GetCursorPos();
+ ImGui::GetWindowDrawList()->AddRectFilled(
+ ImVec2(p.x + x, p.y + y),
+ ImVec2(p.x + x + colWidth, p.y + y + rowHeight),
+ RgbaColor(170, 204, 244).AsImU32());
+
ImRect rect{
ImVec2(x, y),
ImVec2(colWidth, rowHeight),
};
-
- // TODO
+ if (ImGui::ButtonBehavior(rect, id, nullptr, nullptr)) {
+ if (ImGui::GetIO().KeyShift && IsSelected()) {
+ // Select range
+ mSelectionBR = { colIdx, rowIdx };
+ } else {
+ // Select a single cell
+ SelectCell({ colIdx, rowIdx });
+ }
+ }
x += colWidth;
x += kCellSpacing;
@@ -109,6 +142,25 @@ private:
y += rowHeight;
y += kCellSpacing;
}
+
+ ImGui::EndChild();
+ }
+
+ bool IsSelected() const
+ {
+ return mSelectionTL.x != -1;
+ }
+
+ void ClearSelection()
+ {
+ mSelectionTL = { -1, -1 };
+ mSelectionBR = { -1, -1 };
+ }
+
+ void SelectCell(Vec2i cell)
+ {
+ mSelectionTL = cell;
+ mSelectionBR = cell;
}
};
@@ -152,7 +204,8 @@ void UI::TemplatesTab()
ImGui::OpenPopup(I18N_TEXT("Open asset", L10N_ASSET_OPEN_DIALOG_TITLE));
}
if (ImGui::BeginPopupModal(I18N_TEXT("Open asset", L10N_ASSET_OPEN_DIALOG_TITLE), &openedDummy, ImGuiWindowFlags_AlwaysAutoResize)) {
- if (ImGui::Button(I18N_TEXT("Open", L10N_OPEN), state.SelectedAsset == nullptr)) {
+ if (ImGui::Button(ICON_FA_FOLDER_OPEN " " I18N_TEXT("Open", L10N_OPEN), state.SelectedAsset == nullptr)) {
+ ImGui::CloseCurrentPopup();
auto kind = static_cast<Template::Kind>(state.SelectedAsset->Payload);
openTemplate = TemplateUI::CreateByKind(kind);
}
diff --git a/core/src/Utils/Color.hpp b/core/src/Utils/Color.hpp
index 46435c3..19227e0 100644
--- a/core/src/Utils/Color.hpp
+++ b/core/src/Utils/Color.hpp
@@ -115,6 +115,16 @@ public:
return ImColor{ v.x, v.y, v.z, v.w };
}
+ ImU32 AsImU32() const
+ {
+ ImU32 res;
+ res |= r << IM_COL32_R_SHIFT;
+ res |= g << IM_COL32_G_SHIFT;
+ res |= b << IM_COL32_B_SHIFT;
+ res |= a << IM_COL32_A_SHIFT;
+ return res;
+ }
+
constexpr void SetVec(const Vec4f& vec) noexcept
{
r = (uint8_t)(vec.x * 255.0f);