Internals: made ImLowerBound() accessible in internals + take a span. + rearrange child/popup/tooltips section.

Because upcoming rework of ImGuiSelectionBasicStorage will want to do a lower bound on a span.
This commit is contained in:
ocornut 2024-06-10 19:20:12 +02:00
parent 22d65c7949
commit 8caf7afbad
2 changed files with 31 additions and 26 deletions

View File

@ -2503,17 +2503,16 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float&
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// std::lower_bound but without the bullshit // std::lower_bound but without the bullshit
static ImGuiStoragePair* LowerBound(ImVector<ImGuiStoragePair>& data, ImGuiID key) ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key)
{ {
ImGuiStoragePair* first = data.Data; ImGuiStoragePair* in_p = in_begin;
ImGuiStoragePair* last = data.Data + data.Size; for (size_t count = (size_t)(in_end - in_p); count > 0; )
for (size_t count = (size_t)(last - first); count > 0; )
{ {
size_t count2 = count >> 1; size_t count2 = count >> 1;
ImGuiStoragePair* mid = first + count2; ImGuiStoragePair* mid = in_p + count2;
if (mid->key < key) if (mid->key < key)
{ {
first = ++mid; in_p = ++mid;
count -= count2 + 1; count -= count2 + 1;
} }
else else
@ -2521,7 +2520,7 @@ static ImGuiStoragePair* LowerBound(ImVector<ImGuiStoragePair>& data, ImGuiID ke
count = count2; count = count2;
} }
} }
return first; return in_p;
} }
// For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.
@ -2542,7 +2541,7 @@ void ImGuiStorage::BuildSortByKey()
int ImGuiStorage::GetInt(ImGuiID key, int default_val) const int ImGuiStorage::GetInt(ImGuiID key, int default_val) const
{ {
ImGuiStoragePair* it = LowerBound(const_cast<ImVector<ImGuiStoragePair>&>(Data), key); ImGuiStoragePair* it = ImLowerBound(const_cast<ImGuiStoragePair*>(Data.Data), const_cast<ImGuiStoragePair*>(Data.Data + Data.Size), key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
return default_val; return default_val;
return it->val_i; return it->val_i;
@ -2555,7 +2554,7 @@ bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const
float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
{ {
ImGuiStoragePair* it = LowerBound(const_cast<ImVector<ImGuiStoragePair>&>(Data), key); ImGuiStoragePair* it = ImLowerBound(const_cast<ImGuiStoragePair*>(Data.Data), const_cast<ImGuiStoragePair*>(Data.Data + Data.Size), key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
return default_val; return default_val;
return it->val_f; return it->val_f;
@ -2563,7 +2562,7 @@ float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
void* ImGuiStorage::GetVoidPtr(ImGuiID key) const void* ImGuiStorage::GetVoidPtr(ImGuiID key) const
{ {
ImGuiStoragePair* it = LowerBound(const_cast<ImVector<ImGuiStoragePair>&>(Data), key); ImGuiStoragePair* it = ImLowerBound(const_cast<ImGuiStoragePair*>(Data.Data), const_cast<ImGuiStoragePair*>(Data.Data + Data.Size), key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
return NULL; return NULL;
return it->val_p; return it->val_p;
@ -2572,7 +2571,7 @@ void* ImGuiStorage::GetVoidPtr(ImGuiID key) const
// References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. // References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val)
{ {
ImGuiStoragePair* it = LowerBound(Data, key); ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
it = Data.insert(it, ImGuiStoragePair(key, default_val)); it = Data.insert(it, ImGuiStoragePair(key, default_val));
return &it->val_i; return &it->val_i;
@ -2585,7 +2584,7 @@ bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val)
float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
{ {
ImGuiStoragePair* it = LowerBound(Data, key); ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
it = Data.insert(it, ImGuiStoragePair(key, default_val)); it = Data.insert(it, ImGuiStoragePair(key, default_val));
return &it->val_f; return &it->val_f;
@ -2593,7 +2592,7 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
{ {
ImGuiStoragePair* it = LowerBound(Data, key); ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
it = Data.insert(it, ImGuiStoragePair(key, default_val)); it = Data.insert(it, ImGuiStoragePair(key, default_val));
return &it->val_p; return &it->val_p;
@ -2602,7 +2601,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
// FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame)
void ImGuiStorage::SetInt(ImGuiID key, int val) void ImGuiStorage::SetInt(ImGuiID key, int val)
{ {
ImGuiStoragePair* it = LowerBound(Data, key); ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
Data.insert(it, ImGuiStoragePair(key, val)); Data.insert(it, ImGuiStoragePair(key, val));
else else
@ -2616,7 +2615,7 @@ void ImGuiStorage::SetBool(ImGuiID key, bool val)
void ImGuiStorage::SetFloat(ImGuiID key, float val) void ImGuiStorage::SetFloat(ImGuiID key, float val)
{ {
ImGuiStoragePair* it = LowerBound(Data, key); ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
Data.insert(it, ImGuiStoragePair(key, val)); Data.insert(it, ImGuiStoragePair(key, val));
else else
@ -2625,7 +2624,7 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val)
void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val)
{ {
ImGuiStoragePair* it = LowerBound(Data, key); ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key);
if (it == Data.end() || it->key != key) if (it == Data.end() || it->key != key)
Data.insert(it, ImGuiStoragePair(key, val)); Data.insert(it, ImGuiStoragePair(key, val));
else else
@ -11238,8 +11237,8 @@ void ImGui::CloseCurrentPopup()
window->DC.NavHideHighlightOneFrame = true; window->DC.NavHideHighlightOneFrame = true;
} }
// Attention! BeginPopup() adds default flags which BeginPopupEx()! // Attention! BeginPopup() adds default flags when calling BeginPopupEx()!
bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (!IsPopupOpen(id, ImGuiPopupFlags_None)) if (!IsPopupOpen(id, ImGuiPopupFlags_None))
@ -11249,13 +11248,12 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags)
} }
char name[20]; char name[20];
if (flags & ImGuiWindowFlags_ChildMenu) if (extra_window_flags & ImGuiWindowFlags_ChildMenu)
ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginMenuDepth); // Recycle windows based on depth ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginMenuDepth); // Recycle windows based on depth
else else
ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame
flags |= ImGuiWindowFlags_Popup; bool is_open = Begin(name, NULL, extra_window_flags | ImGuiWindowFlags_Popup);
bool is_open = Begin(name, NULL, flags);
if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display)
EndPopup(); EndPopup();

View File

@ -348,6 +348,7 @@ namespace ImStb
// - Helper: ImPool<> // - Helper: ImPool<>
// - Helper: ImChunkStream<> // - Helper: ImChunkStream<>
// - Helper: ImGuiTextIndex // - Helper: ImGuiTextIndex
// - Helper: ImGuiStorage
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Helpers: Hashing // Helpers: Hashing
@ -722,7 +723,7 @@ struct ImChunkStream
void swap(ImChunkStream<T>& rhs) { rhs.Buf.swap(Buf); } void swap(ImChunkStream<T>& rhs) { rhs.Buf.swap(Buf); }
}; };
// Helper: ImGuiTextIndex<> // Helper: ImGuiTextIndex
// Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API. // Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API.
struct ImGuiTextIndex struct ImGuiTextIndex
{ {
@ -736,6 +737,8 @@ struct ImGuiTextIndex
void append(const char* base, int old_size, int new_size); void append(const char* base, int old_size, int new_size);
}; };
// Helper: ImGuiStorage
IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImDrawList support // [SECTION] ImDrawList support
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -3143,16 +3146,16 @@ namespace ImGui
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL); IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix); IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
// Popups, Modals, Tooltips // Childs
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags); IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags);
// Popups, Modals
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags);
IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None); IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsExceptModals(); IMGUI_API void ClosePopupsExceptModals();
IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags); IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags);
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags);
IMGUI_API bool BeginTooltipHidden();
IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window); IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window);
IMGUI_API ImGuiWindow* GetTopMostPopupModal(); IMGUI_API ImGuiWindow* GetTopMostPopupModal();
IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal(); IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal();
@ -3160,6 +3163,10 @@ namespace ImGui
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window); IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy); IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
// Tooltips
IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags);
IMGUI_API bool BeginTooltipHidden();
// Menus // Menus
IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags); IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags);
IMGUI_API bool BeginMenuEx(const char* label, const char* icon, bool enabled = true); IMGUI_API bool BeginMenuEx(const char* label, const char* icon, bool enabled = true);