mirror of
https://github.com/ocornut/imgui.git
synced 2025-04-14 17:13:46 +00:00
Merge branch 'master' into docking
Some checks failed
Some checks failed
This commit is contained in:
commit
f4d9359095
6 changed files with 101 additions and 35 deletions
|
@ -55,8 +55,8 @@ Other changes:
|
|||
- Windows: loosened code to allow hovering of resize grips, borders, and table
|
||||
borders while hovering a sibling child window, so that the code in master matches
|
||||
one in docking (they accidentally diverged). (#8554)
|
||||
- TreeNode: added flags to draw tree hierarchy outlines linking parent
|
||||
and tree nodes: (#2920)
|
||||
- TreeNode: added experimental flags to draw tree hierarchy outlines linking
|
||||
parent and tree nodes: (#2920)
|
||||
- ImGuiTreeNodeFlags_DrawLinesNone: No lines drawn (default value in style.TreeLinesFlags).
|
||||
- ImGuiTreeNodeFlags_DrawLinesFull: Horizontal lines to child nodes. Vertical line drawn down to TreePop() position: cover full contents.
|
||||
- ImGuiTreeNodeFlags_DrawLinesToNodes: Horizontal lines to child nodes. Vertical line drawn down to bottom-most child node.
|
||||
|
@ -69,6 +69,12 @@ Other changes:
|
|||
nodes in unusual ways, using indent to create tree-looking structures, etc.)
|
||||
and the feature may not accurately represent them in every cases.
|
||||
- The feature adds a little cost as extra data needs to be stored.
|
||||
(ImGuiTreeNodeFlags_DrawLinesToNodes is slower than ImGuiTreeNodeFlags_DrawLinesFull
|
||||
which may be meaningful on very large trees, as it needs to record bottom-most
|
||||
Y position even for clipped nodes).
|
||||
- The feature is unlikely to ever work properly when using a coarse clipper
|
||||
such as ImGuiListClipper.
|
||||
- TreeNode: fixed incorrect clipping of arrow/bullet when using ImGuiTreeNodeFlags_SpanAllColumns.
|
||||
- Nav: fixed assertion when holding gamepad FaceLeft/West button to open
|
||||
CTRL+Tab windowing + pressing a keyboard key. (#8525)
|
||||
- Error Handling: added better error report and recovery for extraneous
|
||||
|
|
|
@ -8155,7 +8155,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||
window->DC.MenuBarAppending = false;
|
||||
window->DC.MenuColumns.Update(style.ItemSpacing.x, window_just_activated_by_user);
|
||||
window->DC.TreeDepth = 0;
|
||||
window->DC.TreeHasStackDataDepthMask = 0x00;
|
||||
window->DC.TreeHasStackDataDepthMask = window->DC.TreeRecordsClippedNodesY2Mask = 0x00;
|
||||
window->DC.ChildWindows.resize(0);
|
||||
window->DC.StateStorage = &window->StateStorage;
|
||||
window->DC.CurrentColumns = NULL;
|
||||
|
|
4
imgui.h
4
imgui.h
|
@ -1256,8 +1256,8 @@ enum ImGuiTreeNodeFlags_
|
|||
// [EXPERIMENTAL] Draw lines connecting TreeNode hierarchy. Discuss in GitHub issue #2920.
|
||||
// Default value is pulled from style.TreeLinesFlags. May be overridden in TreeNode calls.
|
||||
ImGuiTreeNodeFlags_DrawLinesNone = 1 << 18, // No lines drawn
|
||||
ImGuiTreeNodeFlags_DrawLinesFull = 1 << 19, // Horizontal lines to child nodes. Vertical line drawn down to TreePop() position: cover full contents.
|
||||
ImGuiTreeNodeFlags_DrawLinesToNodes = 1 << 20, // Horizontal lines to child nodes. Vertical line drawn down to bottom-most child node. A little bit slower.
|
||||
ImGuiTreeNodeFlags_DrawLinesFull = 1 << 19, // Horizontal lines to child nodes. Vertical line drawn down to TreePop() position: cover full contents. Faster (for large trees).
|
||||
ImGuiTreeNodeFlags_DrawLinesToNodes = 1 << 20, // Horizontal lines to child nodes. Vertical line drawn down to bottom-most child node. Slower (for large trees).
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
|
||||
|
|
|
@ -212,6 +212,10 @@ typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // F
|
|||
typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest()
|
||||
typedef int ImGuiWindowRefreshFlags; // -> enum ImGuiWindowRefreshFlags_ // Flags: for SetNextWindowRefreshPolicy()
|
||||
|
||||
// Table column indexing
|
||||
typedef ImS16 ImGuiTableColumnIdx;
|
||||
typedef ImU16 ImGuiTableDrawChannelIdx;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Context pointer
|
||||
// See implementation of this variable in imgui.cpp for comments and details.
|
||||
|
@ -1314,7 +1318,8 @@ struct ImGuiTreeNodeStackData
|
|||
ImGuiItemFlags ItemFlags; // Used for nav landing
|
||||
ImRect NavRect; // Used for nav landing
|
||||
float DrawLinesX1;
|
||||
float DrawLinesY2;
|
||||
float DrawLinesToNodesY2;
|
||||
ImGuiTableColumnIdx DrawLinesTableColumn;
|
||||
};
|
||||
|
||||
// sizeof() = 20
|
||||
|
@ -2681,7 +2686,8 @@ struct IMGUI_API ImGuiWindowTempData
|
|||
ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs.
|
||||
ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement
|
||||
int TreeDepth; // Current tree depth.
|
||||
ImU32 TreeHasStackDataDepthMask; // Store whether given depth has ImGuiTreeNodeStackData data. Could be turned into a ImU64 if necessary.
|
||||
ImU32 TreeHasStackDataDepthMask; // Store whether given depth has ImGuiTreeNodeStackData data. Could be turned into a ImU64 if necessary.
|
||||
ImU32 TreeRecordsClippedNodesY2Mask; // Store whether we should keep recording Y2. Cleared when passing clip max. Equivalent TreeHasStackDataDepthMask value should always be set.
|
||||
ImVector<ImGuiWindow*> ChildWindows;
|
||||
ImGuiStorage* StateStorage; // Current persistent per-window storage (store e.g. tree node open/close state)
|
||||
ImGuiOldColumns* CurrentColumns; // Current columns set
|
||||
|
@ -2942,11 +2948,7 @@ struct IMGUI_API ImGuiTabBar
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
|
||||
#define IMGUI_TABLE_MAX_COLUMNS 512 // May be further lifted
|
||||
|
||||
// Our current column maximum is 64 but we may raise that in the future.
|
||||
typedef ImS16 ImGuiTableColumnIdx;
|
||||
typedef ImU16 ImGuiTableDrawChannelIdx;
|
||||
#define IMGUI_TABLE_MAX_COLUMNS 512 // Arbitrary "safety" maximum, may be lifted in the future if needed. Must fit in ImGuiTableColumnIdx/ImGuiTableDrawChannelIdx.
|
||||
|
||||
// [Internal] sizeof() ~ 112
|
||||
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
|
||||
|
@ -3641,6 +3643,8 @@ namespace ImGui
|
|||
IMGUI_API float TableGetHeaderAngledMaxLabelWidth();
|
||||
IMGUI_API void TablePushBackgroundChannel();
|
||||
IMGUI_API void TablePopBackgroundChannel();
|
||||
IMGUI_API void TablePushColumnChannel(int column_n);
|
||||
IMGUI_API void TablePopColumnChannel();
|
||||
IMGUI_API void TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label_width, const ImGuiTableHeaderData* data, int data_count);
|
||||
|
||||
// Tables: Internals
|
||||
|
@ -3769,6 +3773,7 @@ namespace ImGui
|
|||
// Widgets: Tree Nodes
|
||||
IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
|
||||
IMGUI_API void TreeNodeDrawLineToChildNode(const ImVec2& target_pos);
|
||||
IMGUI_API void TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data);
|
||||
IMGUI_API void TreePushOverrideID(ImGuiID id);
|
||||
IMGUI_API bool TreeNodeGetOpen(ImGuiID storage_id);
|
||||
IMGUI_API void TreeNodeSetOpen(ImGuiID storage_id, bool open);
|
||||
|
|
|
@ -2193,6 +2193,7 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
|
|||
g.LastItemData.StatusFlags = 0;
|
||||
}
|
||||
|
||||
// Also see TablePushColumnChannel()
|
||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||
{
|
||||
// FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
|
||||
|
@ -2466,10 +2467,38 @@ void ImGui::TablePopBackgroundChannel()
|
|||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||
SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect);
|
||||
table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[table->CurrentColumn].DrawChannelCurrent);
|
||||
}
|
||||
|
||||
// Also see TableBeginCell()
|
||||
void ImGui::TablePushColumnChannel(int column_n)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
|
||||
// Optimization: avoid SetCurrentChannel() + PushClipRect()
|
||||
if (table->Flags & ImGuiTableFlags_NoClip)
|
||||
return;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
const ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
|
||||
}
|
||||
|
||||
void ImGui::TablePopColumnChannel()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||
if ((table->Flags & ImGuiTableFlags_NoClip) || (table->CurrentColumn == -1)) // Calling TreePop() after TableNextRow() is supported.
|
||||
return;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
const ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
|
||||
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
|
||||
}
|
||||
|
||||
|
|
|
@ -6569,9 +6569,13 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1)
|
|||
tree_node_data->NavRect = g.LastItemData.NavRect;
|
||||
|
||||
// Initially I tried to latch value for GetColorU32(ImGuiCol_TreeLines) but it's not a good trade-off for very large trees.
|
||||
tree_node_data->DrawLinesX1 = (flags & (ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DrawLinesToNodes)) ? (x1 + g.FontSize * 0.5f + g.Style.FramePadding.x) : +FLT_MAX;
|
||||
tree_node_data->DrawLinesY2 = -FLT_MAX;
|
||||
const bool draw_lines = (flags & (ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DrawLinesToNodes)) != 0;
|
||||
tree_node_data->DrawLinesX1 = draw_lines ? (x1 + g.FontSize * 0.5f + g.Style.FramePadding.x) : +FLT_MAX;
|
||||
tree_node_data->DrawLinesTableColumn = (draw_lines && g.CurrentTable) ? (ImGuiTableColumnIdx)g.CurrentTable->CurrentColumn : -1;
|
||||
tree_node_data->DrawLinesToNodesY2 = -FLT_MAX;
|
||||
window->DC.TreeHasStackDataDepthMask |= (1 << window->DC.TreeDepth);
|
||||
if (flags & ImGuiTreeNodeFlags_DrawLinesToNodes)
|
||||
window->DC.TreeRecordsClippedNodesY2Mask |= (1 << window->DC.TreeDepth);
|
||||
}
|
||||
|
||||
// When using public API, currently 'id == storage_id' is always true, but we separate the values to facilitate advanced user code doing storage queries outside of UI loop.
|
||||
|
@ -6661,10 +6665,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||
const bool is_leaf = (flags & ImGuiTreeNodeFlags_Leaf) != 0;
|
||||
if (!is_visible)
|
||||
{
|
||||
if (draw_tree_lines && (flags & ImGuiTreeNodeFlags_DrawLinesToNodes) && (window->DC.TreeHasStackDataDepthMask & (1 << window->DC.TreeDepth)))
|
||||
if ((flags & ImGuiTreeNodeFlags_DrawLinesToNodes) && (window->DC.TreeRecordsClippedNodesY2Mask & (1 << (window->DC.TreeDepth - 1))))
|
||||
{
|
||||
ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
|
||||
parent_data->DrawLinesY2 = ImMax(parent_data->DrawLinesY2, window->DC.CursorPos.y); // Don't need to aim to mid Y position as we are clipped anyway.
|
||||
parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, window->DC.CursorPos.y); // Don't need to aim to mid Y position as we are clipped anyway.
|
||||
if (frame_bb.Min.y >= window->ClipRect.Max.y)
|
||||
window->DC.TreeRecordsClippedNodesY2Mask &= ~(1 << (window->DC.TreeDepth - 1)); // Done
|
||||
}
|
||||
if (is_open && store_tree_node_stack_data)
|
||||
TreeNodeStoreStackData(flags, text_pos.x - text_offset_x); // Call before TreePushOverrideID()
|
||||
|
@ -6801,6 +6807,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||
const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, true, style.FrameRounding);
|
||||
RenderNavCursor(frame_bb, id, nav_render_cursor_flags);
|
||||
if (span_all_columns && !span_all_columns_label)
|
||||
TablePopBackgroundChannel();
|
||||
if (flags & ImGuiTreeNodeFlags_Bullet)
|
||||
RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col);
|
||||
else if (!is_leaf)
|
||||
|
@ -6821,6 +6829,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||
RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, false);
|
||||
}
|
||||
RenderNavCursor(frame_bb, id, nav_render_cursor_flags);
|
||||
if (span_all_columns && !span_all_columns_label)
|
||||
TablePopBackgroundChannel();
|
||||
if (flags & ImGuiTreeNodeFlags_Bullet)
|
||||
RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col);
|
||||
else if (!is_leaf)
|
||||
|
@ -6832,9 +6842,6 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
|||
if (draw_tree_lines)
|
||||
TreeNodeDrawLineToChildNode(ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.5f));
|
||||
|
||||
if (span_all_columns && !span_all_columns_label)
|
||||
TablePopBackgroundChannel();
|
||||
|
||||
// Label
|
||||
if (display_frame)
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
||||
|
@ -6867,11 +6874,38 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
|
|||
float x1 = ImTrunc(parent_data->DrawLinesX1);
|
||||
float x2 = ImTrunc(target_pos.x - g.Style.ItemInnerSpacing.x);
|
||||
float y = ImTrunc(target_pos.y);
|
||||
parent_data->DrawLinesY2 = ImMax(parent_data->DrawLinesY2, y);
|
||||
parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, y);
|
||||
if (x1 < x2)
|
||||
window->DrawList->AddLine(ImVec2(x1, y), ImVec2(x2, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
|
||||
}
|
||||
|
||||
// Draw vertical line of the hierarchy
|
||||
void ImGui::TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float y1 = ImMax(data->NavRect.Max.y, window->ClipRect.Min.y);
|
||||
float y2 = data->DrawLinesToNodesY2;
|
||||
if (data->TreeFlags & ImGuiTreeNodeFlags_DrawLinesFull)
|
||||
{
|
||||
float y2_full = window->DC.CursorPos.y;
|
||||
if (g.CurrentTable)
|
||||
y2_full = ImMax(g.CurrentTable->RowPosY2, y2_full);
|
||||
y2_full = ImTrunc(y2_full - g.Style.ItemSpacing.y - g.FontSize * 0.5f);
|
||||
if (y2 + g.Style.ItemSpacing.y < y2_full) // FIXME: threshold to use ToNodes Y2 instead of Full Y2 when close by ItemSpacing.y
|
||||
y2 = y2_full;
|
||||
}
|
||||
y2 = ImMin(y2, window->ClipRect.Max.y);
|
||||
if (y2 <= y1)
|
||||
return;
|
||||
float x = ImTrunc(data->DrawLinesX1);
|
||||
if (data->DrawLinesTableColumn != -1)
|
||||
TablePushColumnChannel(data->DrawLinesTableColumn);
|
||||
window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
|
||||
if (data->DrawLinesTableColumn != -1)
|
||||
TablePopColumnChannel();
|
||||
}
|
||||
|
||||
void ImGui::TreePush(const char* str_id)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
@ -6910,24 +6944,16 @@ void ImGui::TreePop()
|
|||
{
|
||||
const ImGuiTreeNodeStackData* data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
|
||||
IM_ASSERT(data->ID == window->IDStack.back());
|
||||
|
||||
// Handle Left arrow to move to parent tree node (when ImGuiTreeNodeFlags_NavLeftJumpsBackHere is enabled)
|
||||
if (data->TreeFlags & ImGuiTreeNodeFlags_NavLeftJumpsBackHere)
|
||||
{
|
||||
// Handle Left arrow to move to parent tree node (when ImGuiTreeNodeFlags_NavLeftJumpsBackHere is enabled)
|
||||
if (g.NavIdIsAlive && g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet())
|
||||
NavMoveRequestResolveWithPastTreeNode(&g.NavMoveResultLocal, data);
|
||||
}
|
||||
|
||||
// Draw hierarchy lines
|
||||
if (data->DrawLinesX1 != +FLT_MAX && window->DC.CursorPos.y >= window->ClipRect.Min.y)
|
||||
{
|
||||
// Draw vertical line of the hierarchy
|
||||
float y1 = ImMax(data->NavRect.Max.y, window->ClipRect.Min.y);
|
||||
float y2 = (data->TreeFlags & ImGuiTreeNodeFlags_DrawLinesToNodes) ? data->DrawLinesY2 : ImTrunc(window->DC.CursorPos.y - g.Style.ItemSpacing.y - g.FontSize * 0.5f);
|
||||
y2 = ImMin(y2, window->ClipRect.Max.y);
|
||||
if (y1 < y2)
|
||||
{
|
||||
float x = ImTrunc(data->DrawLinesX1);
|
||||
window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
|
||||
}
|
||||
}
|
||||
TreeNodeDrawLineToTreePop(data);
|
||||
|
||||
g.TreeNodeStack.pop_back();
|
||||
window->DC.TreeHasStackDataDepthMask &= ~tree_depth_mask;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue