mirror of
https://github.com/wolfpld/tracy.git
synced 2025-03-20 07:40:02 +08:00
Update ImGui to 1.80 + docking.
This commit is contained in:
+146
-88
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.80 WIP
|
||||
// dear imgui, v1.80
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -74,24 +74,30 @@ Index of this file:
|
||||
//-----------------------------------------------------------------------------
|
||||
// About 'outer_size':
|
||||
// Its meaning needs to differ slightly depending of if we are using ScrollX/ScrollY flags.
|
||||
// Default value is ImVec2(-FLT_MIN, 0.0f). When binding this in a scripting language please follow this default value.
|
||||
// Default value is ImVec2(0.0f, 0.0f).
|
||||
// X
|
||||
// - outer_size.x < 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN will right-align exactly on right-most edge. With -1.0f will right-align one pixel away from right-most edge.
|
||||
// - outer_size.x = 0.0f -> Auto width. Generally use all available width. When NOT using scrolling and NOT using any Stretch column, use only necessary width, otherwise same as -FLT_MIN.
|
||||
// - outer_size.x > 0.0f -> Fixed width.
|
||||
// - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge.
|
||||
// - outer_size.x > 0.0f -> Set Fixed width.
|
||||
// Y with ScrollX/ScrollY disabled: we output table directly in current window
|
||||
// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless NoHostExtendV is set)
|
||||
// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless NoHostExtendV is set)
|
||||
// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless NoHostExtendV is set)
|
||||
// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful is parent window can vertically scroll.
|
||||
// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set)
|
||||
// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set)
|
||||
// Y with ScrollX/ScrollY enabled: using a child window for scrolling
|
||||
// - outer_size.y < 0.0f -> Bottom-align
|
||||
// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window.
|
||||
// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis.
|
||||
// - outer_size.y < 0.0f -> Bottom-align. Not meaningful is parent window can vertically scroll.
|
||||
// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window.
|
||||
// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Outer size is also affected by the NoHostExtendX/NoHostExtendY flags.
|
||||
// Important to that note how the two flags have slightly different behaviors!
|
||||
// - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
|
||||
// - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
|
||||
// In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height.
|
||||
// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable)
|
||||
//-----------------------------------------------------------------------------
|
||||
// About 'inner_width':
|
||||
// With ScrollX disabled:
|
||||
// - inner_width -> *ignored*
|
||||
// With ScrollX enable:
|
||||
// With ScrollX enabled:
|
||||
// - inner_width < 0.0f -> *illegal* fit in known width (right align from outer_size.x) <-- weird
|
||||
// - inner_width = 0.0f -> fit in outer_width: Fixed size columns will take space they need (if avail, otherwise shrink down), Stretch columns becomes Fixed columns.
|
||||
// - inner_width > 0.0f -> override scrolling width, generally to be larger than outer_size.x. Fixed column take space they need (if avail, otherwise shrink down), Stretch columns share remaining space!
|
||||
@@ -108,7 +114,6 @@ Index of this file:
|
||||
//-----------------------------------------------------------------------------
|
||||
// About overriding column sizing policy and width/weight with TableSetupColumn():
|
||||
// We use a default parameter of 'init_width_or_weight == -1'.
|
||||
// - with ImGuiTableColumnFlags_WidthAuto, init_width (ignored) --> width is automatic
|
||||
// - with ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic
|
||||
// - with ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom
|
||||
// - with ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f
|
||||
@@ -117,11 +122,11 @@ Index of this file:
|
||||
// and you can fit a 100.0f wide item in it without clipping and with full padding.
|
||||
//-----------------------------------------------------------------------------
|
||||
// About default sizing policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag)
|
||||
// - with Table policy ImGuiTableFlags_SizingFixedFit && (Resizable == 1 || init_width > 0) --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width
|
||||
// - with Table policy ImGuiTableFlags_SizingFixedFit && (Resizable == 0 && init_width <= 0) --> default Column policy is ImGuiTableColumnFlags_WidthAuto, Width always equal to contents width
|
||||
// - with Table policy ImGuiTableFlags_SizingFixedSame --> default Column policy is ImGuiTableColumnFlags_WidthAuto, default Width is max of all contents width
|
||||
// - with Table policy ImGuiTableFlags_SizingStretchSame --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is 1.0f
|
||||
// - with Table policy ImGuiTableFlags_SizingStretchWeight --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is proportional to contents
|
||||
// - with Table policy ImGuiTableFlags_SizingFixedFit --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width
|
||||
// - with Table policy ImGuiTableFlags_SizingFixedSame --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is max of all contents width
|
||||
// - with Table policy ImGuiTableFlags_SizingStretchSame --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is 1.0f
|
||||
// - with Table policy ImGuiTableFlags_SizingStretchWeight --> default Column policy is ImGuiTableColumnFlags_WidthStretch, default Weight is proportional to contents
|
||||
// Default Width and default Weight can be overriden when calling TableSetupColumn().
|
||||
//-----------------------------------------------------------------------------
|
||||
// About mixing Fixed/Auto and Stretch columns together:
|
||||
// - the typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
|
||||
@@ -130,6 +135,16 @@ Index of this file:
|
||||
// - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the maximum contents width.
|
||||
// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths.
|
||||
//-----------------------------------------------------------------------------
|
||||
// About using column width:
|
||||
// If a column is manual resizable or has a width specified with TableSetupColumn():
|
||||
// - you may use GetContentRegionAvail().x to query the width available in a given column.
|
||||
// - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width.
|
||||
// If the column is not resizable and has no width specified with TableSetupColumn():
|
||||
// - its width will be automatic and be the set to the max of items submitted.
|
||||
// - therefore you generally cannot have ALL items of the columns use e.g. SetNextItemWidth(-FLT_MIN).
|
||||
// - but if the column has one or more item of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN).
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TABLES CLIPPING/CULLING
|
||||
@@ -138,11 +153,15 @@ Index of this file:
|
||||
// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows.
|
||||
// ImGuiListClipper is reliant on the fact that rows are of equal height.
|
||||
// See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper.
|
||||
// - Note that columns with the ImGuiTableColumnFlags_WidthAuto policy generally don't play well with using the clipper,
|
||||
// and by default a table with _ScrollX but without _Resizable will have columns default to _WidthAuto.
|
||||
// So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns explicitly with _WidthFixed.
|
||||
// - Note that auto-resizing columns don't play well with using the clipper.
|
||||
// By default a table with _ScrollX but without _Resizable will have column auto-resize.
|
||||
// So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns width explicitly with _WidthFixed.
|
||||
//-----------------------------------------------------------------------------
|
||||
// About clipping/culling of Columns in Tables:
|
||||
// - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing
|
||||
// width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know
|
||||
// it is not going to contribute to row height.
|
||||
// In many situations, you may skip submitting contents for every columns but one (e.g. the first one).
|
||||
// - Case A: column is not hidden by user, and at least partially in sight (most common case).
|
||||
// - Case B: column is clipped / out of sight (because of scrolling or parent ClipRect): TableNextColumn() return false as a hint but we still allow layout output.
|
||||
// - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.).
|
||||
@@ -240,9 +259,9 @@ inline ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_w
|
||||
if (flags & ImGuiTableFlags_Resizable)
|
||||
flags |= ImGuiTableFlags_BordersInnerV;
|
||||
|
||||
// Adjust flags: disable NoHostExtendY if we have any scrolling going on
|
||||
if ((flags & ImGuiTableFlags_NoHostExtendY) && (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0)
|
||||
flags &= ~ImGuiTableFlags_NoHostExtendY;
|
||||
// Adjust flags: disable NoHostExtendX/NoHostExtendY if we have any scrolling going on
|
||||
if (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY))
|
||||
flags &= ~(ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoHostExtendY);
|
||||
|
||||
// Adjust flags: NoBordersInBodyUntilResize takes priority over NoBordersInBody
|
||||
if (flags & ImGuiTableFlags_NoBordersInBodyUntilResize)
|
||||
@@ -309,6 +328,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID");
|
||||
|
||||
// Fix flags
|
||||
table->IsDefaultSizingPolicy = (flags & ImGuiTableFlags_SizingMask_) == 0;
|
||||
flags = TableFixFlags(flags, outer_window);
|
||||
|
||||
// Initialize
|
||||
@@ -320,7 +340,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->ColumnsCount = columns_count;
|
||||
table->IsLayoutLocked = false;
|
||||
table->InnerWidth = inner_width;
|
||||
table->IsOuterRectAutoFitX = (outer_size.x == 0.0f) && (use_child_window == false);
|
||||
table->UserOuterSize = outer_size;
|
||||
|
||||
// When not using a child window, WorkRect.Max will grow as we append contents.
|
||||
if (use_child_window)
|
||||
@@ -341,6 +361,10 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
if (override_content_size.x != FLT_MAX || override_content_size.y != FLT_MAX)
|
||||
SetNextWindowContentSize(ImVec2(override_content_size.x != FLT_MAX ? override_content_size.x : 0.0f, override_content_size.y != FLT_MAX ? override_content_size.y : 0.0f));
|
||||
|
||||
// Reset scroll if we are reactivating it
|
||||
if ((table_last_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
|
||||
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
||||
|
||||
// Create scrolling region (without border and zero window padding)
|
||||
ImGuiWindowFlags child_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
|
||||
BeginChildEx(name, instance_id, outer_rect.GetSize(), false, child_flags);
|
||||
@@ -601,10 +625,9 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
|
||||
// Sizing Policy
|
||||
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0)
|
||||
{
|
||||
// FIXME-TABLE: clarify promotion to WidthAuto?
|
||||
const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_);
|
||||
if (table_sizing_policy == ImGuiTableFlags_SizingFixedFit || table_sizing_policy == ImGuiTableFlags_SizingFixedSame)
|
||||
flags |= ((table->Flags & ImGuiTableFlags_Resizable) && !(flags & ImGuiTableColumnFlags_NoResize)) ? ImGuiTableColumnFlags_WidthFixed : ImGuiTableColumnFlags_WidthAuto;
|
||||
flags |= ImGuiTableColumnFlags_WidthFixed;
|
||||
else
|
||||
flags |= ImGuiTableColumnFlags_WidthStretch;
|
||||
}
|
||||
@@ -614,7 +637,7 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
|
||||
}
|
||||
|
||||
// Resize
|
||||
if ((flags & ImGuiTableColumnFlags_WidthAuto) != 0 || (table->Flags & ImGuiTableFlags_Resizable) == 0)
|
||||
if ((table->Flags & ImGuiTableFlags_Resizable) == 0)
|
||||
flags |= ImGuiTableColumnFlags_NoResize;
|
||||
|
||||
// Sorting
|
||||
@@ -707,7 +730,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
table->IsSortSpecsDirty = true;
|
||||
|
||||
// Auto-fit unsized columns
|
||||
const bool start_auto_fit = (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto)) ? (column->WidthRequest < 0.0f) : (column->StretchWeight < 0.0f);
|
||||
const bool start_auto_fit = (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? (column->WidthRequest < 0.0f) : (column->StretchWeight < 0.0f);
|
||||
if (start_auto_fit)
|
||||
column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1; // Fit for three frames
|
||||
|
||||
@@ -777,7 +800,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0;
|
||||
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
|
||||
if (column->Flags & ImGuiTableColumnFlags_WidthFixed)
|
||||
{
|
||||
// Apply same widths policy
|
||||
float width_auto = column->WidthAuto;
|
||||
@@ -786,7 +809,9 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
|
||||
// Apply automatic width
|
||||
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
|
||||
if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAuto) && column->IsVisibleX) || ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable))
|
||||
if (column->AutoFitQueue != 0x00)
|
||||
column->WidthRequest = width_auto;
|
||||
else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)))
|
||||
column->WidthRequest = width_auto;
|
||||
|
||||
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
|
||||
@@ -823,7 +848,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
}
|
||||
table->ColumnsEnabledFixedCount = (ImGuiTableColumnIdx)count_fixed;
|
||||
|
||||
// [Part 5] Apply final widths based on requested widths
|
||||
// [Part 4] Apply final widths based on requested widths
|
||||
const ImRect work_rect = table->WorkRect;
|
||||
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
|
||||
const float width_avail = ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth();
|
||||
@@ -854,7 +879,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
table->ColumnsGivenWidth += column->WidthGiven;
|
||||
}
|
||||
|
||||
// [Part 6] Redistribute stretch remainder width due to rounding (remainder width is < 1.0f * number of Stretch column).
|
||||
// [Part 5] Redistribute stretch remainder width due to rounding (remainder width is < 1.0f * number of Stretch column).
|
||||
// Using right-to-left distribution (more likely to match resizing cursor).
|
||||
if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths))
|
||||
for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--)
|
||||
@@ -874,7 +899,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table->LastOuterHeight));
|
||||
const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0);
|
||||
|
||||
// [Part 7] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
|
||||
// [Part 6] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
|
||||
// Process columns in their visible orders as we are comparing the visible order and adjusting host_clip_rect while looping.
|
||||
int visible_n = 0;
|
||||
bool offset_x_frozen = (table->FreezeColumnsCount > 0);
|
||||
@@ -994,13 +1019,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
}
|
||||
|
||||
if (visible_n < table->FreezeColumnsCount)
|
||||
host_clip_rect.Min.x = ImMax(host_clip_rect.Min.x, column->MaxX + TABLE_BORDER_SIZE);
|
||||
host_clip_rect.Min.x = ImClamp(column->MaxX + TABLE_BORDER_SIZE, host_clip_rect.Min.x, host_clip_rect.Max.x);
|
||||
|
||||
offset_x += column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f;
|
||||
visible_n++;
|
||||
}
|
||||
|
||||
// [Part 8] Detect/store when we are hovering the unused space after the right-most column (so e.g. context menus can react on it)
|
||||
// [Part 7] Detect/store when we are hovering the unused space after the right-most column (so e.g. context menus can react on it)
|
||||
// Clear Resizable flag if none of our column are actually resizable (either via an explicit _NoResize flag, either
|
||||
// because of using _WidthAuto/_WidthStretch). This will hide the resizing option from the context menu.
|
||||
const float unused_x1 = ImMax(table->WorkRect.Min.x, table->Columns[table->RightMostEnabledColumn].ClipRect.Max.x);
|
||||
@@ -1012,12 +1037,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
if (has_resizable == false && (table->Flags & ImGuiTableFlags_Resizable))
|
||||
table->Flags &= ~ImGuiTableFlags_Resizable;
|
||||
|
||||
// [Part 9] Lock actual OuterRect/WorkRect right-most position.
|
||||
// [Part 8] Lock actual OuterRect/WorkRect right-most position.
|
||||
// This is done late to handle the case of fixed-columns tables not claiming more widths that they need.
|
||||
// Because of this we are careful with uses of WorkRect and InnerClipRect before this point.
|
||||
if (table->RightMostStretchedColumn != -1)
|
||||
table->IsOuterRectAutoFitX = false;
|
||||
if (table->IsOuterRectAutoFitX)
|
||||
table->Flags &= ~ImGuiTableFlags_NoHostExtendX;
|
||||
if (table->Flags & ImGuiTableFlags_NoHostExtendX)
|
||||
{
|
||||
table->OuterRect.Max.x = table->WorkRect.Max.x = unused_x1;
|
||||
table->InnerClipRect.Max.x = ImMin(table->InnerClipRect.Max.x, unused_x1);
|
||||
@@ -1026,17 +1051,17 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
table->BorderX1 = table->InnerClipRect.Min.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : -1.0f);
|
||||
table->BorderX2 = table->InnerClipRect.Max.x;// +((table->Flags & ImGuiTableFlags_BordersOuter) ? 0.0f : +1.0f);
|
||||
|
||||
// [Part 10] Allocate draw channels and setup background cliprect
|
||||
// [Part 9] Allocate draw channels and setup background cliprect
|
||||
TableSetupDrawChannels(table);
|
||||
|
||||
// [Part 11] Hit testing on borders
|
||||
// [Part 10] Hit testing on borders
|
||||
if (table->Flags & ImGuiTableFlags_Resizable)
|
||||
TableUpdateBorders(table);
|
||||
table->LastFirstRowHeight = 0.0f;
|
||||
table->IsLayoutLocked = true;
|
||||
table->IsUsingHeaders = false;
|
||||
|
||||
// [Part 12] Context menu
|
||||
// [Part 11] Context menu
|
||||
if (table->IsContextPopupOpen && table->InstanceCurrent == table->InstanceInteracted)
|
||||
{
|
||||
const ImGuiID context_menu_id = ImHashStr("##ContextMenu", 0, table->ID);
|
||||
@@ -1155,27 +1180,37 @@ void ImGui::EndTable()
|
||||
|
||||
// Context menu in columns body
|
||||
if (flags & ImGuiTableFlags_ContextMenuInBody)
|
||||
if (table->HoveredColumnBody != -1 && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Right))
|
||||
if (table->HoveredColumnBody != -1 && !IsAnyItemHovered() && IsMouseReleased(ImGuiMouseButton_Right))
|
||||
TableOpenContextMenu((int)table->HoveredColumnBody);
|
||||
|
||||
// Finalize table height
|
||||
inner_window->DC.PrevLineSize = table->HostBackupPrevLineSize;
|
||||
inner_window->DC.CurrLineSize = table->HostBackupCurrLineSize;
|
||||
inner_window->DC.CursorMaxPos = table->HostBackupCursorMaxPos;
|
||||
const float inner_content_max_y = table->RowPosY2;
|
||||
IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y);
|
||||
if (inner_window != outer_window)
|
||||
{
|
||||
// Both OuterRect/InnerRect are valid from BeginTable
|
||||
inner_window->DC.CursorMaxPos.y = table->RowPosY2;
|
||||
}
|
||||
inner_window->DC.CursorMaxPos.y = inner_content_max_y;
|
||||
else if (!(flags & ImGuiTableFlags_NoHostExtendY))
|
||||
{
|
||||
// Patch OuterRect/InnerRect height
|
||||
table->OuterRect.Max.y = table->InnerRect.Max.y = ImMax(table->OuterRect.Max.y, inner_window->DC.CursorPos.y);
|
||||
inner_window->DC.CursorMaxPos.y = table->RowPosY2;
|
||||
}
|
||||
table->OuterRect.Max.y = table->InnerRect.Max.y = ImMax(table->OuterRect.Max.y, inner_content_max_y); // Patch OuterRect/InnerRect height
|
||||
table->WorkRect.Max.y = ImMax(table->WorkRect.Max.y, table->OuterRect.Max.y);
|
||||
table->LastOuterHeight = table->OuterRect.GetHeight();
|
||||
|
||||
// Setup inner scrolling range
|
||||
// FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y,
|
||||
// but since the later is likely to be impossible to do we'd rather update both axises together.
|
||||
if (table->Flags & ImGuiTableFlags_ScrollX)
|
||||
{
|
||||
const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
|
||||
float max_pos_x = table->InnerWindow->DC.CursorMaxPos.x;
|
||||
if (table->RightMostEnabledColumn != -1)
|
||||
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].WorkMaxX + table->CellPaddingX + table->OuterPaddingX - outer_padding_for_border);
|
||||
if (table->ResizedColumn != -1)
|
||||
max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
|
||||
table->InnerWindow->DC.CursorMaxPos.x = max_pos_x;
|
||||
}
|
||||
|
||||
// Pop clipping rect
|
||||
if (!(flags & ImGuiTableFlags_NoClip))
|
||||
inner_window->DrawList->PopClipRect();
|
||||
inner_window->ClipRect = inner_window->DrawList->_ClipRectStack.back();
|
||||
@@ -1208,7 +1243,13 @@ void ImGui::EndTable()
|
||||
table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
if (table->EnabledMaskByIndex & ((ImU64)1 << column_n))
|
||||
table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, &table->Columns[column_n]);
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize))
|
||||
table->ColumnsAutoFitWidth += column->WidthRequest;
|
||||
else
|
||||
table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, column);
|
||||
}
|
||||
|
||||
// Update scroll
|
||||
if ((table->Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window)
|
||||
@@ -1240,15 +1281,8 @@ void ImGui::EndTable()
|
||||
IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= table->HostBackupItemWidthStackSize, "Too many PopItemWidth!");
|
||||
PopID();
|
||||
|
||||
// Layout in outer window
|
||||
const float backup_outer_cursor_pos_x = outer_window->DC.CursorPos.x;
|
||||
const float backup_outer_max_pos_x = outer_window->DC.CursorMaxPos.x;
|
||||
const float backup_inner_max_pos_x = inner_window->DC.CursorMaxPos.x;
|
||||
float max_pos_x = backup_inner_max_pos_x;
|
||||
if (table->RightMostEnabledColumn != -1)
|
||||
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].MaxX);
|
||||
if (table->ResizedColumn != -1)
|
||||
max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
|
||||
// Restore window data that we modified
|
||||
const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos;
|
||||
inner_window->WorkRect = table->HostBackupWorkRect;
|
||||
inner_window->ParentWorkRect = table->HostBackupParentWorkRect;
|
||||
inner_window->SkipItems = table->HostSkipItems;
|
||||
@@ -1256,28 +1290,48 @@ void ImGui::EndTable()
|
||||
outer_window->DC.ItemWidth = table->HostBackupItemWidth;
|
||||
outer_window->DC.ItemWidthStack.Size = table->HostBackupItemWidthStackSize;
|
||||
outer_window->DC.ColumnsOffset = table->HostBackupColumnsOffset;
|
||||
const float outer_width = table->IsOuterRectAutoFitX ? table->WorkRect.GetWidth() : table->ColumnsAutoFitWidth;
|
||||
|
||||
// Layout in outer window
|
||||
// (FIXME: To allow auto-fit and allow desirable effect of SameLine() we dissociate 'used' vs 'ideal' size by overriding
|
||||
// CursorPosPrevLine and CursorMaxPos manually. That should be a more general layout feature, see same problem e.g. #3414)
|
||||
if (inner_window != outer_window)
|
||||
{
|
||||
EndChild();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImVec2 item_size(outer_width, table->OuterRect.GetHeight());
|
||||
ItemSize(item_size);
|
||||
ItemSize(table->OuterRect.GetSize());
|
||||
ItemAdd(table->OuterRect, 0);
|
||||
}
|
||||
|
||||
// Override EndChild/ItemSize max extent with our own to enable auto-resize on the X axis when possible
|
||||
// FIXME-TABLE: This can be improved (e.g. for Fixed columns we don't want to auto AutoFitWidth? or propagate window auto-fit to table?)
|
||||
if (table->Flags & ImGuiTableFlags_ScrollX)
|
||||
// Override declared contents width/height to enable auto-resize while not needlessly adding a scrollbar
|
||||
if (table->Flags & ImGuiTableFlags_NoHostExtendX)
|
||||
{
|
||||
inner_window->DC.CursorMaxPos.x = max_pos_x; // Set contents width for scrolling
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, backup_outer_cursor_pos_x + table->ColumnsGivenWidth + inner_window->ScrollbarSizes.x); // For scrolling
|
||||
// FIXME-TABLE: Could we remove this section?
|
||||
// ColumnsAutoFitWidth may be one frame ahead here since for Fixed+NoResize is calculated from latest contents
|
||||
IM_ASSERT((table->Flags & ImGuiTableFlags_ScrollX) == 0);
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth);
|
||||
}
|
||||
else if (table->UserOuterSize.x <= 0.0f)
|
||||
{
|
||||
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f;
|
||||
outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - table->UserOuterSize.x);
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));
|
||||
}
|
||||
else
|
||||
{
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, table->WorkRect.Min.x + outer_width); // For auto-fit
|
||||
outer_window->DC.CursorPosPrevLine.x = table->WorkRect.Max.x; // For consistent reaction to SameLine() // FIXME: Should be a feature of layout/ItemAdd
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Max.x);
|
||||
}
|
||||
if (table->UserOuterSize.y <= 0.0f)
|
||||
{
|
||||
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
|
||||
outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - table->UserOuterSize.y);
|
||||
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y));
|
||||
}
|
||||
else
|
||||
{
|
||||
// OuterRect.Max.y may already have been pushed downward from the initial value (unless ImGuiTableFlags_NoHostExtendY is set)
|
||||
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, table->OuterRect.Max.y);
|
||||
}
|
||||
|
||||
// Save settings
|
||||
@@ -1292,7 +1346,8 @@ void ImGui::EndTable()
|
||||
outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1;
|
||||
}
|
||||
|
||||
// See "COLUMN SIZING POLICIES" comments at the top of this file
|
||||
// See "COLUMN SIZING POLICIES" comments at the top of this file
|
||||
// If (init_width_or_weight <= 0.0f) it is ignored
|
||||
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -1309,6 +1364,11 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
ImGuiTableColumn* column = &table->Columns[table->DeclColumnsCount];
|
||||
table->DeclColumnsCount++;
|
||||
|
||||
// Assert when passing a width or weight if policy is entirely left to default, to avoid storing width into weight and vice-versa.
|
||||
// Give a grace to users of ImGuiTableFlags_ScrollX.
|
||||
if (table->IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0)
|
||||
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitely in either Table or Column.");
|
||||
|
||||
// When passing a width automatically enforce WidthFixed policy
|
||||
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable)
|
||||
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
|
||||
@@ -1320,8 +1380,6 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
flags = column->Flags;
|
||||
|
||||
// Initialize defaults
|
||||
if (flags & ImGuiTableColumnFlags_WidthStretch)
|
||||
IM_ASSERT(init_width_or_weight != 0.0f && "Need to provide a valid weight!");
|
||||
column->InitStretchWeightOrWidth = init_width_or_weight;
|
||||
if (table->IsInitializing)
|
||||
{
|
||||
@@ -1436,7 +1494,7 @@ ImRect ImGui::TableGetCellBgRect(const ImGuiTable* table, int column_n)
|
||||
// Return the resizing ID for the right-side of the given column.
|
||||
ImGuiID ImGui::TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no)
|
||||
{
|
||||
IM_ASSERT(column_n < table->ColumnsCount);
|
||||
IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount);
|
||||
ImGuiID id = table->ID + 1 + (instance_no * table->ColumnsCount) + column_n;
|
||||
return id;
|
||||
}
|
||||
@@ -1451,17 +1509,17 @@ int ImGui::TableGetHoveredColumn()
|
||||
return (int)table->HoveredColumnBody;
|
||||
}
|
||||
|
||||
void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n)
|
||||
void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(bg_target != ImGuiTableBgTarget_None);
|
||||
IM_ASSERT(target != ImGuiTableBgTarget_None);
|
||||
|
||||
if (color == IM_COL32_DISABLE)
|
||||
color = 0;
|
||||
|
||||
// We cannot draw neither the cell or row background immediately as we don't know the row height at this point in time.
|
||||
switch (bg_target)
|
||||
switch (target)
|
||||
{
|
||||
case ImGuiTableBgTarget_CellBg:
|
||||
{
|
||||
@@ -1484,7 +1542,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int colum
|
||||
if (table->RowPosY1 > table->InnerClipRect.Max.y) // Discard
|
||||
return;
|
||||
IM_ASSERT(column_n == -1);
|
||||
int bg_idx = (bg_target == ImGuiTableBgTarget_RowBg1) ? 1 : 0;
|
||||
int bg_idx = (target == ImGuiTableBgTarget_RowBg1) ? 1 : 0;
|
||||
table->RowBgColor[bg_idx] = color;
|
||||
break;
|
||||
}
|
||||
@@ -2249,8 +2307,8 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
|
||||
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
|
||||
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132-bit of storage
|
||||
remaining_mask.ClearBits();
|
||||
remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count - 1);
|
||||
remaining_mask.ClearAllBits();
|
||||
remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
|
||||
remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen);
|
||||
IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
|
||||
int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
|
||||
@@ -2324,7 +2382,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
{
|
||||
ImGuiWindow* inner_window = table->InnerWindow;
|
||||
if (inner_window->Hidden || !table->HostClipRect.Overlaps(table->InnerClipRect))
|
||||
if (!table->OuterWindow->ClipRect.Overlaps(table->OuterRect))
|
||||
return;
|
||||
|
||||
ImDrawList* inner_drawlist = inner_window->DrawList;
|
||||
@@ -2335,7 +2393,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
const float border_size = TABLE_BORDER_SIZE;
|
||||
const float draw_y1 = table->InnerRect.Min.y;
|
||||
const float draw_y2_body = table->InnerRect.Max.y;
|
||||
const float draw_y2_head = table->IsUsingHeaders ? ((table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->LastFirstRowHeight) : draw_y1;
|
||||
const float draw_y2_head = table->IsUsingHeaders ? ImMin(table->InnerRect.Max.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table->LastFirstRowHeight) : draw_y1;
|
||||
if (table->Flags & ImGuiTableFlags_BordersInnerV)
|
||||
{
|
||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||
@@ -2349,11 +2407,12 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceCurrent);
|
||||
const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0;
|
||||
const bool is_frozen_separator = (table->FreezeColumnsCount != -1 && table->FreezeColumnsCount == order_n + 1);
|
||||
|
||||
if (column->MaxX > table->InnerClipRect.Max.x && !is_resized)
|
||||
continue;
|
||||
|
||||
// Decide whether right-most column is visible
|
||||
if (column->NextEnabledColumn == -1 && !is_resizable)
|
||||
if ((table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || table->IsOuterRectAutoFitX)
|
||||
if ((table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || (table->Flags & ImGuiTableFlags_NoHostExtendX))
|
||||
continue;
|
||||
if (column->MaxX <= column->ClipRect.Min.x) // FIXME-TABLE FIXME-STYLE: Assume BorderSize==1, this is problematic if we want to increase the border size..
|
||||
continue;
|
||||
@@ -3367,7 +3426,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
||||
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\n"
|
||||
"MinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n"
|
||||
"ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\n"
|
||||
"Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..",
|
||||
"Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s..",
|
||||
n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, (n < table->FreezeColumnsRequest) ? " (Frozen)" : "",
|
||||
column->IsEnabled, column->IsVisibleX, column->IsVisibleY, column->IsRequestOutput, column->IsSkipItems, column->DrawChannelFrozen, column->DrawChannelUnfrozen,
|
||||
column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight, column->StretchWeight > 0.0f ? (column->StretchWeight / sum_weights) * 100.0f : 0.0f,
|
||||
@@ -3376,7 +3435,6 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
||||
column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? " (Asc)" : (column->SortDirection == ImGuiSortDirection_Descending) ? " (Des)" : "", column->UserID, column->Flags,
|
||||
(column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "",
|
||||
(column->Flags & ImGuiTableColumnFlags_WidthFixed) ? "WidthFixed " : "",
|
||||
(column->Flags & ImGuiTableColumnFlags_WidthAuto) ? "WidthAuto " : "",
|
||||
(column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : "");
|
||||
Bullet();
|
||||
Selectable(buf);
|
||||
|
||||
Reference in New Issue
Block a user