From 311469e9d638dfa6afe3489536a049e462dc2146 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 16 Apr 2019 11:58:17 +0200 Subject: [PATCH] Internals: Columns: Some renaming, extracted code into GetColumnsID(). --- imgui.cpp | 85 ++++++++++++++++++++++++++--------------------- imgui_internal.h | 14 ++++---- imgui_widgets.cpp | 14 ++++---- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d46de3501..80e7bdbcf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2233,8 +2233,8 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) ImGuiWindow* window = ImGui::GetCurrentWindow(); window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage. window->DC.PrevLineSize.y = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. - if (window->DC.ColumnsSet) - window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly + if (window->DC.CurrentColumns) + window->DC.CurrentColumns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly } // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 @@ -2597,7 +2597,7 @@ ImGuiWindow::~ImGuiWindow() IM_ASSERT(DrawList == &DrawListInst); IM_DELETE(Name); for (int i = 0; i != ColumnsStorage.Size; i++) - ColumnsStorage[i].~ImGuiColumnsSet(); + ColumnsStorage[i].~ImGuiColumns(); } ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) @@ -5443,7 +5443,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.ItemFlagsStack.resize(0); window->DC.ItemWidthStack.resize(0); window->DC.TextWrapPosStack.resize(0); - window->DC.ColumnsSet = NULL; + window->DC.CurrentColumns = NULL; window->DC.TreeDepth = 0; window->DC.TreeDepthMayJumpToParentOnPop = 0x00; window->DC.StateStorage = &window->StateStorage; @@ -5627,7 +5627,7 @@ void ImGui::End() ImGuiWindow* window = g.CurrentWindow; - if (window->DC.ColumnsSet != NULL) + if (window->DC.CurrentColumns != NULL) EndColumns(); PopClipRect(); // Inner window clip rectangle @@ -6348,8 +6348,8 @@ ImVec2 ImGui::GetContentRegionMax() { ImGuiWindow* window = GetCurrentWindowRead(); ImVec2 mx = window->ContentsRegionRect.Max - window->Pos; - if (window->DC.ColumnsSet) - mx.x = GetColumnOffset(window->DC.ColumnsSet->Current + 1) - window->WindowPadding.x; + if (window->DC.CurrentColumns) + mx.x = GetColumnOffset(window->DC.CurrentColumns->Current + 1) - window->WindowPadding.x; return mx; } @@ -8275,11 +8275,11 @@ void ImGui::NavUpdateWindowingList() void ImGui::NextColumn() { ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems || window->DC.ColumnsSet == NULL) + if (window->SkipItems || window->DC.CurrentColumns == NULL) return; ImGuiContext& g = *GImGui; - ImGuiColumnsSet* columns = window->DC.ColumnsSet; + ImGuiColumns* columns = window->DC.CurrentColumns; if (columns->Count == 1) { @@ -8318,28 +8318,28 @@ void ImGui::NextColumn() int ImGui::GetColumnIndex() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsSet ? window->DC.ColumnsSet->Current : 0; + return window->DC.CurrentColumns ? window->DC.CurrentColumns->Current : 0; } int ImGui::GetColumnsCount() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsSet ? window->DC.ColumnsSet->Count : 1; + return window->DC.CurrentColumns ? window->DC.CurrentColumns->Count : 1; } -static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_norm) +static float OffsetNormToPixels(const ImGuiColumns* columns, float offset_norm) { return offset_norm * (columns->MaxX - columns->MinX); } -static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset) +static float PixelsToOffsetNorm(const ImGuiColumns* columns, float offset) { return offset / (columns->MaxX - columns->MinX); } static inline float GetColumnsRectHalfWidth() { return 4.0f; } -static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) +static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index) { // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. @@ -8359,7 +8359,7 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) float ImGui::GetColumnOffset(int column_index) { ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; + ImGuiColumns* columns = window->DC.CurrentColumns; IM_ASSERT(columns != NULL); if (column_index < 0) @@ -8371,7 +8371,7 @@ float ImGui::GetColumnOffset(int column_index) return x_offset; } -static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool before_resize = false) +static float GetColumnWidthEx(ImGuiColumns* columns, int column_index, bool before_resize = false) { if (column_index < 0) column_index = columns->Current; @@ -8387,7 +8387,7 @@ static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool b float ImGui::GetColumnWidth(int column_index) { ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; + ImGuiColumns* columns = window->DC.CurrentColumns; IM_ASSERT(columns != NULL); if (column_index < 0) @@ -8399,7 +8399,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - ImGuiColumnsSet* columns = window->DC.ColumnsSet; + ImGuiColumns* columns = window->DC.CurrentColumns; IM_ASSERT(columns != NULL); if (column_index < 0) @@ -8420,7 +8420,7 @@ void ImGui::SetColumnOffset(int column_index, float offset) void ImGui::SetColumnWidth(int column_index, float width) { ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; + ImGuiColumns* columns = window->DC.CurrentColumns; IM_ASSERT(columns != NULL); if (column_index < 0) @@ -8431,46 +8431,57 @@ void ImGui::SetColumnWidth(int column_index, float width) void ImGui::PushColumnClipRect(int column_index) { ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; + ImGuiColumns* columns = window->DC.CurrentColumns; if (column_index < 0) column_index = columns->Current; - PushClipRect(columns->Columns[column_index].ClipRect.Min, columns->Columns[column_index].ClipRect.Max, false); + ImGuiColumnData* column = &columns->Columns[column_index]; + PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false); } -static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id) +ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id) { + // We have few columns per window so for now we don't need bother much with turning this into a faster lookup. for (int n = 0; n < window->ColumnsStorage.Size; n++) if (window->ColumnsStorage[n].ID == id) return &window->ColumnsStorage[n]; - window->ColumnsStorage.push_back(ImGuiColumnsSet()); - ImGuiColumnsSet* columns = &window->ColumnsStorage.back(); + window->ColumnsStorage.push_back(ImGuiColumns()); + ImGuiColumns* columns = &window->ColumnsStorage.back(); columns->ID = id; return columns; } +ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count) +{ + ImGuiWindow* window = GetCurrentWindow(); + + // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. + // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. + PushID(0x11223347 + (str_id ? 0 : columns_count)); + ImGuiID id = window->GetID(str_id ? str_id : "columns"); + PopID(); + + return id; +} + void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(columns_count >= 1); - IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported + IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported - // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. - // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. - PushID(0x11223347 + (str_id ? 0 : columns_count)); - ImGuiID id = window->GetID(str_id ? str_id : "columns"); - PopID(); + ImGuiID id = GetColumnsID(str_id, columns_count); // Acquire storage for the columns set - ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id); + ImGuiColumns* columns = FindOrCreateColumns(window, id); IM_ASSERT(columns->ID == id); columns->Current = 0; columns->Count = columns_count; columns->Flags = flags; - window->DC.ColumnsSet = columns; + window->DC.CurrentColumns = columns; // Set state for first column const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x); @@ -8521,7 +8532,7 @@ void ImGui::EndColumns() { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; + ImGuiColumns* columns = window->DC.CurrentColumns; IM_ASSERT(columns != NULL); PopItemWidth(); @@ -8582,7 +8593,7 @@ void ImGui::EndColumns() } columns->IsBeingResized = is_being_resized; - window->DC.ColumnsSet = NULL; + window->DC.CurrentColumns = NULL; window->DC.ColumnsOffset.x = 0.0f; window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); } @@ -8595,10 +8606,10 @@ void ImGui::Columns(int columns_count, const char* id, bool border) ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior - if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->Count == columns_count && window->DC.ColumnsSet->Flags == flags) + if (window->DC.CurrentColumns != NULL && window->DC.CurrentColumns->Count == columns_count && window->DC.CurrentColumns->Flags == flags) return; - if (window->DC.ColumnsSet != NULL) + if (window->DC.CurrentColumns != NULL) EndColumns(); if (columns_count != 1) @@ -9582,7 +9593,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) { for (int n = 0; n < window->ColumnsStorage.Size; n++) { - const ImGuiColumnsSet* columns = &window->ColumnsStorage[n]; + const ImGuiColumns* columns = &window->ColumnsStorage[n]; if (ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) { ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX); diff --git a/imgui_internal.h b/imgui_internal.h index 7e7ffb44b..240a000e3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -63,7 +63,7 @@ struct ImDrawDataBuilder; // Helper to build a ImDrawData instance struct ImDrawListSharedData; // Data shared between all ImDrawList instances struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiColumnData; // Storage data for a single column -struct ImGuiColumnsSet; // Storage data for a columns set +struct ImGuiColumns; // Storage data for a columns set struct ImGuiContext; // Main imgui context struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box @@ -661,7 +661,7 @@ struct ImGuiColumnData ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; } }; -struct ImGuiColumnsSet +struct ImGuiColumns { ImGuiID ID; ImGuiColumnsFlags Flags; @@ -675,7 +675,7 @@ struct ImGuiColumnsSet float StartMaxPosX; // Copy of CursorMaxPos ImVector Columns; - ImGuiColumnsSet() { Clear(); } + ImGuiColumns() { Clear(); } void Clear() { ID = 0; @@ -1156,7 +1156,7 @@ struct IMGUI_API ImGuiWindowTempData ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) ImVec1 GroupOffset; ImVec1 ColumnsOffset; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. - ImGuiColumnsSet* ColumnsSet; // Current columns set + ImGuiColumns* CurrentColumns; // Current columns set ImGuiWindowTempData() { @@ -1187,7 +1187,7 @@ struct IMGUI_API ImGuiWindowTempData Indent = ImVec1(0.0f); GroupOffset = ImVec1(0.0f); ColumnsOffset = ImVec1(0.0f); - ColumnsSet = NULL; + CurrentColumns = NULL; } }; @@ -1250,7 +1250,7 @@ struct IMGUI_API ImGuiWindow float ItemWidthDefault; ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items ImGuiStorage StateStorage; - ImVector ColumnsStorage; + ImVector ColumnsStorage; float FontWindowScale; // User scale multiplier per-window int SettingsIdx; // Index into SettingsWindow[] (indices are always valid as we only grow the array from the back) @@ -1488,6 +1488,8 @@ namespace ImGui IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns IMGUI_API void PushColumnClipRect(int column_index = -1); + IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count); + IMGUI_API ImGuiColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id); // Tab Bars IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 82696d5af..b209f033d 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1209,7 +1209,7 @@ void ImGui::Separator() } // Horizontal Separator - if (window->DC.ColumnsSet) + if (window->DC.CurrentColumns) PopClipRect(); float x1 = window->Pos.x; @@ -1221,7 +1221,7 @@ void ImGui::Separator() ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. if (!ItemAdd(bb, 0)) { - if (window->DC.ColumnsSet) + if (window->DC.CurrentColumns) PushColumnClipRect(); return; } @@ -1231,10 +1231,10 @@ void ImGui::Separator() if (g.LogEnabled) LogRenderedText(&bb.Min, "--------------------------------"); - if (window->DC.ColumnsSet) + if (window->DC.CurrentColumns) { PushColumnClipRect(); - window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y; + window->DC.CurrentColumns->LineMinY = window->DC.CursorPos.y; } } @@ -5303,7 +5303,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) // FIXME-OPT: Avoid if vertically clipped. + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped. PopClipRect(); ImGuiID id = window->GetID(label); @@ -5347,7 +5347,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl } if (!item_add) { - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) PushColumnClipRect(); return false; } @@ -5392,7 +5392,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); } - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) { PushColumnClipRect(); bb.Max.x -= (GetContentRegionMax().x - max_x);