diff options
Diffstat (limited to 'core/src')
-rw-r--r-- | core/src/Locale/zh_CN.h | 6 | ||||
-rw-r--r-- | core/src/UI/UI_Templates.cpp | 200 |
2 files changed, 138 insertions, 68 deletions
diff --git a/core/src/Locale/zh_CN.h b/core/src/Locale/zh_CN.h index 632c229..f654464 100644 --- a/core/src/Locale/zh_CN.h +++ b/core/src/Locale/zh_CN.h @@ -126,8 +126,9 @@ #define L10N_TABLE "表格" #define L10N_TABLE_CONFIGURE_PROPERTIES "编辑表格属性..." #define L10N_TABLE_PROPERTIES "表格属性" -#define L10N_TABLE_DO_RESIZE "调整表格大小..." -#define L10N_TABLE_RESIZE "调整表格大小" +#define L10N_TABLE_EDIT_TABLE "编辑表格" +#define L10N_TABLE_EDIT_RESIZE_COLS "调整列宽度" +#define L10N_TABLE_EDIT_RESIZE_ROWS "调整行高度" #define L10N_TABLE_WIDTH "宽度" #define L10N_TABLE_HEIGHT "长度" #define L10N_TABLE_SINGLE_PARAMS "参数" @@ -137,7 +138,6 @@ #define L10N_TABLE_CELL_TYPE_CONST "类型:普通单元格" #define L10N_TABLE_CELL_TYPE_PARAM "类型:参数单元格" #define L10N_TABLE_CELL_TYPE_CREATE_AG "类型:列表参数组" -#define L10N_TABLE_CELL_CONV "转换类型..." #define L10N_TABLE_CELL_CONV_CONST "转换为普通单元格" #define L10N_TABLE_CELL_CONV_PARAM "转换为参数单元格" #define L10N_TABLE_CELL_CONV_CREATE_AG "创建列表参数组" 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> |