Skip to content

Commit 32228d8

Browse files
committed
Tables: added Angled headers support. Added ImGuiTableColumnFlags_AngledHeader, ImGui::TableHeadersAngledRow(), style.TableAngledHeadersAngle. (ocornut#2957)
1 parent 9f851eb commit 32228d8

File tree

7 files changed

+250
-28
lines changed

7 files changed

+250
-28
lines changed

docs/CHANGELOG.txt

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,20 @@ Other changes:
9494
- Drag and Drop: Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload()
9595
with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
9696
- TreeNode: Added ImGuiTreeNodeFlags_SpanAllColumns for use in tables. (#3151, #3565, #2451, #2438)
97-
- Tables: Added ImGuiTableFlags_HighlightHoveredColumn flag, currently highlighting column header.
98-
- Tables: Fixed an edge-case when no columns are visible + table scrollbar is visible + user
99-
code is always testing return value of TableSetColumnIndex() to coarse clip. With an active
100-
clipper it would have asserted. Without a clipper, the scrollbar range would be wrong.
101-
- Tables: Request user to submit contents when outer host-window is requesting auto-resize,
102-
so a scrolling table can contribute to initial window size. (#6510)
103-
- Tables: Fixed subtle drawing overlap between borders in some situations.
104-
- Tables: Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein]
105-
- Tables: Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong
106-
in some situations, causing the earlier to be visible underneath when alpha is not 1.0f.
107-
- Tables: fixed right-clicking right-most section (past right-most column) from highlighting a column.
97+
- Tables:
98+
- Added angled headers support. You need to set ImGuiTableColumnFlags_AngledHeader on selected
99+
columns and call TableAngledHeadersRow(). Added style.TableAngledHeadersAngle style option.
100+
- Added ImGuiTableFlags_HighlightHoveredColumn flag, currently highlighting column header.
101+
- Fixed an edge-case when no columns are visible + table scrollbar is visible + user
102+
code is always testing return value of TableSetColumnIndex() to coarse clip. With an active
103+
clipper it would have asserted. Without a clipper, the scrollbar range would be wrong.
104+
- Request user to submit contents when outer host-window is requesting auto-resize,
105+
so a scrolling table can contribute to initial window size. (#6510)
106+
- Fixed subtle drawing overlap between borders in some situations.
107+
- Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein]
108+
- Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong
109+
in some situations, causing the earlier to be visible underneath when alpha is not 1.0f.
110+
- fixed right-clicking right-most section (past right-most column) from highlighting a column.
108111
- TabBar: Fixed position of unsaved document marker (ImGuiTabItemFlags_UnsavedDocument) which was
109112
accidentally offset in 1.89.9. (#6862) [@alektron]
110113
- Fonts: 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer.

imgui.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,7 @@ ImGuiStyle::ImGuiStyle()
11881188
TabBorderSize = 0.0f; // Thickness of border around tabs.
11891189
TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
11901190
TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
1191+
TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees).
11911192
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
11921193
ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text.
11931194
SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.

imgui.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,8 +771,9 @@ namespace ImGui
771771
// - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled.
772772
IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_id = 0);
773773
IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled.
774-
IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu
775774
IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used)
775+
IMGUI_API void TableHeadersRow(); // submit a row with headers cells based on data provided to TableSetupColumn() + submit context menu
776+
IMGUI_API void TableAngledHeadersRow(); // submit a row with angled headers for every column with the ImGuiTableColumnFlags_AngledHeader flag. MUST BE FIRST ROW.
776777

777778
// Tables: Sorting & Miscellaneous functions
778779
// - Sorting: call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting.
@@ -1240,12 +1241,13 @@ enum ImGuiTableColumnFlags_
12401241
ImGuiTableColumnFlags_NoSort = 1 << 9, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
12411242
ImGuiTableColumnFlags_NoSortAscending = 1 << 10, // Disable ability to sort in the ascending direction.
12421243
ImGuiTableColumnFlags_NoSortDescending = 1 << 11, // Disable ability to sort in the descending direction.
1243-
ImGuiTableColumnFlags_NoHeaderLabel = 1 << 12, // TableHeadersRow() will not submit label for this column. Convenient for some small columns. Name will still appear in context menu.
1244+
ImGuiTableColumnFlags_NoHeaderLabel = 1 << 12, // TableHeadersRow() will not submit horizontal label for this column. Convenient for some small columns. Name will still appear in context menu or in angled headers.
12441245
ImGuiTableColumnFlags_NoHeaderWidth = 1 << 13, // Disable header text width contribution to automatic column width.
12451246
ImGuiTableColumnFlags_PreferSortAscending = 1 << 14, // Make the initial sort direction Ascending when first sorting on this column (default).
12461247
ImGuiTableColumnFlags_PreferSortDescending = 1 << 15, // Make the initial sort direction Descending when first sorting on this column.
12471248
ImGuiTableColumnFlags_IndentEnable = 1 << 16, // Use current Indent value when entering cell (default for column 0).
12481249
ImGuiTableColumnFlags_IndentDisable = 1 << 17, // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes _within_ the cell will still be honored.
1250+
ImGuiTableColumnFlags_AngledHeader = 1 << 18, // TableHeadersRow() will submit an angled header row for this column. Note this will add an extra row.
12491251

12501252
// Output status flags, read-only via TableGetColumnFlags()
12511253
ImGuiTableColumnFlags_IsEnabled = 1 << 24, // Status: is enabled == not hidden by user/api (referred to as "Hide" in _DefaultHide and _NoHide) flags.
@@ -1926,6 +1928,7 @@ struct ImGuiStyle
19261928
float TabBorderSize; // Thickness of border around tabs.
19271929
float TabMinWidthForCloseButton; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
19281930
float TabBarBorderSize; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
1931+
float TableAngledHeadersAngle; // Angle of angled headers (supported values range from -50.0f degrees to +50.0f degrees).
19291932
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
19301933
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
19311934
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.

imgui_demo.cpp

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3949,6 +3949,7 @@ static void EditTableColumnsFlags(ImGuiTableColumnFlags* p_flags)
39493949
ImGui::CheckboxFlags("_PreferSortDescending", p_flags, ImGuiTableColumnFlags_PreferSortDescending);
39503950
ImGui::CheckboxFlags("_IndentEnable", p_flags, ImGuiTableColumnFlags_IndentEnable); ImGui::SameLine(); HelpMarker("Default for column 0");
39513951
ImGui::CheckboxFlags("_IndentDisable", p_flags, ImGuiTableColumnFlags_IndentDisable); ImGui::SameLine(); HelpMarker("Default for column >0");
3952+
ImGui::CheckboxFlags("_AngledHeader", p_flags, ImGuiTableColumnFlags_AngledHeader);
39523953
}
39533954

39543955
static void ShowTableColumnsStatusFlags(ImGuiTableColumnFlags flags)
@@ -4695,8 +4696,14 @@ static void ShowDemoWindowTables()
46954696
ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 9);
46964697
if (ImGui::BeginTable("table_columns_flags", column_count, flags, outer_size))
46974698
{
4699+
bool has_angled_header = false;
46984700
for (int column = 0; column < column_count; column++)
4701+
{
4702+
has_angled_header |= (column_flags[column] & ImGuiTableColumnFlags_AngledHeader) != 0;
46994703
ImGui::TableSetupColumn(column_names[column], column_flags[column]);
4704+
}
4705+
if (has_angled_header)
4706+
ImGui::TableAngledHeadersRow();
47004707
ImGui::TableHeadersRow();
47014708
for (int column = 0; column < column_count; column++)
47024709
column_flags_out[column] = ImGui::TableGetColumnFlags(column);
@@ -5182,6 +5189,56 @@ static void ShowDemoWindowTables()
51825189
ImGui::TreePop();
51835190
}
51845191

