mirror of
https://github.com/ocornut/imgui.git
synced 2025-12-28 00:54:34 +00:00
TreeNode: rename/rework ImGuiNavTreeNodeData system to be usable by more features. (#2920, #1131, #7553)
Reworked to it is easier during TreeNode code to request extra data to be stored.
This commit is contained in:
@@ -6310,6 +6310,21 @@ bool ImGui::TreeNodeUpdateNextOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
|
||||
return is_open;
|
||||
}
|
||||
|
||||
// Store ImGuiTreeNodeStackData for just submitted node.
|
||||
static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
g.TreeNodeStack.resize(g.TreeNodeStack.Size + 1);
|
||||
ImGuiTreeNodeStackData* tree_node_data = &g.TreeNodeStack.back();
|
||||
tree_node_data->ID = g.LastItemData.ID;
|
||||
tree_node_data->TreeFlags = flags;
|
||||
tree_node_data->InFlags = g.LastItemData.InFlags;
|
||||
tree_node_data->NavRect = g.LastItemData.NavRect;
|
||||
window->DC.TreeHasStackDataDepthMask |= (1 << window->DC.TreeDepth);
|
||||
}
|
||||
|
||||
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@@ -6379,20 +6394,19 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
// For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop().
|
||||
// It will become tempting to enable ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default or move it to ImGuiStyle.
|
||||
// Currently only supports 32 level deep and we are fine with (1 << Depth) overflowing into a zero, easy to increase.
|
||||
if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavLeftJumpsBackHere) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet())
|
||||
{
|
||||
g.NavTreeNodeStack.resize(g.NavTreeNodeStack.Size + 1);
|
||||
ImGuiNavTreeNodeData* nav_tree_node_data = &g.NavTreeNodeStack.back();
|
||||
nav_tree_node_data->ID = id;
|
||||
nav_tree_node_data->InFlags = g.LastItemData.InFlags;
|
||||
nav_tree_node_data->NavRect = g.LastItemData.NavRect;
|
||||
window->DC.TreeJumpToParentOnPopMask |= (1 << window->DC.TreeDepth);
|
||||
}
|
||||
bool store_tree_node_stack_data = false;
|
||||
if (!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
{
|
||||
if ((flags & ImGuiTreeNodeFlags_NavLeftJumpsBackHere) && is_open && !g.NavIdIsAlive)
|
||||
if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet())
|
||||
store_tree_node_stack_data = true;
|
||||
}
|
||||
|
||||
const bool is_leaf = (flags & ImGuiTreeNodeFlags_Leaf) != 0;
|
||||
if (!item_add)
|
||||
{
|
||||
if (store_tree_node_stack_data && is_open)
|
||||
TreeNodeStoreStackData(flags); // Call before TreePushOverrideID()
|
||||
if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
TreePushOverrideID(id);
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
@@ -6533,8 +6547,11 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
else
|
||||
RenderText(text_pos, label, label_end, false);
|
||||
|
||||
if (store_tree_node_stack_data && is_open)
|
||||
TreeNodeStoreStackData(flags); // Call before TreePushOverrideID()
|
||||
if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
TreePushOverrideID(id);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | (is_leaf ? 0 : ImGuiItemStatusFlags_Openable) | (is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
return is_open;
|
||||
}
|
||||
@@ -6573,16 +6590,19 @@ void ImGui::TreePop()
|
||||
window->DC.TreeDepth--;
|
||||
ImU32 tree_depth_mask = (1 << window->DC.TreeDepth);
|
||||
|
||||
// Handle Left arrow to move to parent tree node (when ImGuiTreeNodeFlags_NavLeftJumpsBackHere is enabled)
|
||||
if (window->DC.TreeJumpToParentOnPopMask & tree_depth_mask) // Only set during request
|
||||
if (window->DC.TreeHasStackDataDepthMask & tree_depth_mask) // Only set during request
|
||||
{
|
||||
ImGuiNavTreeNodeData* nav_tree_node_data = &g.NavTreeNodeStack.back();
|
||||
IM_ASSERT(nav_tree_node_data->ID == window->IDStack.back());
|
||||
if (g.NavIdIsAlive && g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet())
|
||||
NavMoveRequestResolveWithPastTreeNode(&g.NavMoveResultLocal, nav_tree_node_data);
|
||||
g.NavTreeNodeStack.pop_back();
|
||||
ImGuiTreeNodeStackData* data = &g.TreeNodeStack.back();
|
||||
IM_ASSERT(data->ID == window->IDStack.back());
|
||||
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);
|
||||
}
|
||||
g.TreeNodeStack.pop_back();
|
||||
window->DC.TreeHasStackDataDepthMask &= ~tree_depth_mask;
|
||||
}
|
||||
window->DC.TreeJumpToParentOnPopMask &= tree_depth_mask - 1;
|
||||
|
||||
IM_ASSERT(window->IDStack.Size > 1); // There should always be 1 element in the IDStack (pushed during window creation). If this triggers you called TreePop/PopID too much.
|
||||
PopID();
|
||||
|
||||
Reference in New Issue
Block a user