Merge branch 'master' into viewport

# Conflicts:
#	imgui.cpp
#	imgui_internal.h
This commit is contained in:
omar 2018-04-11 21:25:44 +02:00
commit e25da4230b
5 changed files with 93 additions and 67 deletions

View File

@ -41,11 +41,13 @@ VERSION 1.61 WIP
Breaking Changes: Breaking Changes:
(IN PROGRESS, WILL ADD TO THIS LIST AS WE WORK ON 1.61) (IN PROGRESS, WILL ADD TO THIS LIST AS WE WORK ON 1.61)
- ...
- Misc: IM_DELETE() helper function added in 1.60 doesn't clear the input _pointer_ reference, more consistent with expectation and allows passing r-value.
Other Changes: Other Changes:
(IN PROGRESS, WILL ADD TO THIS LIST AS WE WORK ON 1.61) (IN PROGRESS, WILL ADD TO THIS LIST AS WE WORK ON 1.61)
- ...
- Settings: Fixed saving an empty .ini file if CreateContext/DestroyContext are called without a single call to NewFrame(). (#1741)
----------------------------------------------------------------------- -----------------------------------------------------------------------
@ -199,6 +201,7 @@ Other Changes:
- Misc: ImVec2: added [] operator. This is becoming desirable for some code working of either axes independently. Better adding it sooner than later. - Misc: ImVec2: added [] operator. This is becoming desirable for some code working of either axes independently. Better adding it sooner than later.
- Misc: NewFrame(): Added an assert to detect incorrect filling of the io.KeyMap[] array earlier. (#1555) - Misc: NewFrame(): Added an assert to detect incorrect filling of the io.KeyMap[] array earlier. (#1555)
- Misc: Added IM_OFFSETOF() helper in imgui.h (previously was in imgui_internal.h) - Misc: Added IM_OFFSETOF() helper in imgui.h (previously was in imgui_internal.h)
- Misc: Added IM_NEW(), IM_DELETE() helpers in imgui.h (previously were in imgui_internal.h)
- Misc: Added obsolete redirection function GetItemsLineHeightWithSpacing() (which redirects to GetFrameHeightWithSpacing()), as intended and stated in docs of 1.53. - Misc: Added obsolete redirection function GetItemsLineHeightWithSpacing() (which redirects to GetFrameHeightWithSpacing()), as intended and stated in docs of 1.53.
- Misc: Added misc/natvis/imgui.natvis for visual studio debugger users to easily visualize imgui internal types. Added to examples projects. - Misc: Added misc/natvis/imgui.natvis for visual studio debugger users to easily visualize imgui internal types. Added to examples projects.
- Misc: Added IMGUI_USER_CONFIG to define a custom configuration filename. (#255, #1573, #1144, #41) - Misc: Added IMGUI_USER_CONFIG to define a custom configuration filename. (#255, #1573, #1144, #41)

145
imgui.cpp
View File

@ -262,6 +262,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. 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. Also read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2018/04/09 (1.61) - IM_DELETE() helper function added in 1.60 doesn't clear the input _pointer_ reference, more consistent with expectation and allows passing r-value.
- 2018/03/20 (1.60) - Renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, _not_ used by core and only honored by some binding ahead of merging the Nav branch). - 2018/03/20 (1.60) - Renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, _not_ used by core and only honored by some binding ahead of merging the Nav branch).
- 2018/03/12 (1.60) - Removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered as the closing cross uses regular button colors now. - 2018/03/12 (1.60) - Removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered as the closing cross uses regular button colors now.
- 2018/03/08 (1.60) - Changed ImFont::DisplayOffset.y to default to 0 instead of +1. Fixed rounding of Ascent/Descent to match TrueType renderer. If you were adding or subtracting to ImFont::DisplayOffset check if your fonts are correctly aligned vertically. - 2018/03/08 (1.60) - Changed ImFont::DisplayOffset.y to default to 0 instead of +1. Fixed rounding of Ascent/Descent to match TrueType renderer. If you were adding or subtracting to ImFont::DisplayOffset check if your fonts are correctly aligned vertically.
@ -739,7 +740,6 @@ static void SaveIniSettingsToMemory(ImVector<char>& out_buf);
static void MarkIniSettingsDirty(ImGuiWindow* window); static void MarkIniSettingsDirty(ImGuiWindow* window);
static void ClosePopupToLevel(int remaining); static void ClosePopupToLevel(int remaining);
static ImGuiWindow* GetFrontMostModalRootWindow();
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);
@ -1928,6 +1928,7 @@ bool ImGuiListClipper::Step()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
: DrawListInst(&context->DrawListSharedData)
{ {
Name = ImStrdup(name); Name = ImStrdup(name);
ID = ImHash(name, 0); ID = ImHash(name, 0);
@ -1972,7 +1973,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
ItemWidthDefault = 0.0f; ItemWidthDefault = 0.0f;
FontWindowScale = FontDpiScale = 1.0f; FontWindowScale = FontDpiScale = 1.0f;
DrawList = IM_NEW(ImDrawList)(&context->DrawListSharedData); DrawList = &DrawListInst;
DrawList->_OwnerName = Name; DrawList->_OwnerName = Name;
ParentWindow = NULL; ParentWindow = NULL;
RootWindow = NULL; RootWindow = NULL;
@ -1991,7 +1992,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
ImGuiWindow::~ImGuiWindow() ImGuiWindow::~ImGuiWindow()
{ {
IM_DELETE(DrawList); IM_ASSERT(DrawList == &DrawListInst);
IM_DELETE(Name); IM_DELETE(Name);
for (int i = 0; i != ColumnsStorage.Size; i++) for (int i = 0; i != ColumnsStorage.Size; i++)
ColumnsStorage[i].~ImGuiColumnsSet(); ColumnsStorage[i].~ImGuiColumnsSet();
@ -3710,7 +3711,7 @@ void ImGui::NewFrameUpdateHoveredWindowAndCaptureFlags()
IM_ASSERT(g.HoveredWindow == NULL || g.HoveredWindow == g.MovingWindow || g.HoveredWindow->Viewport == g.MousePosViewport); IM_ASSERT(g.HoveredWindow == NULL || g.HoveredWindow == g.MovingWindow || g.HoveredWindow->Viewport == g.MousePosViewport);
// Modal windows prevents cursor from hovering behind them. // Modal windows prevents cursor from hovering behind them.
ImGuiWindow* modal_window = GetFrontMostModalRootWindow(); ImGuiWindow* modal_window = GetFrontMostPopupModal();
if (modal_window) if (modal_window)
if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window)) if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
g.HoveredRootWindow = g.HoveredWindow = NULL; g.HoveredRootWindow = g.HoveredWindow = NULL;
@ -3882,13 +3883,13 @@ void ImGui::NewFrame()
g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime; g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering) // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
NewFrameUpdateMovingWindow(); NewFrameUpdateMovingWindow();
NewFrameUpdateHoveredWindowAndCaptureFlags(); NewFrameUpdateHoveredWindowAndCaptureFlags();
if (GetFrontMostModalRootWindow() != NULL) if (GetFrontMostPopupModal() != NULL)
g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f); g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f);
else else
g.ModalWindowDarkeningRatio = 0.0f; g.ModalWindowDarkeningRatio = 0.0f;
@ -4086,12 +4087,15 @@ void ImGui::Shutdown(ImGuiContext* context)
// The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame)
if (g.IO.Fonts && g.FontAtlasOwnedByContext) if (g.IO.Fonts && g.FontAtlasOwnedByContext)
IM_DELETE(g.IO.Fonts); IM_DELETE(g.IO.Fonts);
g.IO.Fonts = NULL;
// Cleanup of other data are conditional on actually having initialize ImGui. // Cleanup of other data are conditional on actually having initialize ImGui.
if (!g.Initialized) if (!g.Initialized)
return; return;
SaveIniSettingsToDisk(g.IO.IniFilename); // Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file)
if (g.SettingsLoaded)
SaveIniSettingsToDisk(g.IO.IniFilename);
// Destroy platform windows // Destroy platform windows
ImGuiContext* backup_context = ImGui::GetCurrentContext(); ImGuiContext* backup_context = ImGui::GetCurrentContext();
@ -4112,8 +4116,6 @@ void ImGui::Shutdown(ImGuiContext* context)
g.HoveredRootWindow = NULL; g.HoveredRootWindow = NULL;
g.ActiveIdWindow = NULL; g.ActiveIdWindow = NULL;
g.MovingWindow = NULL; g.MovingWindow = NULL;
for (int i = 0; i < g.SettingsWindows.Size; i++)
IM_DELETE(g.SettingsWindows[i].Name);
g.ColorModifiers.clear(); g.ColorModifiers.clear();
g.StyleModifiers.clear(); g.StyleModifiers.clear();
g.FontStack.clear(); g.FontStack.clear();
@ -4128,6 +4130,8 @@ void ImGui::Shutdown(ImGuiContext* context)
g.InputTextState.InitialText.clear(); g.InputTextState.InitialText.clear();
g.InputTextState.TempTextBuffer.clear(); g.InputTextState.TempTextBuffer.clear();
for (int i = 0; i < g.SettingsWindows.Size; i++)
IM_DELETE(g.SettingsWindows[i].Name);
g.SettingsWindows.clear(); g.SettingsWindows.clear();
g.SettingsHandlers.clear(); g.SettingsHandlers.clear();
@ -4138,6 +4142,7 @@ void ImGui::Shutdown(ImGuiContext* context)
} }
if (g.LogClipboard) if (g.LogClipboard)
IM_DELETE(g.LogClipboard); IM_DELETE(g.LogClipboard);
g.LogClipboard = NULL;
g.Initialized = false; g.Initialized = false;
} }
@ -4465,7 +4470,7 @@ void ImGui::EndFrame()
if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove))
g.MovingWindow = g.HoveredWindow; g.MovingWindow = g.HoveredWindow;
} }
else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) else if (g.NavWindow != NULL && GetFrontMostPopupModal() == NULL)
{ {
// Clicking on void disable focus // Clicking on void disable focus
FocusWindow(NULL); FocusWindow(NULL);
@ -4478,7 +4483,7 @@ void ImGui::EndFrame()
{ {
// Find the top-most window between HoveredWindow and the front most Modal Window. // Find the top-most window between HoveredWindow and the front most Modal Window.
// This is where we can trim the popup stack. // This is where we can trim the popup stack.
ImGuiWindow* modal = GetFrontMostModalRootWindow(); ImGuiWindow* modal = GetFrontMostPopupModal();
bool hovered_window_above_modal = false; bool hovered_window_above_modal = false;
if (modal == NULL) if (modal == NULL)
hovered_window_above_modal = true; hovered_window_above_modal = true;
@ -5495,7 +5500,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window)
ClosePopupToLevel(n); ClosePopupToLevel(n);
} }
static ImGuiWindow* GetFrontMostModalRootWindow() ImGuiWindow* ImGui::GetFrontMostPopupModal()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
for (int n = g.OpenPopupStack.Size-1; n >= 0; n--) for (int n = g.OpenPopupStack.Size-1; n >= 0; n--)
@ -5818,15 +5823,18 @@ enum ImGuiPopupPositionPolicy
ImGuiPopupPositionPolicy_ComboBox ImGuiPopupPositionPolicy_ComboBox
}; };
static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window, const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default) static ImRect FindScreenRectForWindow(ImGuiWindow* window)
{
ImVec2 padding = GImGui->Style.DisplaySafeAreaPadding;
ImRect r_screen(ImGui::GetViewportRect(window));
r_screen.Expand(ImVec2((window->Size.x - r_screen.GetWidth() > padding.x * 2) ? -padding.x : 0.0f, (window->Size.y - r_screen.GetHeight() > padding.y * 2) ? -padding.y : 0.0f));
return r_screen;
}
// 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.
static ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default)
{ {
const ImGuiStyle& style = GImGui->Style;
// 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;
ImRect r_outer(ImGui::GetViewportRect(window));
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(ref_pos, r_outer.Min, r_outer.Max - size); ImVec2 base_pos_clamped = ImClamp(ref_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_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)); //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));
@ -5878,6 +5886,49 @@ static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window, const ImVec2& ref_p
return pos; return pos;
} }
static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
ImRect r_screen = FindScreenRectForWindow(window);
if (window->Flags & ImGuiWindowFlags_ChildMenu)
{
// Child menus typically request _any_ position within the parent menu item, and then our FindBestPopupWindowPos() function will move the new menu outside the parent bounds.
// This is how we end up with child menus appearing (most-commonly) on the right of the parent menu.
IM_ASSERT(g.CurrentWindow == window);
ImGuiWindow* parent_menu = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2];
float horizontal_overlap = g.Style.ItemSpacing.x; // We want some overlap to convey the relative depth of each menu (currently the amount of overlap is hard-coded to style.ItemSpacing.x).
ImRect r_avoid;
if (parent_menu->DC.MenuBarAppending)
r_avoid = ImRect(-FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight(), FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight() + parent_menu->MenuBarHeight());
else
r_avoid = ImRect(parent_menu->Pos.x + horizontal_overlap, -FLT_MAX, parent_menu->Pos.x + parent_menu->Size.x - horizontal_overlap - parent_menu->ScrollbarSizes.x, FLT_MAX);
return FindBestWindowPosForPopupEx(window->PosFloat, window->Size, &window->AutoPosLastDirection, r_screen, r_avoid);
}
if (window->Flags & ImGuiWindowFlags_Popup)
{
ImRect r_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1);
return FindBestWindowPosForPopupEx(window->PosFloat, window->Size, &window->AutoPosLastDirection, r_screen, r_avoid);
}
if (window->Flags & ImGuiWindowFlags_Tooltip)
{
// Position tooltip (always follows mouse)
float sc = g.Style.MouseCursorScale;
ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos;
ImRect r_avoid;
if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos))
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
else
r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
ImVec2 pos = FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_screen, r_avoid);
if (window->AutoPosLastDirection == ImGuiDir_None)
pos = 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.
return pos;
}
IM_ASSERT(0);
return window->Pos;
}
static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled) static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled)
{ {
window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags); window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags);
@ -6191,9 +6242,9 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
struct ImGuiResizeGripDef struct ImGuiResizeGripDef
{ {
ImVec2 CornerPos; ImVec2 CornerPos;
ImVec2 InnerDir; ImVec2 InnerDir;
int AngleMin12, AngleMax12; int AngleMin12, AngleMax12;
}; };
const ImGuiResizeGripDef resize_grip_def[4] = const ImGuiResizeGripDef resize_grip_def[4] =
@ -6598,44 +6649,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0);
if (window_pos_with_pivot) if (window_pos_with_pivot)
{ SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); // Position given a pivot (e.g. for centering)
// Position given a pivot (e.g. for centering) else if ((flags & ImGuiWindowFlags_ChildMenu) != 0)
SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); window->PosFloat = FindBestWindowPosForPopup(window);
}
else if (flags & ImGuiWindowFlags_ChildMenu)
{
// Child menus typically request _any_ position within the parent menu item, and then our FindBestPopupWindowPos() function will move the new menu outside the parent bounds.
// This is how we end up with child menus appearing (most-commonly) on the right of the parent menu.
IM_ASSERT(window_pos_set_by_api);
float horizontal_overlap = style.ItemSpacing.x; // We want some overlap to convey the relative depth of each popup (currently the amount of overlap it is hard-coded to style.ItemSpacing.x, may need to introduce another style value).
ImGuiWindow* parent_menu = parent_window_in_stack;
ImRect rect_to_avoid;
if (parent_menu->DC.MenuBarAppending)
rect_to_avoid = ImRect(-FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight(), FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight() + parent_menu->MenuBarHeight());
else
rect_to_avoid = ImRect(parent_menu->Pos.x + horizontal_overlap, -FLT_MAX, parent_menu->Pos.x + parent_menu->Size.x - horizontal_overlap - parent_menu->ScrollbarSizes.x, FLT_MAX);
window->PosFloat = FindBestWindowPosForPopup(window, window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
}
else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize)
{ window->PosFloat = FindBestWindowPosForPopup(window);
ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); else if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip)
window->PosFloat = FindBestWindowPosForPopup(window, window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); window->PosFloat = FindBestWindowPosForPopup(window);
}
// Position tooltip (always follows mouse)
if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip)
{
float sc = g.Style.MouseCursorScale;
ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos;
ImRect rect_to_avoid;
if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos))
rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
else
rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
window->PosFloat = FindBestWindowPosForPopup(window, ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid);
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.
}
// Clamp position so window stays visible within its viewport // Clamp position so window stays visible within its viewport
ImRect viewport_rect(GetViewportRect(window)); ImRect viewport_rect(GetViewportRect(window));
@ -6702,7 +6722,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
PushClipRect(viewport_rect.Min, viewport_rect.Max, true); PushClipRect(viewport_rect.Min, viewport_rect.Max, true);
// Draw modal window background (darkens what is behind them, all viewports) // Draw modal window background (darkens what is behind them, all viewports)
if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow() && window->HiddenFrames <= 0) if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostPopupModal() && window->HiddenFrames <= 0)
for (int viewport_n = 0; viewport_n < g.Viewports.Size; viewport_n++) for (int viewport_n = 0; viewport_n < g.Viewports.Size; viewport_n++)
{ {
ImGuiViewportP* viewport = g.Viewports[viewport_n]; ImGuiViewportP* viewport = g.Viewports[viewport_n];
@ -11516,7 +11536,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents));
if (flags & ImGuiComboFlags_PopupAlignLeft) if (flags & ImGuiComboFlags_PopupAlignLeft)
popup_window->AutoPosLastDirection = ImGuiDir_Left; popup_window->AutoPosLastDirection = ImGuiDir_Left;
ImVec2 pos = FindBestWindowPosForPopup(popup_window, frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiPopupPositionPolicy_ComboBox); ImRect r_outer = FindScreenRectForWindow(popup_window);
ImVec2 pos = FindBestWindowPosForPopupEx(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, r_outer, frame_bb, ImGuiPopupPositionPolicy_ComboBox);
SetNextWindowPos(pos); SetNextWindowPos(pos);
} }

