Просмотр исходного кода

Added SetNextItemStorageID() for tree nodes. (#7553, #6990, #3823, #1131)

Undo/amend 7c6d4ff.
ocornut 1 год назад
Родитель
Сommit
df38704926
4 измененных файлов с 25 добавлено и 8 удалено
  1. 3 0
      docs/CHANGELOG.txt
  2. 1 0
      imgui.h
  3. 3 1
      imgui_internal.h
  4. 18 7
      imgui_widgets.cpp

+ 3 - 0
docs/CHANGELOG.txt

@@ -147,6 +147,9 @@ Other changes:
 - Nav: fixed clicking window decorations (e.g. resize borders) from losing focused item when
 - Nav: fixed clicking window decorations (e.g. resize borders) from losing focused item when
   within a child window using ImGuiChildFlags_NavFlattened.
   within a child window using ImGuiChildFlags_NavFlattened.
 - InputText: added '\' and '/' as word seperator. (#7824, #7704) [@reduf]
 - InputText: added '\' and '/' as word seperator. (#7824, #7704) [@reduf]
+- TreeNode: added SetNextItemStorageID() to specify/override the identifier used for persisting
+  open/close storage. Useful if needing to often read/write from storage without manipulating
+  the ID stack. (#7553, #6990, #3823, #1131)
 - Selectable: added ImGuiSelectableFlags_Highlight flag to highlight items independently from
 - Selectable: added ImGuiSelectableFlags_Highlight flag to highlight items independently from
   the hovered state. (#7820) [@rerilier]
   the hovered state. (#7820) [@rerilier]
 - Clipper: added SeekCursorForItem() function. When using ImGuiListClipper::Begin(INT_MAX) you can
 - Clipper: added SeekCursorForItem() function. When using ImGuiListClipper::Begin(INT_MAX) you can

+ 1 - 0
imgui.h

@@ -661,6 +661,7 @@ namespace ImGui
     IMGUI_API bool          CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0);  // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().
     IMGUI_API bool          CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0);  // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().
     IMGUI_API bool          CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header.
     IMGUI_API bool          CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header.
     IMGUI_API void          SetNextItemOpen(bool is_open, ImGuiCond cond = 0);                  // set next TreeNode/CollapsingHeader open state.
     IMGUI_API void          SetNextItemOpen(bool is_open, ImGuiCond cond = 0);                  // set next TreeNode/CollapsingHeader open state.
+    IMGUI_API void          SetNextItemStorageID(ImGuiID storage_id);                           // set id to use for open/close storage (default to same as item id).
 
 
     // Widgets: Selectables
     // Widgets: Selectables
     // - A selectable highlights when hovered, and can display another color when selected.
     // - A selectable highlights when hovered, and can display another color when selected.

+ 3 - 1
imgui_internal.h

@@ -1215,6 +1215,7 @@ enum ImGuiNextItemDataFlags_
     ImGuiNextItemDataFlags_HasOpen      = 1 << 1,
     ImGuiNextItemDataFlags_HasOpen      = 1 << 1,
     ImGuiNextItemDataFlags_HasShortcut  = 1 << 2,
     ImGuiNextItemDataFlags_HasShortcut  = 1 << 2,
     ImGuiNextItemDataFlags_HasRefVal    = 1 << 3,
     ImGuiNextItemDataFlags_HasRefVal    = 1 << 3,
+    ImGuiNextItemDataFlags_HasStorageID = 1 << 4,
 };
 };
 
 
 struct ImGuiNextItemData
 struct ImGuiNextItemData
@@ -1230,6 +1231,7 @@ struct ImGuiNextItemData
     bool                        OpenVal;            // Set by SetNextItemOpen()
     bool                        OpenVal;            // Set by SetNextItemOpen()
     ImU8                        OpenCond;           // Set by SetNextItemOpen()
     ImU8                        OpenCond;           // Set by SetNextItemOpen()
     ImGuiDataTypeStorage        RefVal;             // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal
     ImGuiDataTypeStorage        RefVal;             // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal
+    ImGuiID                     StorageId;          // Set by SetNextItemStorageID()
 
 
     ImGuiNextItemData()         { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
     ImGuiNextItemData()         { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
     inline void ClearFlags()    { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
     inline void ClearFlags()    { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
@@ -3546,7 +3548,7 @@ namespace ImGui
     IMGUI_API bool          SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f, ImU32 bg_col = 0);
     IMGUI_API bool          SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f, ImU32 bg_col = 0);
 
 
     // Widgets: Tree Nodes
     // Widgets: Tree Nodes
-    IMGUI_API bool          TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
+    IMGUI_API bool          TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
     IMGUI_API void          TreePushOverrideID(ImGuiID id);
     IMGUI_API void          TreePushOverrideID(ImGuiID id);
     IMGUI_API bool          TreeNodeGetOpen(ImGuiID storage_id);
     IMGUI_API bool          TreeNodeGetOpen(ImGuiID storage_id);
     IMGUI_API void          TreeNodeSetOpen(ImGuiID storage_id, bool open);
     IMGUI_API void          TreeNodeSetOpen(ImGuiID storage_id, bool open);

+ 18 - 7
imgui_widgets.cpp

@@ -6226,7 +6226,7 @@ bool ImGui::TreeNode(const char* label)
     if (window->SkipItems)
     if (window->SkipItems)
         return false;
         return false;
     ImGuiID id = window->GetID(label);
     ImGuiID id = window->GetID(label);
-    return TreeNodeBehavior(id, id, ImGuiTreeNodeFlags_None, label, NULL);
+    return TreeNodeBehavior(id, ImGuiTreeNodeFlags_None, label, NULL);
 }
 }
 
 
 bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args)
 bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args)