5192+
// Demonstrate using ImGuiTableColumnFlags_AngledHeader flag to create angled headers
5193+
if (open_action != -1)
5194+
ImGui::SetNextItemOpen(open_action != 0);
5195+
IMGUI_DEMO_MARKER("Tables/Angled headers");
5196+
if (ImGui::TreeNode("Angled headers"))
5197+
{
5198+
const char* column_names[] = { "Track", "cabasa", "ride", "smash", "tom-hi", "tom-mid", "tom-low", "hihat-o", "hihat-c", "snare-s", "snare-c", "clap", "rim", "kick" };
5199+
const int columns_count = IM_ARRAYSIZE(column_names);
5200+
const int rows_count = 12;
5201+
5202+
static ImGuiTableFlags table_flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_Hideable | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_HighlightHoveredColumn;
5203+
static bool bools[columns_count * rows_count] = {}; // Dummy storage selection storage
5204+
static int frozen_rows = 2;
5205+
ImGui::CheckboxFlags("_ScrollX", &table_flags, ImGuiTableFlags_ScrollX);
5206+
ImGui::CheckboxFlags("_ScrollY", &table_flags, ImGuiTableFlags_ScrollY);
5207+
ImGui::CheckboxFlags("_NoBordersInBody", &table_flags, ImGuiTableFlags_NoBordersInBody);
5208+
ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
5209+
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
5210+
ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
5211+
5212+
if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12)))
5213+
{
5214+
ImGui::TableSetupColumn(column_names[0], ImGuiTableColumnFlags_NoHide | ImGuiTableColumnFlags_NoReorder);
5215+
for (int n = 1; n < columns_count; n++)
5216+
ImGui::TableSetupColumn(column_names[n], ImGuiTableColumnFlags_AngledHeader | ImGuiTableColumnFlags_WidthFixed);
5217+
ImGui::TableSetupScrollFreeze(0, frozen_rows);
5218+
5219+
ImGui::TableAngledHeadersRow(); // Draw angled headers for all columns with the ImGuiTableColumnFlags_AngledHeader flag.
5220+
ImGui::TableHeadersRow(); // Draw remaining headers and allow access to context-menu and other functions.
5221+
for (int row = 0; row < rows_count; row++)
5222+
{
5223+
ImGui::PushID(row);
5224+
ImGui::TableNextRow();
5225+
ImGui::TableSetColumnIndex(0);
5226+
ImGui::AlignTextToFramePadding();
5227+
ImGui::Text("Track %d", row);
5228+
for (int column = 1; column < columns_count; column++)
5229+
if (ImGui::TableSetColumnIndex(column))
5230+
{
5231+
ImGui::PushID(column);
5232+
ImGui::Checkbox("", &bools[row * columns_count + column]);
5233+
ImGui::PopID();
5234+
}
5235+
ImGui::PopID();
5236+
}
5237+
ImGui::EndTable();
5238+
}
5239+
ImGui::TreePop();
5240+
}
5241+
51855242
// Demonstrate creating custom context menus inside columns, while playing it nice with context menus provided by TableHeadersRow()/TableHeader()
51865243
if (open_action != -1)
51875244
ImGui::SetNextItemOpen(open_action != 0);
@@ -5428,6 +5485,7 @@ static void ShowDemoWindowTables()
54285485
| ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBody
54295486
| ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
54305487
| ImGuiTableFlags_SizingFixedFit;
5488+
static ImGuiTableColumnFlags columns_base_flags = ImGuiTableColumnFlags_None;
54315489

54325490
enum ContentsType { CT_Text, CT_Button, CT_SmallButton, CT_FillButton, CT_Selectable, CT_SelectableSpanRow };
54335491
static int contents_type = CT_SelectableSpanRow;
@@ -5525,6 +5583,8 @@ static void ShowDemoWindowTables()
55255583
{
55265584
ImGui::Checkbox("show_headers", &show_headers);
55275585
ImGui::CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", &flags, ImGuiTableFlags_HighlightHoveredColumn);
5586+
ImGui::CheckboxFlags("ImGuiTableColumnFlags_AngledHeader", &columns_base_flags, ImGuiTableColumnFlags_AngledHeader);
5587+
ImGui::SameLine(); HelpMarker("Enable AngledHeader on all columns. Best enabled on selected narrow columns (see \"Angled headers\" section of the demo).");
55285588
ImGui::TreePop();
55295589
}
55305590

