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