mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Tables: Angled Headers: fixed support for multi-line labels. various padding/layout fixes. (#6917)
This commit is contained in:
parent
6655ab2e43
commit
405e54ebd5
@ -43,6 +43,10 @@ Breaking changes:
|
|||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
|
|
||||||
|
- Tables: Angled headers: fixed support for multi-line labels. (#6917)
|
||||||
|
- Tables: Angled headers: various fixes to accurately handle CellPadding changes. (#6917)
|
||||||
|
- Tables: Angled headers: properly registers horizontal component of angled headers
|
||||||
|
for auto-resizing of columns. (#6917)
|
||||||
- Tables: Angled headers: fixed TableAngledHeadersRow() incorrect background fill
|
- Tables: Angled headers: fixed TableAngledHeadersRow() incorrect background fill
|
||||||
drawn too low, particularly visible with tables that have no scrolling. (#6917)
|
drawn too low, particularly visible with tables that have no scrolling. (#6917)
|
||||||
|
|
||||||
|
@ -5307,23 +5307,26 @@ static void ShowDemoWindowTables()
|
|||||||
const int rows_count = 12;
|
const int rows_count = 12;
|
||||||
|
|
||||||
static ImGuiTableFlags table_flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_Hideable | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_HighlightHoveredColumn;
|
static ImGuiTableFlags table_flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_Hideable | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_HighlightHoveredColumn;
|
||||||
|
static ImGuiTableColumnFlags column_flags = ImGuiTableColumnFlags_AngledHeader | ImGuiTableColumnFlags_WidthFixed;
|
||||||
static bool bools[columns_count * rows_count] = {}; // Dummy storage selection storage
|
static bool bools[columns_count * rows_count] = {}; // Dummy storage selection storage
|
||||||
static int frozen_cols = 1;
|
static int frozen_cols = 1;
|
||||||
static int frozen_rows = 2;
|
static int frozen_rows = 2;
|
||||||
ImGui::CheckboxFlags("_ScrollX", &table_flags, ImGuiTableFlags_ScrollX);
|
ImGui::CheckboxFlags("_ScrollX", &table_flags, ImGuiTableFlags_ScrollX);
|
||||||
ImGui::CheckboxFlags("_ScrollY", &table_flags, ImGuiTableFlags_ScrollY);
|
ImGui::CheckboxFlags("_ScrollY", &table_flags, ImGuiTableFlags_ScrollY);
|
||||||
|
ImGui::CheckboxFlags("_Resizable", &table_flags, ImGuiTableFlags_Resizable);
|
||||||
ImGui::CheckboxFlags("_NoBordersInBody", &table_flags, ImGuiTableFlags_NoBordersInBody);
|
ImGui::CheckboxFlags("_NoBordersInBody", &table_flags, ImGuiTableFlags_NoBordersInBody);
|
||||||
ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
|
ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
|
||||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||||
ImGui::SliderInt("Frozen columns", &frozen_cols, 0, 2);
|
ImGui::SliderInt("Frozen columns", &frozen_cols, 0, 2);
|
||||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||||
ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
|
ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
|
||||||
|
ImGui::CheckboxFlags("Disable header contributing to column width", &column_flags, ImGuiTableColumnFlags_NoHeaderWidth);
|
||||||
|
|
||||||
if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12)))
|
if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12)))
|
||||||
{
|
{
|
||||||
ImGui::TableSetupColumn(column_names[0], ImGuiTableColumnFlags_NoHide | ImGuiTableColumnFlags_NoReorder);
|
ImGui::TableSetupColumn(column_names[0], ImGuiTableColumnFlags_NoHide | ImGuiTableColumnFlags_NoReorder);
|
||||||
for (int n = 1; n < columns_count; n++)
|
for (int n = 1; n < columns_count; n++)
|
||||||
ImGui::TableSetupColumn(column_names[n], ImGuiTableColumnFlags_AngledHeader | ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn(column_names[n], column_flags);
|
||||||
ImGui::TableSetupScrollFreeze(frozen_cols, frozen_rows);
|
ImGui::TableSetupScrollFreeze(frozen_cols, frozen_rows);
|
||||||
|
|
||||||
ImGui::TableAngledHeadersRow(); // Draw angled headers for all columns with the ImGuiTableColumnFlags_AngledHeader flag.
|
ImGui::TableAngledHeadersRow(); // Draw angled headers for all columns with the ImGuiTableColumnFlags_AngledHeader flag.
|
||||||
|
@ -2962,7 +2962,7 @@ float ImGui::TableGetHeaderAngledMaxLabelWidth()
|
|||||||
if (IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n))
|
if (IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n))
|
||||||
if (table->Columns[column_n].Flags & ImGuiTableColumnFlags_AngledHeader)
|
if (table->Columns[column_n].Flags & ImGuiTableColumnFlags_AngledHeader)
|
||||||
width = ImMax(width, CalcTextSize(TableGetColumnName(table, column_n), NULL, true).x);
|
width = ImMax(width, CalcTextSize(TableGetColumnName(table, column_n), NULL, true).x);
|
||||||
return width + g.Style.CellPadding.x * 2.0f;
|
return width + g.Style.CellPadding.y * 2.0f; // Swap padding
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Public] This is a helper to output TableHeader() calls based on the column names declared in TableSetupColumn().
|
// [Public] This is a helper to output TableHeader() calls based on the column names declared in TableSetupColumn().
|
||||||
@ -3215,6 +3215,7 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
|
|||||||
|
|
||||||
// Draw background and labels in first pass, then all borders.
|
// Draw background and labels in first pass, then all borders.
|
||||||
float max_x = 0.0f;
|
float max_x = 0.0f;
|
||||||
|
ImVec2 padding = g.Style.CellPadding; // We will always use swapped component
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||||
{
|
{
|
||||||
@ -3236,33 +3237,43 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width)
|
|||||||
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableHeaderBg));
|
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableHeaderBg));
|
||||||
if (column_n == highlight_column_n)
|
if (column_n == highlight_column_n)
|
||||||
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_Header)); // Highlight on hover
|
draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_Header)); // Highlight on hover
|
||||||
//draw_list->AddQuad(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableBorderLight), 1.0f);
|
|
||||||
max_x = ImMax(max_x, bg_shape[3].x);
|
max_x = ImMax(max_x, bg_shape[3].x);
|
||||||
|
|
||||||
// Draw label (first draw at an offset where RenderTextXXX() function won't meddle with applying current ClipRect, then transform to final offset)
|
// Draw label
|
||||||
// FIXME: May be worth tidying up all those operations to make them easier to understand.
|
// - First draw at an offset where RenderTextXXX() function won't meddle with applying current ClipRect, then transform to final offset.
|
||||||
|
// - Handle multiple lines manually, as we want each lines to follow on the horizontal border, rather than see a whole block rotated.
|
||||||
const char* label_name = TableGetColumnName(table, column_n);
|
const char* label_name = TableGetColumnName(table, column_n);
|
||||||
const float clip_width = max_label_width - (sin_a * table->RowCellPaddingY);
|
const char* label_name_end = FindRenderedTextEnd(label_name);
|
||||||
ImRect label_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width + (flip_label ? 0.0f : table->CellPaddingX), header_height + table->RowCellPaddingY));
|
const float line_off_step_x = g.FontSize / -sin_a;
|
||||||
ImVec2 label_size = CalcTextSize(label_name, NULL, true);
|
float line_off_curr_x = 0.0f;
|
||||||
ImVec2 label_off = ImVec2(flip_label ? ImMax(0.0f, max_label_width - label_size.x - table->CellPaddingX) : table->CellPaddingX, table->RowCellPaddingY);
|
while (label_name < label_name_end)
|
||||||
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
|
|
||||||
RenderTextEllipsis(draw_list, label_r.Min + label_off, label_r.Max, label_r.Max.x, label_r.Max.x, label_name, NULL, &label_size);
|
|
||||||
int vtx_idx_end = draw_list->_VtxCurrentIdx;
|
|
||||||
|
|
||||||
// Rotate and offset label
|
|
||||||
ImVec2 pivot_in = label_r.GetBL();
|
|
||||||
ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y) + (flip_label ? (unit_right * clip_width) : ImVec2(header_height, 0.0f));
|
|
||||||
ShadeVertsTransformPos(draw_list, vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset
|
|
||||||
|
|
||||||
// Debug draw
|
|
||||||
/*if (g.IO.KeyShift)
|
|
||||||
{
|
{
|
||||||
vtx_idx_begin = GetForegroundDrawList()->_VtxCurrentIdx;
|
const char* label_name_eol = strchr(label_name, '\n');
|
||||||
GetForegroundDrawList()->AddRect(label_r.Min, label_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 2.0f);
|
if (label_name_eol == NULL)
|
||||||
vtx_idx_end = GetForegroundDrawList()->_VtxCurrentIdx;
|
label_name_eol = label_name_end;
|
||||||
ShadeVertsTransformPos(GetForegroundDrawList(), vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset
|
|
||||||
}*/
|
ImVec2 label_size = CalcTextSize(label_name, label_name_eol);
|
||||||
|
float clip_width = max_label_width - padding.y; // Using padding.y*2.0f would be symetrical but hide more text.
|
||||||
|
ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, label_size.y));
|
||||||
|
int vtx_idx_begin = draw_list->_VtxCurrentIdx;
|
||||||
|
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, clip_r.Max.x, label_name, label_name_eol, &label_size);
|
||||||
|
int vtx_idx_end = draw_list->_VtxCurrentIdx;
|
||||||
|
|
||||||
|
// Rotate and offset label
|
||||||
|
ImVec2 pivot_in = ImVec2(window->ClipRect.Min.x, window->ClipRect.Min.y + label_size.y);
|
||||||
|
ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y);
|
||||||
|
line_off_curr_x += line_off_step_x;
|
||||||
|
pivot_out += unit_right * padding.y;
|
||||||
|
if (flip_label)
|
||||||
|
pivot_out += unit_right * (clip_width - ImMax(0.0f, clip_width - label_size.x));
|
||||||
|
pivot_out.x += flip_label ? line_off_curr_x - line_off_step_x : line_off_curr_x;
|
||||||
|
ShadeVertsTransformPos(draw_list, vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset
|
||||||
|
//if (g.IO.KeyShift) { ImDrawList* fg_dl = GetForegroundDrawList(); vtx_idx_begin = fg_dl->_VtxCurrentIdx; fg_dl->AddRect(clip_r.Min, clip_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 2.0f); ShadeVertsTransformPos(fg_dl, vtx_idx_begin, fg_dl->_VtxCurrentIdx, pivot_in, label_cos_a, label_sin_a, pivot_out); }
|
||||||
|
|
||||||
|
// Register header width
|
||||||
|
column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX + ImCeil(line_off_curr_x);
|
||||||
|
label_name = label_name_eol + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user