@@ -5590,12 +5650,12 @@ static void ShowDemoWindowTables()
55905650
// Declare columns
55915651
// We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications.
55925652
// This is so our sort function can identify a column given our own identifier. We could also identify them based on their index!
5593-
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHide, 0.0f, MyItemColumnID_ID);
5594-
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name);
5595-
ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action);
5596-
ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, 0.0f, MyItemColumnID_Quantity);
5597-
ImGui::TableSetupColumn("Description", (flags & ImGuiTableFlags_NoHostExtendX) ? 0 : ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Description);
5598-
ImGui::TableSetupColumn("Hidden", ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort);
5653+
ImGui::TableSetupColumn("ID", columns_base_flags | ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHide, 0.0f, MyItemColumnID_ID);
5654+
ImGui::TableSetupColumn("Name", columns_base_flags | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name);
5655+
ImGui::TableSetupColumn("Action", columns_base_flags | ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action);
5656+
ImGui::TableSetupColumn("Quantity", columns_base_flags | ImGuiTableColumnFlags_PreferSortDescending, 0.0f, MyItemColumnID_Quantity);
5657+
ImGui::TableSetupColumn("Description", columns_base_flags | ((flags & ImGuiTableFlags_NoHostExtendX) ? 0 : ImGuiTableColumnFlags_WidthStretch), 0.0f, MyItemColumnID_Description);
5658+
ImGui::TableSetupColumn("Hidden", columns_base_flags | ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort);
55995659
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
56005660

56015661
// Sort our data if sort specs have been changed!
@@ -5614,6 +5674,8 @@ static void ShowDemoWindowTables()
56145674
const bool sorts_specs_using_quantity = (ImGui::TableGetColumnFlags(3) & ImGuiTableColumnFlags_IsSorted) != 0;
56155675

56165676
// Show headers
5677+
if (show_headers && (columns_base_flags & ImGuiTableColumnFlags_AngledHeader) != 0)
5678+
ImGui::TableAngledHeadersRow();
56175679
if (show_headers)
56185680
ImGui::TableHeadersRow();
56195681

@@ -6400,7 +6462,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
64006462
ImGui::SeparatorText("Main");
64016463
ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f");
64026464
ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f");
6403-
ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f, 20.0f, "%.0f");
64046465
ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f");
64056466
ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
64066467
ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f");
@@ -6425,6 +6486,10 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
64256486
ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
64266487
ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
64276488

6489+
ImGui::SeparatorText("Tables");
6490+
ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f, 20.0f, "%.0f");
6491+
ImGui::SliderAngle("TableAngledHeadersAngle", &style.TableAngledHeadersAngle, -50.0f, +50.0f);
6492+
64286493
ImGui::SeparatorText("Widgets");
64296494
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
64306495
int window_menu_button_position = style.WindowMenuButtonPosition + 1;

imgui_draw.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,14 @@ void ImGui::ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int ve
19891989
}
19901990
}
19911991

1992+
void ImGui::ShadeVertsTransformPos(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& pivot_in, float cos_a, float sin_a, const ImVec2& pivot_out)
1993+
{
1994+
ImDrawVert* vert_start = draw_list->VtxBuffer.Data + vert_start_idx;
1995+
ImDrawVert* vert_end = draw_list->VtxBuffer.Data + vert_end_idx;
1996+
for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex)
1997+
vertex->pos = ImRotate(vertex->pos- pivot_in, cos_a, sin_a) + pivot_out;
1998+
}
1999+
19922000
//-----------------------------------------------------------------------------
19932001
// [SECTION] ImFontConfig
19942002
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)