Explorar el Código

TreeNode: added ImGuiTreeNodeFlags_OpenOnArrow flag (#581, #324, #190)

ocornut hace 9 años
padre
commit
f79b2d6ce3
Se han modificado 3 ficheros con 28 adiciones y 12 borrados
  1. 18 3
      imgui.cpp
  2. 6 5
      imgui.h
  3. 4 4
      imgui_demo.cpp

+ 18 - 3
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();

+ 6 - 5
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
 };
 

+ 4 - 4
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();
                     }
                 }