mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-23 21:09:01 +08:00
Tables: simplified and tidying up TableSetColumnWidth(), fixes resizing a fixed column surrounded by stretch column (manually or via auto-fit menu). TableHeader() showing highlighted when held.
This commit is contained in:
parent
972ca8166f
commit
d497f112e7
2
imgui.h
2
imgui.h
@ -1050,7 +1050,7 @@ enum ImGuiTabItemFlags_
|
||||
// - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable().
|
||||
// - Mixing up columns with different sizing policy is possible BUT can be tricky and has some side-effects and restrictions.
|
||||
// (their visible order and the scrolling state have subtle but necessary effects on how they can be manually resized).
|
||||
// The typical use of mixing sizing policies is to have ScrollX disabled, one or two Stretch Column and many Fixed Columns.
|
||||
// The typical use of mixing sizing policies is to have ScrollX disabled, first Fixed columns and then one or two TRAILING Stretch columns.
|
||||
enum ImGuiTableFlags_
|
||||
{
|
||||
// Features
|
||||
|
@ -1876,6 +1876,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
|
||||
if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
|
||||
return;
|
||||
|
||||
//IMGUI_DEBUG_LOG("TableSetColumnWidth(%d, %.1f->%.1f)\n", column_0_idx, column_0->WidthGiven, column_0_width);
|
||||
ImGuiTableColumn* column_1 = (column_0->NextEnabledColumn != -1) ? &table->Columns[column_0->NextEnabledColumn] : NULL;
|
||||
|
||||
// In this surprisingly not simple because of how we support mixing Fixed and multiple Stretch columns.
|
||||
@ -1897,66 +1898,44 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
|
||||
// - W1 F2 F3 resize from F3| --> ok: no-op (disabled by Resize Rule 1)
|
||||
// - W1 F2 resize from F2| --> ok: no-op (disabled by Resize Rule 1)
|
||||
// - W1 W2 F3 resize from W1| or W2| --> ok
|
||||
// - W1 F2 W3 resize from W1| or F2| --> FIXME
|
||||
// - W1 F2 W3 resize from W1| or F2| --> ok
|
||||
// - F1 W2 F3 resize from W2| --> ok
|
||||
// - F1 W3 F2 resize from W3| --> ok
|
||||
// - W1 F2 F3 resize from W1| --> ok: equivalent to resizing |F2. F3 will not move. (forwarded by Resize Rule 2)
|
||||
// - W1 F2 F3 resize from W1| --> ok: equivalent to resizing |F2. F3 will not move.
|
||||
// - W1 F2 F3 resize from F2| --> ok
|
||||
// All resizes from a Wx columns are locking other columns.
|
||||
|
||||
// Possible improvements:
|
||||
// - W1 W2 W3 resize W1| --> to not be stuck, both W2 and W3 would stretch down. Seems possible to fix. Would be most beneficial to simplify resize of all-weighted columns.
|
||||
// - W1 F2 W3 resize W1| or F2| --> symmetrical resize is weird and glitchy. Seems possible to fix.
|
||||
// - W3 F1 F2 resize W3| --> to not be stuck past F1|, both F1 and F2 would need to stretch down, which would be lossy or ambiguous. Seems hard to fix.
|
||||
|
||||
// Rules:
|
||||
// - [Resize Rule 1] Can't resize from right of right-most visible column if there is any Stretch column. Implemented in TableUpdateLayout().
|
||||
// - [Resize Rule 2] Resizing from right-side of a Stretch column before a fixed column forward sizing to left-side of fixed column.
|
||||
// - [Resize Rule 3] If we are are followed by a fixed column and we have a Stretch column before, we need to ensure that our left border won't move.
|
||||
table->IsSettingsDirty = true;
|
||||
// [Resize Rule 1] Can't resize from right of right-most visible column if there is any Stretch column. Implemented in TableUpdateLayout().
|
||||
|
||||
// If we have all Fixed columns OR resizing a Fixed column that doesn't come after a Stretch one, we can do an offsetting resize.
|
||||
// This is the preferred resize path
|
||||
if (column_0->Flags & ImGuiTableColumnFlags_WidthFixed)
|
||||
{
|
||||
// [Resize Rule 3] If we are are followed by a fixed column and we have a Stretch column before, we need to ensure
|
||||
// that our left border won't move, which we can do by making sure column_a/column_b resizes cancels each others.
|
||||
if (column_1 && (column_1->Flags & ImGuiTableColumnFlags_WidthFixed))
|
||||
if (table->LeftMostStretchedColumn != -1 && table->Columns[table->LeftMostStretchedColumn].DisplayOrder < column_0->DisplayOrder)
|
||||
{
|
||||
// (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b)
|
||||
float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width);
|
||||
column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width;
|
||||
column_1->WidthRequest = column_1_width;
|
||||
}
|
||||
|
||||
// Apply
|
||||
//IMGUI_DEBUG_LOG("TableSetColumnWidth(%d, %.1f->%.1f)\n", column_0_idx, column_0->WidthRequested, column_0_width);
|
||||
column_0->WidthRequest = column_0_width;
|
||||
}
|
||||
else if (column_0->Flags & ImGuiTableColumnFlags_WidthStretch)
|
||||
{
|
||||
// We can also use previous column if there's no next one (this is used when doing an auto-fit on the right-most stretch column)
|
||||
if (column_1 == NULL)
|
||||
column_1 = (column_0->PrevEnabledColumn != -1) ? &table->Columns[column_0->PrevEnabledColumn] : NULL;
|
||||
if (column_1 == NULL)
|
||||
return;
|
||||
|
||||
if (column_1->Flags & ImGuiTableColumnFlags_WidthFixed)
|
||||
if (!column_1 || table->LeftMostStretchedColumn == -1 || table->Columns[table->LeftMostStretchedColumn].DisplayOrder >= column_0->DisplayOrder)
|
||||
{
|
||||
// [Resize Rule 2]
|
||||
float off = (column_0->WidthGiven - column_0_width);
|
||||
float column_1_width = column_1->WidthGiven + off;
|
||||
column_1->WidthRequest = ImMax(min_width, column_1_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
// At this point column_1 is the next OR previous column and we know it is a stretch column.
|
||||
// (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b)
|
||||
float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width);
|
||||
column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width;
|
||||
column_1->WidthRequest = column_1_width;
|
||||
column_0->WidthRequest = column_0_width;
|
||||
TableUpdateColumnsWeightFromWidth(table);
|
||||
table->IsSettingsDirty = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We can also use previous column if there's no next one (this is used when doing an auto-fit on the right-most stretch column)
|
||||
if (column_1 == NULL)
|
||||
column_1 = (column_0->PrevEnabledColumn != -1) ? &table->Columns[column_0->PrevEnabledColumn] : NULL;
|
||||
if (column_1 == NULL)
|
||||
return;
|
||||
|
||||
// Resizing from right-side of a Stretch column before a Fixed column forward sizing to left-side of fixed column.
|
||||
// (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b)
|
||||
float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width);
|
||||
column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width;
|
||||
column_0->WidthRequest = column_0_width;
|
||||
column_1->WidthRequest = column_1_width;
|
||||
if ((column_0->Flags | column_1->Flags) & ImGuiTableColumnFlags_WidthStretch)
|
||||
TableUpdateColumnsWeightFromWidth(table);
|
||||
table->IsSettingsDirty = true;
|
||||
}
|
||||
|
||||
// Disable clipping then auto-fit, will take 2 frames
|
||||
@ -2715,7 +2694,7 @@ void ImGui::TableHeader(const char* label)
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowItemOverlap);
|
||||
if (g.ActiveId != id)
|
||||
SetItemAllowOverlap();
|
||||
if (hovered || selected)
|
||||
if (held || hovered || selected)
|
||||
{
|
||||
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