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

Undo/amend 7c6d4ff.
This commit is contained in:
ocornut 2024-07-29 22:08:06 +02:00
parent b847c41437
commit df38704926
4 changed files with 25 additions and 8 deletions

View File

@ -147,6 +147,9 @@ Other changes:
- Nav: fixed clicking window decorations (e.g. resize borders) from losing focused item when
within a child window using ImGuiChildFlags_NavFlattened.
- 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
the hovered state. (#7820) [@rerilier]
- Clipper: added SeekCursorForItem() function. When using ImGuiListClipper::Begin(INT_MAX) you can

View File

@ -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, 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 SetNextItemStorageID(ImGuiID storage_id); // set id to use for open/close storage (default to same as item id).
// Widgets: Selectables
// - A selectable highlights when hovered, and can display another color when selected.

View File

@ -1215,6 +1215,7 @@ enum ImGuiNextItemDataFlags_
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
ImGuiNextItemDataFlags_HasShortcut = 1 << 2,
ImGuiNextItemDataFlags_HasRefVal = 1 << 3,
ImGuiNextItemDataFlags_HasStorageID = 1 << 4,
};
struct ImGuiNextItemData
@ -1230,6 +1231,7 @@ struct ImGuiNextItemData
bool OpenVal; // Set by SetNextItemOpen()
ImU8 OpenCond; // Set by SetNextItemOpen()
ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal
ImGuiID StorageId; // Set by SetNextItemStorageID()
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
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);
// 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 bool TreeNodeGetOpen(ImGuiID storage_id);
IMGUI_API void TreeNodeSetOpen(ImGuiID storage_id, bool open);

View File

@ -6226,7 +6226,7 @@ bool ImGui::TreeNode(const char* label)
if (window->SkipItems)
return false;
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)
@ -6245,7 +6245,7 @@ bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags)
if (window->SkipItems)
return false;
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, ...)
@ -6275,7 +6275,7 @@ bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char
ImGuiID id = window->GetID(str_id);
const char* label, *label_end;
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)
@ -6287,7 +6287,7 @@ bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char
ImGuiID id = window->GetID(ptr_id);
const char* label, *label_end;
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)
@ -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.
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();
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);
// 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_visible;
@ -6694,6 +6695,16 @@ void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond)
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).
// 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)
@ -6702,7 +6713,7 @@ bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
if (window->SkipItems)
return false;
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
@ -6722,7 +6733,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
if (p_visible)
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)
{
// Create a small overlapping close button