summaryrefslogtreecommitdiff
path: root/core/src/UI
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-06-19 22:41:05 -0700
committerrtk0c <[email protected]>2021-06-19 22:41:05 -0700
commit4378dcd83d2387534f3b10276365d1003832fe81 (patch)
tree6bc055a1bd81d5a27c9066f05e28e5115f5de944 /core/src/UI
parenteec8dfd8a21b8bb37f6acac1da84cde8fbf7ace7 (diff)
Add cell type conversion mechanism
Diffstat (limited to 'core/src/UI')
-rw-r--r--core/src/UI/UI.hpp2
-rw-r--r--core/src/UI/UI_Templates.cpp166
-rw-r--r--core/src/UI/UI_Utils.cpp9
3 files changed, 168 insertions, 9 deletions
diff --git a/core/src/UI/UI.hpp b/core/src/UI/UI.hpp
index 0a80b4c..b0f0a6f 100644
--- a/core/src/UI/UI.hpp
+++ b/core/src/UI/UI.hpp
@@ -13,6 +13,8 @@ void PopDisabled();
bool Button(const char* label, bool disabled);
bool Button(const char* label, const ImVec2& sizeArg, bool disabled);
+bool MenuItemConditional(const char* name, bool disabled);
+
void ErrorIcon();
void ErrorMessage(const char* fmt, ...);
void WarningIcon();
diff --git a/core/src/UI/UI_Templates.cpp b/core/src/UI/UI_Templates.cpp
index ab9c317..e77bef3 100644
--- a/core/src/UI/UI_Templates.cpp
+++ b/core/src/UI/UI_Templates.cpp
@@ -25,6 +25,10 @@ public:
virtual void Display() = 0;
};
+// Table template styles
+constexpr ImU32 kSingleParamOutline = IM_COL32(255, 255, 0, 255);
+constexpr ImU32 kArrayGroupOutline = IM_COL32(255, 0, 0, 255);
+
class TableTemplateUI : public TemplateUI
{
private:
@@ -38,9 +42,41 @@ private:
};
std::vector<UICell> mUICells;
+ struct UIArrayGroup
+ {
+ ImVec2 Pos;
+ ImVec2 Size;
+ };
+ std::vector<UIArrayGroup> mUIArrayGroups;
+
+ /* Selection range */
Vec2i mSelectionTL;
Vec2i mSelectionBR;
+ /* Selection states */
+ union
+ {
+ /// "CS" stands for "Constant cell selection States"
+ struct
+ {
+ } mCS{}; // Initialize to this element
+
+ /// "SS" stands for "Singular parameter selection States".
+ struct
+ {
+ bool ErrorDuplicateVarName;
+ bool HasLeftAG;
+ bool HasRightAG;
+ } mSS;
+
+ /// "AS" stands for "Array group parameter selection States".
+ struct
+ {
+ bool ErrorDuplicateVarName;
+ } mAS;
+ };
+
+ /* Table states */
bool mDirty = false;
bool mFirstDraw = true;
@@ -75,15 +111,38 @@ public:
{
mTable->Resize(width, height);
mUICells.resize(width * height);
+ mUIArrayGroups.resize(mTable->GetArrayGroupCount());
+
+ for (size_t i = 0; i < mUIArrayGroups.size(); ++i) {
+ auto& ag = mTable->GetArrayGroup(i);
+ auto& uag = mUIArrayGroups[i];
+
+ auto itemSpacing = ImGui::GetStyle().ItemSpacing;
+ uag.Pos.x = 0;
+ for (int x = 0; x < ag.LeftCell; ++x) {
+ uag.Pos.x += mTable->GetColumnWidth(x) + itemSpacing.x;
+ }
+ uag.Pos.y = 0;
+ for (int y = 0; y < ag.Row; ++y) {
+ uag.Pos.y += mTable->GetRowHeight(y) + itemSpacing.y;
+ }
+
+ uag.Size.x = mTable->GetRowHeight(ag.Row);
+ uag.Size.y = 0;
+ for (int x = ag.LeftCell; x <= ag.RightCell; ++x) {
+ uag.Size.y += mTable->GetColumnWidth(x);
+ }
+ }
}
private:
void DisplayInspector()
{
+ // This is an id, no need to localize
if (ImGui::BeginTabBar("Inspector")) {
- if (ImGui::BeginTabItem("Cell")) {
+ if (ImGui::BeginTabItem(I18N_TEXT("Cell", L10N_TABLE_CELL))) {
if (!IsSelected()) {
- ImGui::Text("Select a cell to edit");
+ ImGui::Text(I18N_TEXT("Select a cell to edit", L10N_TABLE_CELL_SELECT_MSG));
} else if (mSelectionTL == mSelectionBR) {
auto& selectCell = mTable->GetCell(mSelectionTL);
DisplayCellProperties(mSelectionTL);
@@ -93,8 +152,8 @@ private:
ImGui::EndTabItem();
}
- if (ImGui::BeginTabItem("Table")) {
- DisplayTableInspector();
+ if (ImGui::BeginTabItem(I18N_TEXT("Table", L10N_TABLE))) {
+ DisplayTableProperties();
ImGui::EndTabItem();
}
@@ -107,6 +166,36 @@ private:
auto& cell = mTable->GetCell(pos);
auto& uiCell = mUICells[pos.y * mTable->GetTableWidth() + pos.x];
+ if (ImGui::Button(I18N_TEXT("Convert to...", L10N_TABLE_CELL_CONV))) {
+ ImGui::OpenPopup("ConvertCtxMenu");
+ }
+ if (ImGui::BeginPopup("ConvertCtxMenu")) {
+ if (ImGui::MenuItem(I18N_TEXT("Single parameter", L10N_TABLE_CELL_CONV_PARAM))) {
+ mTable->SetCellType(pos, TableCell::SingularParametricCell);
+ }
+
+ bool createDisabled = cell.Type == TableCell::ArrayParametricCell;
+ if (ImGui::MenuItemConditional(I18N_TEXT("Create array group", L10N_TABLE_CELL_CONV_CREATE_AG), createDisabled)) {
+ mTable->AddArrayGroup(pos.x, pos.x, pos.y);
+ }
+
+ bool leftDisabled = !mSS.HasLeftAG || cell.Type == TableCell::ArrayParametricCell;
+ if (ImGui::MenuItemConditional(I18N_TEXT("Add to array group to the left", L10N_TABLE_CELL_CONV_ADD_AG_LEFT), leftDisabled)) {
+ auto& leftCell = mTable->GetCell((Vec2i){ pos.x - 1, pos.y });
+ mTable->ExtendArrayGroupRight(leftCell.DataId, 1);
+ }
+
+ bool rightDisabled = !mSS.HasRightAG || cell.Type == TableCell::ArrayParametricCell;
+ if (ImGui::MenuItemConditional(I18N_TEXT("Add to array group to the right", L10N_TABLE_CELL_CONV_ADD_AG_RIGHT), rightDisabled)) {
+ auto& rightCell = mTable->GetCell((Vec2i){ pos.x + 1, pos.y });
+ mTable->ExtendArrayGroupLeft(rightCell.DataId, 1);
+ }
+
+ ImGui::EndPopup();
+ }
+
+ ImGui::Spacing();
+
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);
@@ -162,20 +251,31 @@ private:
case TableCell::SingularParametricCell:
if (ImGui::InputText(I18N_TEXT("Variable name", L10N_TABLE_CELL_VAR_NAME), &cell.Content)) {
- // TODO validate if name is repeat
+ auto c = mTable->FindCell(cell.Content);
+ mSS.ErrorDuplicateVarName = c != nullptr;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(I18N_TEXT("Name of the parameter link to this cell.", L10N_TABLE_CELL_VAR_TOOLTIP));
}
+
+ if (mSS.ErrorDuplicateVarName) {
+ ImGui::ErrorMessage(I18N_TEXT("Variable name duplicated.", L10N_TABLE_CELL_VAR_NAME_DUP));
+ }
break;
case TableCell::ArrayParametricCell:
if (ImGui::InputText(I18N_TEXT("Variable name", L10N_TABLE_CELL_VAR_NAME), &cell.Content)) {
- // TODO validate if name is repeat
+ auto ag = mTable->GetArrayGroup(cell.DataId);
+ auto cl = ag.FindCell(cell.Content);
+ mAS.ErrorDuplicateVarName = cl.x != -1 && cl.y != -1;
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip(I18N_TEXT("Name of the parameter lnk to this cell; local within the array group.", L10N_TABLE_CELL_ARRAY_VAR_TOOLTIP));
}
+
+ if (mAS.ErrorDuplicateVarName) {
+ ImGui::ErrorMessage(I18N_TEXT("Variable name duplicated.", L10N_TABLE_CELL_VAR_NAME_DUP));
+ }
break;
}
}
@@ -185,7 +285,7 @@ private:
// TODO
}
- void DisplayTableInspector()
+ void DisplayTableProperties()
{
// TODO
}
@@ -193,6 +293,7 @@ private:
void DisplayTable()
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8));
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8, 8));
ImGui::BeginChild("TableTemplate");
auto regularColor = ImGui::GetColorU32(ImGuiCol_Button);
@@ -222,7 +323,6 @@ private:
window->DC.CursorPos + ImGui::CalcItemSize(size, 0.0f, 0.0f),
};
- // TODO draw indicator for parameter cells
/* Draw cell body */
if (uiCell.Selected) {
@@ -242,6 +342,22 @@ private:
window->DrawList->AddRectFilled(rect.Min, rect.Max, color);
}
+ /* Draw cell type indicator */
+ switch (cell.Type) {
+ // No indicator
+ case TableCell::ConstantCell: break;
+
+ case TableCell::SingularParametricCell:
+ window->DrawList->AddRect(
+ rect.Min - ImVec2(1, 1),
+ rect.Max + ImVec2(1, 1),
+ kSingleParamOutline);
+ break;
+
+ // Drawn separately in loop below
+ case TableCell::ArrayParametricCell: break;
+ }
+
/* Draw cell content */
auto content = cell.Content.c_str();
@@ -283,8 +399,15 @@ private:
}
}
+ for (auto& uag : mUIArrayGroups) {
+ ImGui::GetCurrentWindow()->DrawList->AddRect(
+ uag.Pos - ImVec2(1, 1),
+ uag.Pos + uag.Size + ImVec2(1, 1),
+ kArrayGroupOutline);
+ }
+
ImGui::EndChild();
- ImGui::PopStyleVar();
+ ImGui::PopStyleVar(2);
}
template <class TFunction>
@@ -314,6 +437,13 @@ private:
mSelectionTL = { -1, -1 };
mSelectionBR = { -1, -1 };
+
+ ResetCS();
+ }
+
+ void ResetCS()
+ {
+ mCS = {};
}
void SelectRange(Vec2i p1, Vec2i p2)
@@ -334,6 +464,16 @@ private:
auto& uiCell = mUICells[i];
uiCell.Selected = true;
});
+
+ ResetAS();
+ }
+
+ void ResetSS(Vec2i pos)
+ {
+ mSS = {};
+ mSS.ErrorDuplicateVarName = false;
+ mSS.HasLeftAG = pos.x >= 1;
+ mSS.HasRightAG = pos.x < mTable->GetTableWidth();
}
void SelectCell(Vec2i cell)
@@ -345,6 +485,14 @@ private:
int i = cell.y * mTable->GetTableWidth() + cell.x;
mUICells[i].Selected = true;
+
+ ResetSS(cell);
+ }
+
+ void ResetAS()
+ {
+ mAS = {};
+ mAS.ErrorDuplicateVarName = false;
}
};
diff --git a/core/src/UI/UI_Utils.cpp b/core/src/UI/UI_Utils.cpp
index e3ac097..0dcde8f 100644
--- a/core/src/UI/UI_Utils.cpp
+++ b/core/src/UI/UI_Utils.cpp
@@ -44,6 +44,15 @@ bool ImGui::Button(const char* label, const ImVec2& sizeArg, bool disabled)
return res;
}
+bool ImGui::MenuItemConditional(const char* name, bool disabled)
+{
+ if (disabled) PushDisabled();
+ bool res = MenuItem(name, nullptr, false, disabled);
+ if (disabled) PopDisabled();
+
+ return res;
+}
+
void ImGui::ErrorIcon()
{
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{ 237 / 255.0f, 67 / 255.0f, 55 / 255.0f, 1.0f }); // #ED4337