mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-26 05:27:01 +00:00
SetNextWindowPos: added a ImVec2 pivot parameter for positioning a given a center, bottom-right position, etc. As a generalization of SetNextWindowPosCenter() which is now obsolete. This will be useful for combo-like popups as well.
Demo: Simple-overlay window uses the SetWindowPos pivot to select a corner to position itself at.
This commit is contained in:
parent
0a55573288
commit
4b82759598
37
imgui.cpp
37
imgui.cpp
@ -204,6 +204,7 @@
|
||||
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
|
||||
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete).
|
||||
- 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)".
|
||||
- 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete).
|
||||
- renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete).
|
||||
@ -1804,7 +1805,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
|
||||
AutoPosLastDirection = -1;
|
||||
HiddenFrames = 0;
|
||||
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
|
||||
SetWindowPosCenterWanted = false;
|
||||
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
|
||||
|
||||
LastFrameActive = -1;
|
||||
ItemWidthDefault = 0.0f;
|
||||
@ -3619,11 +3620,15 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext
|
||||
return false;
|
||||
}
|
||||
|
||||
// Center modal windows by default
|
||||
if ((window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) == 0)
|
||||
SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings;
|
||||
bool is_open = ImGui::Begin(name, p_open, flags);
|
||||
if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
{
|
||||
ImGui::EndPopup();
|
||||
EndPopup();
|
||||
if (is_open)
|
||||
ClosePopup(id);
|
||||
return false;
|
||||
@ -3994,9 +3999,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
||||
if (window->Appearing)
|
||||
window->SetWindowPosAllowFlags |= ImGuiCond_Appearing;
|
||||
window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0;
|
||||
if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f)
|
||||
if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f)
|
||||
{
|
||||
window->SetWindowPosCenterWanted = true; // May be processed on the next frame if this is our first frame and we are measuring size
|
||||
// May be processed on the next frame if this is our first frame and we are measuring size
|
||||
// FIXME: Look into removing the branch so everything can go through this same codepath for consistency.
|
||||
window->SetWindowPosVal = g.SetNextWindowPosVal;
|
||||
window->SetWindowPosPivot = g.SetNextWindowPosPivot;
|
||||
window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing);
|
||||
}
|
||||
else
|
||||
@ -4178,13 +4186,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
||||
window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user passed via BeginChild()->Begin().
|
||||
}
|
||||
|
||||
bool window_pos_center = false;
|
||||
window_pos_center |= (window->SetWindowPosCenterWanted && window->HiddenFrames == 0);
|
||||
window_pos_center |= ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize);
|
||||
if (window_pos_center)
|
||||
const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0);
|
||||
if (window_pos_with_pivot)
|
||||
{
|
||||
// Center (any sort of window)
|
||||
SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, fullscreen_rect.GetCenter() - window->SizeFull * 0.5f), 0);
|
||||
// Position given a pivot (e.g. for centering)
|
||||
SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0);
|
||||
}
|
||||
else if (flags & ImGuiWindowFlags_ChildMenu)
|
||||
{
|
||||
@ -5010,7 +5016,7 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond)
|
||||
if (cond && (window->SetWindowPosAllowFlags & cond) == 0)
|
||||
return;
|
||||
window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing);
|
||||
window->SetWindowPosCenterWanted = false;
|
||||
window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX);
|
||||
|
||||
// Set
|
||||
const ImVec2 old_pos = window->Pos;
|
||||
@ -5133,19 +5139,20 @@ void ImGui::SetWindowFocus(const char* name)
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond)
|
||||
void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.SetNextWindowPosVal = pos;
|
||||
g.SetNextWindowPosPivot = pivot;
|
||||
g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always;
|
||||
}
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
void ImGui::SetNextWindowPosCenter(ImGuiCond cond)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.SetNextWindowPosVal = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always;
|
||||
SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, cond, ImVec2(0.5f, 0.5f));
|
||||
}
|
||||
#endif
|
||||
|
||||
void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond)
|
||||
{
|
||||
|
4
imgui.h
4
imgui.h
@ -152,8 +152,7 @@ namespace ImGui
|
||||
IMGUI_API bool IsWindowAppearing();
|
||||
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows
|
||||
|
||||
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // set next window position. call before Begin()
|
||||
IMGUI_API void SetNextWindowPosCenter(ImGuiCond cond = 0); // set next window position to be centered on screen. call before Begin()
|
||||
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc.
|
||||
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin()
|
||||
IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints.
|
||||
IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin()
|
||||
@ -489,6 +488,7 @@ namespace ImGui
|
||||
|
||||
// Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp)
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
static void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+
|
||||
static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+
|
||||
static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead.
|
||||
static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+
|
||||
|
@ -2114,20 +2114,30 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Demonstrate creating a simple static window with no decoration.
|
||||
// Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use.
|
||||
static void ShowExampleAppFixedOverlay(bool* p_open)
|
||||
{
|
||||
ImGui::SetNextWindowPos(ImVec2(10,10));
|
||||
const float DISTANCE = 10.0f;
|
||||
static int corner = 0;
|
||||
ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE);
|
||||
ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
|
||||
if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings))
|
||||
if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings))
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
ImGui::Text("Simple overlay\non the top-left side of the screen.");
|
||||
ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y);
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
{
|
||||
if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0;
|
||||
if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1;
|
||||
if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2;
|
||||
if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3;
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
|
@ -437,6 +437,7 @@ struct ImGuiContext
|
||||
|
||||
// Storage for SetNexWindow** and SetNextTreeNode*** functions
|
||||
ImVec2 SetNextWindowPosVal;
|
||||
ImVec2 SetNextWindowPosPivot;
|
||||
ImVec2 SetNextWindowSizeVal;
|
||||
ImVec2 SetNextWindowContentSizeVal;
|
||||
bool SetNextWindowCollapsedVal;
|
||||
@ -696,7 +697,8 @@ struct IMGUI_API ImGuiWindow
|
||||
ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call.
|
||||
ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call.
|
||||
ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call.
|
||||
bool SetWindowPosCenterWanted;
|
||||
ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
|
||||
ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right.
|
||||
|
||||
ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame
|
||||
ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack
|
||||
|
Loading…
Reference in New Issue
Block a user