View File

@ -1236,7 +1236,7 @@ inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; }
inline void operator delete(void*, ImNewDummy, void*) {} // This is only required so we can use the symetrical new() inline void operator delete(void*, ImNewDummy, void*) {} // This is only required so we can use the symetrical new()
#define IM_PLACEMENT_NEW(_PTR) new(ImNewDummy(), _PTR) #define IM_PLACEMENT_NEW(_PTR) new(ImNewDummy(), _PTR)
#define IM_NEW(_TYPE) new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE #define IM_NEW(_TYPE) new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE
template<typename T> void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p); p = NULL; } } template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } }
// Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. // Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame.
// Usage: static ImGuiOnceUponAFrame oaf; if (oaf) ImGui::Text("This will be called only once per frame"); // Usage: static ImGuiOnceUponAFrame oaf; if (oaf) ImGui::Text("This will be called only once per frame");

View File

@ -1733,7 +1733,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas));
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
IM_ASSERT(font_offset >= 0); IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
{ {
atlas->TexWidth = atlas->TexHeight = 0; // Reset output on failure atlas->TexWidth = atlas->TexHeight = 0; // Reset output on failure

View File

@ -991,7 +991,8 @@ struct IMGUI_API ImGuiWindow
ImVector<ImGuiColumnsSet> ColumnsStorage; ImVector<ImGuiColumnsSet> ColumnsStorage;
float FontWindowScale; // User scale multiplier per-window float FontWindowScale; // User scale multiplier per-window
float FontDpiScale; float FontDpiScale;
ImDrawList* DrawList; ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
ImDrawList DrawListInst;
ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL. ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL.
ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window.
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active. ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
@ -1109,6 +1110,7 @@ namespace ImGui
IMGUI_API bool IsPopupOpen(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id);
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, bool override_previous_tooltip = true); IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true);
IMGUI_API ImGuiWindow* GetFrontMostPopupModal();
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
IMGUI_API void NavMoveRequestCancel(); IMGUI_API void NavMoveRequestCancel();