mirror of
https://github.com/ocornut/imgui.git
synced 2025-01-31 03:53:44 +01:00
Tables, Nav, Scrolling: fixed scrolling functions and focus tracking with frozen rows and columns. (#5143, #4868, #3692)
This commit is contained in:
parent
16cee3d009
commit
fd0b3734d3
@ -42,7 +42,10 @@ Other changes:
|
|||||||
- Fixed cases where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with
|
- Fixed cases where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with
|
||||||
zero triangles, which would makes the render loop of some backends assert (e.g. Metal with
|
zero triangles, which would makes the render loop of some backends assert (e.g. Metal with
|
||||||
debugging, Allegro). (#4857, #5937)
|
debugging, Allegro). (#4857, #5937)
|
||||||
- Tables, Columns: Fixed cases where empty columns may lead to empty ImDrawCmd. (#4857, #5937)
|
- Tables, Nav, Scrolling: fixed scrolling functions and focus tracking with frozen rows and
|
||||||
|
frozen columns. Windows now have a better understanding of outer/inner decoration sizes,
|
||||||
|
which should later lead us toward more flexible uses of menu/status bars. (#5143, #4868, #3692)
|
||||||
|
- Tables, Columns: fixed cases where empty columns may lead to empty ImDrawCmd. (#4857, #5937)
|
||||||
- Inputs, IO: reworked ImGuiMod_Shortcut to redirect to Ctrl/Super at runtime instead of
|
- Inputs, IO: reworked ImGuiMod_Shortcut to redirect to Ctrl/Super at runtime instead of
|
||||||
compile-time, being consistent with our support for io.ConfigMacOSXBehaviors and making it
|
compile-time, being consistent with our support for io.ConfigMacOSXBehaviors and making it
|
||||||
easier for bindings generators to process that value. (#5923, #456)
|
easier for bindings generators to process that value. (#5923, #456)
|
||||||
|
13
imgui.cpp
13
imgui.cpp
@ -6467,6 +6467,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
// Apply scrolling
|
// Apply scrolling
|
||||||
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||||
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
|
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
|
||||||
|
window->DecoInnerSizeX1 = window->DecoInnerSizeY1 = 0.0f;
|
||||||
|
|
||||||
// DRAWING
|
// DRAWING
|
||||||
|
|
||||||
@ -9589,7 +9590,7 @@ static float CalcScrollEdgeSnap(float target, float snap_min, float snap_max, fl
|
|||||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
|
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImVec2 scroll = window->Scroll;
|
ImVec2 scroll = window->Scroll;
|
||||||
ImVec2 decoration_size(window->DecoOuterSizeX1 + window->DecoOuterSizeX2, window->DecoOuterSizeY1 + window->DecoOuterSizeY2);
|
ImVec2 decoration_size(window->DecoOuterSizeX1 + window->DecoInnerSizeX1 + window->DecoOuterSizeX2, window->DecoOuterSizeY1 + window->DecoInnerSizeY1 + window->DecoOuterSizeY2);
|
||||||
for (int axis = 0; axis < 2; axis++)
|
for (int axis = 0; axis < 2; axis++)
|
||||||
{
|
{
|
||||||
if (window->ScrollTarget[axis] < FLT_MAX)
|
if (window->ScrollTarget[axis] < FLT_MAX)
|
||||||
@ -9628,6 +9629,8 @@ ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGui
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImRect scroll_rect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1));
|
ImRect scroll_rect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1));
|
||||||
|
scroll_rect.Min.x = ImMin(scroll_rect.Min.x + window->DecoInnerSizeX1, scroll_rect.Max.x);
|
||||||
|
scroll_rect.Min.y = ImMin(scroll_rect.Min.y + window->DecoInnerSizeY1, scroll_rect.Max.y);
|
||||||
//GetForegroundDrawList(window)->AddRect(item_rect.Min, item_rect.Max, IM_COL32(255,0,0,255), 0.0f, 0, 5.0f); // [DEBUG]
|
//GetForegroundDrawList(window)->AddRect(item_rect.Min, item_rect.Max, IM_COL32(255,0,0,255), 0.0f, 0, 5.0f); // [DEBUG]
|
||||||
//GetForegroundDrawList(window)->AddRect(scroll_rect.Min, scroll_rect.Max, IM_COL32_WHITE); // [DEBUG]
|
//GetForegroundDrawList(window)->AddRect(scroll_rect.Min, scroll_rect.Max, IM_COL32_WHITE); // [DEBUG]
|
||||||
|
|
||||||
@ -9757,7 +9760,7 @@ void ImGui::SetScrollY(float scroll_y)
|
|||||||
void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio)
|
void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio)
|
||||||
{
|
{
|
||||||
IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
|
IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
|
||||||
window->ScrollTarget.x = IM_FLOOR(local_x - window->DecoOuterSizeX1 + window->Scroll.x); // Convert local position to scroll offset
|
window->ScrollTarget.x = IM_FLOOR(local_x - window->DecoOuterSizeX1 - window->DecoInnerSizeX1 + window->Scroll.x); // Convert local position to scroll offset
|
||||||
window->ScrollTargetCenterRatio.x = center_x_ratio;
|
window->ScrollTargetCenterRatio.x = center_x_ratio;
|
||||||
window->ScrollTargetEdgeSnapDist.x = 0.0f;
|
window->ScrollTargetEdgeSnapDist.x = 0.0f;
|
||||||
}
|
}
|
||||||
@ -9765,7 +9768,7 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x
|
|||||||
void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
|
void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
|
||||||
{
|
{
|
||||||
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
|
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
|
||||||
window->ScrollTarget.y = IM_FLOOR(local_y - window->DecoOuterSizeY1 + window->Scroll.y); // Convert local position to scroll offset
|
window->ScrollTarget.y = IM_FLOOR(local_y - window->DecoOuterSizeY1 - window->DecoInnerSizeY1 + window->Scroll.y); // Convert local position to scroll offset
|
||||||
window->ScrollTargetCenterRatio.y = center_y_ratio;
|
window->ScrollTargetCenterRatio.y = center_y_ratio;
|
||||||
window->ScrollTargetEdgeSnapDist.y = 0.0f;
|
window->ScrollTargetEdgeSnapDist.y = 0.0f;
|
||||||
}
|
}
|
||||||
@ -13215,8 +13218,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|||||||
else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; }
|
else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; }
|
||||||
else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); } // Note: y1/y2 not always accurate
|
else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); } // Note: y1/y2 not always accurate
|
||||||
else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); }
|
else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); }
|
||||||
else if (rect_type == TRT_ColumnsContentFrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXFrozen, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); }
|
else if (rect_type == TRT_ColumnsContentFrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXFrozen, table->InnerClipRect.Min.y + table_instance->LastFrozenHeight); }
|
||||||
else if (rect_type == TRT_ColumnsContentUnfrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); }
|
else if (rect_type == TRT_ColumnsContentUnfrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y + table_instance->LastFrozenHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); }
|
||||||
IM_ASSERT(0);
|
IM_ASSERT(0);
|
||||||
return ImRect();
|
return ImRect();
|
||||||
}
|
}
|
||||||
|
2
imgui.h
2
imgui.h
@ -23,7 +23,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
|
||||||
#define IMGUI_VERSION "1.89.2 WIP"
|
#define IMGUI_VERSION "1.89.2 WIP"
|
||||||
#define IMGUI_VERSION_NUM 18914
|
#define IMGUI_VERSION_NUM 18915
|
||||||
#define IMGUI_HAS_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2250,6 +2250,7 @@ struct IMGUI_API ImGuiWindow
|
|||||||
float WindowBorderSize; // Window border size at the time of Begin().
|
float WindowBorderSize; // Window border size at the time of Begin().
|
||||||
float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin().
|
float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin().
|
||||||
float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y).
|
float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y).
|
||||||
|
float DecoInnerSizeX1, DecoInnerSizeY1; // Applied AFTER/OVER InnerRect. Specialized for Tables as they use specialized form of clipping and frozen rows/columns are inside InnerRect (and not part of regular decoration sizes).
|
||||||
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
|
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
|
||||||
ImGuiID MoveId; // == window->GetID("#MOVE")
|
ImGuiID MoveId; // == window->GetID("#MOVE")
|
||||||
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
|
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
|
||||||
@ -2519,9 +2520,10 @@ struct ImGuiTableCellData
|
|||||||
struct ImGuiTableInstanceData
|
struct ImGuiTableInstanceData
|
||||||
{
|
{
|
||||||
float LastOuterHeight; // Outer height from last frame
|
float LastOuterHeight; // Outer height from last frame
|
||||||
float LastFirstRowHeight; // Height of first row from last frame
|
float LastFirstRowHeight; // Height of first row from last frame (FIXME: this is used as "header height" and may be reworked)
|
||||||
|
float LastFrozenHeight; // Height of frozen section from last frame
|
||||||
|
|
||||||
ImGuiTableInstanceData() { LastOuterHeight = LastFirstRowHeight = 0.0f; }
|
ImGuiTableInstanceData() { LastOuterHeight = LastFirstRowHeight = LastFrozenHeight = 0.0f; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME-TABLE: more transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData
|
// FIXME-TABLE: more transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData
|
||||||
|
@ -1124,6 +1124,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable))
|
if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable))
|
||||||
TableSortSpecsBuild(table);
|
TableSortSpecsBuild(table);
|
||||||
|
|
||||||
|
// [Part 14] Setup inner window decoration size (for scrolling / nav tracking to properly take account of frozen rows/columns)
|
||||||
|
if (table->FreezeColumnsRequest > 0)
|
||||||
|
table->InnerWindow->DecoInnerSizeX1 = table->Columns[table->DisplayOrderToIndex[table->FreezeColumnsRequest - 1]].MaxX - table->OuterRect.Min.x;
|
||||||
|
if (table->FreezeRowsRequest > 0)
|
||||||
|
table->InnerWindow->DecoInnerSizeY1 = table_instance->LastFrozenHeight;
|
||||||
|
table_instance->LastFrozenHeight = 0.0f;
|
||||||
|
|
||||||
// Initial state
|
// Initial state
|
||||||
ImGuiWindow* inner_window = table->InnerWindow;
|
ImGuiWindow* inner_window = table->InnerWindow;
|
||||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||||
@ -1846,10 +1853,11 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
|||||||
if (unfreeze_rows_actual)
|
if (unfreeze_rows_actual)
|
||||||
{
|
{
|
||||||
IM_ASSERT(table->IsUnfrozenRows == false);
|
IM_ASSERT(table->IsUnfrozenRows == false);
|
||||||
|
const float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
|
||||||
table->IsUnfrozenRows = true;
|
table->IsUnfrozenRows = true;
|
||||||
|
TableGetInstanceData(table, table->InstanceCurrent)->LastFrozenHeight = y0 - table->OuterRect.Min.y;
|
||||||
|
|
||||||
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
|
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
|
||||||
float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
|
|
||||||
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
|
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
|
||||||
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
|
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
|
||||||
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
|
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user