@@ -6245,7 +6245,7 @@ bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags)
     if (window->SkipItems)
     if (window->SkipItems)
         return false;
         return false;
     ImGuiID id = window->GetID(label);
     ImGuiID id = window->GetID(label);
-    return TreeNodeBehavior(id, id, flags, label, NULL);
+    return TreeNodeBehavior(id, flags, label, NULL);
 }
 }
 
 
 bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
 bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
@@ -6275,7 +6275,7 @@ bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char
     ImGuiID id = window->GetID(str_id);
     ImGuiID id = window->GetID(str_id);
     const char* label, *label_end;
     const char* label, *label_end;
     ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
     ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
-    return TreeNodeBehavior(id, id, flags, label, label_end);
+    return TreeNodeBehavior(id, flags, label, label_end);
 }
 }
 
 
 bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
 bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
@@ -6287,7 +6287,7 @@ bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char
     ImGuiID id = window->GetID(ptr_id);
     ImGuiID id = window->GetID(ptr_id);
     const char* label, *label_end;
     const char* label, *label_end;
     ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
     ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
-    return TreeNodeBehavior(id, id, flags, label, label_end);
+    return TreeNodeBehavior(id, flags, label, label_end);
 }
 }
 
 
 bool ImGui::TreeNodeGetOpen(ImGuiID storage_id)
 bool ImGui::TreeNodeGetOpen(ImGuiID storage_id)
@@ -6367,7 +6367,7 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags)
 }
 }
 
 
 // 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.
 // 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.
-bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
+bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
     if (window->SkipItems)
     if (window->SkipItems)
@@ -6410,6 +6410,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags
         interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f);
         interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f);
 
 
     // Compute open and multi-select states before ItemAdd() as it clear NextItem data.
     // Compute open and multi-select states before ItemAdd() as it clear NextItem data.
+    ImGuiID storage_id = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasStorageID) ? g.NextItemData.StorageId : id;
     bool is_open = TreeNodeUpdateNextOpen(storage_id, flags);
     bool is_open = TreeNodeUpdateNextOpen(storage_id, flags);
 
 
     bool is_visible;
     bool is_visible;
@@ -6694,6 +6695,16 @@ void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond)
     g.NextItemData.OpenCond = (ImU8)(cond ? cond : ImGuiCond_Always);
     g.NextItemData.OpenCond = (ImU8)(cond ? cond : ImGuiCond_Always);
 }
 }
 
 
+// Set next TreeNode/CollapsingHeader storage id.
+void ImGui::SetNextItemStorageID(ImGuiID storage_id)
+{
+    ImGuiContext& g = *GImGui;
+    if (g.CurrentWindow->SkipItems)
+        return;
+    g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasStorageID;
+    g.NextItemData.StorageId = storage_id;
+}
+
 // CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag).
 // CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag).
 // This is basically the same as calling TreeNodeEx(label, ImGuiTreeNodeFlags_CollapsingHeader). You can remove the _NoTreePushOnOpen flag if you want behavior closer to normal TreeNode().
 // This is basically the same as calling TreeNodeEx(label, ImGuiTreeNodeFlags_CollapsingHeader). You can remove the _NoTreePushOnOpen flag if you want behavior closer to normal TreeNode().
 bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
 bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
@@ -6702,7 +6713,7 @@ bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
     if (window->SkipItems)
     if (window->SkipItems)
         return false;
         return false;
     ImGuiID id = window->GetID(label);
     ImGuiID id = window->GetID(label);
-    return TreeNodeBehavior(id, id, flags | ImGuiTreeNodeFlags_CollapsingHeader, label);
+    return TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader, label);
 }
 }
 
 
 // p_visible == NULL                        : regular collapsing header
 // p_visible == NULL                        : regular collapsing header
@@ -6722,7 +6733,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
     flags |= ImGuiTreeNodeFlags_CollapsingHeader;
     flags |= ImGuiTreeNodeFlags_CollapsingHeader;
     if (p_visible)
     if (p_visible)
         flags |= ImGuiTreeNodeFlags_AllowOverlap | (ImGuiTreeNodeFlags)ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
         flags |= ImGuiTreeNodeFlags_AllowOverlap | (ImGuiTreeNodeFlags)ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
-    bool is_open = TreeNodeBehavior(id, id, flags, label);
+    bool is_open = TreeNodeBehavior(id, flags, label);
     if (p_visible != NULL)
     if (p_visible != NULL)
     {
     {
         // Create a small overlapping close button
         // Create a small overlapping close button