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
|
||||
zero triangles, which would makes the render loop of some backends assert (e.g. Metal with
|
||||
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
|
||||
compile-time, being consistent with our support for io.ConfigMacOSXBehaviors and making it
|
||||
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
|
||||
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
|
||||
window->DecoInnerSizeX1 = window->DecoInnerSizeY1 = 0.0f;
|
||||
|
||||
// DRAWING
|
||||
|
||||
@ -9589,7 +9590,7 @@ static float CalcScrollEdgeSnap(float target, float snap_min, float snap_max, fl
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
if (window->ScrollTarget[axis] < FLT_MAX)
|
||||
@ -9628,6 +9629,8 @@ ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGui
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
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(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)
|
||||
{
|
||||
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->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)
|
||||
{
|
||||
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->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_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_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_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_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->LastFrozenHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); }
|
||||
IM_ASSERT(0);
|
||||
return ImRect();
|
||||
}
|
||||
|
2
imgui.h
2
imgui.h
@ -23,7 +23,7 @@
|
||||
// Library Version
|
||||
// (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_NUM 18914
|
||||
#define IMGUI_VERSION_NUM 18915
|
||||
#define IMGUI_HAS_TABLE
|
||||
|
||||
/*
|
||||
|
@ -2250,6 +2250,7 @@ struct IMGUI_API ImGuiWindow
|
||||
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 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)!
|
||||
ImGuiID MoveId; // == window->GetID("#MOVE")
|
||||
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
|
||||
{
|
||||
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
|
||||
|
@ -1124,6 +1124,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
||||
if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable))
|
||||
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
|
||||
ImGuiWindow* inner_window = table->InnerWindow;
|
||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||
@ -1846,10 +1853,11 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
if (unfreeze_rows_actual)
|
||||
{
|
||||
IM_ASSERT(table->IsUnfrozenRows == false);
|
||||
const float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
|
||||
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
|
||||
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.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
|
||||
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
|
||||
|
Loading…
Reference in New Issue
Block a user