|
@@ -432,6 +432,14 @@ CODE
|
|
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
|
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
|
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
|
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
|
|
|
|
|
|
|
+ - 2023/11/02 (1.90.0) - BeginChild: upgraded 'bool border = true' parameter to 'ImGuiChildFlags flags' type, added ImGuiChildFlags_Border equivalent. As with our prior "bool-to-flags" API updates, the ImGuiChildFlags_Border value is guaranteed to be == true forever to ensure a smoother transition, meaning all existing calls will still work.
|
|
|
|
+ - old: BeginChild("Name", size, true)
|
|
|
|
+ - new: BeginChild("Name", size, ImGuiChildFlags_Border)
|
|
|
|
+ - old: BeginChild("Name", size, false)
|
|
|
|
+ - new: BeginChild("Name", size) or BeginChild("Name", 0) or BeginChild("Name", size, ImGuiChildFlags_None)
|
|
|
|
+ - 2023/11/02 (1.90.0) - BeginChild: added child-flag ImGuiChildFlags_AlwaysUseWindowPadding as a replacement for the window-flag ImGuiWindowFlags_AlwaysUseWindowPadding: the feature only ever made sense for BeginChild() anyhow.
|
|
|
|
+ - old: BeginChild("Name", size, 0, ImGuiWindowFlags_AlwaysUseWindowPadding);
|
|
|
|
+ - new: BeginChild("Name", size, ImGuiChildFlags_AlwaysUseWindowPadding, 0);
|
|
- 2023/09/27 (1.90.0) - io: removed io.MetricsActiveAllocations introduced in 1.63. Same as 'g.DebugMemAllocCount - g.DebugMemFreeCount' (still displayed in Metrics, unlikely to be accessed by end-user).
|
|
- 2023/09/27 (1.90.0) - io: removed io.MetricsActiveAllocations introduced in 1.63. Same as 'g.DebugMemAllocCount - g.DebugMemFreeCount' (still displayed in Metrics, unlikely to be accessed by end-user).
|
|
- 2023/09/26 (1.90.0) - debug tools: Renamed ShowStackToolWindow() ("Stack Tool") to ShowIDStackToolWindow() ("ID Stack Tool"), as earlier name was misleading. Kept inline redirection function. (#4631)
|
|
- 2023/09/26 (1.90.0) - debug tools: Renamed ShowStackToolWindow() ("Stack Tool") to ShowIDStackToolWindow() ("ID Stack Tool"), as earlier name was misleading. Kept inline redirection function. (#4631)
|
|
- 2023/09/15 (1.90.0) - ListBox, Combo: changed signature of "name getter" callback in old one-liner ListBox()/Combo() apis. kept inline redirection function (will obsolete).
|
|
- 2023/09/15 (1.90.0) - ListBox, Combo: changed signature of "name getter" callback in old one-liner ListBox()/Combo() apis. kept inline redirection function (will obsolete).
|
|
@@ -1109,9 +1117,9 @@ static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt);
|
|
|
|
|
|
// Misc
|
|
// Misc
|
|
static void UpdateSettings();
|
|
static void UpdateSettings();
|
|
-static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
|
|
|
|
-static void RenderWindowOuterBorders(ImGuiWindow* window);
|
|
|
|
-static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
|
|
|
|
|
+static int UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_hovered, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
|
|
|
|
+static void RenderWindowOuterBorders(ImGuiWindow* window, int border_hovered, int border_held);
|
|
|
|
+static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size, int border_hovered, int border_held);
|
|
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
|
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
|
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
|
|
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
|
|
static void RenderDimmedBackgrounds();
|
|
static void RenderDimmedBackgrounds();
|
|
@@ -5505,7 +5513,7 @@ static void FindHoveredWindow()
|
|
continue;
|
|
continue;
|
|
|
|
|
|
// Using the clipped AABB, a child window will typically be clipped by its parent (not always)
|
|
// Using the clipped AABB, a child window will typically be clipped by its parent (not always)
|
|
- ImVec2 hit_padding = (window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) ? padding_regular : padding_for_resize;
|
|
|
|
|
|
+ ImVec2 hit_padding = (window->Flags & (ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) ? padding_regular : padding_for_resize;
|
|
if (!window->OuterRectClipped.ContainsWithPad(g.IO.MousePos, hit_padding))
|
|
if (!window->OuterRectClipped.ContainsWithPad(g.IO.MousePos, hit_padding))
|
|
continue;
|
|
continue;
|
|
|
|
|
|
@@ -5688,26 +5696,49 @@ ImVec2 ImGui::GetItemRectSize()
|
|
return g.LastItemData.Rect.GetSize();
|
|
return g.LastItemData.Rect.GetSize();
|
|
}
|
|
}
|
|
|
|
|
|
-bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
|
|
|
|
|
|
+// Prior to v1.90 2023/10/16, the BeginChild() function took a 'bool border = false' parameter instead of 'ImGuiChildFlags child_flags = 0'.
|
|
|
|
+// ImGuiChildFlags_Border is defined as always == 1 in order to allow old code passing 'true'.
|
|
|
|
+bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags)
|
|
{
|
|
{
|
|
ImGuiID id = GetCurrentWindow()->GetID(str_id);
|
|
ImGuiID id = GetCurrentWindow()->GetID(str_id);
|
|
- return BeginChildEx(str_id, id, size_arg, border, window_flags);
|
|
|
|
|
|
+ return BeginChildEx(str_id, id, size_arg, child_flags, window_flags);
|
|
}
|
|
}
|
|
|
|
|
|
-bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
|
|
|
|
|
|
+bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags)
|
|
{
|
|
{
|
|
- IM_ASSERT(id != 0);
|
|
|
|
- return BeginChildEx(NULL, id, size_arg, border, window_flags);
|
|
|
|
|
|
+ return BeginChildEx(NULL, id, size_arg, child_flags, window_flags);
|
|
}
|
|
}
|
|
|
|
|
|
-bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
|
|
|
|
|
|
+bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiWindow* parent_window = g.CurrentWindow;
|
|
ImGuiWindow* parent_window = g.CurrentWindow;
|
|
- window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking;
|
|
|
|
- window_flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag
|
|
|
|
|
|
+ IM_ASSERT(id != 0);
|
|
|
|
+
|
|
|
|
+ // Sanity check as it is likely that some user will accidentally pass ImGuiWindowFlags into the ImGuiChildFlags argument.
|
|
|
|
+ const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY;
|
|
|
|
+ IM_UNUSED(ImGuiChildFlags_SupportedMask_);
|
|
|
|
+ IM_ASSERT((child_flags & ~ImGuiChildFlags_SupportedMask_) == 0 && "Illegal ImGuiChildFlags value. Did you pass ImGuiWindowFlags values instead of ImGuiChildFlags?");
|
|
|
|
+ if (window_flags & ImGuiWindowFlags_AlwaysAutoResize)
|
|
|
|
+ IM_ASSERT((child_flags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0 && "Cannot combine ImGuiChildFlags_ResizeX/ImGuiChildFlags_ResizeY with ImGuiWindowFlags_AlwaysAutoResize.");
|
|
|
|
+#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
|
|
+ if (window_flags & ImGuiWindowFlags_AlwaysUseWindowPadding)
|
|
|
|
+ child_flags |= ImGuiChildFlags_AlwaysUseWindowPadding;
|
|
|
|
+#endif
|
|
|
|
|
|
- // Size
|
|
|
|
|
|
+ window_flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDocking;
|
|
|
|
+ window_flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag
|
|
|
|
+
|
|
|
|
+ if ((child_flags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0)
|
|
|
|
+ window_flags |= ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings;
|
|
|
|
+
|
|
|
|
+ // Forward child flags
|
|
|
|
+ g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasChildFlags;
|
|
|
|
+ g.NextWindowData.ChildFlags = child_flags;
|
|
|
|
+
|
|
|
|
+ // Forward size
|
|
|
|
+ // Important: Begin() has special processing to switch condition to ImGuiCond_FirstUseEver for a given axis when ImGuiChildFlags_ResizeXXX is set.
|
|
|
|
+ // (the alternative would to store conditional flags per axis, which is possible but more code)
|
|
const ImVec2 content_avail = GetContentRegionAvail();
|
|
const ImVec2 content_avail = GetContentRegionAvail();
|
|
ImVec2 size = ImTrunc(size_arg);
|
|
ImVec2 size = ImTrunc(size_arg);
|
|
if (size.x <= 0.0f)
|
|
if (size.x <= 0.0f)
|
|
@@ -5718,13 +5749,15 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
|
|
|
|
|
|
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
|
|
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
|
|
const char* temp_window_name;
|
|
const char* temp_window_name;
|
|
- if (name)
|
|
|
|
|
|
+ if (name && parent_window->IDStack.back() == parent_window->ID)
|
|
|
|
+ ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s", parent_window->Name, name); // May omit ID if in root of ID stack
|
|
|
|
+ else if (name)
|
|
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s_%08X", parent_window->Name, name, id);
|
|
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s_%08X", parent_window->Name, name, id);
|
|
else
|
|
else
|
|
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%08X", parent_window->Name, id);
|
|
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%08X", parent_window->Name, id);
|
|
|
|
|
|
const float backup_border_size = g.Style.ChildBorderSize;
|
|
const float backup_border_size = g.Style.ChildBorderSize;
|
|
- if (!border)
|
|
|
|
|
|
+ if ((child_flags & ImGuiChildFlags_Border) == 0)
|
|
g.Style.ChildBorderSize = 0.0f;
|
|
g.Style.ChildBorderSize = 0.0f;
|
|
|
|
|
|
// Begin into window
|
|
// Begin into window
|
|
@@ -5804,7 +5837,7 @@ bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags ext
|
|
PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding);
|
|
PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding);
|
|
PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize);
|
|
PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize);
|
|
PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
|
|
PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
|
|
- bool ret = BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags);
|
|
|
|
|
|
+ bool ret = BeginChild(id, size, ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding, ImGuiWindowFlags_NoMove | extra_flags);
|
|
PopStyleVar(3);
|
|
PopStyleVar(3);
|
|
PopStyleColor();
|
|
PopStyleColor();
|
|
return ret;
|
|
return ret;
|
|
@@ -5941,6 +5974,25 @@ static ImGuiWindow* GetWindowForTitleAndMenuHeight(ImGuiWindow* window)
|
|
return (window->DockNodeAsHost && window->DockNodeAsHost->VisibleWindow) ? window->DockNodeAsHost->VisibleWindow : window;
|
|
return (window->DockNodeAsHost && window->DockNodeAsHost->VisibleWindow) ? window->DockNodeAsHost->VisibleWindow : window;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline ImVec2 CalcWindowMinSize(ImGuiWindow* window)
|
|
|
|
+{
|
|
|
|
+ // Popups, menus and childs bypass style.WindowMinSize by default, but we give then a non-zero minimum size to facilitate understanding problematic cases (e.g. empty popups)
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImVec2 size_min;
|
|
|
|
+ if (window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_ChildWindow))
|
|
|
|
+ {
|
|
|
|
+ size_min.x = (window->ChildFlags & ImGuiChildFlags_ResizeX) ? g.Style.WindowMinSize.x : 4.0f;
|
|
|
|
+ size_min.y = (window->ChildFlags & ImGuiChildFlags_ResizeY) ? g.Style.WindowMinSize.y : 4.0f;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window);
|
|
|
|
+ size_min = g.Style.WindowMinSize;
|
|
|
|
+ size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
|
|
|
|
+ }
|
|
|
|
+ return size_min;
|
|
|
|
+}
|
|
|
|
+
|
|
static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& size_desired)
|
|
static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& size_desired)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -5966,14 +6018,8 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& s
|
|
}
|
|
}
|
|
|
|
|
|
// Minimum size
|
|
// Minimum size
|
|
- if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize)))
|
|
|
|
- {
|
|
|
|
- ImGuiWindow* window_for_height = GetWindowForTitleAndMenuHeight(window);
|
|
|
|
- new_size = ImMax(new_size, g.Style.WindowMinSize);
|
|
|
|
- const float minimum_height = window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f);
|
|
|
|
- new_size.y = ImMax(new_size.y, minimum_height); // Reduce artifacts with very small windows
|
|
|
|
- }
|
|
|
|
- return new_size;
|
|
|
|
|
|
+ ImVec2 size_min = CalcWindowMinSize(window);
|
|
|
|
+ return ImMax(new_size, size_min);
|
|
}
|
|
}
|
|
|
|
|
|
static void CalcWindowContentSizes(ImGuiWindow* window, ImVec2* content_size_current, ImVec2* content_size_ideal)
|
|
static void CalcWindowContentSizes(ImGuiWindow* window, ImVec2* content_size_current, ImVec2* content_size_ideal)
|
|
@@ -6012,12 +6058,7 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont
|
|
else
|
|
else
|
|
{
|
|
{
|
|
// Maximum window size is determined by the viewport size or monitor size
|
|
// Maximum window size is determined by the viewport size or monitor size
|
|
- const bool is_popup = (window->Flags & ImGuiWindowFlags_Popup) != 0;
|
|
|
|
- const bool is_menu = (window->Flags & ImGuiWindowFlags_ChildMenu) != 0;
|
|
|
|
- ImVec2 size_min = style.WindowMinSize;
|
|
|
|
- if (is_popup || is_menu) // Popups and menus bypass style.WindowMinSize by default, but we give then a non-zero minimum size to facilitate understanding problematic cases (e.g. empty popups)
|
|
|
|
- size_min = ImMin(size_min, ImVec2(4.0f, 4.0f));
|
|
|
|
-
|
|
|
|
|
|
+ ImVec2 size_min = CalcWindowMinSize(window);
|
|
ImVec2 avail_size = window->Viewport->WorkSize;
|
|
ImVec2 avail_size = window->Viewport->WorkSize;
|
|
if (window->ViewportOwned)
|
|
if (window->ViewportOwned)
|
|
avail_size = ImVec2(FLT_MAX, FLT_MAX);
|
|
avail_size = ImVec2(FLT_MAX, FLT_MAX);
|
|
@@ -6072,7 +6113,7 @@ static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& co
|
|
*out_size = size_constrained;
|
|
*out_size = size_constrained;
|
|
}
|
|
}
|
|
|
|
|
|
-// Data for resizing from corner
|
|
|
|
|
|
+// Data for resizing from resize grip / corner
|
|
struct ImGuiResizeGripDef
|
|
struct ImGuiResizeGripDef
|
|
{
|
|
{
|
|
ImVec2 CornerPosN;
|
|
ImVec2 CornerPosN;
|
|
@@ -6090,9 +6131,9 @@ static const ImGuiResizeGripDef resize_grip_def[4] =
|
|
// Data for resizing from borders
|
|
// Data for resizing from borders
|
|
struct ImGuiResizeBorderDef
|
|
struct ImGuiResizeBorderDef
|
|
{
|
|
{
|
|
- ImVec2 InnerDir;
|
|
|
|
- ImVec2 SegmentN1, SegmentN2;
|
|
|
|
- float OuterAngle;
|
|
|
|
|
|
+ ImVec2 InnerDir; // Normal toward inside
|
|
|
|
+ ImVec2 SegmentN1, SegmentN2; // End positions, normalized (0,0: upper left)
|
|
|
|
+ float OuterAngle; // Angle toward outside
|
|
};
|
|
};
|
|
static const ImGuiResizeBorderDef resize_border_def[4] =
|
|
static const ImGuiResizeBorderDef resize_border_def[4] =
|
|
{
|
|
{
|
|
@@ -6138,7 +6179,7 @@ ImGuiID ImGui::GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir)
|
|
|
|
|
|
// Handle resize for: Resize Grips, Borders, Gamepad
|
|
// Handle resize for: Resize Grips, Borders, Gamepad
|
|
// Return true when using auto-fit (double-click on resize grip)
|
|
// Return true when using auto-fit (double-click on resize grip)
|
|
-static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect)
|
|
|
|
|
|
+static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_hovered, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiWindowFlags flags = window->Flags;
|
|
ImGuiWindowFlags flags = window->Flags;
|
|
@@ -6148,8 +6189,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
if (window->WasActive == false) // Early out to avoid running this code for e.g. a hidden implicit/fallback Debug window.
|
|
if (window->WasActive == false) // Early out to avoid running this code for e.g. a hidden implicit/fallback Debug window.
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- bool ret_auto_fit = false;
|
|
|
|
- const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0;
|
|
|
|
|
|
+ int ret_auto_fit_mask = 0x00;
|
|
const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
|
const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
|
const float grip_hover_inner_size = IM_TRUNC(grip_draw_size * 0.75f);
|
|
const float grip_hover_inner_size = IM_TRUNC(grip_draw_size * 0.75f);
|
|
const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f;
|
|
const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f;
|
|
@@ -6194,11 +6234,11 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
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;
|
|
|
|
|
|
- if (held && g.IO.MouseClickedCount[0] == 2)
|
|
|
|
|
|
+ if (held && g.IO.MouseDoubleClicked[0])
|
|
{
|
|
{
|
|
- // Manual auto-fit when double-clicking
|
|
|
|
|
|
+ // Auto-fit when double-clicking
|
|
size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit);
|
|
size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit);
|
|
- ret_auto_fit = true;
|
|
|
|
|
|
+ ret_auto_fit_mask = 0x03; // Both axises
|
|
ClearActiveID();
|
|
ClearActiveID();
|
|
}
|
|
}
|
|
else if (held)
|
|
else if (held)
|
|
@@ -6216,8 +6256,16 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
if (resize_grip_n == 0 || held || hovered)
|
|
if (resize_grip_n == 0 || held || hovered)
|
|
resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
|
|
resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
|
|
}
|
|
}
|
|
- for (int border_n = 0; border_n < resize_border_count; border_n++)
|
|
|
|
|
|
+
|
|
|
|
+ int resize_border_mask = 0x00;
|
|
|
|
+ if (window->Flags & ImGuiWindowFlags_ChildWindow)
|
|
|
|
+ resize_border_mask |= ((window->ChildFlags & ImGuiChildFlags_ResizeX) ? 0x02 : 0) | ((window->ChildFlags & ImGuiChildFlags_ResizeY) ? 0x08 : 0);
|
|
|
|
+ else
|
|
|
|
+ resize_border_mask = g.IO.ConfigWindowsResizeFromEdges ? 0x0F : 0x00;
|
|
|
|
+ for (int border_n = 0; border_n < 4; border_n++)
|
|
{
|
|
{
|
|
|
|
+ if ((resize_border_mask & (1 << border_n)) == 0)
|
|
|
|
+ continue;
|
|
const ImGuiResizeBorderDef& def = resize_border_def[border_n];
|
|
const ImGuiResizeBorderDef& def = resize_border_def[border_n];
|
|
const ImGuiAxis axis = (border_n == ImGuiDir_Left || border_n == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y;
|
|
const ImGuiAxis axis = (border_n == ImGuiDir_Left || border_n == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y;
|
|
|
|
|
|
@@ -6226,22 +6274,68 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID()
|
|
ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID()
|
|
ItemAdd(border_rect, border_id, NULL, ImGuiItemFlags_NoNav);
|
|
ItemAdd(border_rect, border_id, NULL, ImGuiItemFlags_NoNav);
|
|
ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
|
|
ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
|
|
- //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
|
|
|
|
- if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held)
|
|
|
|
- {
|
|
|
|
|
|
+ //GetForegroundDrawList(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
|
|
|
|
+ if (hovered && g.HoveredIdTimer <= WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER)
|
|
|
|
+ hovered = false;
|
|
|
|
+ if (hovered || held)
|
|
g.MouseCursor = (axis == ImGuiAxis_X) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
|
|
g.MouseCursor = (axis == ImGuiAxis_X) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
|
|
- if (held)
|
|
|
|
- *border_held = border_n;
|
|
|
|
|
|
+ if (held && g.IO.MouseDoubleClicked[0])
|
|
|
|
+ {
|
|
|
|
+ // Double-clicking bottom or right border auto-fit on this axis
|
|
|
|
+ // FIXME: Support top and right borders: rework CalcResizePosSizeFromAnyCorner() to be reusable in both cases.
|
|
|
|
+ if (border_n == 1 || border_n == 3) // Right and bottom border
|
|
|
|
+ {
|
|
|
|
+ size_target[axis] = CalcWindowSizeAfterConstraint(window, size_auto_fit)[axis];
|
|
|
|
+ ret_auto_fit_mask |= (1 << axis);
|
|
|
|
+ hovered = held = false; // So border doesn't show highlighted at new position
|
|
|
|
+ }
|
|
|
|
+ ClearActiveID();
|
|
}
|
|
}
|
|
- if (held)
|
|
|
|
|
|
+ else if (held)
|
|
{
|
|
{
|
|
|
|
+ // Switch to relative resizing mode when border geometry moved (e.g. resizing a child altering parent scroll), in order to avoid resizing feedback loop.
|
|
|
|
+ // Currently only using relative mode on resizable child windows, as the problem to solve is more likely noticeable for them, but could apply for all windows eventually.
|
|
|
|
+ // FIXME: May want to generalize this idiom at lower-level, so more widgets can use it!
|
|
|
|
+ const bool just_scrolled_manually_while_resizing = (g.WheelingWindow != NULL && g.WheelingWindowScrolledFrame == g.FrameCount && IsWindowChildOf(window, g.WheelingWindow, false, true));
|
|
|
|
+ if (g.ActiveIdIsJustActivated || just_scrolled_manually_while_resizing)
|
|
|
|
+ {
|
|
|
|
+ g.WindowResizeBorderExpectedRect = border_rect;
|
|
|
|
+ g.WindowResizeRelativeMode = false;
|
|
|
|
+ }
|
|
|
|
+ if ((window->Flags & ImGuiWindowFlags_ChildWindow) && memcmp(&g.WindowResizeBorderExpectedRect, &border_rect, sizeof(ImRect)) != 0)
|
|
|
|
+ g.WindowResizeRelativeMode = true;
|
|
|
|
+
|
|
|
|
+ const ImVec2 border_curr = (window->Pos + ImMin(def.SegmentN1, def.SegmentN2) * window->Size);
|
|
|
|
+ const float border_target_rel_mode_for_axis = border_curr[axis] + g.IO.MouseDelta[axis];
|
|
|
|
+ const float border_target_abs_mode_for_axis = g.IO.MousePos[axis] - g.ActiveIdClickOffset[axis] + WINDOWS_HOVER_PADDING; // Match ButtonBehavior() padding above.
|
|
|
|
+
|
|
|
|
+ // Use absolute mode position
|
|
|
|
+ ImVec2 border_target = window->Pos;
|
|
|
|
+ border_target[axis] = border_target_abs_mode_for_axis;
|
|
|
|
+
|
|
|
|
+ // Use relative mode target for child window, ignore resize when moving back toward the ideal absolute position.
|
|
|
|
+ bool ignore_resize = false;
|
|
|
|
+ if (g.WindowResizeRelativeMode)
|
|
|
|
+ {
|
|
|
|
+ //GetForegroundDrawList()->AddText(GetMainViewport()->WorkPos, IM_COL32_WHITE, "Relative Mode");
|
|
|
|
+ border_target[axis] = border_target_rel_mode_for_axis;
|
|
|
|
+ if (g.IO.MouseDelta[axis] == 0.0f || (g.IO.MouseDelta[axis] > 0.0f) == (border_target_rel_mode_for_axis > border_target_abs_mode_for_axis))
|
|
|
|
+ ignore_resize = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Clamp, apply
|
|
ImVec2 clamp_min(border_n == ImGuiDir_Right ? clamp_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down || (border_n == ImGuiDir_Up && window_move_from_title_bar) ? clamp_rect.Min.y : -FLT_MAX);
|
|
ImVec2 clamp_min(border_n == ImGuiDir_Right ? clamp_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down || (border_n == ImGuiDir_Up && window_move_from_title_bar) ? clamp_rect.Min.y : -FLT_MAX);
|
|
ImVec2 clamp_max(border_n == ImGuiDir_Left ? clamp_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? clamp_rect.Max.y : +FLT_MAX);
|
|
ImVec2 clamp_max(border_n == ImGuiDir_Left ? clamp_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? clamp_rect.Max.y : +FLT_MAX);
|
|
- ImVec2 border_target = window->Pos;
|
|
|
|
- border_target[axis] = g.IO.MousePos[axis] - g.ActiveIdClickOffset[axis] + WINDOWS_HOVER_PADDING;
|
|
|
|
border_target = ImClamp(border_target, clamp_min, clamp_max);
|
|
border_target = ImClamp(border_target, clamp_min, clamp_max);
|
|
- CalcResizePosSizeFromAnyCorner(window, border_target, ImMin(def.SegmentN1, def.SegmentN2), &pos_target, &size_target);
|
|
|
|
|
|
+ if (window->Flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent
|
|
|
|
+ border_target = ImClamp(border_target, window->ParentWindow->InnerClipRect.Min, window->ParentWindow->InnerClipRect.Max);
|
|
|
|
+ if (!ignore_resize)
|
|
|
|
+ CalcResizePosSizeFromAnyCorner(window, border_target, ImMin(def.SegmentN1, def.SegmentN2), &pos_target, &size_target);
|
|
}
|
|
}
|
|
|
|
+ if (hovered)
|
|
|
|
+ *border_hovered = border_n;
|
|
|
|
+ if (held)
|
|
|
|
+ *border_held = border_n;
|
|
}
|
|
}
|
|
PopID();
|
|
PopID();
|
|
|
|
|
|
@@ -6279,18 +6373,21 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
|
|
|
|
|
// Apply back modified position/size to window
|
|
// Apply back modified position/size to window
|
|
if (size_target.x != FLT_MAX)
|
|
if (size_target.x != FLT_MAX)
|
|
- {
|
|
|
|
- window->SizeFull = size_target;
|
|
|
|
- MarkIniSettingsDirty(window);
|
|
|
|
- }
|
|
|
|
|
|
+ window->Size.x = window->SizeFull.x = size_target.x;
|
|
|
|
+ if (size_target.y != FLT_MAX)
|
|
|
|
+ window->Size.y = window->SizeFull.y = size_target.y;
|
|
if (pos_target.x != FLT_MAX)
|
|
if (pos_target.x != FLT_MAX)
|
|
- {
|
|
|
|
- window->Pos = ImTrunc(pos_target);
|
|
|
|
|
|
+ window->Pos.x = ImTrunc(pos_target.x);
|
|
|
|
+ if (pos_target.y != FLT_MAX)
|
|
|
|
+ window->Pos.y = ImTrunc(pos_target.y);
|
|
|
|
+ if (size_target.x != FLT_MAX || size_target.y != FLT_MAX || pos_target.x != FLT_MAX || pos_target.y != FLT_MAX)
|
|
MarkIniSettingsDirty(window);
|
|
MarkIniSettingsDirty(window);
|
|
- }
|
|
|
|
|
|
|
|
- window->Size = window->SizeFull;
|
|
|
|
- return ret_auto_fit;
|
|
|
|
|
|
+ // Recalculate next expected border expected coordinates
|
|
|
|
+ if (*border_held != -1)
|
|
|
|
+ g.WindowResizeBorderExpectedRect = GetResizeBorderRect(window, *border_held, grip_hover_inner_size, WINDOWS_HOVER_PADDING);
|
|
|
|
+
|
|
|
|
+ return ret_auto_fit_mask;
|
|
}
|
|
}
|
|
|
|
|
|
static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_rect)
|
|
static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_rect)
|
|
@@ -6302,7 +6399,7 @@ static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_
|
|
window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max);
|
|
window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max);
|
|
}
|
|
}
|
|
|
|
|
|
-static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
|
|
|
|
|
+static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window, int border_hovered, int border_held)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
float rounding = window->WindowRounding;
|
|
float rounding = window->WindowRounding;
|
|
@@ -6310,14 +6407,15 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
|
if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground))
|
|
if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground))
|
|
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
|
|
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, 0, border_size);
|
|
|
|
|
|
- int border_held = window->ResizeBorderHeld;
|
|
|
|
- if (border_held != -1)
|
|
|
|
|
|
+ if (border_hovered != -1 || border_held != -1)
|
|
{
|
|
{
|
|
- const ImGuiResizeBorderDef& def = resize_border_def[border_held];
|
|
|
|
- ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f);
|
|
|
|
|
|
+ const int border_n = (border_held != -1) ? border_held : border_hovered;
|
|
|
|
+ const ImGuiResizeBorderDef& def = resize_border_def[border_n];
|
|
|
|
+ const ImRect border_r = GetResizeBorderRect(window, border_n, rounding, 0.0f);
|
|
|
|
+ const ImU32 border_col = GetColorU32((border_held != -1) ? ImGuiCol_SeparatorActive : ImGuiCol_SeparatorHovered);
|
|
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI * 0.25f, def.OuterAngle);
|
|
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI * 0.25f, def.OuterAngle);
|
|
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI * 0.25f);
|
|
window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.SegmentN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI * 0.25f);
|
|
- window->DrawList->PathStroke(GetColorU32(ImGuiCol_SeparatorActive), 0, ImMax(2.0f, border_size)); // Thicker than usual
|
|
|
|
|
|
+ window->DrawList->PathStroke(border_col, 0, ImMax(2.0f, border_size)); // Thicker than usual
|
|
}
|
|
}
|
|
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
|
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
|
{
|
|
{
|
|
@@ -6328,7 +6426,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
|
|
|
|
|
// Draw background and borders
|
|
// Draw background and borders
|
|
// Draw and handle scrollbars
|
|
// Draw and handle scrollbars
|
|
-void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size)
|
|
|
|
|
|
+void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size, int border_hovered, int border_held)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiStyle& style = g.Style;
|
|
ImGuiStyle& style = g.Style;
|
|
@@ -6467,7 +6565,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
|
|
|
|
|
// Borders (for dock node host they will be rendered over after the tab bar)
|
|
// Borders (for dock node host they will be rendered over after the tab bar)
|
|
if (handle_borders_and_resize_grips && !window->DockNodeAsHost)
|
|
if (handle_borders_and_resize_grips && !window->DockNodeAsHost)
|
|
- RenderWindowOuterBorders(window);
|
|
|
|
|
|
+ RenderWindowOuterBorders(window, border_hovered, border_held);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6669,6 +6767,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true);
|
|
SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true);
|
|
window->FlagsPreviousFrame = window->Flags;
|
|
window->FlagsPreviousFrame = window->Flags;
|
|
window->Flags = (ImGuiWindowFlags)flags;
|
|
window->Flags = (ImGuiWindowFlags)flags;
|
|
|
|
+ window->ChildFlags = (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : 0;
|
|
window->LastFrameActive = current_frame;
|
|
window->LastFrameActive = current_frame;
|
|
window->LastTimeActive = (float)g.Time;
|
|
window->LastTimeActive = (float)g.Time;
|
|
window->BeginOrderWithinParent = 0;
|
|
window->BeginOrderWithinParent = 0;
|
|
@@ -6779,6 +6878,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
{
|
|
{
|
|
window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f);
|
|
window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f);
|
|
window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f);
|
|
window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f);
|
|
|
|
+ if ((window->ChildFlags & ImGuiChildFlags_ResizeX) && (window->SetWindowSizeAllowFlags & ImGuiCond_FirstUseEver) == 0) // Axis-specific conditions for BeginChild()
|
|
|
|
+ g.NextWindowData.SizeVal.x = window->SizeFull.x;
|
|
|
|
+ if ((window->ChildFlags & ImGuiChildFlags_ResizeY) && (window->SetWindowSizeAllowFlags & ImGuiCond_FirstUseEver) == 0)
|
|
|
|
+ g.NextWindowData.SizeVal.y = window->SizeFull.y;
|
|
SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond);
|
|
SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond);
|
|
}
|
|
}
|
|
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll)
|
|
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll)
|
|
@@ -6893,10 +6996,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
window->WindowBorderSize = style.ChildBorderSize;
|
|
window->WindowBorderSize = style.ChildBorderSize;
|
|
else
|
|
else
|
|
window->WindowBorderSize = ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize;
|
|
window->WindowBorderSize = ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize;
|
|
- if (!window->DockIsActive && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f)
|
|
|
|
|
|
+ window->WindowPadding = style.WindowPadding;
|
|
|
|
+ if (!window->DockIsActive && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !(window->ChildFlags & ImGuiChildFlags_AlwaysUseWindowPadding) && window->WindowBorderSize == 0.0f)
|
|
window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f);
|
|
window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f);
|
|
- else
|
|
|
|
- window->WindowPadding = style.WindowPadding;
|
|
|
|
|
|
|
|
// Lock menu offset so size calculation can use it as menu-bar windows need a minimum size.
|
|
// Lock menu offset so size calculation can use it as menu-bar windows need a minimum size.
|
|
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
|
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
|
|
@@ -7088,14 +7190,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
const bool handle_borders_and_resize_grips = (window->DockNodeAsHost || !window->DockIsActive);
|
|
const bool handle_borders_and_resize_grips = (window->DockNodeAsHost || !window->DockIsActive);
|
|
|
|
|
|
// Handle manual resize: Resize Grips, Borders, Gamepad
|
|
// Handle manual resize: Resize Grips, Borders, Gamepad
|
|
- int border_held = -1;
|
|
|
|
|
|
+ int border_hovered = -1, border_held = -1;
|
|
ImU32 resize_grip_col[4] = {};
|
|
ImU32 resize_grip_col[4] = {};
|
|
- const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
|
|
|
|
|
+ const int resize_grip_count = (window->Flags & ImGuiWindowFlags_ChildWindow) ? 0 : g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
|
const float resize_grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
|
const float resize_grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
|
if (handle_borders_and_resize_grips && !window->Collapsed)
|
|
if (handle_borders_and_resize_grips && !window->Collapsed)
|
|
- if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
|
|
|
|
- use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
|
|
|
|
- window->ResizeBorderHeld = (signed char)border_held;
|
|
|
|
|
|
+ if (int auto_fit_mask = UpdateWindowManualResize(window, size_auto_fit, &border_hovered, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
|
|
|
|
+ {
|
|
|
|
+ if (auto_fit_mask & (1 << ImGuiAxis_X))
|
|
|
|
+ use_current_size_for_scrollbar_x = true;
|
|
|
|
+ if (auto_fit_mask & (1 << ImGuiAxis_Y))
|
|
|
|
+ use_current_size_for_scrollbar_y = true;
|
|
|
|
+ }
|
|
|
|
|
|
// Synchronize window --> viewport again and one last time (clamping and manual resize may have affected either)
|
|
// Synchronize window --> viewport again and one last time (clamping and manual resize may have affected either)
|
|
if (window->ViewportOwned)
|
|
if (window->ViewportOwned)
|
|
@@ -7227,7 +7333,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
// Handle title bar, scrollbar, resize grips and resize borders
|
|
// Handle title bar, scrollbar, resize grips and resize borders
|
|
const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow;
|
|
const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow;
|
|
const bool title_bar_is_highlight = want_focus || (window_to_highlight && (window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight || (window->DockNode && window->DockNode == window_to_highlight->DockNode)));
|
|
const bool title_bar_is_highlight = want_focus || (window_to_highlight && (window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight || (window->DockNode && window->DockNode == window_to_highlight->DockNode)));
|
|
- RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, handle_borders_and_resize_grips, resize_grip_count, resize_grip_col, resize_grip_draw_size);
|
|
|
|
|
|
+ RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, handle_borders_and_resize_grips, resize_grip_count, resize_grip_col, resize_grip_draw_size, border_hovered, border_held);
|
|
|
|
|
|
if (render_decorations_in_parent)
|
|
if (render_decorations_in_parent)
|
|
window->DrawList = &window->DrawListInst;
|
|
window->DrawList = &window->DrawListInst;
|
|
@@ -7404,18 +7510,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
window->HiddenFramesCanSkipItems = 1;
|
|
window->HiddenFramesCanSkipItems = 1;
|
|
}
|
|
}
|
|
|
|
|
|
- if (flags & ImGuiWindowFlags_ChildWindow)
|
|
|
|
|
|
+ if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ChildMenu))
|
|
{
|
|
{
|
|
// Child window can be out of sight and have "negative" clip windows.
|
|
// Child window can be out of sight and have "negative" clip windows.
|
|
// Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
|
|
// Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
|
|
- IM_ASSERT((flags& ImGuiWindowFlags_NoTitleBar) != 0 || (window->DockIsActive));
|
|
|
|
- if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) // FIXME: Doesn't make sense for ChildWindow??
|
|
|
|
- {
|
|
|
|
- const bool nav_request = (flags & ImGuiWindowFlags_NavFlattened) && (g.NavAnyRequest && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav);
|
|
|
|
- if (!g.LogEnabled && !nav_request)
|
|
|
|
- if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
|
|
|
|
- window->HiddenFramesCanSkipItems = 1;
|
|
|
|
- }
|
|
|
|
|
|
+ IM_ASSERT((flags& ImGuiWindowFlags_NoTitleBar) != 0 || window->DockIsActive);
|
|
|
|
+ const bool nav_request = (flags & ImGuiWindowFlags_NavFlattened) && (g.NavAnyRequest && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav);
|
|
|
|
+ if (!g.LogEnabled && !nav_request)
|
|
|
|
+ if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
|
|
|
|
+ window->HiddenFramesCanSkipItems = 1;
|
|
|
|
|
|
// Hide along with parent or if parent is collapsed
|
|
// Hide along with parent or if parent is collapsed
|
|
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0))
|
|
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0))
|
|
@@ -9470,6 +9573,7 @@ void ImGui::UpdateMouseWheel()
|
|
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
|
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
|
float scroll_step = ImTrunc(ImMin(2 * window->CalcFontSize(), max_step));
|
|
float scroll_step = ImTrunc(ImMin(2 * window->CalcFontSize(), max_step));
|
|
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
|
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
|
|
|
+ g.WheelingWindowScrolledFrame = g.FrameCount;
|
|
}
|
|
}
|
|
if (do_scroll[ImGuiAxis_Y])
|
|
if (do_scroll[ImGuiAxis_Y])
|
|
{
|
|
{
|
|
@@ -9477,6 +9581,7 @@ void ImGui::UpdateMouseWheel()
|
|
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
|
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
|
float scroll_step = ImTrunc(ImMin(5 * window->CalcFontSize(), max_step));
|
|
float scroll_step = ImTrunc(ImMin(5 * window->CalcFontSize(), max_step));
|
|
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
|
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
|
|
|
+ g.WheelingWindowScrolledFrame = g.FrameCount;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -9750,6 +9855,12 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// This is the only public API until we expose owner_id versions of the API as replacements.
|
|
|
|
+bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord)
|
|
|
|
+{
|
|
|
|
+ return IsKeyChordPressed(key_chord, 0, ImGuiInputFlags_None);
|
|
|
|
+}
|
|
|
|
+
|
|
// This is equivalent to comparing KeyMods + doing a IsKeyPressed()
|
|
// This is equivalent to comparing KeyMods + doing a IsKeyPressed()
|
|
bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
|
|
bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
|
|
{
|
|
{
|
|
@@ -13953,6 +14064,7 @@ static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*,
|
|
else if (sscanf(line, "ViewportId=0x%08X", &u1) == 1) { settings->ViewportId = u1; }
|
|
else if (sscanf(line, "ViewportId=0x%08X", &u1) == 1) { settings->ViewportId = u1; }
|
|
else if (sscanf(line, "ViewportPos=%i,%i", &x, &y) == 2){ settings->ViewportPos = ImVec2ih((short)x, (short)y); }
|
|
else if (sscanf(line, "ViewportPos=%i,%i", &x, &y) == 2){ settings->ViewportPos = ImVec2ih((short)x, (short)y); }
|
|
else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); }
|
|
else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); }
|
|
|
|
+ else if (sscanf(line, "IsChild=%d", &i) == 1) { settings->IsChild = (i != 0); }
|
|
else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; }
|
|
else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; }
|
|
else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; }
|
|
else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; }
|
|
else if (sscanf(line, "ClassId=0x%X", &u1) == 1) { settings->ClassId = u1; }
|
|
else if (sscanf(line, "ClassId=0x%X", &u1) == 1) { settings->ClassId = u1; }
|
|
@@ -13997,6 +14109,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
|
|
settings->ClassId = window->WindowClass.ClassId;
|
|
settings->ClassId = window->WindowClass.ClassId;
|
|
settings->DockOrder = window->DockOrder;
|
|
settings->DockOrder = window->DockOrder;
|
|
settings->Collapsed = window->Collapsed;
|
|
settings->Collapsed = window->Collapsed;
|
|
|
|
+ settings->IsChild = (window->Flags & ImGuiWindowFlags_ChildWindow) != 0;
|
|
settings->WantDelete = false;
|
|
settings->WantDelete = false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -14008,25 +14121,33 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
|
|
continue;
|
|
continue;
|
|
const char* settings_name = settings->GetName();
|
|
const char* settings_name = settings->GetName();
|
|
buf->appendf("[%s][%s]\n", handler->TypeName, settings_name);
|
|
buf->appendf("[%s][%s]\n", handler->TypeName, settings_name);
|
|
- if (settings->ViewportId != 0 && settings->ViewportId != ImGui::IMGUI_VIEWPORT_DEFAULT_ID)
|
|
|
|
|
|
+ if (settings->IsChild)
|
|
{
|
|
{
|
|
- buf->appendf("ViewportPos=%d,%d\n", settings->ViewportPos.x, settings->ViewportPos.y);
|
|
|
|
- buf->appendf("ViewportId=0x%08X\n", settings->ViewportId);
|
|
|
|
- }
|
|
|
|
- if (settings->Pos.x != 0 || settings->Pos.y != 0 || settings->ViewportId == ImGui::IMGUI_VIEWPORT_DEFAULT_ID)
|
|
|
|
- buf->appendf("Pos=%d,%d\n", settings->Pos.x, settings->Pos.y);
|
|
|
|
- if (settings->Size.x != 0 || settings->Size.y != 0)
|
|
|
|
|
|
+ buf->appendf("IsChild=1\n");
|
|
buf->appendf("Size=%d,%d\n", settings->Size.x, settings->Size.y);
|
|
buf->appendf("Size=%d,%d\n", settings->Size.x, settings->Size.y);
|
|
- buf->appendf("Collapsed=%d\n", settings->Collapsed);
|
|
|
|
- if (settings->DockId != 0)
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
{
|
|
{
|
|
- //buf->appendf("TabId=0x%08X\n", ImHashStr("#TAB", 4, settings->ID)); // window->TabId: this is not read back but writing it makes "debugging" the .ini data easier.
|
|
|
|
- if (settings->DockOrder == -1)
|
|
|
|
- buf->appendf("DockId=0x%08X\n", settings->DockId);
|
|
|
|
- else
|
|
|
|
- buf->appendf("DockId=0x%08X,%d\n", settings->DockId, settings->DockOrder);
|
|
|
|
- if (settings->ClassId != 0)
|
|
|
|
- buf->appendf("ClassId=0x%08X\n", settings->ClassId);
|
|
|
|
|
|
+ if (settings->ViewportId != 0 && settings->ViewportId != ImGui::IMGUI_VIEWPORT_DEFAULT_ID)
|
|
|
|
+ {
|
|
|
|
+ buf->appendf("ViewportPos=%d,%d\n", settings->ViewportPos.x, settings->ViewportPos.y);
|
|
|
|
+ buf->appendf("ViewportId=0x%08X\n", settings->ViewportId);
|
|
|
|
+ }
|
|
|
|
+ if (settings->Pos.x != 0 || settings->Pos.y != 0 || settings->ViewportId == ImGui::IMGUI_VIEWPORT_DEFAULT_ID)
|
|
|
|
+ buf->appendf("Pos=%d,%d\n", settings->Pos.x, settings->Pos.y);
|
|
|
|
+ if (settings->Size.x != 0 || settings->Size.y != 0)
|
|
|
|
+ buf->appendf("Size=%d,%d\n", settings->Size.x, settings->Size.y);
|
|
|
|
+ buf->appendf("Collapsed=%d\n", settings->Collapsed);
|
|
|
|
+ if (settings->DockId != 0)
|
|
|
|
+ {
|
|
|
|
+ //buf->appendf("TabId=0x%08X\n", ImHashStr("#TAB", 4, settings->ID)); // window->TabId: this is not read back but writing it makes "debugging" the .ini data easier.
|
|
|
|
+ if (settings->DockOrder == -1)
|
|
|
|
+ buf->appendf("DockId=0x%08X\n", settings->DockId);
|
|
|
|
+ else
|
|
|
|
+ buf->appendf("DockId=0x%08X,%d\n", settings->DockId, settings->DockOrder);
|
|
|
|
+ if (settings->ClassId != 0)
|
|
|
|
+ buf->appendf("ClassId=0x%08X\n", settings->ClassId);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
buf->append("\n");
|
|
buf->append("\n");
|
|
}
|
|
}
|
|
@@ -18614,7 +18735,8 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
|
|
|
|
|
|
// Update window flag
|
|
// Update window flag
|
|
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) == 0);
|
|
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) == 0);
|
|
- window->Flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoResize;
|
|
|
|
|
|
+ window->Flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoResize;
|
|
|
|
+ window->ChildFlags |= ImGuiChildFlags_AlwaysUseWindowPadding;
|
|
if (node->IsHiddenTabBar() || node->IsNoTabBar())
|
|
if (node->IsHiddenTabBar() || node->IsNoTabBar())
|
|
window->Flags |= ImGuiWindowFlags_NoTitleBar;
|
|
window->Flags |= ImGuiWindowFlags_NoTitleBar;
|
|
else
|
|
else
|
|
@@ -20550,7 +20672,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
|
|
SameLine();
|
|
SameLine();
|
|
if (SmallButton("Copy"))
|
|
if (SmallButton("Copy"))
|
|
SetClipboardText(g.DebugLogBuf.c_str());
|
|
SetClipboardText(g.DebugLogBuf.c_str());
|
|
- BeginChild("##log", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
|
|
|
|
|
+ BeginChild("##log", ImVec2(0.0f, 0.0f), ImGuiChildFlags_Border, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
|
|
|
|
|
ImGuiListClipper clipper;
|
|
ImGuiListClipper clipper;
|
|
clipper.Begin(g.DebugLogIndex.size());
|
|
clipper.Begin(g.DebugLogIndex.size());
|