| 6119 | } |
| 6120 | |
| 6121 | bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) |
| 6122 | { |
| 6123 | ImGuiWindow* window = GetCurrentWindow(); |
| 6124 | if (window->SkipItems) |
| 6125 | return false; |
| 6126 | |
| 6127 | ImGuiContext& g = *GImGui; |
| 6128 | const ImGuiStyle& style = g.Style; |
| 6129 | const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; |
| 6130 | const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y)); |
| 6131 | |
| 6132 | if (!label_end) |
| 6133 | label_end = FindRenderedTextEnd(label); |
| 6134 | const ImVec2 label_size = CalcTextSize(label, label_end, false); |
| 6135 | |
| 6136 | // We vertically grow up to current line height up the typical widget height. |
| 6137 | const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2); |
| 6138 | ImRect frame_bb; |
| 6139 | frame_bb.Min.x = (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x; |
| 6140 | frame_bb.Min.y = window->DC.CursorPos.y; |
| 6141 | frame_bb.Max.x = window->WorkRect.Max.x; |
| 6142 | frame_bb.Max.y = window->DC.CursorPos.y + frame_height; |
| 6143 | if (display_frame) |
| 6144 | { |
| 6145 | // Framed header expand a little outside the default padding, to the edge of InnerClipRect |
| 6146 | // (FIXME: May remove this at some point and make InnerClipRect align with WindowPadding.x instead of WindowPadding.x*0.5f) |
| 6147 | frame_bb.Min.x -= IM_FLOOR(window->WindowPadding.x * 0.5f - 1.0f); |
| 6148 | frame_bb.Max.x += IM_FLOOR(window->WindowPadding.x * 0.5f); |
| 6149 | } |
| 6150 | |
| 6151 | const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapser arrow width + Spacing |
| 6152 | const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it |
| 6153 | const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x * 2 : 0.0f); // Include collapser |
| 6154 | ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y); |
| 6155 | ItemSize(ImVec2(text_width, frame_height), padding.y); |
| 6156 | |
| 6157 | // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing |
| 6158 | ImRect interact_bb = frame_bb; |
| 6159 | if (!display_frame && (flags & (ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth)) == 0) |
| 6160 | interact_bb.Max.x = frame_bb.Min.x + text_width + style.ItemSpacing.x * 2.0f; |
| 6161 | |
| 6162 | // Compute open and multi-select states before ItemAdd() as it clear NextItem data. |
| 6163 | bool is_open = TreeNodeUpdateNextOpen(id, flags); |
| 6164 | bool item_add = ItemAdd(interact_bb, id); |
| 6165 | g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; |
| 6166 | g.LastItemData.DisplayRect = frame_bb; |
| 6167 | |
| 6168 | // If a NavLeft request is happening and ImGuiTreeNodeFlags_NavLeftJumpsBackHere enabled: |
| 6169 | // Store data for the current depth to allow returning to this node from any child item. |
| 6170 | // For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop(). |
| 6171 | // It will become tempting to enable ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default or move it to ImGuiStyle. |
| 6172 | // Currently only supports 32 level deep and we are fine with (1 << Depth) overflowing into a zero, easy to increase. |
| 6173 | if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavLeftJumpsBackHere) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) |
| 6174 | if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet()) |
| 6175 | { |
| 6176 | g.NavTreeNodeStack.resize(g.NavTreeNodeStack.Size + 1); |
| 6177 | ImGuiNavTreeNodeData* nav_tree_node_data = &g.NavTreeNodeStack.back(); |
| 6178 | nav_tree_node_data->ID = id; |