Tables: added ImGuiTableFlags_HighlightHoveredColumn.
This commit is contained in:
parent
be1311cfc1
commit
9f851ebfe4
@ -94,6 +94,7 @@ Other changes:
|
||||
- Drag and Drop: Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload()
|
||||
with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
|
||||
- TreeNode: Added ImGuiTreeNodeFlags_SpanAllColumns for use in tables. (#3151, #3565, #2451, #2438)
|
||||
- Tables: Added ImGuiTableFlags_HighlightHoveredColumn flag, currently highlighting column header.
|
||||
- Tables: Fixed an edge-case when no columns are visible + table scrollbar is visible + user
|
||||
code is always testing return value of TableSetColumnIndex() to coarse clip. With an active
|
||||
clipper it would have asserted. Without a clipper, the scrollbar range would be wrong.
|
||||
|
2
imgui.h
2
imgui.h
@ -1216,6 +1216,8 @@ enum ImGuiTableFlags_
|
||||
// Sorting
|
||||
ImGuiTableFlags_SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
|
||||
ImGuiTableFlags_SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
|
||||
// Miscellaneous
|
||||
ImGuiTableFlags_HighlightHoveredColumn = 1 << 28, // Highlight column headers when hovered (may evolve into a fuller highlight)
|
||||
|
||||
// [Internal] Combinations and masks
|
||||
ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame,
|
||||
|
@ -3973,10 +3973,10 @@ static void ShowDemoWindowTables()
|
||||
ImGui::PushID("Tables");
|
||||
|
||||
int open_action = -1;
|
||||
if (ImGui::Button("Open all"))
|
||||
if (ImGui::Button("Expand all"))
|
||||
open_action = 1;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Close all"))
|
||||
if (ImGui::Button("Collapse all"))
|
||||
open_action = 0;
|
||||
ImGui::SameLine();
|
||||
|
||||
@ -4262,6 +4262,7 @@ static void ShowDemoWindowTables()
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_Hideable", &flags, ImGuiTableFlags_Hideable);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags, ImGuiTableFlags_NoBordersInBodyUntilResize); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appear in Headers)");
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", &flags, ImGuiTableFlags_HighlightHoveredColumn);
|
||||
PopStyleCompact();
|
||||
|
||||
if (ImGui::BeginTable("table1", 3, flags))
|
||||
@ -5299,6 +5300,7 @@ static void ShowDemoWindowTables()
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings;
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_SizingFixedFit", &flags, ImGuiTableFlags_SizingFixedFit);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", &flags, ImGuiTableFlags_HighlightHoveredColumn);
|
||||
for (int n = 0; n < 3; n++)
|
||||
{
|
||||
char buf[32];
|
||||
@ -5519,9 +5521,15 @@ static void ShowDemoWindowTables()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNodeEx("Other:", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
if (ImGui::TreeNodeEx("Headers:", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::Checkbox("show_headers", &show_headers);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", &flags, ImGuiTableFlags_HighlightHoveredColumn);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNodeEx("Other:", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::Checkbox("show_wrapped_text", &show_wrapped_text);
|
||||
|
||||
ImGui::DragFloat2("##OuterSize", &outer_size_value.x);
|
||||
|
@ -2669,6 +2669,7 @@ struct ImGuiTableCellData
|
||||
};
|
||||
|
||||
// Per-instance data that needs preserving across frames (seemingly most others do not need to be preserved aside from debug needs. Does that means they could be moved to ImGuiTableTempData?)
|
||||
// sizeof() ~ 24 bytes
|
||||
struct ImGuiTableInstanceData
|
||||
{
|
||||
ImGuiID TableInstanceID;
|
||||
@ -2754,6 +2755,7 @@ struct IMGUI_API ImGuiTable
|
||||
ImGuiTableColumnIdx DeclColumnsCount; // Count calls to TableSetupColumn()
|
||||
ImGuiTableColumnIdx HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == ColumnsCount when hovering empty region after the right-most column!
|
||||
ImGuiTableColumnIdx HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing).
|
||||
ImGuiTableColumnIdx HighlightColumnHeader; // Index of column which should be highlighted.
|
||||
ImGuiTableColumnIdx AutoFitSingleColumn; // Index of single column requesting auto-fit.
|
||||
ImGuiTableColumnIdx ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0.
|
||||
ImGuiTableColumnIdx LastResizedColumn; // Index of column being resized from previous frame.
|
||||
@ -2786,6 +2788,8 @@ struct IMGUI_API ImGuiTable
|
||||
bool IsResetDisplayOrderRequest;
|
||||
bool IsUnfrozenRows; // Set when we got past the frozen row.
|
||||
bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable()
|
||||
bool IsActiveIdAliveBeforeTable;
|
||||
bool IsActiveIdInTable;
|
||||
bool HasScrollbarYCurr; // Whether ANY instance of this table had a vertical scrollbar during the current frame.
|
||||
bool HasScrollbarYPrev; // Whether ANY instance of this table had a vertical scrollbar during the previous.
|
||||
bool MemoryCompacted;
|
||||
|
@ -346,7 +346,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
flags = TableFixFlags(flags, outer_window);
|
||||
|
||||
// Initialize
|
||||
const int instance_no = (table->LastFrameActive != g.FrameCount) ? 0 : table->InstanceCurrent + 1;
|
||||
const int previous_frame_active = table->LastFrameActive;
|
||||
const int instance_no = (previous_frame_active != g.FrameCount) ? 0 : table->InstanceCurrent + 1;
|
||||
table->ID = id;
|
||||
table->Flags = flags;
|
||||
table->LastFrameActive = g.FrameCount;
|
||||
@ -478,6 +479,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->FreezeColumnsRequest = table->FreezeColumnsCount = 0;
|
||||
table->IsUnfrozenRows = true;
|
||||
table->DeclColumnsCount = 0;
|
||||
if (previous_frame_active + 1 < g.FrameCount)
|
||||
table->IsActiveIdInTable = false;
|
||||
|
||||
// Using opaque colors facilitate overlapping lines of the grid, otherwise we'd need to improve TableDrawBorders()
|
||||
table->BorderColorStrong = GetColorU32(ImGuiCol_TableBorderStrong);
|
||||
@ -974,8 +977,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
|
||||
table_instance->HoveredRowLast = table_instance->HoveredRowNext;
|
||||
table_instance->HoveredRowNext = -1;
|
||||
table->HoveredColumnBody = -1;
|
||||
table->HoveredColumnBorder = -1;
|
||||
table->HoveredColumnBody = table->HoveredColumnBorder = -1;
|
||||
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_instance->LastOuterHeight));
|
||||
const ImGuiID backup_active_id = g.ActiveId;
|
||||
g.ActiveId = 0;
|
||||
@ -1122,13 +1124,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
// 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);
|
||||
if (is_hovering_table && table->HoveredColumnBody == -1)
|
||||
{
|
||||
if (g.IO.MousePos.x >= unused_x1)
|
||||
table->HoveredColumnBody = (ImGuiTableColumnIdx)table->ColumnsCount;
|
||||
}
|
||||
if (has_resizable == false && (table->Flags & ImGuiTableFlags_Resizable))
|
||||
table->Flags &= ~ImGuiTableFlags_Resizable;
|
||||
|
||||
table->IsActiveIdAliveBeforeTable = (g.ActiveIdIsAlive != 0);
|
||||
|
||||
// [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.
|
||||
@ -1161,6 +1163,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
table->IsLayoutLocked = true;
|
||||
table->IsUsingHeaders = false;
|
||||
|
||||
// Highlight header
|
||||
table->HighlightColumnHeader = -1;
|
||||
if (table->IsContextPopupOpen && table->ContextPopupColumn != -1 && table->InstanceInteracted == table->InstanceCurrent)
|
||||
table->HighlightColumnHeader = table->ContextPopupColumn;
|
||||
else if ((table->Flags & ImGuiTableFlags_HighlightHoveredColumn) && table->HoveredColumnBody != -1 && table->HoveredColumnBody != table->ColumnsCount && table->HoveredColumnBorder == -1)
|
||||
if (g.ActiveId == 0 || (table->IsActiveIdInTable || g.DragDropActive))
|
||||
table->HighlightColumnHeader = table->HoveredColumnBody;
|
||||
|
||||
// [Part 11] Context menu
|
||||
if (TableBeginContextMenuPopup(table))
|
||||
{
|
||||
@ -1382,6 +1392,8 @@ void ImGui::EndTable()
|
||||
table->ResizedColumnNextWidth = new_width;
|
||||
}
|
||||
|
||||
table->IsActiveIdInTable = (g.ActiveIdIsAlive != 0 && table->IsActiveIdAliveBeforeTable == false);
|
||||
|
||||
// Pop from id stack
|
||||
IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table_instance->TableInstanceID, "Mismatching PushID/PopID!");
|
||||
IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= temp_data->HostBackupItemWidthStackSize, "Too many PopItemWidth!");
|
||||
@ -2301,6 +2313,7 @@ void ImGui::TableUpdateColumnsWeightFromWidth(ImGuiTable* table)
|
||||
// - TablePopBackgroundChannel() [Internal]
|
||||
// - TableSetupDrawChannels() [Internal]
|
||||
// - TableMergeDrawChannels() [Internal]
|
||||
// - TableGetColumnBorderCol() [Internal]
|
||||
// - TableDrawBorders() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@ -2584,6 +2597,18 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
}
|
||||
}
|
||||
|
||||
static ImU32 TableGetColumnBorderCol(ImGuiTable* table, int order_n, int column_n)
|
||||
{
|
||||
const bool is_hovered = (table->HoveredColumnBorder == column_n);
|
||||
const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceCurrent);
|
||||
const bool is_frozen_separator = (table->FreezeColumnsCount == order_n + 1);
|
||||
if (is_resized || is_hovered)
|
||||
return ImGui::GetColorU32(is_resized ? ImGuiCol_SeparatorActive : ImGuiCol_SeparatorHovered);
|
||||
if (is_frozen_separator || (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)))
|
||||
return table->BorderColorStrong;
|
||||
return table->BorderColorLight;
|
||||
}
|
||||
|
||||
// FIXME-TABLE: This is a mess, need to redesign how we render borders (as some are also done in TableEndRow)
|
||||
void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
{
|
||||
@ -2626,21 +2651,9 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
|
||||
// Draw in outer window so right-most column won't be clipped
|
||||
// Always draw full height border when being resized/hovered, or on the delimitation of frozen column scrolling.
|
||||
ImU32 col;
|
||||
float draw_y2;
|
||||
if (is_hovered || is_resized || is_frozen_separator)
|
||||
{
|
||||
draw_y2 = draw_y2_body;
|
||||
col = is_resized ? GetColorU32(ImGuiCol_SeparatorActive) : is_hovered ? GetColorU32(ImGuiCol_SeparatorHovered) : table->BorderColorStrong;
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_y2 = (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) ? draw_y2_head : draw_y2_body;
|
||||
col = (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) ? table->BorderColorStrong : table->BorderColorLight;
|
||||
}
|
||||
|
||||
float draw_y2 = (is_hovered || is_resized || is_frozen_separator || (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) == 0) ? draw_y2_body : draw_y2_head;
|
||||
if (draw_y2 > draw_y1)
|
||||
inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), col, border_size);
|
||||
inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), TableGetColumnBorderCol(table, order_n, column_n), border_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2994,7 +3007,6 @@ void ImGui::TableHeader(const char* label)
|
||||
column->ContentMaxXHeadersIdeal = ImMax(column->ContentMaxXHeadersIdeal, max_pos_x);
|
||||
|
||||
// Keep header highlighted when context menu is open.
|
||||
const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent);
|
||||
ImGuiID id = window->GetID(label);
|
||||
ImRect bb(cell_r.Min.x, cell_r.Min.y, cell_r.Max.x, ImMax(cell_r.Max.y, cell_r.Min.y + label_height + g.Style.CellPadding.y * 2.0f));
|
||||
ItemSize(ImVec2(0.0f, label_height)); // Don't declare unclipped width, it'll be fed ContentMaxPosHeadersIdeal
|
||||
@ -3005,9 +3017,10 @@ void ImGui::TableHeader(const char* label)
|
||||
//GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG]
|
||||
|
||||
// Using AllowOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items.
|
||||
const bool highlight = (table->HighlightColumnHeader == column_n);
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowOverlap);
|
||||
if (held || hovered || selected)
|
||||
if (held || hovered || highlight)
|
||||
{
|
||||
const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||
//RenderFrame(bb.Min, bb.Max, col, false, 0.0f);
|
||||
|
Loading…
Reference in New Issue
Block a user