|
@@ -661,7 +661,7 @@ static ImRect GetVisibleRect();
|
|
|
static void CloseInactivePopups(ImGuiWindow* ref_window);
|
|
static void CloseInactivePopups(ImGuiWindow* ref_window);
|
|
|
static void ClosePopupToLevel(int remaining);
|
|
static void ClosePopupToLevel(int remaining);
|
|
|
static ImGuiWindow* GetFrontMostModalRootWindow();
|
|
static ImGuiWindow* GetFrontMostModalRootWindow();
|
|
|
-static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid);
|
|
|
|
|
|
|
+static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& rect_to_avoid);
|
|
|
|
|
|
|
|
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data);
|
|
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data);
|
|
|
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
|
|
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
|
|
@@ -1850,7 +1850,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
|
|
|
AutoFitFramesX = AutoFitFramesY = -1;
|
|
AutoFitFramesX = AutoFitFramesY = -1;
|
|
|
AutoFitOnlyGrows = false;
|
|
AutoFitOnlyGrows = false;
|
|
|
AutoFitChildAxises = 0x00;
|
|
AutoFitChildAxises = 0x00;
|
|
|
- AutoPosLastDirection = -1;
|
|
|
|
|
|
|
+ AutoPosLastDirection = ImGuiDir_None;
|
|
|
HiddenFrames = 0;
|
|
HiddenFrames = 0;
|
|
|
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
|
|
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
|
|
|
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
|
|
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
|
|
@@ -2238,6 +2238,11 @@ int ImGui::GetFrameCount()
|
|
|
return GImGui->FrameCount;
|
|
return GImGui->FrameCount;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ImDrawList* ImGui::GetOverlayDrawList()
|
|
|
|
|
+{
|
|
|
|
|
+ return &GImGui->OverlayDrawList;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void ImGui::NewFrame()
|
|
void ImGui::NewFrame()
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -4017,28 +4022,39 @@ static void CheckStacksSize(ImGuiWindow* window, bool write)
|
|
|
IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
|
|
IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& r_inner)
|
|
|
|
|
|
|
+static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid)
|
|
|
{
|
|
{
|
|
|
const ImGuiStyle& style = GImGui->Style;
|
|
const ImGuiStyle& style = GImGui->Style;
|
|
|
|
|
|
|
|
- // Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it.
|
|
|
|
|
|
|
+ // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.)
|
|
|
|
|
+ // r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it.
|
|
|
ImVec2 safe_padding = style.DisplaySafeAreaPadding;
|
|
ImVec2 safe_padding = style.DisplaySafeAreaPadding;
|
|
|
ImRect r_outer(GetVisibleRect());
|
|
ImRect r_outer(GetVisibleRect());
|
|
|
r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f));
|
|
r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f));
|
|
|
ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size);
|
|
ImVec2 base_pos_clamped = ImClamp(base_pos, r_outer.Min, r_outer.Max - size);
|
|
|
|
|
+ //GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255));
|
|
|
|
|
+ //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));
|
|
|
|
|
|
|
|
- for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction).
|
|
|
|
|
|
|
+ const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
|
|
|
|
|
+ for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++)
|
|
|
{
|
|
{
|
|
|
- const int dir = (n == -1) ? *last_dir : n;
|
|
|
|
|
- ImRect rect(dir == 0 ? r_inner.Max.x : r_outer.Min.x, dir == 1 ? r_inner.Max.y : r_outer.Min.y, dir == 3 ? r_inner.Min.x : r_outer.Max.x, dir == 2 ? r_inner.Min.y : r_outer.Max.y);
|
|
|
|
|
- if (rect.GetWidth() < size.x || rect.GetHeight() < size.y)
|
|
|
|
|
|
|
+ const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
|
|
|
|
|
+ float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x);
|
|
|
|
|
+ if (avail_w < size.x)
|
|
|
continue;
|
|
continue;
|
|
|
|
|
+ float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y);
|
|
|
|
|
+ if (avail_h < size.y)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ ImVec2 pos;
|
|
|
|
|
+ pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x;
|
|
|
|
|
+ pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y;
|
|
|
*last_dir = dir;
|
|
*last_dir = dir;
|
|
|
- return ImVec2(dir == 0 ? r_inner.Max.x : dir == 3 ? r_inner.Min.x - size.x : base_pos_clamped.x, dir == 1 ? r_inner.Max.y : dir == 2 ? r_inner.Min.y - size.y : base_pos_clamped.y);
|
|
|
|
|
|
|
+ return pos;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Fallback, try to keep within display
|
|
// Fallback, try to keep within display
|
|
|
- *last_dir = -1;
|
|
|
|
|
|
|
+ *last_dir = ImGuiDir_None;
|
|
|
ImVec2 pos = base_pos;
|
|
ImVec2 pos = base_pos;
|
|
|
pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x);
|
|
pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x);
|
|
|
pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y);
|
|
pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y);
|
|
@@ -4382,7 +4398,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
if (window_just_activated_by_user)
|
|
if (window_just_activated_by_user)
|
|
|
{
|
|
{
|
|
|
// Popup first latch mouse position, will position itself when it appears next frame
|
|
// Popup first latch mouse position, will position itself when it appears next frame
|
|
|
- window->AutoPosLastDirection = -1;
|
|
|
|
|
|
|
+ window->AutoPosLastDirection = ImGuiDir_None;
|
|
|
if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api)
|
|
if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api)
|
|
|
window->PosFloat = g.IO.MousePos;
|
|
window->PosFloat = g.IO.MousePos;
|
|
|
}
|
|
}
|
|
@@ -4436,28 +4452,29 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
|
|
|
|
|
// Calculate auto-fit size, handle automatic resize
|
|
// Calculate auto-fit size, handle automatic resize
|
|
|
const ImVec2 size_auto_fit = CalcSizeAutoFit(window);
|
|
const ImVec2 size_auto_fit = CalcSizeAutoFit(window);
|
|
|
|
|
+ ImVec2 size_for_scrollbars_visibility = window->SizeFullAtLastBegin;
|
|
|
if (window->Collapsed)
|
|
if (window->Collapsed)
|
|
|
{
|
|
{
|
|
|
// We still process initial auto-fit on collapsed windows to get a window width,
|
|
// We still process initial auto-fit on collapsed windows to get a window width,
|
|
|
// But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed.
|
|
// But otherwise we don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed.
|
|
|
if (window->AutoFitFramesX > 0)
|
|
if (window->AutoFitFramesX > 0)
|
|
|
- window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
|
|
|
|
|
|
|
+ window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
|
|
|
if (window->AutoFitFramesY > 0)
|
|
if (window->AutoFitFramesY > 0)
|
|
|
- window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
|
|
|
|
|
|
|
+ window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
|
|
|
}
|
|
}
|
|
|
else if (!window_size_set_by_api)
|
|
else if (!window_size_set_by_api)
|
|
|
{
|
|
{
|
|
|
if (flags & ImGuiWindowFlags_AlwaysAutoResize)
|
|
if (flags & ImGuiWindowFlags_AlwaysAutoResize)
|
|
|
{
|
|
{
|
|
|
- window->SizeFull = size_auto_fit;
|
|
|
|
|
|
|
+ window->SizeFull = size_for_scrollbars_visibility = size_auto_fit;
|
|
|
}
|
|
}
|
|
|
else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
|
|
else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
|
|
|
{
|
|
{
|
|
|
// Auto-fit only grows during the first few frames
|
|
// Auto-fit only grows during the first few frames
|
|
|
if (window->AutoFitFramesX > 0)
|
|
if (window->AutoFitFramesX > 0)
|
|
|
- window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
|
|
|
|
|
|
|
+ window->SizeFull.x = size_for_scrollbars_visibility.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
|
|
|
if (window->AutoFitFramesY > 0)
|
|
if (window->AutoFitFramesY > 0)
|
|
|
- window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
|
|
|
|
|
|
|
+ window->SizeFull.y = size_for_scrollbars_visibility.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
|
|
|
MarkIniSettingsDirty(window);
|
|
MarkIniSettingsDirty(window);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -4476,10 +4493,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
// Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size).
|
|
// Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size).
|
|
|
if (!window->Collapsed)
|
|
if (!window->Collapsed)
|
|
|
{
|
|
{
|
|
|
- window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->SizeFullAtLastBegin.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
|
|
|
|
|
- window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->SizeFullAtLastBegin.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
|
|
|
|
|
|
|
+ window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_for_scrollbars_visibility.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
|
|
|
|
|
+ window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_for_scrollbars_visibility.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
|
|
|
if (window->ScrollbarX && !window->ScrollbarY)
|
|
if (window->ScrollbarX && !window->ScrollbarY)
|
|
|
- window->ScrollbarY = (window->SizeContents.y > window->SizeFullAtLastBegin.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
|
|
|
|
|
|
|
+ window->ScrollbarY = (window->SizeContents.y > size_for_scrollbars_visibility.y + style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
|
|
|
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
|
|
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4523,9 +4540,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api)
|
|
if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api)
|
|
|
{
|
|
{
|
|
|
ImVec2 ref_pos = g.IO.MousePos;
|
|
ImVec2 ref_pos = g.IO.MousePos;
|
|
|
- ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Perhaps center on cursor hit-point instead?
|
|
|
|
|
|
|
+ ImRect rect_to_avoid(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24, ref_pos.y + 24); // FIXME: Completely hard-coded. Store boxes in mouse cursor data? Scale? Center on cursor hit-point?
|
|
|
window->PosFloat = FindBestPopupWindowPos(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
|
|
window->PosFloat = FindBestPopupWindowPos(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
|
|
|
- if (window->AutoPosLastDirection == -1)
|
|
|
|
|
|
|
+ if (window->AutoPosLastDirection == ImGuiDir_None)
|
|
|
window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
|
|
window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4603,7 +4620,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size);
|
|
ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size);
|
|
|
resize_rect.FixInverted();
|
|
resize_rect.FixInverted();
|
|
|
bool hovered, held;
|
|
bool hovered, held;
|
|
|
- ButtonBehavior(resize_rect, window->GetID((void*)intptr_t(resize_grip_n)), &hovered, &held, ImGuiButtonFlags_FlattenChilds);
|
|
|
|
|
|
|
+ ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChilds);
|
|
|
if (hovered || held)
|
|
if (hovered || held)
|
|
|
g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
|
|
g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
|
|
|
|
|
|
|
@@ -4629,7 +4646,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
|
const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise
|
|
const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise
|
|
|
bool hovered, held;
|
|
bool hovered, held;
|
|
|
ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE);
|
|
ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE);
|
|
|
- ButtonBehavior(border_rect, window->GetID((void*)intptr_t(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds);
|
|
|
|
|
|
|
+ ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n+4)), &hovered, &held, ImGuiButtonFlags_FlattenChilds);
|
|
|
if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held)
|
|
if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held)
|
|
|
{
|
|
{
|
|
|
g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
|
|
g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
|