Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_demo.cpp
This commit is contained in:
omar 2020-06-25 14:03:40 +02:00
commit 5628416bd3
5 changed files with 156 additions and 78 deletions

View File

@ -108,6 +108,8 @@ Breaking Changes:
- Removed unncessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please - Removed unncessary ID (first arg) of ImFontAtlas::AddCustomRectRegular() function. Please
note that this is a Beta api and will likely be reworked to support multi-monitor multi-DPI. note that this is a Beta api and will likely be reworked to support multi-monitor multi-DPI.
- Renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete). - Renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete).
- Removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor
of BeginPopupContextWindow(const char*, ImGuiPopupFlags flags) with ImGuiPopupFlags_NoOverItems.
- Removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017. - Removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017.
Other Changes: Other Changes:
@ -123,6 +125,16 @@ Other Changes:
Set to an intermediary value to toggle behavior based on width (same as Firefox). 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 - Tab: Added a ImGuiTabItemFlags_NoTooltip flag to disable the tooltip for individual tab item
(vs ImGuiTabBarFlags_NoTooltip for entire tab bar). [@Xipiryon] (vs ImGuiTabBarFlags_NoTooltip for entire tab bar). [@Xipiryon]
- Popups: All functions capable of opening popups (OpenPopup*, BeginPopupContext*) now take a new
ImGuiPopupFlags sets of flags instead of a mouse button index. The API is automatically backward
compatible as ImGuiPopupFlags is guaranteed to hold mouse button index in the lower bits.
- Popups: Added ImGuiPopupFlags_NoOpenOverExistingPopup for OpenPopup*/BeginPopupContext* functions
to first test for the presence of another popup at the same level.
- Popups: Added ImGuiPopupFlags_NoOpenOverItems for BeginPopupContextWindow() - similar to testing
for !IsAnyItemHovered() prior to doing an OpenPopup.
- 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 - 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) would attempt to focus it and close other popups. (#2880)
- Popups: Fix BeginPopupContextVoid() when clicking over the area made unavailable by a modal. (#1636) - Popups: Fix BeginPopupContextVoid() when clicking over the area made unavailable by a modal. (#1636)

106
imgui.cpp
View File

@ -375,14 +375,15 @@ CODE
You can read releases logs https://github.com/ocornut/imgui/releases for more details. You can read releases logs https://github.com/ocornut/imgui/releases for more details.
(Docking/Viewport Branch) (Docking/Viewport Branch)
- 2019/XX/XX (1.XX) - when multi-viewports are enabled, all positions will be in your natural OS coordinates space. It means that: - 2020/XX/XX (1.XX) - when multi-viewports are enabled, all positions will be in your natural OS coordinates space. It means that:
- reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are probably not what you want anymore. - reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are probably not what you want anymore.
you may use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos) you may use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos)
- likewise io.MousePos and GetMousePos() will use OS coordinates. - likewise io.MousePos and GetMousePos() will use OS coordinates.
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos. If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
- 2019/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api. - 2020/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2020/06/23 (1.77) - removed BeginPopupContextWindow(const char*, int mouse_button, bool also_over_items) in favor of BeginPopupContextWindow(const char*, ImGuiPopupFlags flags) with ImGuiPopupFlags_NoOverItems.
- 2020/06/15 (1.77) - renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete). - 2020/06/15 (1.77) - renamed OpenPopupOnItemClick() to OpenPopupContextItem(). Kept inline redirection function (will obsolete).
- 2020/06/15 (1.77) - removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017. - 2020/06/15 (1.77) - removed CalcItemRectClosestPoint() entry point which was made obsolete and asserting in December 2017.
- 2020/04/23 (1.77) - removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular(). - 2020/04/23 (1.77) - removed unnecessary ID (first arg) of ImFontAtlas::AddCustomRectRegular().
@ -3313,11 +3314,21 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
if (wrap_pos_x < 0.0f) if (wrap_pos_x < 0.0f)
return 0.0f; return 0.0f;
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (wrap_pos_x == 0.0f) if (wrap_pos_x == 0.0f)
{
// We could decide to setup a default wrapping max point for auto-resizing windows,
// or have auto-wrap (with unspecified wrapping pos) behave as a ContentSize extending function?
//if (window->Hidden && (window->Flags & ImGuiWindowFlags_AlwaysAutoResize))
// wrap_pos_x = ImMax(window->WorkRect.Min.x + g.FontSize * 10.0f, window->WorkRect.Max.x);
//else
wrap_pos_x = window->WorkRect.Max.x; wrap_pos_x = window->WorkRect.Max.x;
}
else if (wrap_pos_x > 0.0f) else if (wrap_pos_x > 0.0f)
{
wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space
}
return ImMax(wrap_pos_x - pos.x, 1.0f); return ImMax(wrap_pos_x - pos.x, 1.0f);
} }
@ -3608,7 +3619,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
// Handle the edge case of a popup being closed while clicking in its empty space. // 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. // 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.HoveredWindow ? g.HoveredWindow->RootWindowDockStop : NULL; ImGuiWindow* root_window = g.HoveredWindow ? g.HoveredWindow->RootWindowDockStop : NULL;
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) if (root_window != NULL && !is_closed_popup)
{ {
@ -8357,35 +8368,45 @@ void ImGui::SetTooltip(const char* fmt, ...)
// [SECTION] POPUPS // [SECTION] POPUPS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Return true if the popup is open at the current BeginPopup() level of the popup stack // Supported flags: ImGuiPopupFlags_AnyPopupId, ImGuiPopupFlags_AnyPopupLevel
bool ImGui::IsPopupOpen(ImGuiID id) 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;
}
// Return true if the popup is open at the current BeginPopup() level of the popup stack
bool ImGui::IsPopupOpen(const char* str_id)
{
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; ImGuiContext& g = *GImGui;
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++) for (int n = 0; n < g.OpenPopupStack.Size; n++)
if (g.OpenPopupStack[n].PopupId == id) if (g.OpenPopupStack[n].PopupId == id)
return true; return true;
return false; 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 any popup is open at the current BeginPopup() level of the popup stack bool ImGui::IsPopupOpen(const char* str_id, ImGuiPopupFlags popup_flags)
// 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; 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() ImGuiWindow* ImGui::GetTopMostPopupModal()
@ -8398,21 +8419,26 @@ ImGuiWindow* ImGui::GetTopMostPopupModal()
return NULL; return NULL;
} }
void ImGui::OpenPopup(const char* str_id) void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
OpenPopupEx(g.CurrentWindow->GetID(str_id)); OpenPopupEx(g.CurrentWindow->GetID(str_id), popup_flags);
} }
// Mark popup as open (toggle toward open state). // Mark popup as open (toggle toward open state).
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. // Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) // One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
void ImGui::OpenPopupEx(ImGuiID id) void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* parent_window = g.CurrentWindow; ImGuiWindow* parent_window = g.CurrentWindow;
int current_stack_size = g.BeginPopupStack.Size; const int current_stack_size = g.BeginPopupStack.Size;
if (popup_flags & ImGuiPopupFlags_NoOpenOverExistingPopup)
if (IsPopupOpen(0u, ImGuiPopupFlags_AnyPopupId))
return;
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. 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.PopupId = id;
popup_ref.Window = NULL; popup_ref.Window = NULL;
@ -8550,7 +8576,7 @@ void ImGui::CloseCurrentPopup()
bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (!IsPopupOpen(id)) if (!IsPopupOpen(id, ImGuiPopupFlags_None))
{ {
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
return false; return false;
@ -8589,7 +8615,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
const ImGuiID id = window->GetID(name); 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 g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
return false; return false;
@ -8635,14 +8661,15 @@ void ImGui::EndPopup()
g.WithinEndChild = false; g.WithinEndChild = false;
} }
bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiMouseButton mouse_button) bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
{ {
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
OpenPopupEx(id); OpenPopupEx(id, popup_flags);
return true; return true;
} }
return false; return false;
@ -8653,39 +8680,42 @@ bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiMouseButton mouse_butt
// - You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters). // - You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
// - This is essentially the same as calling OpenPopupContextItem() + BeginPopup() but written to avoid // - This is essentially the same as calling OpenPopupContextItem() + BeginPopup() but written to avoid
// computing the ID twice because BeginPopupContextXXX functions are called very frequently. // computing the ID twice because BeginPopupContextXXX functions are called very frequently.
bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiMouseButton mouse_button) bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
if (window->SkipItems) if (window->SkipItems)
return false; return false;
ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
OpenPopupEx(id); OpenPopupEx(id, popup_flags);
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings);
} }
bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mouse_button, bool also_over_items) bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_flags)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
if (!str_id) if (!str_id)
str_id = "window_context"; str_id = "window_context";
ImGuiID id = window->GetID(str_id); ImGuiID id = window->GetID(str_id);
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
if (also_over_items || !IsAnyItemHovered()) if (!(popup_flags & ImGuiPopupFlags_NoOpenOverItems) || !IsAnyItemHovered())
OpenPopupEx(id); OpenPopupEx(id, popup_flags);
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings);
} }
bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiMouseButton mouse_button) bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flags)
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
if (!str_id) if (!str_id)
str_id = "void_context"; str_id = "void_context";
ImGuiID id = window->GetID(str_id); ImGuiID id = window->GetID(str_id);
int mouse_button = (popup_flags & ImGuiPopupFlags_MouseButtonMask_);
if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow))
if (GetTopMostPopupModal() == NULL) if (GetTopMostPopupModal() == NULL)
OpenPopupEx(id); OpenPopupEx(id, popup_flags);
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings);
} }

