aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/src/Locale/zh_CN.h9
-rw-r--r--core/src/Model/Template/TableTemplate.cpp4
-rw-r--r--core/src/Model/Template/Template_Main.cpp10
-rw-r--r--core/src/Model/Workflow/Workflow_Main.cpp10
-rw-r--r--core/src/UI/UI_Templates.cpp218
5 files changed, 206 insertions, 45 deletions
diff --git a/core/src/Locale/zh_CN.h b/core/src/Locale/zh_CN.h
index 478c627..b01017f 100644
--- a/core/src/Locale/zh_CN.h
+++ b/core/src/Locale/zh_CN.h
@@ -81,3 +81,12 @@
#define L10N_DELETE_ASSET_DIALOG_TITLE "确认删除资源"
#define L10N_RENAME_ASSET_DIALOG_TITLE "重命名资源"
#define L10N_TEMPLATE_INVALID_TYPE_ERROR "无效的模板类型"
+
+#define L10N_TABLE_CELL_HORIZONTAL_ALIGNMENT "水平对齐"
+#define L10N_TABLE_CELL_VERTICAL_ALIGNMENT "垂直对齐"
+#define L10N_TABLE_CELL_ALIGN_LEFT "左对齐"
+#define L10N_TABLE_CELL_ALIGN_CENTER "居中"
+#define L10N_TABLE_CELL_ALIGN_RIGHT "右对齐"
+#define L10N_TABLE_CELL_ALIGN_TOP "顶部对齐"
+#define L10N_TABLE_CELL_ALIGN_MIDDLE "居中"
+#define L10N_TABLE_CELL_ALIGN_BOTTOM "底部对齐"
diff --git a/core/src/Model/Template/TableTemplate.cpp b/core/src/Model/Template/TableTemplate.cpp
index f2524a0..be61606 100644
--- a/core/src/Model/Template/TableTemplate.cpp
+++ b/core/src/Model/Template/TableTemplate.cpp
@@ -107,8 +107,8 @@ void TableTemplate::Resize(int newWidth, int newHeight)
}
mCells = std::move(cells);
- mColumnWidths.resize(newWidth);
- mRowHeights.resize(newHeight);
+ mColumnWidths.resize(newWidth, 80);
+ mRowHeights.resize(newHeight, 20);
}
int TableTemplate::GetRowHeight(int row) const
diff --git a/core/src/Model/Template/Template_Main.cpp b/core/src/Model/Template/Template_Main.cpp
index 8b659cf..a681c4a 100644
--- a/core/src/Model/Template/Template_Main.cpp
+++ b/core/src/Model/Template/Template_Main.cpp
@@ -8,6 +8,8 @@
#include <imgui.h>
#include <imgui_stdlib.h>
+#include <algorithm>
+#include <cstdint>
#include <fstream>
using namespace std::literals::string_view_literals;
@@ -34,8 +36,13 @@ std::string TemplateAssetList::RetrieveNameFromFile(const fs::path& file) const
std::ifstream ifs(file);
if (!ifs) return "";
+ uint64_t len;
+ ifs >> len;
+
std::string name;
- ifs >> name;
+ name.reserve(len);
+ std::copy_n(std::istreambuf_iterator(ifs), len, std::back_inserter(name));
+
return name;
}
@@ -56,6 +63,7 @@ void TemplateAssetList::SaveEmptyInstance(const SavedAsset& asset) const
std::ofstream ofs(path);
if (!ofs) return;
+ ofs << (uint64_t)asset.Name.size();
ofs << asset.Name;
ofs << static_cast<Template::Kind>(asset.Payload);
}
diff --git a/core/src/Model/Workflow/Workflow_Main.cpp b/core/src/Model/Workflow/Workflow_Main.cpp
index 77b64d3..af5103d 100644
--- a/core/src/Model/Workflow/Workflow_Main.cpp
+++ b/core/src/Model/Workflow/Workflow_Main.cpp
@@ -10,7 +10,9 @@
#include <imgui_node_editor.h>
#include <imgui_stdlib.h>
#include <tsl/robin_set.h>
+#include <algorithm>
#include <cassert>
+#include <cstdint>
#include <fstream>
#include <iostream>
#include <queue>
@@ -755,8 +757,13 @@ std::string WorkflowAssetList::RetrieveNameFromFile(const fs::path& file) const
std::ifstream ifs(file);
if (!ifs) return "";
+ uint64_t len;
+ ifs >> len;
+
std::string name;
- ifs >> name;
+ name.reserve(len);
+ std::copy_n(std::istreambuf_iterator(ifs), len, std::back_inserter(name));
+
return name;
}
@@ -777,6 +784,7 @@ void WorkflowAssetList::SaveEmptyInstance(const SavedAsset& asset) const
std::ofstream ofs(path);
if (!ofs) return;
+ ofs << (uint64_t)asset.Name.size();
ofs << asset.Name;
}
diff --git a/core/src/UI/UI_Templates.cpp b/core/src/UI/UI_Templates.cpp
index 7d0251a..48393dc 100644
--- a/core/src/UI/UI_Templates.cpp
+++ b/core/src/UI/UI_Templates.cpp
@@ -1,4 +1,4 @@
-#include "UI.hpp"
+#include "UI.hpp"
#include "Model/GlobalStates.hpp"
#include "Model/Project.hpp"
@@ -22,7 +22,7 @@ public:
static std::unique_ptr<TemplateUI> CreateByKind(Template::Kind kind);
virtual ~TemplateUI() = default;
- virtual void Draw() = 0;
+ virtual void Display() = 0;
};
class TableTemplateUI : public TemplateUI
@@ -30,6 +30,14 @@ class TableTemplateUI : public TemplateUI
private:
std::unique_ptr<TableTemplate> mTable;
+ struct UICell
+ {
+ bool Hovered = false;
+ bool Held = false;
+ bool Selected = false;
+ };
+ std::vector<UICell> mUICells;
+
Vec2i mSelectionTL;
Vec2i mSelectionBR;
@@ -39,12 +47,14 @@ private:
public:
TableTemplateUI(std::unique_ptr<TableTemplate> table)
: mTable{ std::move(table) }
+ , mSelectionTL{ -1, -1 }
+ , mSelectionBR{ -1, -1 }
{
// TODO debug code
- mTable->Resize(6, 2);
+ Resize(6, 5);
}
- virtual void Draw() override
+ virtual void Display() override
{
ImGui::Columns(2);
if (mFirstDraw) {
@@ -52,60 +62,122 @@ public:
ImGui::SetColumnWidth(0, ImGui::GetWindowWidth() * 0.15f);
}
- DrawInspector();
+ DisplayInspector();
ImGui::NextColumn();
- DrawTable();
+ DisplayTable();
ImGui::NextColumn();
ImGui::Columns(1);
}
+ void Resize(int width, int height)
+ {
+ mTable->Resize(width, height);
+ mUICells.resize(width * height);
+ }
+
private:
- void DrawInspector()
+ void DisplayInspector()
{
if (ImGui::BeginTabBar("Inspector")) {
if (ImGui::BeginTabItem("Cell")) {
- DrawCellInspector();
+ if (!IsSelected()) {
+ ImGui::Text("Select a cell to edit");
+ } else if (mSelectionTL == mSelectionBR) {
+ auto& selectCell = mTable->GetCell(mSelectionTL);
+ DisplayCellProperties(mSelectionTL);
+ } else {
+ DisplayRangeProperties(mSelectionTL, mSelectionBR);
+ }
ImGui::EndTabItem();
}
+
if (ImGui::BeginTabItem("Table")) {
- DrawTableInspector();
+ DisplayTableInspector();
ImGui::EndTabItem();
}
+
ImGui::EndTabBar();
}
}
- void DrawCellInspector()
+ void DisplayCellProperties(Vec2i pos)
{
- if (IsSelected()) {
- if (mSelectionTL == mSelectionBR) {
- auto& selectCell = mTable->GetCell(mSelectionTL);
- // TODO
- } else {
- // TODO
+ auto& cell = mTable->GetCell(pos);
+ auto& uiCell = mUICells[pos.y * mTable->GetTableWidth() + pos.x];
+
+ constexpr auto kLeft = I18N_TEXT("Left", L10N_TABLE_CELL_ALIGN_LEFT);
+ constexpr auto kCenter = I18N_TEXT("Center", L10N_TABLE_CELL_ALIGN_CENTER);
+ constexpr auto kRight = I18N_TEXT("Right", L10N_TABLE_CELL_ALIGN_RIGHT);
+
+ const char* horizontalText;
+ switch (cell.HorizontalAlignment) {
+ case TableCell::AlignAxisMin: horizontalText = kLeft; break;
+ case TableCell::AlignCenter: horizontalText = kCenter; break;
+ case TableCell::AlignAxisMax: horizontalText = kRight; break;
+ }
+
+ if (ImGui::BeginCombo(I18N_TEXT("Horizontal alignment", L10N_TABLE_CELL_HORIZONTAL_ALIGNMENT), horizontalText)) {
+ if (ImGui::Selectable(kLeft, cell.HorizontalAlignment == TableCell::AlignAxisMin)) {
+ cell.HorizontalAlignment = TableCell::AlignAxisMin;
+ }
+ if (ImGui::Selectable(kCenter, cell.HorizontalAlignment == TableCell::AlignCenter)) {
+ cell.HorizontalAlignment = TableCell::AlignCenter;
}
- } else {
- ImGui::Text("Select a cell to edit");
+ if (ImGui::Selectable(kRight, cell.HorizontalAlignment == TableCell::AlignAxisMax)) {
+ cell.HorizontalAlignment = TableCell::AlignAxisMax;
+ }
+ ImGui::EndCombo();
+ }
+
+ constexpr auto kTop = I18N_TEXT("Left", L10N_TABLE_CELL_ALIGN_TOP);
+ constexpr auto kMiddle = I18N_TEXT("Middle", L10N_TABLE_CELL_ALIGN_MIDDLE);
+ constexpr auto kBottom = I18N_TEXT("Right", L10N_TABLE_CELL_ALIGN_BOTTOM);
+
+ const char* verticalText;
+ switch (cell.VerticalAlignment) {
+ case TableCell::AlignAxisMin: verticalText = kTop; break;
+ case TableCell::AlignCenter: verticalText = kMiddle; break;
+ case TableCell::AlignAxisMax: verticalText = kBottom; break;
+ }
+
+ if (ImGui::BeginCombo(I18N_TEXT("Vertical alignment", L10N_TABLE_CELL_VERTICAL_ALIGNMENT), verticalText)) {
+ if (ImGui::Selectable(kTop, cell.VerticalAlignment == TableCell::AlignAxisMin)) {
+ cell.VerticalAlignment = TableCell::AlignAxisMin;
+ }
+ if (ImGui::Selectable(kMiddle, cell.VerticalAlignment == TableCell::AlignCenter)) {
+ cell.VerticalAlignment = TableCell::AlignCenter;
+ }
+ if (ImGui::Selectable(kBottom, cell.VerticalAlignment == TableCell::AlignAxisMax)) {
+ cell.VerticalAlignment = TableCell::AlignAxisMax;
+ }
+ ImGui::EndCombo();
}
}
- void DrawTableInspector()
+ void DisplayRangeProperties(Vec2i tl, Vec2i br)
{
// TODO
}
- void DrawTable()
+ void DisplayTableInspector()
{
- constexpr int kCellSpacing = 20;
+ // TODO
+ }
+ void DisplayTable()
+ {
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8));
ImGui::BeginChild("TableTemplate");
+ auto regularColor = ImGui::GetColorU32(ImGuiCol_Button);
+ auto hoveredColor = ImGui::GetColorU32(ImGuiCol_ButtonHovered);
+ auto activeColor = ImGui::GetColorU32(ImGuiCol_ButtonActive);
+ auto navHighlight = ImGui::GetColorU32(ImGuiCol_NavHighlight);
+
int colCount = mTable->GetTableWidth();
int rowCount = mTable->GetTableHeight();
- float x = 0.0f;
- float y = 0.0f;
for (int rowIdx = 0; rowIdx < rowCount; ++rowIdx) {
int rowHeight = mTable->GetRowHeight(rowIdx);
@@ -113,37 +185,69 @@ private:
int colWidth = mTable->GetColumnWidth(colIdx);
int i = rowIdx * colCount + colIdx;
- ImGuiID id = ImGui::GetCurrentWindow()->GetID(i);
+ auto window = ImGui::GetCurrentWindow();
+ auto id = window->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());
+ Vec2i cellLoc{ colIdx, rowIdx };
+ auto& cell = mTable->GetCell(cellLoc);
+ auto& uiCell = mUICells[i];
+ ImVec2 size(colWidth, rowHeight);
ImRect rect{
- ImVec2(x, y),
- ImVec2(colWidth, rowHeight),
+ window->DC.CursorPos,
+ window->DC.CursorPos + ImGui::CalcItemSize(size, 0.0f, 0.0f),
};
- if (ImGui::ButtonBehavior(rect, id, nullptr, nullptr)) {
+
+ if (uiCell.Selected) {
+ window->DrawList->AddRectFilled(
+ rect.Min - ImVec2(2, 1),
+ rect.Max + ImVec2(2, 1),
+ navHighlight);
+ } else {
+ ImU32 color;
+ if (uiCell.Held) {
+ color = activeColor;
+ } else if (uiCell.Hovered) {
+ color = hoveredColor;
+ } else {
+ color = regularColor;
+ }
+ window->DrawList->AddRectFilled(rect.Min, rect.Max, color);
+ }
+
+ ImGui::ItemSize(size);
+ if (!ImGui::ItemAdd(rect, id)) {
+ continue;
+ }
+
+ if (ImGui::ButtonBehavior(rect, id, &uiCell.Hovered, &uiCell.Held)) {
if (ImGui::GetIO().KeyShift && IsSelected()) {
- // Select range
- mSelectionBR = { colIdx, rowIdx };
+ SelectRange(mSelectionTL, { colIdx, rowIdx });
} else {
- // Select a single cell
SelectCell({ colIdx, rowIdx });
}
}
- x += colWidth;
- x += kCellSpacing;
+ // Don't SameLine() if we are on the last cell in the row
+ if (colIdx != colCount - 1) {
+ ImGui::SameLine();
+ }
}
-
- y += rowHeight;
- y += kCellSpacing;
}
ImGui::EndChild();
+ ImGui::PopStyleVar();
+ }
+
+ template <class TFunction>
+ void ForeachSelectedCell(const TFunction& func)
+ {
+ for (int y = mSelectionTL.y; y <= mSelectionBR.y; ++y) {
+ for (int x = mSelectionTL.x; x <= mSelectionBR.x; ++x) {
+ int i = y * mTable->GetTableWidth() + x;
+ func(i, x, y);
+ }
+ }
}
bool IsSelected() const
@@ -153,14 +257,46 @@ private:
void ClearSelection()
{
+ if (IsSelected()) {
+ ForeachSelectedCell([this](int i, int, int) {
+ auto& uiCell = mUICells[i];
+ uiCell.Selected = false;
+ });
+ }
+
mSelectionTL = { -1, -1 };
mSelectionBR = { -1, -1 };
}
+ void SelectRange(Vec2i p1, Vec2i p2)
+ {
+ ClearSelection();
+
+ if (p2.x < p1.x) {
+ std::swap(p2.x, p1.x);
+ }
+ if (p2.y < p1.y) {
+ std::swap(p2.y, p1.y);
+ }
+
+ mSelectionTL = p1;
+ mSelectionBR = p2;
+
+ ForeachSelectedCell([this](int i, int, int) {
+ auto& uiCell = mUICells[i];
+ uiCell.Selected = true;
+ });
+ }
+
void SelectCell(Vec2i cell)
{
+ ClearSelection();
+
mSelectionTL = cell;
mSelectionBR = cell;
+
+ int i = cell.y * mTable->GetTableWidth() + cell.x;
+ mUICells[i].Selected = true;
}
};
@@ -228,6 +364,6 @@ void UI::TemplatesTab()
}
if (openTemplate) {
- openTemplate->Draw();
+ openTemplate->Display();
}
}