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.
| 6570 | |
| 6571 | // 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. |
| 6572 | bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) |
| 6573 | { |
| 6574 | ImGuiWindow* window = GetCurrentWindow(); |
| 6575 | if (window->SkipItems) |
| 6576 | return false; |
| 6577 | |
| 6578 | ImGuiContext& g = *GImGui; |
| 6579 | const ImGuiStyle& style = g.Style; |
| 6580 | const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; |
| 6581 | const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y)); |
| 6582 | |
| 6583 | if (!label_end) |
| 6584 | label_end = FindRenderedTextEnd(label); |
| 6585 | const ImVec2 label_size = CalcTextSize(label, label_end, false); |
| 6586 | |
| 6587 | const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing |
| 6588 | const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it |
| 6589 | const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow |
| 6590 | |
| 6591 | // We vertically grow up to current line height up the typical widget height. |
| 6592 | const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2); |
| 6593 | const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL); |
| 6594 | const bool span_all_columns_label = (flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) != 0 && (g.CurrentTable != NULL); |
| 6595 | ImRect frame_bb; |
| 6596 | frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x; |
| 6597 | frame_bb.Min.y = window->DC.CursorPos.y; |
| 6598 | frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanLabelWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x; |
| 6599 | frame_bb.Max.y = window->DC.CursorPos.y + frame_height; |
| 6600 | if (display_frame) |
| 6601 | { |
| 6602 | const float outer_extend = IM_TRUNC(window->WindowPadding.x * 0.5f); // Framed header expand a little outside of current limits |
| 6603 | frame_bb.Min.x -= outer_extend; |
| 6604 | frame_bb.Max.x += outer_extend; |
| 6605 | } |
| 6606 | |
| 6607 | ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y); |
| 6608 | ItemSize(ImVec2(text_width, frame_height), padding.y); |
| 6609 | |
| 6610 | // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing |
| 6611 | ImRect interact_bb = frame_bb; |
| 6612 | if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanLabelWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0) |
| 6613 | interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f); |
| 6614 | |
| 6615 | // Compute open and multi-select states before ItemAdd() as it clear NextItem data. |
| 6616 | ImGuiID storage_id = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasStorageID) ? g.NextItemData.StorageId : id; |
| 6617 | bool is_open = TreeNodeUpdateNextOpen(storage_id, flags); |
| 6618 | |
| 6619 | bool is_visible; |
| 6620 | if (span_all_columns || span_all_columns_label) |
| 6621 | { |
| 6622 | // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. |
| 6623 | const float backup_clip_rect_min_x = window->ClipRect.Min.x; |
| 6624 | const float backup_clip_rect_max_x = window->ClipRect.Max.x; |
| 6625 | window->ClipRect.Min.x = window->ParentWorkRect.Min.x; |
| 6626 | window->ClipRect.Max.x = window->ParentWorkRect.Max.x; |
| 6627 | is_visible = ItemAdd(interact_bb, id); |
| 6628 | window->ClipRect.Min.x = backup_clip_rect_min_x; |
| 6629 | window->ClipRect.Max.x = backup_clip_rect_max_x; |
nothing calls this directly
no test coverage detected