48
imgui.h
View File

@ -169,6 +169,7 @@ typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: f
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline() typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline()
typedef int ImGuiKeyModFlags; // -> enum ImGuiKeyModFlags_ // Flags: for io.KeyMods (Ctrl/Shift/Alt/Super) 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 ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar() typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar()
typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem() typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem()
@ -617,20 +618,27 @@ namespace ImGui
IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // return true if the modal is open, and you can start outputting to it. IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // return true if the modal is open, and you can start outputting to it.
IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true!
// Popups: open/close functions // Popups: open/close functions
// - OpenPopup(): set popup state to open. // - OpenPopup(): set popup state to open. ImGuiPopupFlags are available for opening options.
// - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE. // - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
// - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually. // - CloseCurrentPopup(): use inside the BeginPopup()/EndPopup() scope to close manually.
// - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options). // - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options).
IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). // - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup().
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 OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!).
IMGUI_API bool OpenPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 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 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 // 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. // - 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. // - 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! // - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future.
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. // - We exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter. Passing a mouse button to ImGuiPopupFlags is guaranteed to be legal.
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). IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 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, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window.
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 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 // Columns
// - You can also use SameLine(pos_x) to mimic simplified columns. // - You can also use SameLine(pos_x) to mimic simplified columns.
@ -909,6 +917,26 @@ enum ImGuiTreeNodeFlags_
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog
}; };
// Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions.
// - To be backward compatible with older API which took an 'int mouse_button = 1' argument, we need to treat
// small flags values as a mouse button index, so we encode the mouse button in the first few bits of the flags.
// It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags.
// - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0.
enum ImGuiPopupFlags_
{
ImGuiPopupFlags_None = 0,
ImGuiPopupFlags_MouseButtonLeft = 0, // For BeginPopupContext*(): open on Left Mouse release. Guaranted to always be == 0 (same as ImGuiMouseButton_Left)
ImGuiPopupFlags_MouseButtonRight = 1, // For BeginPopupContext*(): open on Right Mouse release. Guaranted to always be == 1 (same as ImGuiMouseButton_Right)
ImGuiPopupFlags_MouseButtonMiddle = 2, // For BeginPopupContext*(): open on Middle Mouse release. Guaranted to always be == 2 (same as ImGuiMouseButton_Middle)
ImGuiPopupFlags_MouseButtonMask_ = 0x1F,
ImGuiPopupFlags_MouseButtonDefault_ = 1,
ImGuiPopupFlags_NoOpenOverExistingPopup = 1 << 5, // For OpenPopup*(), BeginPopupContext*(): don't open if there's already a popup at the same level of the popup stack
ImGuiPopupFlags_NoOpenOverItems = 1 << 6, // For BeginPopupContextWindow(): don't return true when hovering items, only when hovering empty space
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() // Flags for ImGui::Selectable()
enum ImGuiSelectableFlags_ enum ImGuiSelectableFlags_
{ {
@ -1352,7 +1380,8 @@ enum ImGuiMouseCursor_
// Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always. // Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always.
enum ImGuiCond_ enum ImGuiCond_
{ {
ImGuiCond_Always = 1 << 0, // Set the variable ImGuiCond_None = 0, // No condition (always set the variable), same as _Always
ImGuiCond_Always = 1 << 0, // No condition (always set the variable)
ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call will succeed) ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call will succeed)
ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file) ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file)
ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time) ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time)
@ -1745,7 +1774,8 @@ struct ImGuiPayload
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.77 (from June 2020) // OBSOLETED in 1.77 (from June 2020)
static inline bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiMouseButton mouse_button = 1) { return OpenPopupContextItem(str_id, mouse_button); } static inline bool OpenPopupOnItemClick(const char* str_id = NULL, ImGuiMouseButton mb = 1) { return OpenPopupContextItem(str_id, mb); } // Passing a mouse button to ImGuiPopupFlags is legal
static inline bool BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mb, bool over_items) { return BeginPopupContextWindow(str_id, mb | (over_items ? 0 : ImGuiPopupFlags_NoOpenOverItems)); }
// OBSOLETED in 1.72 (from July 2019) // OBSOLETED in 1.72 (from July 2019)
static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); } static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); }
// OBSOLETED in 1.71 (from June 2019) // OBSOLETED in 1.71 (from June 2019)

