aboutsummaryrefslogtreecommitdiff
path: root/core/src/UI
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2021-07-07 12:43:52 -0700
committerrtk0c <[email protected]>2021-07-07 12:43:52 -0700
commitf0326e5c5deca0fb719d8522b45c59364b566300 (patch)
treecaf198ab282d4aaa18c726e637d9cc19af81d338 /core/src/UI
parent170ce5d5cf761c7f397a78408c1dc9da0d63e598 (diff)
Finalize table row/column resizers
Diffstat (limited to 'core/src/UI')
-rw-r--r--core/src/UI/UI_Templates.cpp200
1 files changed, 135 insertions, 65 deletions
diff --git a/core/src/UI/UI_Templates.cpp b/core/src/UI/UI_Templates.cpp
index 182cfa4..309ff21 100644
--- a/core/src/UI/UI_Templates.cpp
+++ b/core/src/UI/UI_Templates.cpp
@@ -108,6 +108,18 @@ private:
int mNewTableHeight;
/* Table states */
+ enum EditMode
+ {
+ ModeEditing,
+ ModeColumnResizing,
+ ModeRowResizing,
+ };
+ EditMode mMode = ModeEditing;
+
+ float mStartDragDim;
+ /// Depending on row/column sizer being dragged, this will be the y/x coordinate
+ float mStartDragMouseCoordinate;
+
bool mDirty = false;
bool mFirstDraw = true;
@@ -162,7 +174,9 @@ public:
DisplayInspector();
ImGui::NextColumn();
+ auto initialPos = ImGui::GetCursorPos();
DisplayTable();
+ DisplayTableResizers(initialPos);
ImGui::NextColumn();
ImGui::Columns(1);
@@ -181,14 +195,8 @@ public:
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.Pos.x = CalcTablePixelWidth() + itemSpacing.x;
+ uag.Pos.y = CalcTablePixelHeight() + itemSpacing.y;
uag.Size.x = mTable->GetRowHeight(ag.Row);
uag.Size.y = 0;
@@ -230,15 +238,17 @@ private:
};
if (ImGui::BeginTabItem(I18N_TEXT("Table", L10N_TABLE))) {
if (ImGui::Button(I18N_TEXT("Configure table properties...", L10N_TABLE_CONFIGURE_PROPERTIES))) {
- OpenPopup(I18N_TEXT("Table properties", L10N_TABLE_PROPERTIES));
- }
-
- if (ImGui::Button(I18N_TEXT("Resize table...", L10N_TABLE_DO_RESIZE))) {
mNewTableWidth = mTable->GetTableWidth();
mNewTableHeight = mTable->GetTableHeight();
- OpenPopup(I18N_TEXT("Resize table", L10N_TABLE_RESIZE));
+ OpenPopup(I18N_TEXT("Table properties", L10N_TABLE_PROPERTIES));
}
+ int mode = mMode;
+ ImGui::RadioButton(I18N_TEXT("Edit table", L10N_TABLE_EDIT_TABLE), &mode, ModeEditing);
+ ImGui::RadioButton(I18N_TEXT("Resize column widths", L10N_TABLE_EDIT_RESIZE_COLS), &mode, ModeColumnResizing);
+ ImGui::RadioButton(I18N_TEXT("Resize rows heights", L10N_TABLE_EDIT_RESIZE_ROWS), &mode, ModeRowResizing);
+ mMode = static_cast<EditMode>(mode);
+
// Table contents
DisplayTableContents();
@@ -248,10 +258,6 @@ private:
DisplayTableProperties();
ImGui::EndPopup();
}
- if (ImGui::BeginPopupModal(I18N_TEXT("Resize table", L10N_TABLE_RESIZE), &openedDummy, ImGuiWindowFlags_AlwaysAutoResize)) {
- DisplayTableResizer();
- ImGui::EndPopup();
- }
ImGui::EndTabBar();
}
@@ -322,7 +328,8 @@ private:
break;
}
- if (ImGui::Button(I18N_TEXT("Convert to...", L10N_TABLE_CELL_CONV))) {
+ ImGui::SameLine();
+ if (ImGui::Button(ICON_FA_EDIT)) {
ImGui::OpenPopup("ConvertCtxMenu");
}
if (ImGui::BeginPopup("ConvertCtxMenu")) {
@@ -500,11 +507,6 @@ private:
void DisplayTableProperties()
{
- // TODO
- }
-
- void DisplayTableResizer()
- {
ImGui::InputInt(I18N_TEXT("Width", L10N_TABLE_WIDTH), &mNewTableWidth);
ImGui::InputInt(I18N_TEXT("Height", L10N_TABLE_HEIGHT), &mNewTableHeight);
@@ -516,6 +518,8 @@ private:
if (ImGui::Button(I18N_TEXT("Cancel", L10N_CANCEL))) {
ImGui::CloseCurrentPopup();
}
+
+ // TODO
}
void DisplayTable()
@@ -553,8 +557,6 @@ private:
auto navHighlight = ImGui::GetColorU32(ImGuiCol_NavHighlight);
- auto initialCursorPos = ImGui::GetCurrentWindow()->DC.CursorPos;
-
int colCount = mTable->GetTableWidth();
int rowCount = mTable->GetTableHeight();
for (int rowIdx = 0; rowIdx < rowCount; ++rowIdx) {
@@ -644,9 +646,12 @@ private:
ImGui::ItemSize(size);
if (!ImGui::ItemAdd(rect, id)) {
- continue;
+ goto logicEnd;
}
+ if (mMode != ModeEditing) {
+ goto logicEnd;
+ }
if (ImGui::ButtonBehavior(rect, id, &uiCell.Hovered, &uiCell.Held)) {
if (ImGui::GetIO().KeyShift && IsSelected()) {
SelectRange(mSelectionTL, { colIdx, rowIdx });
@@ -655,6 +660,7 @@ private:
}
}
+ logicEnd:
// Don't SameLine() if we are on the last cell in the row
if (colIdx != colCount - 1) {
ImGui::SameLine();
@@ -668,58 +674,122 @@ private:
uag.Pos + uag.Size + ImVec2(1, 1),
kArrayGroupOutline);
}
+ }
- // Display row/column sizers
+ void DisplayResizers(
+ ImVec2 pos,
+ ImVec2 sizerDim,
+ ImVec2 sizerOffset,
+ std::type_identity_t<float ImVec2::*> vecCompGetter,
+ std::type_identity_t<int (TableTemplate::*)() const> lenGetter,
+ std::type_identity_t<int (TableTemplate::*)(int) const> dimGetter,
+ std::type_identity_t<void (TableTemplate::*)(int, int)> dimSetter)
+ {
+ auto window = ImGui::GetCurrentWindow();
+ auto spacing = ImGui::GetStyle().ItemSpacing.*vecCompGetter;
- if (true) { // TODO add shortcut
- constexpr int kLongEdge = 24;
- constexpr int kShortEdge = 10;
+ auto regularColor = ImGui::GetColorU32(ImGuiCol_Button);
+ auto hoveredColor = ImGui::GetColorU32(ImGuiCol_ButtonHovered);
+ auto activeColor = ImGui::GetColorU32(ImGuiCol_ButtonActive);
- auto window = ImGui::GetCurrentWindow();
- auto spacing = ImGui::GetStyle().ItemSpacing;
+ auto GetColor = [&](const Sizer& sizer) -> ImU32 {
+ if (sizer.Held) {
+ return activeColor;
+ } else if (sizer.Hovered) {
+ return hoveredColor;
+ } else {
+ return regularColor;
+ }
+ };
- auto regularColor = ImGui::GetColorU32(ImGuiCol_Button);
- auto hoveredColor = ImGui::GetColorU32(ImGuiCol_ButtonHovered);
- auto activeColor = ImGui::GetColorU32(ImGuiCol_ButtonActive);
+ for (int ix = 0; ix < (mTable.get()->*lenGetter)(); ++ix) {
+ // ImGui uses float for sizes, our table uses int (because excel uses int)
+ // Convert here to avoid mountains of narrowing warnings below
+ auto dim = (float)(mTable.get()->*dimGetter)(ix);
- auto GetColor = [&](const Sizer& sizer) -> ImU32 {
- if (sizer.Held) {
- return activeColor;
- } else if (sizer.Hovered) {
- return hoveredColor;
- } else {
- return regularColor;
- }
+ pos.*vecCompGetter += dim;
+ ImRect rect{
+ pos - sizerOffset,
+ pos - sizerOffset + ImGui::CalcItemSize(sizerDim, 0.0f, 0.0f),
};
+ pos.*vecCompGetter += spacing;
- int x = 0;
- for (int ix = 0; ix < mTable->GetTableWidth(); ++ix) {
- x += mTable->GetColumnWidth(ix);
-
- auto& sizer = mColSizers[ix];
- int middle = x + spacing.x / 2;
- window->DrawList->AddRectFilled(
- initialCursorPos + ImVec2(middle - kShortEdge / 2, 0),
- initialCursorPos + ImVec2(middle + kShortEdge / 2, 0 + kLongEdge),
- GetColor(sizer));
+ auto& sizer = mColSizers[ix];
+ auto id = window->GetID(ix);
+ window->DrawList->AddRectFilled(rect.Min, rect.Max, GetColor(sizer));
- x += spacing.x;
+ if (ImGui::ButtonBehavior(rect, id, &sizer.Hovered, &sizer.Held, ImGuiButtonFlags_PressedOnClick)) {
+ mStartDragDim = dim;
+ mStartDragMouseCoordinate = ImGui::GetMousePos().*vecCompGetter;
+ }
+ if (sizer.Held) {
+ float change = ImGui::GetMousePos().*vecCompGetter - mStartDragMouseCoordinate;
+ float colWidth = std::max(mStartDragDim + change, 1.0f);
+ (mTable.get()->*dimSetter)(ix, (int)colWidth);
}
+ }
+ }
- int y = 0;
- for (int iy = 0; iy < mTable->GetTableHeight(); ++iy) {
- y += mTable->GetRowHeight(iy);
+ void DisplayTableResizers(ImVec2 topLeftPixelPos)
+ {
+ constexpr float kExtraSideLength = 5.0f;
+ constexpr float kExtraAxialLength = 2.0f;
- auto& sizer = mRowSizers[iy];
- int middle = y + spacing.y / 2;
- window->DrawList->AddRectFilled(
- initialCursorPos + ImVec2(middle - kShortEdge / 2, 0),
- initialCursorPos + ImVec2(middle + kShortEdge / 2, 0 + kLongEdge),
- GetColor(sizer));
+ switch (mMode) {
+ case ModeEditing: break;
- y += spacing.y;
- }
+ case ModeColumnResizing:
+ ImGui::PushID("Cols");
+ DisplayResizers(
+ topLeftPixelPos,
+ ImVec2(
+ ImGui::GetStyle().ItemSpacing.x + kExtraSideLength * 2,
+ CalcTablePixelHeight() + kExtraAxialLength * 2),
+ ImVec2(kExtraSideLength, kExtraAxialLength),
+ &ImVec2::x,
+ &TableTemplate::GetTableWidth,
+ &TableTemplate::GetColumnWidth,
+ &TableTemplate::SetColumnWidth);
+ ImGui::PopID();
+ break;
+
+ case ModeRowResizing:
+ ImGui::PushID("Rows");
+ DisplayResizers(
+ topLeftPixelPos,
+ ImVec2(
+ CalcTablePixelWidth() + kExtraAxialLength * 2,
+ ImGui::GetStyle().ItemSpacing.y + kExtraSideLength * 2),
+ ImVec2(kExtraAxialLength, kExtraSideLength),
+ &ImVec2::y,
+ &TableTemplate::GetTableHeight,
+ &TableTemplate::GetRowHeight,
+ &TableTemplate::SetRowHeight);
+ ImGui::PopID();
+ break;
+ }
+ }
+
+ float CalcTablePixelWidth() const
+ {
+ float horizontalSpacing = ImGui::GetStyle().ItemSpacing.x;
+ float width = 0;
+ for (int x = 0; x < mTable->GetTableWidth(); ++x) {
+ width += mTable->GetColumnWidth(x);
+ width += horizontalSpacing;
+ }
+ return width - horizontalSpacing;
+ }
+
+ float CalcTablePixelHeight() const
+ {
+ float verticalSpacing = ImGui::GetStyle().ItemSpacing.y;
+ float height = 0;
+ for (int y = 0; y < mTable->GetTableHeight(); ++y) {
+ height += mTable->GetRowHeight(y);
+ height += verticalSpacing;
}
+ return height - verticalSpacing;
}
template <class TFunction>