From f79b2d6ce38e119e72a2a1a04a617f05be7ac802 Mon Sep 17 00:00:00 2001 From: ocornut Date: Sun, 1 May 2016 20:12:14 +0200 Subject: [PATCH] TreeNode: added ImGuiTreeNodeFlags_OpenOnArrow flag (#581, #324, #190) --- imgui.cpp | 21 ++++++++++++++++++--- imgui.h | 11 ++++++----- imgui_demo.cpp | 8 ++++---- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 43f2c63e..b632e398 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5677,12 +5677,27 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l return opened; } - ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowOverlapMode : 0) | ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) ? ImGuiButtonFlags_PressedOnDoubleClick : 0); + // Flags that affects opening behavior: + // - 0(default) ..................... single-click anywhere to open + // - OpenOnDoubleClick .............. double-click anywhere to open + // - OpenOnArrow .................... single-click on arrow to open + // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open + ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowOverlapMode) ? ImGuiButtonFlags_AllowOverlapMode : 0); + if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); if (pressed) { - opened = !opened; - window->DC.StateStorage->SetInt(id, opened); + bool toggled = !(flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)); + if (flags & ImGuiTreeNodeFlags_OpenOnArrow) + toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + collapser_width, interact_bb.Max.y)); + if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + toggled |= g.IO.MouseDoubleClicked[0]; + if (toggled) + { + opened = !opened; + window->DC.StateStorage->SetInt(id, opened); + } } if (flags & ImGuiTreeNodeFlags_AllowOverlapMode) SetItemAllowOverlap(); diff --git a/imgui.h b/imgui.h index ce484f8d..c82e1422 100644 --- a/imgui.h +++ b/imgui.h @@ -528,13 +528,14 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader) ImGuiTreeNodeFlags_AllowOverlapMode = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when opened (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack - ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes). + ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be opened ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node - //ImGuiTreeNodeFlags_OpenOnArrowOnly = 1 << 7, // FIXME: TODO - //ImGuiTreeNodeFlags_UnindentArrow = 1 << 8, // FIXME: TODO - //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 9, // FIXME: TODO: Extend hit box horizontally even if not framed - //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 10, // FIXME: TODO: Automatically scroll on TreePop() if node got just opened and contents is not visible + ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. + //ImGuiTreeNodeFlags_AlwaysOpen = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). + //ImGuiTreeNodeFlags_UnindentArrow = 1 << 9, // FIXME: TODO: Unindent tree so that Label is aligned to current X position + //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 10, // FIXME: TODO: Extend hit box horizontally even if not framed + //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 11, // FIXME: TODO: Automatically scroll on TreePop() if node got just opened and contents is not visible ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog }; diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 3a9df979..acdc0330 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -285,18 +285,18 @@ void ImGui::ShowTestWindow(bool* p_opened) if (ImGui::TreeNode("With selectable nodes")) { - ShowHelpMarker("Click to select, CTRL+Click to toggle, double-click to open"); + ShowHelpMarker("Click to select, CTRL+Click to toggle, click on arrows to open"); static int selection_mask = 0x02; // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit. int node_clicked = -1; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 6; i++) { - ImGuiTreeNodeFlags node_flags = ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnDoubleClick; + ImGuiTreeNodeFlags node_flags = ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick; bool opened = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Child %d", i); if (ImGui::IsItemClicked()) node_clicked = i; if (opened) { - ImGui::Text("blah blah"); + ImGui::Text("Blah blah"); ImGui::TreePop(); } }