|
@@ -204,11 +204,14 @@
|
|
|
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.
|
|
|
|
|
|
|
|
- - 2016/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency.
|
|
|
|
|
- - 2016/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix.
|
|
|
|
|
|
|
+ - 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).
|
|
|
|
|
+ - renamed IsMouseHoveringWindow() to IsWindowRectHovered() for consistency. Kept inline redirection function (will obsolete).
|
|
|
|
|
+ - 2017/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency.
|
|
|
|
|
+ - 2017/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix.
|
|
|
- 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame.
|
|
- 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame.
|
|
|
- 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow() from (const char*,int buttons,bool also_over_items) to (const char*,int buttons,bool also_over_items). Note that most calls relied on default parameters completely.
|
|
- 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow() from (const char*,int buttons,bool also_over_items) to (const char*,int buttons,bool also_over_items). Note that most calls relied on default parameters completely.
|
|
|
- - 2017/08/13 (1.51) - renamed ImGuiCol_Columns_*** to ImGuiCol_Separator_***
|
|
|
|
|
|
|
+ - 2017/08/13 (1.51) - renamed ImGuiCol_Columns*** to ImGuiCol_Separator***. Kept redirection enums (will obsolete).
|
|
|
- 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete).
|
|
- 2017/08/11 (1.51) - renamed ImGuiSetCond_*** types and flags to ImGuiCond_***. Kept redirection enums (will obsolete).
|
|
|
- 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton().
|
|
- 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton().
|
|
|
- 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu.
|
|
- 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu.
|
|
@@ -620,7 +623,7 @@ static ImGuiIniData* FindWindowSettings(const char* name);
|
|
|
static ImGuiIniData* AddWindowSettings(const char* name);
|
|
static ImGuiIniData* AddWindowSettings(const char* name);
|
|
|
static void LoadIniSettingsFromDisk(const char* ini_filename);
|
|
static void LoadIniSettingsFromDisk(const char* ini_filename);
|
|
|
static void SaveIniSettingsToDisk(const char* ini_filename);
|
|
static void SaveIniSettingsToDisk(const char* ini_filename);
|
|
|
-static void MarkIniSettingsDirty();
|
|
|
|
|
|
|
+static void MarkIniSettingsDirty(ImGuiWindow* window);
|
|
|
|
|
|
|
|
static ImRect GetVisibleRect();
|
|
static ImRect GetVisibleRect();
|
|
|
|
|
|
|
@@ -747,6 +750,7 @@ ImGuiIO::ImGuiIO()
|
|
|
// Most fields are initialized with zero
|
|
// Most fields are initialized with zero
|
|
|
memset(this, 0, sizeof(*this));
|
|
memset(this, 0, sizeof(*this));
|
|
|
|
|
|
|
|
|
|
+ // Settings
|
|
|
DisplaySize = ImVec2(-1.0f, -1.0f);
|
|
DisplaySize = ImVec2(-1.0f, -1.0f);
|
|
|
DeltaTime = 1.0f/60.0f;
|
|
DeltaTime = 1.0f/60.0f;
|
|
|
IniSavingRate = 5.0f;
|
|
IniSavingRate = 5.0f;
|
|
@@ -779,6 +783,7 @@ ImGuiIO::ImGuiIO()
|
|
|
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
|
|
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
|
|
|
ClipboardUserData = NULL;
|
|
ClipboardUserData = NULL;
|
|
|
ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
|
|
ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
|
|
|
|
|
+ ImeWindowHandle = NULL;
|
|
|
|
|
|
|
|
// Set OS X style defaults based on __APPLE__ compile time flag
|
|
// Set OS X style defaults based on __APPLE__ compile time flag
|
|
|
#ifdef __APPLE__
|
|
#ifdef __APPLE__
|
|
@@ -1778,6 +1783,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
|
|
|
PopupId = 0;
|
|
PopupId = 0;
|
|
|
AutoFitFramesX = AutoFitFramesY = -1;
|
|
AutoFitFramesX = AutoFitFramesY = -1;
|
|
|
AutoFitOnlyGrows = false;
|
|
AutoFitOnlyGrows = false;
|
|
|
|
|
+ AutoFitChildAxises = 0x00;
|
|
|
AutoPosLastDirection = -1;
|
|
AutoPosLastDirection = -1;
|
|
|
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;
|
|
@@ -1939,7 +1945,6 @@ bool ImGui::IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
|
-
|
|
|
|
|
if (!bb.Overlaps(window->ClipRect))
|
|
if (!bb.Overlaps(window->ClipRect))
|
|
|
if (!id || *id != GImGui->ActiveId)
|
|
if (!id || *id != GImGui->ActiveId)
|
|
|
if (clip_even_when_logged || !g.LogEnabled)
|
|
if (clip_even_when_logged || !g.LogEnabled)
|
|
@@ -2151,7 +2156,8 @@ void ImGui::NewFrame()
|
|
|
g.RenderDrawData.CmdLists = NULL;
|
|
g.RenderDrawData.CmdLists = NULL;
|
|
|
g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0;
|
|
g.RenderDrawData.CmdListsCount = g.RenderDrawData.TotalVtxCount = g.RenderDrawData.TotalIdxCount = 0;
|
|
|
|
|
|
|
|
- // Update inputs state
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Update mouse input state
|
|
|
if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0)
|
|
if (g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0)
|
|
|
g.IO.MousePos = ImVec2(-9999.0f, -9999.0f);
|
|
g.IO.MousePos = ImVec2(-9999.0f, -9999.0f);
|
|
|
if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta
|
|
if ((g.IO.MousePos.x < 0 && g.IO.MousePos.y < 0) || (g.IO.MousePosPrev.x < 0 && g.IO.MousePosPrev.y < 0)) // if mouse just appeared or disappeared (negative coordinate) we cancel out movement in MouseDelta
|
|
@@ -2218,7 +2224,7 @@ void ImGui::NewFrame()
|
|
|
{
|
|
{
|
|
|
g.MovedWindow->PosFloat += g.IO.MouseDelta;
|
|
g.MovedWindow->PosFloat += g.IO.MouseDelta;
|
|
|
if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings) && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f))
|
|
if (!(g.MovedWindow->Flags & ImGuiWindowFlags_NoSavedSettings) && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f))
|
|
|
- MarkIniSettingsDirty();
|
|
|
|
|
|
|
+ MarkIniSettingsDirty(g.MovedWindow);
|
|
|
}
|
|
}
|
|
|
FocusWindow(g.MovedWindow);
|
|
FocusWindow(g.MovedWindow);
|
|
|
}
|
|
}
|
|
@@ -2296,23 +2302,20 @@ void ImGui::NewFrame()
|
|
|
if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed)
|
|
if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed)
|
|
|
{
|
|
{
|
|
|
ImGuiWindow* window = g.HoveredWindow;
|
|
ImGuiWindow* window = g.HoveredWindow;
|
|
|
- if (g.IO.KeyCtrl)
|
|
|
|
|
|
|
+ if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
|
|
|
{
|
|
{
|
|
|
- if (g.IO.FontAllowUserScaling)
|
|
|
|
|
- {
|
|
|
|
|
- // Zoom / Scale window
|
|
|
|
|
- float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
|
|
|
|
|
- float scale = new_font_scale / window->FontWindowScale;
|
|
|
|
|
- window->FontWindowScale = new_font_scale;
|
|
|
|
|
-
|
|
|
|
|
- const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
|
|
|
|
|
- window->Pos += offset;
|
|
|
|
|
- window->PosFloat += offset;
|
|
|
|
|
- window->Size *= scale;
|
|
|
|
|
- window->SizeFull *= scale;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // Zoom / Scale window
|
|
|
|
|
+ const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
|
|
|
|
|
+ const float scale = new_font_scale / window->FontWindowScale;
|
|
|
|
|
+ window->FontWindowScale = new_font_scale;
|
|
|
|
|
+
|
|
|
|
|
+ const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
|
|
|
|
|
+ window->Pos += offset;
|
|
|
|
|
+ window->PosFloat += offset;
|
|
|
|
|
+ window->Size *= scale;
|
|
|
|
|
+ window->SizeFull *= scale;
|
|
|
}
|
|
}
|
|
|
- else if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
|
|
|
|
|
|
|
+ else if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
|
|
|
{
|
|
{
|
|
|
// Scroll
|
|
// Scroll
|
|
|
const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
|
|
const int scroll_lines = (window->Flags & ImGuiWindowFlags_ComboBox) ? 3 : 5;
|
|
@@ -2322,8 +2325,8 @@ void ImGui::NewFrame()
|
|
|
|
|
|
|
|
// Pressing TAB activate widget focus
|
|
// Pressing TAB activate widget focus
|
|
|
// NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus.
|
|
// NB: Don't discard FocusedWindow if it isn't active, so that a window that go on/off programatically won't lose its keyboard focus.
|
|
|
- if (g.ActiveId == 0 && g.FocusedWindow != NULL && g.FocusedWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false))
|
|
|
|
|
- g.FocusedWindow->FocusIdxTabRequestNext = 0;
|
|
|
|
|
|
|
+ if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false))
|
|
|
|
|
+ g.NavWindow->FocusIdxTabRequestNext = 0;
|
|
|
|
|
|
|
|
// Mark all windows as not visible
|
|
// Mark all windows as not visible
|
|
|
for (int i = 0; i != g.Windows.Size; i++)
|
|
for (int i = 0; i != g.Windows.Size; i++)
|
|
@@ -2335,7 +2338,7 @@ void ImGui::NewFrame()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Closing the focused window restore focus to the first active root window in descending z-order
|
|
// Closing the focused window restore focus to the first active root window in descending z-order
|
|
|
- if (g.FocusedWindow && !g.FocusedWindow->WasActive)
|
|
|
|
|
|
|
+ if (g.NavWindow && !g.NavWindow->WasActive)
|
|
|
for (int i = g.Windows.Size-1; i >= 0; i--)
|
|
for (int i = g.Windows.Size-1; i >= 0; i--)
|
|
|
if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow))
|
|
if (g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow))
|
|
|
{
|
|
{
|
|
@@ -2378,7 +2381,7 @@ void ImGui::Shutdown()
|
|
|
g.WindowsSortBuffer.clear();
|
|
g.WindowsSortBuffer.clear();
|
|
|
g.CurrentWindow = NULL;
|
|
g.CurrentWindow = NULL;
|
|
|
g.CurrentWindowStack.clear();
|
|
g.CurrentWindowStack.clear();
|
|
|
- g.FocusedWindow = NULL;
|
|
|
|
|
|
|
+ g.NavWindow = NULL;
|
|
|
g.HoveredWindow = NULL;
|
|
g.HoveredWindow = NULL;
|
|
|
g.HoveredRootWindow = NULL;
|
|
g.HoveredRootWindow = NULL;
|
|
|
g.ActiveIdWindow = NULL;
|
|
g.ActiveIdWindow = NULL;
|
|
@@ -2396,11 +2399,7 @@ void ImGui::Shutdown()
|
|
|
for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++)
|
|
for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++)
|
|
|
g.RenderDrawLists[i].clear();
|
|
g.RenderDrawLists[i].clear();
|
|
|
g.OverlayDrawList.ClearFreeMemory();
|
|
g.OverlayDrawList.ClearFreeMemory();
|
|
|
- if (g.PrivateClipboard)
|
|
|
|
|
- {
|
|
|
|
|
- ImGui::MemFree(g.PrivateClipboard);
|
|
|
|
|
- g.PrivateClipboard = NULL;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ g.PrivateClipboard.clear();
|
|
|
g.InputTextState.Text.clear();
|
|
g.InputTextState.Text.clear();
|
|
|
g.InputTextState.InitialText.clear();
|
|
g.InputTextState.InitialText.clear();
|
|
|
g.InputTextState.TempTextBuffer.clear();
|
|
g.InputTextState.TempTextBuffer.clear();
|
|
@@ -2535,11 +2534,12 @@ static void SaveIniSettingsToDisk(const char* ini_filename)
|
|
|
fclose(f);
|
|
fclose(f);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void MarkIniSettingsDirty()
|
|
|
|
|
|
|
+static void MarkIniSettingsDirty(ImGuiWindow* window)
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- if (g.SettingsDirtyTimer <= 0.0f)
|
|
|
|
|
- g.SettingsDirtyTimer = g.IO.IniSavingRate;
|
|
|
|
|
|
|
+ if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
|
|
|
|
|
+ if (g.SettingsDirtyTimer <= 0.0f)
|
|
|
|
|
+ g.SettingsDirtyTimer = g.IO.IniSavingRate;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Add a more explicit sort order in the window structure.
|
|
// FIXME: Add a more explicit sort order in the window structure.
|
|
@@ -2658,7 +2658,7 @@ void ImGui::EndFrame()
|
|
|
// Click to focus window and start moving (after we're done with all our widgets)
|
|
// Click to focus window and start moving (after we're done with all our widgets)
|
|
|
if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0])
|
|
if (g.ActiveId == 0 && g.HoveredId == 0 && g.IO.MouseClicked[0])
|
|
|
{
|
|
{
|
|
|
- if (!(g.FocusedWindow && !g.FocusedWindow->WasActive && g.FocusedWindow->Active)) // Unless we just made a popup appear
|
|
|
|
|
|
|
+ if (!(g.NavWindow && !g.NavWindow->WasActive && g.NavWindow->Active)) // Unless we just made a popup appear
|
|
|
{
|
|
{
|
|
|
if (g.HoveredRootWindow != NULL)
|
|
if (g.HoveredRootWindow != NULL)
|
|
|
{
|
|
{
|
|
@@ -2670,7 +2670,7 @@ void ImGui::EndFrame()
|
|
|
SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow);
|
|
SetActiveID(g.MovedWindowMoveId, g.HoveredRootWindow);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- else if (g.FocusedWindow != NULL && GetFrontMostModalRootWindow() == NULL)
|
|
|
|
|
|
|
+ else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL)
|
|
|
{
|
|
{
|
|
|
// Clicking on void disable focus
|
|
// Clicking on void disable focus
|
|
|
FocusWindow(NULL);
|
|
FocusWindow(NULL);
|
|
@@ -2689,6 +2689,7 @@ void ImGui::EndFrame()
|
|
|
continue;
|
|
continue;
|
|
|
AddWindowToSortedBuffer(g.WindowsSortBuffer, window);
|
|
AddWindowToSortedBuffer(g.WindowsSortBuffer, window);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong
|
|
IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong
|
|
|
g.Windows.swap(g.WindowsSortBuffer);
|
|
g.Windows.swap(g.WindowsSortBuffer);
|
|
|
|
|
|
|
@@ -3108,20 +3109,14 @@ bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool c
|
|
|
// Clip
|
|
// Clip
|
|
|
ImRect rect_clipped(r_min, r_max);
|
|
ImRect rect_clipped(r_min, r_max);
|
|
|
if (clip)
|
|
if (clip)
|
|
|
- rect_clipped.Clip(window->ClipRect);
|
|
|
|
|
|
|
+ rect_clipped.ClipWith(window->ClipRect);
|
|
|
|
|
|
|
|
// Expand for touch input
|
|
// Expand for touch input
|
|
|
const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding);
|
|
const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding);
|
|
|
return rect_for_touch.Contains(g.IO.MousePos);
|
|
return rect_for_touch.Contains(g.IO.MousePos);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool ImGui::IsMouseHoveringWindow()
|
|
|
|
|
-{
|
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
|
- return g.HoveredWindow == g.CurrentWindow;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-bool ImGui::IsMouseHoveringAnyWindow()
|
|
|
|
|
|
|
+bool ImGui::IsAnyWindowHovered()
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
return g.HoveredWindow != NULL;
|
|
return g.HoveredWindow != NULL;
|
|
@@ -3285,7 +3280,7 @@ bool ImGui::IsItemHovered()
|
|
|
return window->DC.LastItemHoveredAndUsable;
|
|
return window->DC.LastItemHoveredAndUsable;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool ImGui::IsItemHoveredRect()
|
|
|
|
|
|
|
+bool ImGui::IsItemRectHovered()
|
|
|
{
|
|
{
|
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
|
return window->DC.LastItemHoveredRect;
|
|
return window->DC.LastItemHoveredRect;
|
|
@@ -3320,8 +3315,7 @@ bool ImGui::IsAnyItemActive()
|
|
|
bool ImGui::IsItemVisible()
|
|
bool ImGui::IsItemVisible()
|
|
|
{
|
|
{
|
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
|
- ImRect r(window->ClipRect);
|
|
|
|
|
- return r.Overlaps(window->DC.LastItemRect);
|
|
|
|
|
|
|
+ return window->ClipRect.Overlaps(window->DC.LastItemRect);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
|
|
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
|
|
@@ -3445,7 +3439,7 @@ static void CloseInactivePopups()
|
|
|
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
|
|
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
|
|
|
// Don't close our own child popup windows
|
|
// Don't close our own child popup windows
|
|
|
int n = 0;
|
|
int n = 0;
|
|
|
- if (g.FocusedWindow)
|
|
|
|
|
|
|
+ if (g.NavWindow)
|
|
|
{
|
|
{
|
|
|
for (n = 0; n < g.OpenPopupStack.Size; n++)
|
|
for (n = 0; n < g.OpenPopupStack.Size; n++)
|
|
|
{
|
|
{
|
|
@@ -3458,7 +3452,7 @@ static void CloseInactivePopups()
|
|
|
|
|
|
|
|
bool has_focus = false;
|
|
bool has_focus = false;
|
|
|
for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++)
|
|
for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++)
|
|
|
- has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.FocusedWindow->RootWindow);
|
|
|
|
|
|
|
+ has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.NavWindow->RootWindow);
|
|
|
if (!has_focus)
|
|
if (!has_focus)
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -3500,7 +3494,7 @@ void ImGui::CloseCurrentPopup()
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
int popup_idx = g.CurrentPopupStack.Size - 1;
|
|
int popup_idx = g.CurrentPopupStack.Size - 1;
|
|
|
- if (popup_idx < 0 || popup_idx > g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId)
|
|
|
|
|
|
|
+ if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId)
|
|
|
return;
|
|
return;
|
|
|
while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu))
|
|
while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu))
|
|
|
popup_idx--;
|
|
popup_idx--;
|
|
@@ -3554,7 +3548,6 @@ bool ImGui::BeginPopup(const char* str_id)
|
|
|
return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders);
|
|
return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// FIXME
|
|
|
|
|
bool ImGui::IsPopupOpen(ImGuiID id)
|
|
bool ImGui::IsPopupOpen(ImGuiID id)
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -3604,7 +3597,7 @@ void ImGui::EndPopup()
|
|
|
// This is a helper to handle the most simple case of associating one named popup to one given widget.
|
|
// This is a helper to handle the most simple case of associating one named popup to one given widget.
|
|
|
// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling
|
|
// 1. If you have many possible popups (for different "instances" of a same widget, or for wholly different widgets), you may be better off handling
|
|
|
// this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers.
|
|
// this yourself so you can store data relative to the widget that opened the popup instead of choosing different popup identifiers.
|
|
|
-// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemHoveredRect()
|
|
|
|
|
|
|
+// 2. If you want right-clicking on the same item to reopen the popup at new location, use the same code replacing IsItemHovered() with IsItemRectHovered()
|
|
|
// and passing true to the OpenPopupEx().
|
|
// and passing true to the OpenPopupEx().
|
|
|
// Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that
|
|
// Because: hovering an item in a window below the popup won't normally trigger is hovering behavior/coloring. The pattern of ignoring the fact that
|
|
|
// the item can be interacted with (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu
|
|
// the item can be interacted with (because it is blocked by the active popup) may useful in some situation when e.g. large canvas as one item, content of menu
|
|
@@ -3637,37 +3630,31 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button)
|
|
|
|
|
|
|
|
static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
|
|
static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
|
|
|
{
|
|
{
|
|
|
- ImGuiWindow* window = ImGui::GetCurrentWindow();
|
|
|
|
|
|
|
+ ImGuiWindow* parent_window = ImGui::GetCurrentWindow();
|
|
|
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
|
|
ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow;
|
|
|
|
|
|
|
|
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
|
|
const ImVec2 content_avail = ImGui::GetContentRegionAvail();
|
|
|
ImVec2 size = ImFloor(size_arg);
|
|
ImVec2 size = ImFloor(size_arg);
|
|
|
|
|
+ const int auto_fit_axises = ((size.x == 0.0f) ? 0x01 : 0x00) | ((size.y == 0.0f) ? 0x02 : 0x00);
|
|
|
if (size.x <= 0.0f)
|
|
if (size.x <= 0.0f)
|
|
|
- {
|
|
|
|
|
- if (size.x == 0.0f)
|
|
|
|
|
- flags |= ImGuiWindowFlags_ChildWindowAutoFitX;
|
|
|
|
|
size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues)
|
|
size.x = ImMax(content_avail.x, 4.0f) - fabsf(size.x); // Arbitrary minimum zero-ish child size of 4.0f (0.0f causing too much issues)
|
|
|
- }
|
|
|
|
|
if (size.y <= 0.0f)
|
|
if (size.y <= 0.0f)
|
|
|
- {
|
|
|
|
|
- if (size.y == 0.0f)
|
|
|
|
|
- flags |= ImGuiWindowFlags_ChildWindowAutoFitY;
|
|
|
|
|
size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y);
|
|
size.y = ImMax(content_avail.y, 4.0f) - fabsf(size.y);
|
|
|
- }
|
|
|
|
|
if (border)
|
|
if (border)
|
|
|
flags |= ImGuiWindowFlags_ShowBorders;
|
|
flags |= ImGuiWindowFlags_ShowBorders;
|
|
|
flags |= extra_flags;
|
|
flags |= extra_flags;
|
|
|
|
|
|
|
|
char title[256];
|
|
char title[256];
|
|
|
if (name)
|
|
if (name)
|
|
|
- ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", window->Name, name, id);
|
|
|
|
|
|
|
+ ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s.%08X", parent_window->Name, name, id);
|
|
|
else
|
|
else
|
|
|
- ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", window->Name, id);
|
|
|
|
|
|
|
+ ImFormatString(title, IM_ARRAYSIZE(title), "%s.%08X", parent_window->Name, id);
|
|
|
|
|
|
|
|
bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags);
|
|
bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags);
|
|
|
-
|
|
|
|
|
- if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
|
|
|
|
|
- ImGui::GetCurrentWindow()->Flags &= ~ImGuiWindowFlags_ShowBorders;
|
|
|
|
|
|
|
+ ImGuiWindow* child_window = ImGui::GetCurrentWindow();
|
|
|
|
|
+ child_window->AutoFitChildAxises = auto_fit_axises;
|
|
|
|
|
+ if (!(parent_window->Flags & ImGuiWindowFlags_ShowBorders))
|
|
|
|
|
+ child_window->Flags &= ~ImGuiWindowFlags_ShowBorders;
|
|
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|
|
@@ -3696,15 +3683,15 @@ void ImGui::EndChild()
|
|
|
{
|
|
{
|
|
|
// When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting.
|
|
// When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting.
|
|
|
ImVec2 sz = GetWindowSize();
|
|
ImVec2 sz = GetWindowSize();
|
|
|
- if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitX) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f
|
|
|
|
|
|
|
+ if (window->AutoFitChildAxises & 0x01) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f
|
|
|
sz.x = ImMax(4.0f, sz.x);
|
|
sz.x = ImMax(4.0f, sz.x);
|
|
|
- if (window->Flags & ImGuiWindowFlags_ChildWindowAutoFitY)
|
|
|
|
|
|
|
+ if (window->AutoFitChildAxises & 0x02)
|
|
|
sz.y = ImMax(4.0f, sz.y);
|
|
sz.y = ImMax(4.0f, sz.y);
|
|
|
|
|
|
|
|
ImGui::End();
|
|
ImGui::End();
|
|
|
|
|
|
|
|
- window = GetCurrentWindow();
|
|
|
|
|
- ImRect bb(window->DC.CursorPos, window->DC.CursorPos + sz);
|
|
|
|
|
|
|
+ ImGuiWindow* parent_window = GetCurrentWindow();
|
|
|
|
|
+ ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz);
|
|
|
ItemSize(sz);
|
|
ItemSize(sz);
|
|
|
ItemAdd(bb, NULL);
|
|
ItemAdd(bb, NULL);
|
|
|
}
|
|
}
|
|
@@ -3750,7 +3737,7 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size,
|
|
|
// Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it.
|
|
// Clamp into visible area while not overlapping the cursor. Safety padding is optional if our popup size won't fit without it.
|
|
|
ImVec2 safe_padding = style.DisplaySafeAreaPadding;
|
|
ImVec2 safe_padding = style.DisplaySafeAreaPadding;
|
|
|
ImRect r_outer(GetVisibleRect());
|
|
ImRect r_outer(GetVisibleRect());
|
|
|
- r_outer.Reduce(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);
|
|
|
|
|
|
|
|
for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction).
|
|
for (int n = (*last_dir != -1) ? -1 : 0; n < 4; n++) // Last, Right, down, up, left. (Favor last used direction).
|
|
@@ -4028,8 +4015,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
|
|
if (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0])
|
|
if (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0])
|
|
|
{
|
|
{
|
|
|
window->Collapsed = !window->Collapsed;
|
|
window->Collapsed = !window->Collapsed;
|
|
|
- if (!(flags & ImGuiWindowFlags_NoSavedSettings))
|
|
|
|
|
- MarkIniSettingsDirty();
|
|
|
|
|
|
|
+ MarkIniSettingsDirty(window);
|
|
|
FocusWindow(window);
|
|
FocusWindow(window);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -4103,8 +4089,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
|
|
window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
|
|
window->SizeFull.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 = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
|
|
|
- if (!(flags & ImGuiWindowFlags_NoSavedSettings))
|
|
|
|
|
- MarkIniSettingsDirty();
|
|
|
|
|
|
|
+ MarkIniSettingsDirty(window);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -4238,16 +4223,14 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
|
|
{
|
|
{
|
|
|
// Manual auto-fit when double-clicking
|
|
// Manual auto-fit when double-clicking
|
|
|
ApplySizeFullWithConstraint(window, size_auto_fit);
|
|
ApplySizeFullWithConstraint(window, size_auto_fit);
|
|
|
- if (!(flags & ImGuiWindowFlags_NoSavedSettings))
|
|
|
|
|
- MarkIniSettingsDirty();
|
|
|
|
|
|
|
+ MarkIniSettingsDirty(window);
|
|
|
ClearActiveID();
|
|
ClearActiveID();
|
|
|
}
|
|
}
|
|
|
else if (held)
|
|
else if (held)
|
|
|
{
|
|
{
|
|
|
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
|
|
// We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
|
|
|
ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos);
|
|
ApplySizeFullWithConstraint(window, (g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize()) - window->Pos);
|
|
|
- if (!(flags & ImGuiWindowFlags_NoSavedSettings))
|
|
|
|
|
- MarkIniSettingsDirty();
|
|
|
|
|
|
|
+ MarkIniSettingsDirty(window);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
window->Size = window->SizeFull;
|
|
window->Size = window->SizeFull;
|
|
@@ -4279,7 +4262,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
|
|
|
|
|
|
|
// Title bar
|
|
// Title bar
|
|
|
if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
|
if (!(flags & ImGuiWindowFlags_NoTitleBar))
|
|
|
- window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32((g.FocusedWindow && window->RootNonPopupWindow == g.FocusedWindow->RootNonPopupWindow) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImGuiCorner_TopLeft|ImGuiCorner_TopRight);
|
|
|
|
|
|
|
+ window->DrawList->AddRectFilled(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32((g.NavWindow && window->RootNonPopupWindow == g.NavWindow->RootNonPopupWindow) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg), window_rounding, ImGuiCorner_TopLeft|ImGuiCorner_TopRight);
|
|
|
|
|
|
|
|
// Menu bar
|
|
// Menu bar
|
|
|
if (flags & ImGuiWindowFlags_MenuBar)
|
|
if (flags & ImGuiWindowFlags_MenuBar)
|
|
@@ -4396,7 +4379,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
|
|
|
|
|
|
|
// Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
|
|
// Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
|
|
|
window->WindowRectClipped = window->Rect();
|
|
window->WindowRectClipped = window->Rect();
|
|
|
- window->WindowRectClipped.Clip(window->ClipRect);
|
|
|
|
|
|
|
+ window->WindowRectClipped.ClipWith(window->ClipRect);
|
|
|
|
|
|
|
|
// Pressing CTRL+C while holding on a window copy its content to the clipboard
|
|
// Pressing CTRL+C while holding on a window copy its content to the clipboard
|
|
|
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
|
|
// This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
|
|
@@ -4413,7 +4396,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
|
|
|
// Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior.
|
|
// Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior.
|
|
|
const ImRect title_bar_rect = window->TitleBarRect();
|
|
const ImRect title_bar_rect = window->TitleBarRect();
|
|
|
const float border_size = window->BorderSize;
|
|
const float border_size = window->BorderSize;
|
|
|
- ImRect clip_rect; // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
|
|
|
|
|
|
|
+ // Force round to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
|
|
|
|
|
+ ImRect clip_rect;
|
|
|
clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
|
|
clip_rect.Min.x = ImFloor(0.5f + title_bar_rect.Min.x + ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
|
|
|
clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size);
|
|
clip_rect.Min.y = ImFloor(0.5f + title_bar_rect.Max.y + window->MenuBarHeight() + border_size);
|
|
|
clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
|
|
clip_rect.Max.x = ImFloor(0.5f + window->Pos.x + window->Size.x - window->ScrollbarSizes.x - ImMax(border_size, ImFloor(window->WindowPadding.x*0.5f)));
|
|
@@ -4502,7 +4486,7 @@ static void Scrollbar(ImGuiWindow* window, bool horizontal)
|
|
|
else
|
|
else
|
|
|
window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BottomRight);
|
|
window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImGuiCorner_TopRight : 0) | (other_scrollbar ? 0 : ImGuiCorner_BottomRight);
|
|
|
window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners);
|
|
window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_ScrollbarBg), window_rounding, window_rounding_corners);
|
|
|
- bb.Reduce(ImVec2(ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f)));
|
|
|
|
|
|
|
+ bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f)));
|
|
|
|
|
|
|
|
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
|
|
// V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar)
|
|
|
float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight();
|
|
float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight();
|
|
@@ -4583,7 +4567,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
|
|
// Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing.
|
|
// Always mark the window we passed as focused. This is used for keyboard interactions such as tabbing.
|
|
|
- g.FocusedWindow = window;
|
|
|
|
|
|
|
+ g.NavWindow = window;
|
|
|
|
|
|
|
|
// Passing NULL allow to disable keyboard focus
|
|
// Passing NULL allow to disable keyboard focus
|
|
|
if (!window)
|
|
if (!window)
|
|
@@ -4892,22 +4876,28 @@ bool ImGui::IsWindowHovered()
|
|
|
return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow);
|
|
return g.HoveredWindow == g.CurrentWindow && IsWindowContentHoverable(g.HoveredRootWindow);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+bool ImGui::IsWindowRectHovered()
|
|
|
|
|
+{
|
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
|
+ return g.HoveredWindow == g.CurrentWindow;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
bool ImGui::IsWindowFocused()
|
|
bool ImGui::IsWindowFocused()
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- return g.FocusedWindow == g.CurrentWindow;
|
|
|
|
|
|
|
+ return g.NavWindow == g.CurrentWindow;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool ImGui::IsRootWindowFocused()
|
|
bool ImGui::IsRootWindowFocused()
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- return g.FocusedWindow == g.CurrentWindow->RootWindow;
|
|
|
|
|
|
|
+ return g.NavWindow == g.CurrentWindow->RootWindow;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool ImGui::IsRootWindowOrAnyChildFocused()
|
|
bool ImGui::IsRootWindowOrAnyChildFocused()
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- return g.FocusedWindow && g.FocusedWindow->RootWindow == g.CurrentWindow->RootWindow;
|
|
|
|
|
|
|
+ return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool ImGui::IsRootWindowOrAnyChildHovered()
|
|
bool ImGui::IsRootWindowOrAnyChildHovered()
|
|
@@ -4937,7 +4927,7 @@ ImVec2 ImGui::GetWindowPos()
|
|
|
|
|
|
|
|
static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y)
|
|
static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y)
|
|
|
{
|
|
{
|
|
|
- window->DC.CursorMaxPos.y += window->Scroll.y;
|
|
|
|
|
|
|
+ window->DC.CursorMaxPos.y += window->Scroll.y; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it.
|
|
|
window->Scroll.y = new_scroll_y;
|
|
window->Scroll.y = new_scroll_y;
|
|
|
window->DC.CursorMaxPos.y -= window->Scroll.y;
|
|
window->DC.CursorMaxPos.y -= window->Scroll.y;
|
|
|
}
|
|
}
|
|
@@ -5566,8 +5556,8 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window)
|
|
|
// An active popup disable hovering on other windows (apart from its own children)
|
|
// An active popup disable hovering on other windows (apart from its own children)
|
|
|
// FIXME-OPT: This could be cached/stored within the window.
|
|
// FIXME-OPT: This could be cached/stored within the window.
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- if (ImGuiWindow* focused_window = g.FocusedWindow)
|
|
|
|
|
- if (ImGuiWindow* focused_root_window = focused_window->RootWindow)
|
|
|
|
|
|
|
+ if (g.NavWindow)
|
|
|
|
|
+ if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow)
|
|
|
if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow)
|
|
if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) != 0 && focused_root_window->WasActive && focused_root_window != window->RootWindow)
|
|
|
return false;
|
|
return false;
|
|
|
|
|
|
|
@@ -5587,6 +5577,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Default behavior requires click+release on same spot
|
|
|
if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0)
|
|
if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0)
|
|
|
flags |= ImGuiButtonFlags_PressedOnClickRelease;
|
|
flags |= ImGuiButtonFlags_PressedOnClickRelease;
|
|
|
|
|
|
|
@@ -6475,13 +6466,18 @@ int ImGui::ParseFormatPrecision(const char* fmt, int default_precision)
|
|
|
return precision;
|
|
return precision;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
|
|
|
|
|
+{
|
|
|
|
|
+ static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f };
|
|
|
|
|
+ return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
float ImGui::RoundScalar(float value, int decimal_precision)
|
|
float ImGui::RoundScalar(float value, int decimal_precision)
|
|
|
{
|
|
{
|
|
|
// Round past decimal precision
|
|
// Round past decimal precision
|
|
|
// So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
|
|
// So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0
|
|
|
// FIXME: Investigate better rounding methods
|
|
// FIXME: Investigate better rounding methods
|
|
|
- static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f };
|
|
|
|
|
- float min_step = (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision);
|
|
|
|
|
|
|
+ const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision);
|
|
|
bool negative = value < 0.0f;
|
|
bool negative = value < 0.0f;
|
|
|
value = fabsf(value);
|
|
value = fabsf(value);
|
|
|
float remainder = fmodf(value, min_step);
|
|
float remainder = fmodf(value, min_step);
|
|
@@ -6559,13 +6555,23 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
|
|
|
bool value_changed = false;
|
|
bool value_changed = false;
|
|
|
if (g.ActiveId == id)
|
|
if (g.ActiveId == id)
|
|
|
{
|
|
{
|
|
|
|
|
+ bool set_new_value = false;
|
|
|
|
|
+ float clicked_t = 0.0f;
|
|
|
if (g.IO.MouseDown[0])
|
|
if (g.IO.MouseDown[0])
|
|
|
{
|
|
{
|
|
|
const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y;
|
|
const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y;
|
|
|
- float clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f;
|
|
|
|
|
|
|
+ clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f;
|
|
|
if (!is_horizontal)
|
|
if (!is_horizontal)
|
|
|
clicked_t = 1.0f - clicked_t;
|
|
clicked_t = 1.0f - clicked_t;
|
|
|
|
|
+ set_new_value = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ ClearActiveID();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ if (set_new_value)
|
|
|
|
|
+ {
|
|
|
float new_value;
|
|
float new_value;
|
|
|
if (is_non_linear)
|
|
if (is_non_linear)
|
|
|
{
|
|
{
|
|
@@ -6603,16 +6609,10 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v
|
|
|
value_changed = true;
|
|
value_changed = true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- ClearActiveID();
|
|
|
|
|
- }
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Calculate slider grab positioning
|
|
|
|
|
- float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos);
|
|
|
|
|
-
|
|
|
|
|
// Draw
|
|
// Draw
|
|
|
|
|
+ float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos);
|
|
|
if (!is_horizontal)
|
|
if (!is_horizontal)
|
|
|
grab_t = 1.0f - grab_t;
|
|
grab_t = 1.0f - grab_t;
|
|
|
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
|
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
|
@@ -6876,32 +6876,32 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s
|
|
|
g.DragLastMouseDelta = ImVec2(0.f, 0.f);
|
|
g.DragLastMouseDelta = ImVec2(0.f, 0.f);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX)
|
|
|
|
|
+ v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio;
|
|
|
float v_cur = g.DragCurrentValue;
|
|
float v_cur = g.DragCurrentValue;
|
|
|
const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f);
|
|
const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f);
|
|
|
if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f)
|
|
if (fabsf(mouse_drag_delta.x - g.DragLastMouseDelta.x) > 0.0f)
|
|
|
{
|
|
{
|
|
|
float speed = v_speed;
|
|
float speed = v_speed;
|
|
|
- if (speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX)
|
|
|
|
|
- speed = (v_max - v_min) * g.DragSpeedDefaultRatio;
|
|
|
|
|
if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f)
|
|
if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f)
|
|
|
speed = speed * g.DragSpeedScaleFast;
|
|
speed = speed * g.DragSpeedScaleFast;
|
|
|
if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f)
|
|
if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f)
|
|
|
speed = speed * g.DragSpeedScaleSlow;
|
|
speed = speed * g.DragSpeedScaleSlow;
|
|
|
|
|
|
|
|
- float delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed;
|
|
|
|
|
|
|
+ float adjust_delta = (mouse_drag_delta.x - g.DragLastMouseDelta.x) * speed;
|
|
|
if (fabsf(power - 1.0f) > 0.001f)
|
|
if (fabsf(power - 1.0f) > 0.001f)
|
|
|
{
|
|
{
|
|
|
// Logarithmic curve on both side of 0.0
|
|
// Logarithmic curve on both side of 0.0
|
|
|
float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur;
|
|
float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur;
|
|
|
float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f;
|
|
float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f;
|
|
|
- float v1 = powf(v0_abs, 1.0f / power) + (delta * v0_sign);
|
|
|
|
|
|
|
+ float v1 = powf(v0_abs, 1.0f / power) + (adjust_delta * v0_sign);
|
|
|
float v1_abs = v1 >= 0.0f ? v1 : -v1;
|
|
float v1_abs = v1 >= 0.0f ? v1 : -v1;
|
|
|
float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line
|
|
float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line
|
|
|
v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign
|
|
v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- v_cur += delta;
|
|
|
|
|
|
|
+ v_cur += adjust_delta;
|
|
|
}
|
|
}
|
|
|
g.DragLastMouseDelta.x = mouse_drag_delta.x;
|
|
g.DragLastMouseDelta.x = mouse_drag_delta.x;
|
|
|
|
|
|
|
@@ -7300,7 +7300,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over
|
|
|
// Render
|
|
// Render
|
|
|
fraction = ImSaturate(fraction);
|
|
fraction = ImSaturate(fraction);
|
|
|
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
|
- bb.Reduce(ImVec2(window->BorderSize, window->BorderSize));
|
|
|
|
|
|
|
+ bb.Expand(ImVec2(-window->BorderSize, -window->BorderSize));
|
|
|
const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y);
|
|
const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y);
|
|
|
RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding);
|
|
RenderFrame(bb.Min, fill_br, GetColorU32(ImGuiCol_PlotHistogram), false, style.FrameRounding);
|
|
|
|
|
|
|
@@ -8220,7 +8220,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
|
|
ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true);
|
|
ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true);
|
|
|
if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((unsigned short)' ') * 0.50f); // So we can see selected empty lines
|
|
if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((unsigned short)' ') * 0.50f); // So we can see selected empty lines
|
|
|
ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos +ImVec2(rect_size.x, bg_offy_dn));
|
|
ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos +ImVec2(rect_size.x, bg_offy_dn));
|
|
|
- rect.Clip(clip_rect);
|
|
|
|
|
|
|
+ rect.ClipWith(clip_rect);
|
|
|
if (rect.Overlaps(clip_rect))
|
|
if (rect.Overlaps(clip_rect))
|
|
|
draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color);
|
|
draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color);
|
|
|
}
|
|
}
|
|
@@ -8516,7 +8516,6 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
|
|
const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f);
|
|
const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f);
|
|
|
const bool hovered = IsHovered(frame_bb, id);
|
|
const bool hovered = IsHovered(frame_bb, id);
|
|
|
bool popup_open = IsPopupOpen(id);
|
|
bool popup_open = IsPopupOpen(id);
|
|
|
- bool popup_opened_now = false;
|
|
|
|
|
|
|
|
|
|
const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
|
|
const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
|
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
|
|
@@ -8533,22 +8532,27 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
|
|
if (label_size.x > 0)
|
|
if (label_size.x > 0)
|
|
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
|
|
|
|
|
|
|
|
|
+ bool popup_toggled = false;
|
|
|
if (hovered)
|
|
if (hovered)
|
|
|
{
|
|
{
|
|
|
SetHoveredID(id);
|
|
SetHoveredID(id);
|
|
|
if (g.IO.MouseClicked[0])
|
|
if (g.IO.MouseClicked[0])
|
|
|
{
|
|
{
|
|
|
ClearActiveID();
|
|
ClearActiveID();
|
|
|
- if (IsPopupOpen(id))
|
|
|
|
|
- {
|
|
|
|
|
- ClosePopup(id);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- FocusWindow(window);
|
|
|
|
|
- OpenPopup(label);
|
|
|
|
|
- popup_open = popup_opened_now = true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ popup_toggled = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (popup_toggled)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (IsPopupOpen(id))
|
|
|
|
|
+ {
|
|
|
|
|
+ ClosePopup(id);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ FocusWindow(window);
|
|
|
|
|
+ OpenPopup(label);
|
|
|
|
|
+ popup_open = true;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -8577,6 +8581,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
|
|
if (BeginPopupEx(id, flags))
|
|
if (BeginPopupEx(id, flags))
|
|
|
{
|
|
{
|
|
|
// Display items
|
|
// Display items
|
|
|
|
|
+ // FIXME-OPT: Use clipper
|
|
|
Spacing();
|
|
Spacing();
|
|
|
for (int i = 0; i < items_count; i++)
|
|
for (int i = 0; i < items_count; i++)
|
|
|
{
|
|
{
|
|
@@ -8591,7 +8596,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
|
|
|
value_changed = true;
|
|
value_changed = true;
|
|
|
*current_item = i;
|
|
*current_item = i;
|
|
|
}
|
|
}
|
|
|
- if (item_selected && popup_opened_now)
|
|
|
|
|
|
|
+ if (item_selected && popup_toggled)
|
|
|
SetScrollHere();
|
|
SetScrollHere();
|
|
|
PopID();
|
|
PopID();
|
|
|
}
|
|
}
|
|
@@ -8764,7 +8769,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
|
|
|
|
|
|
|
|
// Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper.
|
|
// Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper.
|
|
|
bool value_changed = false;
|
|
bool value_changed = false;
|
|
|
- ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing());
|
|
|
|
|
|
|
+ ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to.
|
|
|
while (clipper.Step())
|
|
while (clipper.Step())
|
|
|
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
|
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
|
|
{
|
|
{
|
|
@@ -8896,13 +8901,13 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
const ImGuiID id = window->GetID(label);
|
|
const ImGuiID id = window->GetID(label);
|
|
|
|
|
|
|
|
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
|
- ImGuiWindow* backed_focused_window = g.FocusedWindow;
|
|
|
|
|
|
|
|
|
|
bool pressed;
|
|
bool pressed;
|
|
|
bool menu_is_open = IsPopupOpen(id);
|
|
bool menu_is_open = IsPopupOpen(id);
|
|
|
bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus"));
|
|
bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus"));
|
|
|
|
|
+ ImGuiWindow* backed_nav_window = g.NavWindow;
|
|
|
if (menuset_is_open)
|
|
if (menuset_is_open)
|
|
|
- g.FocusedWindow = window;
|
|
|
|
|
|
|
+ g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent)
|
|
|
|
|
|
|
|
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos).
|
|
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos).
|
|
|
ImVec2 popup_pos, pos = window->DC.CursorPos;
|
|
ImVec2 popup_pos, pos = window->DC.CursorPos;
|
|
@@ -8930,7 +8935,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
|
|
|
|
|
bool hovered = enabled && IsHovered(window->DC.LastItemRect, id);
|
|
bool hovered = enabled && IsHovered(window->DC.LastItemRect, id);
|
|
|
if (menuset_is_open)
|
|
if (menuset_is_open)
|
|
|
- g.FocusedWindow = backed_focused_window;
|
|
|
|
|
|
|
+ g.NavWindow = backed_nav_window;
|
|
|
|
|
|
|
|
bool want_open = false, want_close = false;
|
|
bool want_open = false, want_close = false;
|
|
|
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
|
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
|
@@ -8957,7 +8962,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
|
|
want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle);
|
|
want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle);
|
|
|
want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed);
|
|
want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed);
|
|
|
}
|
|
}
|
|
|
- else if (menu_is_open && pressed && menuset_is_open) // menu-bar: click open menu to close
|
|
|
|
|
|
|
+ else if (menu_is_open && pressed && menuset_is_open) // Menu bar: click an open menu again to close it
|
|
|
{
|
|
{
|
|
|
want_close = true;
|
|
want_close = true;
|
|
|
want_open = menu_is_open = false;
|
|
want_open = menu_is_open = false;
|
|
@@ -10082,7 +10087,7 @@ void ImGui::BeginColumns(const char* id, int columns_count, ImGuiColumnsFlags fl
|
|
|
float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f);
|
|
float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index) - 1.0f);
|
|
|
float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f);
|
|
float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(column_index + 1) - 1.0f);
|
|
|
window->DC.ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
|
|
window->DC.ColumnsData[column_index].ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
|
|
|
- window->DC.ColumnsData[column_index].ClipRect.Clip(window->ClipRect);
|
|
|
|
|
|
|
+ window->DC.ColumnsData[column_index].ClipRect.ClipWith(window->ClipRect);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
window->DrawList->ChannelsSplit(window->DC.ColumnsCount);
|
|
window->DrawList->ChannelsSplit(window->DC.ColumnsCount);
|
|
@@ -10307,21 +10312,18 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
|
|
|
// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
|
|
// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
|
|
|
static const char* GetClipboardTextFn_DefaultImpl(void*)
|
|
static const char* GetClipboardTextFn_DefaultImpl(void*)
|
|
|
{
|
|
{
|
|
|
- return GImGui->PrivateClipboard;
|
|
|
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
|
+ return g.PrivateClipboard.empty() ? NULL : g.PrivateClipboard.begin();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
|
|
// Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
|
|
|
static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
|
|
static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
|
|
|
{
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
- if (g.PrivateClipboard)
|
|
|
|
|
- {
|
|
|
|
|
- ImGui::MemFree(g.PrivateClipboard);
|
|
|
|
|
- g.PrivateClipboard = NULL;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ g.PrivateClipboard.clear();
|
|
|
const char* text_end = text + strlen(text);
|
|
const char* text_end = text + strlen(text);
|
|
|
- g.PrivateClipboard = (char*)ImGui::MemAlloc((size_t)(text_end - text) + 1);
|
|
|
|
|
- memcpy(g.PrivateClipboard, text, (size_t)(text_end - text));
|
|
|
|
|
|
|
+ g.PrivateClipboard.resize((size_t)(text_end - text) + 1);
|
|
|
|
|
+ memcpy(&g.PrivateClipboard[0], text, (size_t)(text_end - text));
|
|
|
g.PrivateClipboard[(int)(text_end - text)] = 0;
|
|
g.PrivateClipboard[(int)(text_end - text)] = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -10475,12 +10477,12 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
|
|
}
|
|
}
|
|
|
if (ImGui::TreeNode("Basic state"))
|
|
if (ImGui::TreeNode("Basic state"))
|
|
|
{
|
|
{
|
|
|
- ImGui::Text("FocusedWindow: '%s'", g.FocusedWindow ? g.FocusedWindow->Name : "NULL");
|
|
|
|
|
ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
|
|
ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
|
|
|
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
|
|
ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
|
|
|
- ImGui::Text("HoveredID: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
|
|
|
|
|
- ImGui::Text("ActiveID: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame);
|
|
|
|
|
|
|
+ ImGui::Text("HoveredId: 0x%08X/0x%08X", g.HoveredId, g.HoveredIdPreviousFrame); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
|
|
|
|
|
+ ImGui::Text("ActiveId: 0x%08X/0x%08X", g.ActiveId, g.ActiveIdPreviousFrame);
|
|
|
ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
|
ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
|
|
|
|
|
+ ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL");
|
|
|
ImGui::TreePop();
|
|
ImGui::TreePop();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|