mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
Popups: Added ImGuiPopupFlags type, ImGuiPopupFlags_AnyPopupId and ImGuiPopupFlags_AnyPopupLevel flags for IsPopupOpen().
# Conflicts: # docs/CHANGELOG.txt
This commit is contained in:
parent
1c35750ee0
commit
5acf6d861a
@ -54,6 +54,9 @@ Other Changes:
|
||||
Set to an intermediary value to toggle behavior based on width (same as Firefox).
|
||||
- Tab: Added a ImGuiTabItemFlags_NoTooltip flag to disable the tooltip for individual tab item
|
||||
(vs ImGuiTabBarFlags_NoTooltip for entire tab bar). [@Xipiryon]
|
||||
- Popups: Added ImGuiPopupFlags_AnyPopupId and ImGuiPopupFlags_AnyPopupLevel flags for IsPopupOpen(),
|
||||
allowing to check if any popup is open at the current level, if a given popup is open at any popup
|
||||
level, if any popup is open at all.
|
||||
- Popups: Fix an edge case where programatically closing a popup while clicking on its empty space
|
||||
would attempt to focus it and close other popups. (#2880)
|
||||
- Popups: Fix BeginPopupContextVoid() when clicking over the area made unavailable by a modal. (#1636)
|
||||
|
64
imgui.cpp
64
imgui.cpp
@ -3468,7 +3468,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||
// Handle the edge case of a popup being closed while clicking in its empty space.
|
||||
// If we try to focus it, FocusWindow() > ClosePopupsOverWindow() will accidentally close any parent popups because they are not linked together any more.
|
||||
ImGuiWindow* root_window = g.HoveredRootWindow;
|
||||
const bool is_closed_popup = root_window && (root_window->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpenAtAnyLevel(root_window->PopupId);
|
||||
const bool is_closed_popup = root_window && (root_window->Flags & ImGuiWindowFlags_Popup) && !IsPopupOpen(root_window->PopupId, ImGuiPopupFlags_AnyPopupLevel);
|
||||
|
||||
if (root_window != NULL && !is_closed_popup)
|
||||
{
|
||||
@ -7619,35 +7619,45 @@ void ImGui::SetTooltip(const char* fmt, ...)
|
||||
// [SECTION] POPUPS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Return true if the popup is open at the current BeginPopup() level of the popup stack
|
||||
bool ImGui::IsPopupOpen(ImGuiID id)
|
||||
// Supported flags: ImGuiPopupFlags_AnyPopupId, ImGuiPopupFlags_AnyPopupLevel
|
||||
bool ImGui::IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id;
|
||||
if (popup_flags & ImGuiPopupFlags_AnyPopupId)
|
||||
{
|
||||
// Return true if any popup is open at the current BeginPopup() level of the popup stack
|
||||
// This may be used to e.g. test for another popups already opened to handle popups priorities at the same level.
|
||||
IM_ASSERT(id == 0);
|
||||
if (popup_flags & ImGuiPopupFlags_AnyPopupLevel)
|
||||
return g.OpenPopupStack.Size > 0;
|
||||
else
|
||||
return g.OpenPopupStack.Size > g.BeginPopupStack.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (popup_flags & ImGuiPopupFlags_AnyPopupLevel)
|
||||
{
|
||||
// Return true if the popup is open anywhere in the popup stack
|
||||
for (int n = 0; n < g.OpenPopupStack.Size; n++)
|
||||
if (g.OpenPopupStack[n].PopupId == id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return true if the popup is open at the current BeginPopup() level of the popup stack (this is the most-common query)
|
||||
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if the popup is open at the current BeginPopup() level of the popup stack
|
||||
bool ImGui::IsPopupOpen(const char* str_id)
|
||||
bool ImGui::IsPopupOpen(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id);
|
||||
}
|
||||
|
||||
bool ImGui::IsPopupOpenAtAnyLevel(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
for (int n = 0; n < g.OpenPopupStack.Size; n++)
|
||||
if (g.OpenPopupStack[n].PopupId == id)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true if any popup is open at the current BeginPopup() level of the popup stack
|
||||
// This may be used to e.g. test for another popups already opened in the same frame to handle popups priorities at the same level.
|
||||
bool ImGui::IsAnyPopupOpen()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return g.OpenPopupStack.Size > g.BeginPopupStack.Size;
|
||||
ImGuiID id = (popup_flags & ImGuiPopupFlags_AnyPopupId) ? 0 : g.CurrentWindow->GetID(str_id);
|
||||
if ((popup_flags & ImGuiPopupFlags_AnyPopupLevel) && id != 0)
|
||||
IM_ASSERT(0 && "Cannot use IsPopupOpen() with a string id and ImGuiPopupFlags_AnyPopupLevel."); // But non-string version is legal and used internally
|
||||
return IsPopupOpen(id, popup_flags);
|
||||
}
|
||||
|
||||
ImGuiWindow* ImGui::GetTopMostPopupModal()
|
||||
@ -7674,7 +7684,7 @@ void ImGui::OpenPopupEx(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
int current_stack_size = g.BeginPopupStack.Size;
|
||||
const int current_stack_size = g.BeginPopupStack.Size;
|
||||
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
|
||||
popup_ref.PopupId = id;
|
||||
popup_ref.Window = NULL;
|
||||
@ -7811,7 +7821,7 @@ void ImGui::CloseCurrentPopup()
|
||||
bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!IsPopupOpen(id))
|
||||
if (!IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||
{
|
||||
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
||||
return false;
|
||||
@ -7850,7 +7860,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
const ImGuiID id = window->GetID(name);
|
||||
if (!IsPopupOpen(id))
|
||||
if (!IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||
{
|
||||
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
||||
return false;
|
||||
|
16
imgui.h
16
imgui.h
@ -161,6 +161,7 @@ typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: f
|
||||
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
|
||||
typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline()
|
||||
typedef int ImGuiKeyModFlags; // -> enum ImGuiKeyModFlags_ // Flags: for io.KeyMods (Ctrl/Shift/Alt/Super)
|
||||
typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen()
|
||||
typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
|
||||
typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar()
|
||||
typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem()
|
||||
@ -612,13 +613,17 @@ namespace ImGui
|
||||
IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!).
|
||||
IMGUI_API bool OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1); // helper to open popup when clicked on last item. return true when just opened. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors)
|
||||
IMGUI_API void CloseCurrentPopup(); // manually close the popup we have begin-ed into.
|
||||
IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open at the current BeginPopup() level of the popup stack
|
||||
// Popups: open+begin combined functions helpers
|
||||
// - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking.
|
||||
// - They are convenient to easily create context menus, hence the name.
|
||||
IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1); // open+begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp!
|
||||
IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1, bool also_over_items = true); // open+begin popup when clicked on current window.
|
||||
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiMouseButton mouse_b = 1); // open+begin popup when clicked in void (where there are no windows).
|
||||
// Popups: test function
|
||||
// - IsPopupOpen(): return true if the popup is open at the current BeginPopup() level of the popup stack.
|
||||
// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId: return true if any popup is open at the current BeginPopup() level of the popup stack.
|
||||
// - IsPopupOpen() with ImGuiPopupFlags_AnyPopupId + ImGuiPopupFlags_AnyPopupLevel: return true if any popup is open.
|
||||
IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open.
|
||||
|
||||
// Columns
|
||||
// - You can also use SameLine(pos_x) to mimic simplified columns.
|
||||
@ -865,6 +870,15 @@ enum ImGuiTreeNodeFlags_
|
||||
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog
|
||||
};
|
||||
|
||||
// Flags for IsPopupOpen() function.
|
||||
enum ImGuiPopupFlags_
|
||||
{
|
||||
ImGuiPopupFlags_None = 0,
|
||||
ImGuiPopupFlags_AnyPopupId = 1 << 7, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup.
|
||||
ImGuiPopupFlags_AnyPopupLevel = 1 << 8, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level)
|
||||
ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel
|
||||
};
|
||||
|
||||
// Flags for ImGui::Selectable()
|
||||
enum ImGuiSelectableFlags_
|
||||
{
|
||||
|
@ -1853,9 +1853,7 @@ namespace ImGui
|
||||
IMGUI_API void OpenPopupEx(ImGuiID id);
|
||||
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 bool IsPopupOpen(ImGuiID id); // Test for id at the current BeginPopup() level of the popup stack (this doesn't scan the whole popup stack!)
|
||||
IMGUI_API bool IsPopupOpenAtAnyLevel(ImGuiID id);
|
||||
IMGUI_API bool IsAnyPopupOpen(); // Return true if any popup is open at the current BeginPopup() level of the popup stack
|
||||
IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags);
|
||||
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
|
||||
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags);
|
||||
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
|
||||
|
@ -1492,7 +1492,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held);
|
||||
bool popup_open = IsPopupOpen(id);
|
||||
bool popup_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||
|
||||
const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
const float value_x2 = ImMax(frame_bb.Min.x, frame_bb.Max.x - arrow_size);
|
||||
@ -6288,7 +6288,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
bool menu_is_open = IsPopupOpen(id);
|
||||
bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||
|
||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
@ -6414,7 +6414,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
|
||||
if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
|
||||
want_close = true;
|
||||
if (want_close && IsPopupOpen(id))
|
||||
if (want_close && IsPopupOpen(id, ImGuiPopupFlags_None))
|
||||
ClosePopupToLevel(g.BeginPopupStack.Size, true);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));
|
||||
|
Loading…
Reference in New Issue
Block a user