View File

@ -2066,12 +2066,10 @@ namespace ImGui
// Popups, Modals, Tooltips // Popups, Modals, Tooltips
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags); IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
IMGUI_API void OpenPopupEx(ImGuiID id); 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 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 IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags);
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 BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags); IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags);
IMGUI_API ImGuiWindow* GetTopMostPopupModal(); IMGUI_API ImGuiWindow* GetTopMostPopupModal();
@ -2224,6 +2222,7 @@ namespace ImGui
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0); IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
IMGUI_API void Scrollbar(ImGuiAxis axis); IMGUI_API void Scrollbar(ImGuiAxis axis);
IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float avail_v, float contents_v, ImDrawCornerFlags rounding_corners); IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float avail_v, float contents_v, ImDrawCornerFlags rounding_corners);
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col);
IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders

View File

@ -988,28 +988,16 @@ void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2&
} }
} }
// frame_padding < 0: uses FramePadding from style (default) // ImageButton() is flawed as 'id' is always derived from 'texture_id' (see #2464 #1390)
// frame_padding = 0: no framing // We provide this internal helper to write your own variant while we figure out how to redesign the public ImageButton() API.
// frame_padding > 0: set framing size bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col)
// The color used are the button colors.
bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
{ {
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
return false; return false;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
// Default to using texture ID as ID. User can still push string/integer prefixes.
// We could hash the size/uv to create a unique ID but that would prevent the user from animating UV.
PushID((void*)(intptr_t)user_texture_id);
const ImGuiID id = window->GetID("#image");
PopID();
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding;
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2);
const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size);
ItemSize(bb); ItemSize(bb);
if (!ItemAdd(bb, id)) if (!ItemAdd(bb, id))
return false; return false;
@ -1020,14 +1008,33 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I
// Render // Render
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
RenderNavHighlight(bb, id); RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, style.FrameRounding)); RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, g.Style.FrameRounding));
if (bg_col.w > 0.0f) if (bg_col.w > 0.0f)
window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, GetColorU32(bg_col)); window->DrawList->AddRectFilled(bb.Min + padding, bb.Max - padding, GetColorU32(bg_col));
window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, GetColorU32(tint_col)); window->DrawList->AddImage(texture_id, bb.Min + padding, bb.Max - padding, uv0, uv1, GetColorU32(tint_col));
return pressed; return pressed;
} }
// frame_padding < 0: uses FramePadding from style (default)
// frame_padding = 0: no framing
// frame_padding > 0: set framing size
bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (window->SkipItems)
return false;
// Default to using texture ID as ID. User can still push string/integer prefixes.
PushID((void*)(intptr_t)user_texture_id);
const ImGuiID id = window->GetID("#image");
PopID();
const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding;
return ImageButtonEx(id, user_texture_id, size, uv0, uv1, padding, bg_col, tint_col);
}
bool ImGui::Checkbox(const char* label, bool* v) bool ImGui::Checkbox(const char* label, bool* v)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
@ -1492,7 +1499,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
bool hovered, held; bool hovered, held;
bool pressed = ButtonBehavior(frame_bb, id, &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 ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
const float value_x2 = ImMax(frame_bb.Min.x, frame_bb.Max.x - arrow_size); const float value_x2 = ImMax(frame_bb.Min.x, frame_bb.Max.x - arrow_size);
@ -1517,7 +1524,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
{ {
if (window->DC.NavLayerCurrent == 0) if (window->DC.NavLayerCurrent == 0)
window->NavLastIds[0] = id; window->NavLastIds[0] = id;
OpenPopupEx(id); OpenPopupEx(id, ImGuiPopupFlags_None);
popup_open = true; popup_open = true;
} }
@ -6312,7 +6319,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label); 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) // 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; ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
@ -6438,7 +6445,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.. }' 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; want_close = true;
if (want_close && IsPopupOpen(id)) if (want_close && IsPopupOpen(id, ImGuiPopupFlags_None))
ClosePopupToLevel(g.BeginPopupStack.Size, true); ClosePopupToLevel(g.BeginPopupStack.Size, true);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0)); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0));