Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_internal.h
This commit is contained in:
omar 2019-06-05 16:09:06 +02:00
commit e6850891cc
7 changed files with 364 additions and 189 deletions

View File

@ -106,6 +106,13 @@ Breaking Changes:
- Renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete). - Renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete).
Other Changes: Other Changes:
- Window: clarified behavior of SetNextWindowContentSize(). Content size is defined as the size available
after removal of WindowPadding on each sides. So SetNextWindowContentSize(ImVec2(100,100)) + auto-resize
will always allow submitting a 100x100 item without creating a scrollbar, regarding of WindowPadding.
The exact meaning of ContentSize for decorated windows was previously ill-defined.
- Window: Fixed auto-resize with AlwaysVerticalScrollbar or AlwaysHorizontalScrollbar flags.
- Window: Fixed one case where auto-resize by double-clicking the resize grip would make either scrollbar
appear for a single frame after the resize.
- Columns: Fixed Separator from creating an extraneous draw command. (#125) - Columns: Fixed Separator from creating an extraneous draw command. (#125)
- Columns: Fixed Selectable with SpanAllColumns flag from creating an extraneous draw command. (#125) - Columns: Fixed Selectable with SpanAllColumns flag from creating an extraneous draw command. (#125)
- Separator: Revert 1.70 "Declare its thickness (1.0f) to the layout" change. It's not incorrect - Separator: Revert 1.70 "Declare its thickness (1.0f) to the layout" change. It's not incorrect
@ -121,7 +128,8 @@ Other Changes:
- ColorEdit: Fixed the color picker popup only displaying inputs as HSV instead of showing multiple - ColorEdit: Fixed the color picker popup only displaying inputs as HSV instead of showing multiple
options. (#2587, broken in 1.69 by #2384). options. (#2587, broken in 1.69 by #2384).
- CollapsingHeader: Better clipping when a close button is enabled and it overlaps the label. (#600) - CollapsingHeader: Better clipping when a close button is enabled and it overlaps the label. (#600)
- Scrollbar: Very minor bounding box adjustment to cope with various border size. - Scrollbar: Minor bounding box adjustment to cope with various border size.
- Scrollbar, Style: Changed default style.ScrollbarSize from 16 to 14.
- Combo: Fixed rounding not applying with the ImGuiComboFlags_NoArrowButton flag. (#2607) [@DucaRii] - Combo: Fixed rounding not applying with the ImGuiComboFlags_NoArrowButton flag. (#2607) [@DucaRii]
- Nav: Fixed gamepad/keyboard moving of window affecting contents size incorrectly, sometimes leading - Nav: Fixed gamepad/keyboard moving of window affecting contents size incorrectly, sometimes leading
to scrollbars appearing during the movement. to scrollbars appearing during the movement.
@ -129,6 +137,12 @@ Other Changes:
frame as clearing the focus. This was in most noticeable in back-ends such as Glfw and SDL which frame as clearing the focus. This was in most noticeable in back-ends such as Glfw and SDL which
emits key release events when focusing another viewport, leading to Alt+clicking on void on another emits key release events when focusing another viewport, leading to Alt+clicking on void on another
viewport triggering the issue. (#2609) viewport triggering the issue. (#2609)
- TreeNode, CollapsingHeader: Fixed highlight frame not covering horizontal area fully when using
horizontal scrolling. (#2211, #2579)
- TabBar: Fixed BeginTabBar() within a window with horizontal scrolling from creating a feedback
loop with the horizontal contents size.
- Columns: Fixed Columns() within a window with horizontal scrolling from not covering the full
horizontal area (previously only worked with an explicit contents size). (#125)
- Style: Added style.WindowMenuButtonPosition (left/right, defaults to ImGuiDir_Left) to move the - Style: Added style.WindowMenuButtonPosition (left/right, defaults to ImGuiDir_Left) to move the
collapsing/docking button to the other side of the title bar. collapsing/docking button to the other side of the title bar.
- Style: Made window close button cross slightly smaller. - Style: Made window close button cross slightly smaller.

View File

@ -70,6 +70,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- widgets: selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection) - widgets: selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection)
- widgets: checkbox: checkbox with custom glyph inside frame. - widgets: checkbox: checkbox with custom glyph inside frame.
- widgets: coloredit: keep reporting as active when picker is on? - widgets: coloredit: keep reporting as active when picker is on?
- widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow.
- input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. - input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile.
- input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541)
@ -258,6 +259,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc. - style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc.
- style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation). - style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation).
- style: global scale setting. - style: global scale setting.
- style: FramePadding could be different for up vs down (#584)
- style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle - style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle
- style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223) - style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223)
- style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners. - style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners.

312
imgui.cpp
View File

@ -1090,7 +1090,7 @@ static int FindWindowFocusIndex(ImGuiWindow* window);
// Misc // Misc
static void UpdateMouseInputs(); static void UpdateMouseInputs();
static void UpdateMouseWheel(); static void UpdateMouseWheel();
static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); static bool UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
static void RenderWindowOuterBorders(ImGuiWindow* window); 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 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 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);
@ -1174,7 +1174,7 @@ ImGuiStyle::ImGuiStyle()
TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1). ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar ScrollbarSize = 14.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar
ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar
GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
@ -2599,7 +2599,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
ViewportPos = ImVec2(FLT_MAX, FLT_MAX); ViewportPos = ImVec2(FLT_MAX, FLT_MAX);
Pos = ImVec2(0.0f, 0.0f); Pos = ImVec2(0.0f, 0.0f);
Size = SizeFull = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f);
SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); ContentSize = ContentSizeExplicit = ImVec2(0.0f, 0.0f);
WindowPadding = ImVec2(0.0f, 0.0f); WindowPadding = ImVec2(0.0f, 0.0f);
WindowRounding = 0.0f; WindowRounding = 0.0f;
WindowBorderSize = 0.0f; WindowBorderSize = 0.0f;
@ -3060,7 +3060,7 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
if (wrap_pos_x == 0.0f) if (wrap_pos_x == 0.0f)
wrap_pos_x = GetContentRegionMaxAbs().x; wrap_pos_x = window->WorkRect.Max.x;
else if (wrap_pos_x > 0.0f) else if (wrap_pos_x > 0.0f)
wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space
@ -3393,7 +3393,7 @@ static void ScaleWindow(ImGuiWindow* window, float scale)
window->Pos = ImFloor((window->Pos - origin) * scale + origin); window->Pos = ImFloor((window->Pos - origin) * scale + origin);
window->Size = ImFloor(window->Size * scale); window->Size = ImFloor(window->Size * scale);
window->SizeFull = ImFloor(window->SizeFull * scale); window->SizeFull = ImFloor(window->SizeFull * scale);
window->SizeContents = ImFloor(window->SizeContents * scale); window->ContentSize = ImFloor(window->ContentSize * scale);
} }
static bool IsWindowActiveAndVisible(ImGuiWindow* window) static bool IsWindowActiveAndVisible(ImGuiWindow* window)
@ -4965,8 +4965,8 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
window->DockId = settings->DockId; window->DockId = settings->DockId;
window->DockOrder = settings->DockOrder; window->DockOrder = settings->DockOrder;
} }
window->Size = window->SizeFull = window->SizeFullAtLastBegin = ImFloor(size); window->Size = window->SizeFull = ImFloor(size);
window->DC.CursorMaxPos = window->Pos; // So first call to CalcSizeContents() doesn't return crazy values window->DC.CursorStartPos = window->DC.CursorMaxPos = window->Pos; // So first call to CalcContentSize() doesn't return crazy values
if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0)
{ {
@ -5033,28 +5033,31 @@ static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size)
return new_size; return new_size;
} }
static ImVec2 CalcSizeContents(ImGuiWindow* window) static ImVec2 CalcContentSize(ImGuiWindow* window)
{ {
if (window->Collapsed) if (window->Collapsed)
if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
return window->SizeContents; return window->ContentSize;
if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0) if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0)
return window->SizeContents; return window->ContentSize;
ImVec2 sz; ImVec2 sz;
sz.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : (window->DC.CursorMaxPos.x - window->Pos.x + window->Scroll.x)); sz.x = (float)(int)((window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
sz.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : (window->DC.CursorMaxPos.y - window->Pos.y + window->Scroll.y)); sz.y = (float)(int)((window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
return sz + window->WindowPadding; return sz;
} }
static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents) static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiStyle& style = g.Style; ImGuiStyle& style = g.Style;
ImVec2 size_decorations = ImVec2(0.0f, window->TitleBarHeight() + window->MenuBarHeight());
ImVec2 size_pad = window->WindowPadding * 2.0f;
ImVec2 size_desired = size_contents + size_pad + size_decorations;
if (window->Flags & ImGuiWindowFlags_Tooltip) if (window->Flags & ImGuiWindowFlags_Tooltip)
{ {
// Tooltip always resize // Tooltip always resize
return size_contents; return size_desired;
} }
else else
{ {
@ -5071,14 +5074,16 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents)
const int monitor_idx = window->ViewportAllowPlatformMonitorExtend; const int monitor_idx = window->ViewportAllowPlatformMonitorExtend;
if (monitor_idx >= 0 && monitor_idx < g.PlatformIO.Monitors.Size) if (monitor_idx >= 0 && monitor_idx < g.PlatformIO.Monitors.Size)
avail_size = g.PlatformIO.Monitors[monitor_idx].WorkSize; avail_size = g.PlatformIO.Monitors[monitor_idx].WorkSize;
ImVec2 size_auto_fit = ImClamp(size_contents, size_min, ImMax(size_min, avail_size - g.Style.DisplaySafeAreaPadding * 2.0f)); ImVec2 size_auto_fit = ImClamp(size_desired, size_min, ImMax(size_min, avail_size - g.Style.DisplaySafeAreaPadding * 2.0f));
// When the window cannot fit all contents (either because of constraints, either because screen is too small), // When the window cannot fit all contents (either because of constraints, either because screen is too small),
// we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding. // we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding.
ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit); ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit);
if (size_auto_fit_after_constraint.x < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - size_decorations.x < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar);
bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - size_decorations.y < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar);
if (will_have_scrollbar_x)
size_auto_fit.y += style.ScrollbarSize; size_auto_fit.y += style.ScrollbarSize;
if (size_auto_fit_after_constraint.y < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) if (will_have_scrollbar_y)
size_auto_fit.x += style.ScrollbarSize; size_auto_fit.x += style.ScrollbarSize;
return size_auto_fit; return size_auto_fit;
} }
@ -5086,20 +5091,10 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents)
ImVec2 ImGui::CalcWindowExpectedSize(ImGuiWindow* window) ImVec2 ImGui::CalcWindowExpectedSize(ImGuiWindow* window)
{ {
ImVec2 size_contents = CalcSizeContents(window); ImVec2 size_contents = CalcContentSize(window);
return CalcSizeAfterConstraint(window, CalcSizeAutoFit(window, size_contents)); return CalcSizeAfterConstraint(window, CalcSizeAutoFit(window, size_contents));
} }
float ImGui::GetWindowScrollMaxX(ImGuiWindow* window)
{
return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x));
}
float ImGui::GetWindowScrollMaxY(ImGuiWindow* window)
{
return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y));
}
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges) static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -5107,7 +5102,7 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool s
if (window->ScrollTarget.x < FLT_MAX) if (window->ScrollTarget.x < FLT_MAX)
{ {
float cr_x = window->ScrollTargetCenterRatio.x; float cr_x = window->ScrollTargetCenterRatio.x;
scroll.x = window->ScrollTarget.x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x); scroll.x = window->ScrollTarget.x - cr_x * window->InnerRect.GetWidth();
} }
if (window->ScrollTarget.y < FLT_MAX) if (window->ScrollTarget.y < FLT_MAX)
{ {
@ -5116,15 +5111,15 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool s
float target_y = window->ScrollTarget.y; float target_y = window->ScrollTarget.y;
if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y) if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y)
target_y = 0.0f; target_y = 0.0f;
if (snap_on_edges && cr_y >= 1.0f && target_y >= window->SizeContents.y - window->WindowPadding.y + g.Style.ItemSpacing.y) if (snap_on_edges && cr_y >= 1.0f && target_y >= window->ContentSize.y + window->WindowPadding.y + g.Style.ItemSpacing.y)
target_y = window->SizeContents.y; target_y = window->ContentSize.y + window->WindowPadding.y * 2.0f;
scroll.y = target_y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y); scroll.y = target_y - cr_y * window->InnerRect.GetHeight();
} }
scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); scroll = ImMax(scroll, ImVec2(0.0f, 0.0f));
if (!window->Collapsed && !window->SkipItems) if (!window->Collapsed && !window->SkipItems)
{ {
scroll.x = ImMin(scroll.x, ImGui::GetWindowScrollMaxX(window)); scroll.x = ImMin(scroll.x, window->ScrollMax.x);
scroll.y = ImMin(scroll.y, ImGui::GetWindowScrollMaxY(window)); scroll.y = ImMin(scroll.y, window->ScrollMax.y);
} }
return scroll; return scroll;
} }
@ -5180,15 +5175,18 @@ static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_
} }
// Handle resize for: Resize Grips, Borders, Gamepad // Handle resize for: Resize Grips, Borders, Gamepad
static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]) // Return true when using auto-fit (double click on resize grip)
static bool ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4])
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindowFlags flags = window->Flags; ImGuiWindowFlags flags = window->Flags;
if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
return;
if (window->WasActive == false) // Early out to avoid running this code for e.g. an hidden implicit/fallback Debug window.
return;
if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
return false;
if (window->WasActive == false) // Early out to avoid running this code for e.g. an hidden implicit/fallback Debug window.
return false;
bool ret_auto_fit = false;
const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0; const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0;
const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f);
const float grip_hover_inner_size = (float)(int)(grip_draw_size * 0.75f); const float grip_hover_inner_size = (float)(int)(grip_draw_size * 0.75f);
@ -5222,6 +5220,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
{ {
// Manual auto-fit when double-clicking // Manual auto-fit when double-clicking
size_target = CalcSizeAfterConstraint(window, size_auto_fit); size_target = CalcSizeAfterConstraint(window, size_auto_fit);
ret_auto_fit = true;
ClearActiveID(); ClearActiveID();
} }
else if (held) else if (held)
@ -5296,6 +5295,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main); window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
window->Size = window->SizeFull; window->Size = window->SizeFull;
return ret_auto_fit;
} }
static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, const ImVec2& padding) static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, const ImVec2& padding)
@ -5685,16 +5685,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond);
} }
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasContentSize) if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasContentSize)
{ window->ContentSizeExplicit = g.NextWindowData.ContentSizeVal;
// Adjust passed "client size" to become a "window size"
window->SizeContentsExplicit = g.NextWindowData.ContentSizeVal;
if (window->SizeContentsExplicit.y != 0.0f)
window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight();
}
else if (first_begin_of_the_frame) else if (first_begin_of_the_frame)
{ window->ContentSizeExplicit = ImVec2(0.0f, 0.0f);
window->SizeContentsExplicit = ImVec2(0.0f, 0.0f);
}
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasWindowClass) if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasWindowClass)
window->WindowClass = g.NextWindowData.WindowClass; window->WindowClass = g.NextWindowData.WindowClass;
if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasCollapsed) if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasCollapsed)
@ -5733,7 +5726,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
// Update contents size from last frame for auto-fitting (or use explicit size) // Update contents size from last frame for auto-fitting (or use explicit size)
window->SizeContents = CalcSizeContents(window); window->ContentSize = CalcContentSize(window);
if (window->HiddenFramesCanSkipItems > 0) if (window->HiddenFramesCanSkipItems > 0)
window->HiddenFramesCanSkipItems--; window->HiddenFramesCanSkipItems--;
if (window->HiddenFramesCannotSkipItems > 0) if (window->HiddenFramesCannotSkipItems > 0)
@ -5744,7 +5737,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->HiddenFramesCannotSkipItems = 1; window->HiddenFramesCannotSkipItems = 1;
// Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows)
// We reset Size/SizeContents for reappearing popups/tooltips early in this function, so further code won't be tempted to use the old size. // We reset Size/ContentSize for reappearing popups/tooltips early in this function, so further code won't be tempted to use the old size.
if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0) if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0)
{ {
window->HiddenFramesCannotSkipItems = 1; window->HiddenFramesCannotSkipItems = 1;
@ -5754,7 +5747,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Size.x = window->SizeFull.x = 0.f; window->Size.x = window->SizeFull.x = 0.f;
if (!window_size_y_set_by_api) if (!window_size_y_set_by_api)
window->Size.y = window->SizeFull.y = 0.f; window->Size.y = window->SizeFull.y = 0.f;
window->SizeContents = ImVec2(0.f, 0.f); window->ContentSize = ImVec2(0.f, 0.f);
} }
} }
@ -5767,8 +5760,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
SetCurrentWindow(window); SetCurrentWindow(window);
flags = window->Flags; flags = window->Flags;
// Lock border size and padding for the frame (so that altering them doesn't cause inconsistencies) // LOCK BORDER SIZE AND PADDING FOR THE FRAME (so that altering them doesn't cause inconsistencies)
// We read Style data after the call to UpdateSelectWindowViewport() which might be swapping the style. // We read Style data after the call to UpdateSelectWindowViewport() which might be swapping the style.
if (flags & ImGuiWindowFlags_ChildWindow) if (flags & ImGuiWindowFlags_ChildWindow)
window->WindowBorderSize = style.ChildBorderSize; window->WindowBorderSize = style.ChildBorderSize;
else else
@ -5804,24 +5798,37 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// SIZE // SIZE
// Calculate auto-fit size, handle automatic resize // Calculate auto-fit size, handle automatic resize
const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->ContentSize);
ImVec2 size_full_modified(FLT_MAX, FLT_MAX); bool use_current_size_for_scrollbar_x = window_just_created;
bool use_current_size_for_scrollbar_y = window_just_created;
if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed) if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed)
{ {
// Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc.
if (!window_size_x_set_by_api) if (!window_size_x_set_by_api)
window->SizeFull.x = size_full_modified.x = size_auto_fit.x; {
window->SizeFull.x = size_auto_fit.x;
use_current_size_for_scrollbar_x = true;
}
if (!window_size_y_set_by_api) if (!window_size_y_set_by_api)
window->SizeFull.y = size_full_modified.y = size_auto_fit.y; {
window->SizeFull.y = size_auto_fit.y;
use_current_size_for_scrollbar_y = true;
}
} }
else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
{ {
// Auto-fit may only grow window during the first few frames // Auto-fit may only grow window during the first few frames
// We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed.
if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) if (!window_size_x_set_by_api && window->AutoFitFramesX > 0)
window->SizeFull.x = size_full_modified.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;
use_current_size_for_scrollbar_x = true;
}
if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) if (!window_size_y_set_by_api && window->AutoFitFramesY > 0)
window->SizeFull.y = size_full_modified.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;
use_current_size_for_scrollbar_y = true;
}
if (!window->Collapsed) if (!window->Collapsed)
MarkIniSettingsDirty(window); MarkIniSettingsDirty(window);
} }
@ -5830,20 +5837,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull); window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull);
window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull;
// SCROLLBAR STATUS // Decoration size
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
// Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size).
if (!window->Collapsed)
{
// When reading the current size we need to read it after size constraints have been applied
float size_x_for_scrollbars = size_full_modified.x != FLT_MAX ? window->SizeFull.x : window->SizeFullAtLastBegin.x;
float size_y_for_scrollbars = size_full_modified.y != FLT_MAX ? window->SizeFull.y : window->SizeFullAtLastBegin.y;
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar));
window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
if (window->ScrollbarX && !window->ScrollbarY)
window->ScrollbarY = (window->SizeContents.y > size_y_for_scrollbars - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar);
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
}
// POSITION // POSITION
@ -5949,7 +5944,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->Viewport->Flags = viewport_flags; window->Viewport->Flags = viewport_flags;
} }
// Clamp position so window stays visible within its viewport or monitor // Clamp position/size so window stays visible within its viewport or monitor
// Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
ImRect viewport_rect = window->Viewport->GetRect(); ImRect viewport_rect = window->Viewport->GetRect();
if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
@ -5978,10 +5973,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if (window->ViewportOwned) if (window->ViewportOwned)
window->WindowRounding = 0.0f; window->WindowRounding = 0.0f;
// Apply scrolling
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true);
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
// Apply window focus (new and reactivated windows are moved to front) // Apply window focus (new and reactivated windows are moved to front)
bool want_focus = false; bool want_focus = false;
if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing))
@ -6001,7 +5992,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // 4 const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // 4
const float resize_grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); const float resize_grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f);
if (handle_borders_and_resize_grips && !window->Collapsed) if (handle_borders_and_resize_grips && !window->Collapsed)
UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]); if (UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
window->ResizeBorderHeld = (signed char)border_held; window->ResizeBorderHeld = (signed char)border_held;
// 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)
@ -6017,14 +6009,23 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Save last known viewport position within the window itself (so it can be saved in .ini file and restored) // Save last known viewport position within the window itself (so it can be saved in .ini file and restored)
window->ViewportPos = window->Viewport->Pos; window->ViewportPos = window->Viewport->Pos;
// Default item width. Make it proportional to window size if window manually resizes // Update scrollbar visibility (based on the Size that was effective during last frame or the auto-resized Size).
if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) if (!window->Collapsed)
window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); {
else // When reading the current size we need to read it after size constraints have been applied.
window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f); // When we use InnerRect here we are intentionally reading last frame size, same for ScrollbarSizes values before we set them again.
ImVec2 avail_size_from_current_frame = ImVec2(window->SizeFull.x, window->SizeFull.y - decoration_up_height);
// Store a backup of SizeFull which we will use next frame to decide if we need scrollbars. ImVec2 avail_size_from_last_frame = window->InnerRect.GetSize() + window->ScrollbarSizes;
window->SizeFullAtLastBegin = window->SizeFull; ImVec2 needed_size_from_last_frame = window_just_created ? ImVec2(0, 0) : window->ContentSize + window->WindowPadding * 2.0f;
float size_x_for_scrollbars = use_current_size_for_scrollbar_x ? avail_size_from_current_frame.x : avail_size_from_last_frame.x;
float size_y_for_scrollbars = use_current_size_for_scrollbar_y ? avail_size_from_current_frame.y : avail_size_from_last_frame.y;
//bool scrollbar_y_from_last_frame = window->ScrollbarY; // FIXME: May want to use that in the ScrollbarX expression? How many pros vs cons?
window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar));
window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((needed_size_from_last_frame.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
if (window->ScrollbarX && !window->ScrollbarY)
window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar);
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
}
// UPDATE RECTANGLES (1- THOSE NOT AFFECTED BY SCROLLING) // UPDATE RECTANGLES (1- THOSE NOT AFFECTED BY SCROLLING)
// Update various regions. Variables they depends on should be set above in this function. // Update various regions. Variables they depends on should be set above in this function.
@ -6035,31 +6036,24 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// - FindHoveredWindow() (w/ extra padding when border resize is enabled) // - FindHoveredWindow() (w/ extra padding when border resize is enabled)
// - Begin() initial clipping rect for drawing window background and borders. // - Begin() initial clipping rect for drawing window background and borders.
// - Begin() clipping whole child // - Begin() clipping whole child
ImRect host_rect = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) ? parent_window->ClipRect : viewport_rect; const ImRect host_rect = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) ? parent_window->ClipRect : viewport_rect;
window->OuterRectClipped = window->Rect(); const ImRect outer_rect = window->Rect();
const ImRect title_bar_rect = window->TitleBarRect();
window->OuterRectClipped = outer_rect;
if (window->DockIsActive) if (window->DockIsActive)
window->OuterRectClipped.Min.y += window->TitleBarHeight(); window->OuterRectClipped.Min.y += window->TitleBarHeight();
window->OuterRectClipped.ClipWith(host_rect); window->OuterRectClipped.ClipWith(host_rect);
// Inner rectangle // Inner rectangle
// Used by: // Not affected by window border size. Used by:
// - InnerClipRect
// - NavScrollToBringItemIntoView() // - NavScrollToBringItemIntoView()
// - NavUpdatePageUpPageDown() // - NavUpdatePageUpPageDown()
// - Scrollbar() // - Scrollbar()
const ImRect title_bar_rect = window->TitleBarRect(); window->InnerRect.Min.x = window->Pos.x;
window->InnerRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize; window->InnerRect.Min.y = window->Pos.y + decoration_up_height;
window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x;
window->InnerRect.Max.x = window->Pos.x + window->Size.x - ImMax(window->ScrollbarSizes.x, window->WindowBorderSize); window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y;
window->InnerRect.Max.y = window->Pos.y + window->Size.y - ImMax(window->ScrollbarSizes.y, window->WindowBorderSize);
// Work rectangle.
// Affected by window padding and border size. Used by:
// - Columns() for right-most edge
// - BeginTabBar() for right-most edge
window->WorkRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
window->WorkRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y);
window->WorkRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
window->WorkRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y);
// Inner clipping rectangle. // Inner clipping rectangle.
// Will extend a little bit outside the normal work region. // Will extend a little bit outside the normal work region.
@ -6068,9 +6062,31 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior. // Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior.
// Affected by window/frame border size. Used by: // Affected by window/frame border size. Used by:
// - Begin() initial clip rect // - Begin() initial clip rect
window->InnerClipRect = window->WorkRect; float top_border_size = (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize);
window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize));
window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + top_border_size);
window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(ImFloor(window->WindowPadding.y * 0.5f), window->WindowBorderSize));
window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - window->WindowBorderSize);
window->InnerClipRect.ClipWithFull(host_rect); window->InnerClipRect.ClipWithFull(host_rect);
// Default item width. Make it proportional to window size if window manually resizes
if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize))
window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f);
else
window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f);
// SCROLLING
// Lock down maximum scrolling
// The value of ScrollMax are ahead from ScrollbarX/ScrollbarY which is intentionally using InnerRect from previous rect in order to accommodate
// for right/bottom aligned items without creating a scrollbar.
window->ScrollMax.x = ImMax(0.0f, window->ContentSize.x + window->WindowPadding.x * 2.0f - window->InnerRect.GetWidth());
window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight());
// Apply scrolling
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true);
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
// DRAWING // DRAWING
// Setup draw list and outer clipping rectangle // Setup draw list and outer clipping rectangle
@ -6102,30 +6118,42 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// UPDATE RECTANGLES (2- THOSE AFFECTED BY SCROLLING) // UPDATE RECTANGLES (2- THOSE AFFECTED BY SCROLLING)
// Work rectangle.
// Affected by window padding and border size. Used by:
// - Columns() for right-most edge
// - TreeNode(), CollapsingHeader() for right-most edge
// - BeginTabBar() for right-most edge
const bool allow_scrollbar_x = !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar);
const bool allow_scrollbar_y = !(flags & ImGuiWindowFlags_NoScrollbar);
const float work_rect_size_x = (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : ImMax(allow_scrollbar_x ? window->ContentSize.x : 0.0f, window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x));
const float work_rect_size_y = (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : ImMax(allow_scrollbar_y ? window->ContentSize.y : 0.0f, window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y));
window->WorkRect.Min.x = ImFloor(window->InnerRect.Min.x - window->Scroll.x + ImMax(window->WindowPadding.x, window->WindowBorderSize));
window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize));
window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
// [LEGACY] Contents Region // [LEGACY] Contents Region
// FIXME: window->ContentsRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it. // FIXME-OBSOLETE: window->ContentsRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
// NB: WindowBorderSize is included in WindowPadding _and_ ScrollbarSizes so we need to cancel one out when we have both.
// Used by: // Used by:
// - Mouse wheel scrolling // - Mouse wheel scrolling + many other things
// - ... (many things)
window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x; window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + decoration_up_height;
window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x + ImMin(window->ScrollbarSizes.x, window->WindowBorderSize))); window->ContentsRegionRect.Max.x = window->ContentsRegionRect.Min.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x));
window->ContentsRegionRect.Max.y = window->Pos.y - window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y + ImMin(window->ScrollbarSizes.y, window->WindowBorderSize))); window->ContentsRegionRect.Max.y = window->ContentsRegionRect.Min.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y));
// Setup drawing context // Setup drawing context
// (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.)
window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x; window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x;
window->DC.GroupOffset.x = 0.0f; window->DC.GroupOffset.x = 0.0f;
window->DC.ColumnsOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.Indent.x + window->DC.ColumnsOffset.x, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y); window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.Indent.x + window->DC.ColumnsOffset.x, decoration_up_height + window->WindowPadding.y - window->Scroll.y);
window->DC.CursorPos = window->DC.CursorStartPos; window->DC.CursorPos = window->DC.CursorStartPos;
window->DC.CursorPosPrevLine = window->DC.CursorPos; window->DC.CursorPosPrevLine = window->DC.CursorPos;
window->DC.CursorMaxPos = window->DC.CursorStartPos; window->DC.CursorMaxPos = window->DC.CursorStartPos;
window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f;
window->DC.NavHideHighlightOneFrame = false; window->DC.NavHideHighlightOneFrame = false;
window->DC.NavHasScroll = (GetWindowScrollMaxY(window) > 0.0f); window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f);
window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext; window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext;
window->DC.NavLayerActiveMaskNext = 0x00; window->DC.NavLayerActiveMaskNext = 0x00;
window->DC.MenuBarAppending = false; window->DC.MenuBarAppending = false;
@ -6920,16 +6948,12 @@ ImVec2 ImGui::GetWindowPos()
void ImGui::SetWindowScrollX(ImGuiWindow* window, float new_scroll_x) void ImGui::SetWindowScrollX(ImGuiWindow* window, float new_scroll_x)
{ {
window->DC.CursorMaxPos.x += window->Scroll.x; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it.
window->Scroll.x = new_scroll_x; window->Scroll.x = new_scroll_x;
window->DC.CursorMaxPos.x -= window->Scroll.x;
} }
void ImGui::SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) void ImGui::SetWindowScrollY(ImGuiWindow* window, float new_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;
} }
void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond)
@ -6945,8 +6969,10 @@ void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond)
// Set // Set
const ImVec2 old_pos = window->Pos; const ImVec2 old_pos = window->Pos;
window->Pos = ImFloor(pos); window->Pos = ImFloor(pos);
window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor ImVec2 offset = window->Pos - old_pos;
window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. window->DC.CursorPos += offset; // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
window->DC.CursorMaxPos += offset; // And more importantly we need to offset CursorMaxPos/CursorStartPos this so ContentSize calculation doesn't get affected.
window->DC.CursorStartPos += offset;
} }
void ImGui::SetWindowPos(const ImVec2& pos, ImGuiCond cond) void ImGui::SetWindowPos(const ImVec2& pos, ImGuiCond cond)
@ -7107,11 +7133,13 @@ void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& s
g.NextWindowData.SizeCallbackUserData = custom_callback_user_data; g.NextWindowData.SizeCallbackUserData = custom_callback_user_data;
} }
// Content size = inner scrollable rectangle, padded with WindowPadding.
// SetNextWindowContentSize(ImVec2(100,100) + ImGuiWindowFlags_AlwaysAutoResize will always allow submitting a 100x100 item.
void ImGui::SetNextWindowContentSize(const ImVec2& size) void ImGui::SetNextWindowContentSize(const ImVec2& size)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize; g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasContentSize;
g.NextWindowData.ContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. g.NextWindowData.ContentSizeVal = size;
} }
void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond)
@ -7332,22 +7360,26 @@ void ImGui::SetCursorScreenPos(const ImVec2& pos)
float ImGui::GetScrollX() float ImGui::GetScrollX()
{ {
return GImGui->CurrentWindow->Scroll.x; ImGuiWindow* window = GImGui->CurrentWindow;
return window->Scroll.x;
} }
float ImGui::GetScrollY() float ImGui::GetScrollY()
{ {
return GImGui->CurrentWindow->Scroll.y; ImGuiWindow* window = GImGui->CurrentWindow;
return window->Scroll.y;
} }
float ImGui::GetScrollMaxX() float ImGui::GetScrollMaxX()
{ {
return GetWindowScrollMaxX(GImGui->CurrentWindow); ImGuiWindow* window = GImGui->CurrentWindow;
return window->ScrollMax.x;
} }
float ImGui::GetScrollMaxY() float ImGui::GetScrollMaxY()
{ {
return GetWindowScrollMaxY(GImGui->CurrentWindow); ImGuiWindow* window = GImGui->CurrentWindow;
return window->ScrollMax.y;
} }
void ImGui::SetScrollX(float scroll_x) void ImGui::SetScrollX(float scroll_x)
@ -7360,7 +7392,7 @@ void ImGui::SetScrollX(float scroll_x)
void ImGui::SetScrollY(float scroll_y) void ImGui::SetScrollY(float scroll_y)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
window->ScrollTarget.y = scroll_y + window->TitleBarHeight() + window->MenuBarHeight(); // title bar height canceled out when using ScrollTargetRelY window->ScrollTarget.y = scroll_y;
window->ScrollTargetCenterRatio.y = 0.0f; window->ScrollTargetCenterRatio.y = 0.0f;
} }
@ -8380,7 +8412,7 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags mov
ImGuiDir clip_dir = g.NavMoveDir; ImGuiDir clip_dir = g.NavMoveDir;
if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
{ {
bb_rel.Min.x = bb_rel.Max.x = ImMax(window->SizeFull.x, window->SizeContents.x) - window->Scroll.x; bb_rel.Min.x = bb_rel.Max.x = ImMax(window->SizeFull.x, window->ContentSize.x + window->WindowPadding.x * 2.0f) - window->Scroll.x;
if (move_flags & ImGuiNavMoveFlags_WrapX) { bb_rel.TranslateY(-bb_rel.GetHeight()); clip_dir = ImGuiDir_Up; } if (move_flags & ImGuiNavMoveFlags_WrapX) { bb_rel.TranslateY(-bb_rel.GetHeight()); clip_dir = ImGuiDir_Up; }
NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags); NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
} }
@ -8392,7 +8424,7 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags mov
} }
if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
{ {
bb_rel.Min.y = bb_rel.Max.y = ImMax(window->SizeFull.y, window->SizeContents.y) - window->Scroll.y; bb_rel.Min.y = bb_rel.Max.y = ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y;
if (move_flags & ImGuiNavMoveFlags_WrapY) { bb_rel.TranslateX(-bb_rel.GetWidth()); clip_dir = ImGuiDir_Left; } if (move_flags & ImGuiNavMoveFlags_WrapY) { bb_rel.TranslateX(-bb_rel.GetWidth()); clip_dir = ImGuiDir_Left; }
NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags); NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
} }
@ -9403,9 +9435,8 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
window->DC.CurrentColumns = columns; window->DC.CurrentColumns = columns;
// Set state for first column // Set state for first column
const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->WorkRect.Max.x - window->Pos.x); columns->OffMinX = window->DC.Indent.x - g.Style.ItemSpacing.x;
columns->OffMinX = window->DC.Indent.x - g.Style.ItemSpacing.x; // Lock our horizontal range columns->OffMaxX = ImMax(window->WorkRect.Max.x - window->Pos.x, columns->OffMinX + 1.0f);
columns->OffMaxX = ImMax(content_region_width - window->Scroll.x, columns->OffMinX + 1.0f);
columns->HostCursorPosY = window->DC.CursorPos.y; columns->HostCursorPosY = window->DC.CursorPos.y;
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x; columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->HostClipRect = window->ClipRect; columns->HostClipRect = window->ClipRect;
@ -14442,7 +14473,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
return; return;
} }
enum { RT_OuterRect, RT_OuterRectClipped, RT_InnerRect, RT_InnerClipRect, RT_WorkRect, RT_Contents, RT_ContentsRegionRect }; enum { RT_OuterRect, RT_OuterRectClipped, RT_InnerRect, RT_InnerClipRect, RT_WorkRect, RT_Contents, RT_ContentsRegionRect, RT_Count };
static bool show_windows_begin_order = false; static bool show_windows_begin_order = false;
static bool show_windows_rects = false; static bool show_windows_rects = false;
static int show_windows_rect_type = RT_WorkRect; static int show_windows_rect_type = RT_WorkRect;
@ -14465,7 +14496,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
else if (rect_type == RT_InnerRect) { return window->InnerRect; } else if (rect_type == RT_InnerRect) { return window->InnerRect; }
else if (rect_type == RT_InnerClipRect) { return window->InnerClipRect; } else if (rect_type == RT_InnerClipRect) { return window->InnerClipRect; }
else if (rect_type == RT_WorkRect) { return window->WorkRect; } else if (rect_type == RT_WorkRect) { return window->WorkRect; }
else if (rect_type == RT_Contents) { return ImRect(window->Pos, window->Pos + window->SizeContents); } else if (rect_type == RT_Contents) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
else if (rect_type == RT_ContentsRegionRect) { return window->ContentsRegionRect; } else if (rect_type == RT_ContentsRegionRect) { return window->ContentsRegionRect; }
IM_ASSERT(0); IM_ASSERT(0);
return ImRect(); return ImRect();
@ -14570,12 +14601,12 @@ void ImGui::ShowMetricsWindow(bool* p_open)
return; return;
ImGuiWindowFlags flags = window->Flags; ImGuiWindowFlags flags = window->Flags;
NodeDrawList(window, window->Viewport, window->DrawList, "DrawList"); NodeDrawList(window, window->Viewport, window->DrawList, "DrawList");
ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->ContentSize.x, window->ContentSize.y);
ImGui::BulletText("Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..)", flags, ImGui::BulletText("Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..)", flags,
(flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "", (flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "",
(flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "", (flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "",
(flags & ImGuiWindowFlags_NoMouseInputs)? "NoMouseInputs":"", (flags & ImGuiWindowFlags_NoNavInputs) ? "NoNavInputs" : "", (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : ""); (flags & ImGuiWindowFlags_NoMouseInputs)? "NoMouseInputs":"", (flags & ImGuiWindowFlags_NoNavInputs) ? "NoNavInputs" : "", (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : "");
ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetWindowScrollMaxX(window), window->Scroll.y, GetWindowScrollMaxY(window)); ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, window->ScrollMax.x, window->Scroll.y, window->ScrollMax.y);
ImGui::BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1); ImGui::BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1);
ImGui::BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems); ImGui::BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems);
ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
@ -14691,11 +14722,18 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::Checkbox("Show windows rectangles", &show_windows_rects); ImGui::Checkbox("Show windows rectangles", &show_windows_rects);
ImGui::SameLine(); ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 12); ImGui::SetNextItemWidth(ImGui::GetFontSize() * 12);
show_windows_rects |= ImGui::Combo("##rects_type", &show_windows_rect_type, "OuterRect\0" "OuterRectClipped\0" "InnerRect\0" "InnerClipRect\0" "WorkRect\0" "Contents\0" "ContentsRegionRect\0"); const char* rects_names[RT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Contents", "ContentsRegionRect" };
show_windows_rects |= ImGui::Combo("##rects_type", &show_windows_rect_type, rects_names, RT_Count);
if (show_windows_rects && g.NavWindow) if (show_windows_rects && g.NavWindow)
{ {
ImRect r = Funcs::GetRect(g.NavWindow, show_windows_rect_type); ImGui::BulletText("'%s':", g.NavWindow->Name);
ImGui::BulletText("'%s': (%.1f,%.1f) (%.1f,%.1f) Size (%.1f,%.1f)", g.NavWindow->Name, r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight()); ImGui::Indent();
for (int n = 0; n < RT_Count; n++)
{
ImRect r = Funcs::GetRect(g.NavWindow, n);
ImGui::Text("(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), rects_names[n]);
}
ImGui::Unindent();
} }
ImGui::Checkbox("Show clipping rectangle when hovering ImDrawCmd node", &show_drawcmd_clip_rects); ImGui::Checkbox("Show clipping rectangle when hovering ImDrawCmd node", &show_drawcmd_clip_rects);
ImGui::TreePop(); ImGui::TreePop();

22
imgui.h
View File

@ -282,7 +282,7 @@ namespace ImGui
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc.
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin()
IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Sizes will be rounded down. Use callback to apply non-trivial programmatic constraints. IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Sizes will be rounded down. Use callback to apply non-trivial programmatic constraints.
IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). not including window decorations (title bar, menu bar, etc.). set an axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ scrollable client area, which enforce the range of scrollbars). Not including window decorations (title bar, menu bar, etc.) nor WindowPadding. set an axis to 0.0f to leave it automatic. call before Begin()
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin()
IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin()
IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground. IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground.
@ -831,7 +831,7 @@ enum ImGuiTreeNodeFlags_
// Obsolete names (will be removed) // Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiTreeNodeFlags_AllowOverlapMode = ImGuiTreeNodeFlags_AllowItemOverlap , ImGuiTreeNodeFlags_AllowOverlapMode = ImGuiTreeNodeFlags_AllowItemOverlap // [renamed in 1.53]
#endif #endif
}; };
@ -842,7 +842,7 @@ enum ImGuiSelectableFlags_
ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window
ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column)
ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, // Generate press events on double clicks too ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, // Generate press events on double clicks too
ImGuiSelectableFlags_Disabled = 1 << 3 // Cannot be selected, display greyed out text ImGuiSelectableFlags_Disabled = 1 << 3 // Cannot be selected, display grayed out text
}; };
// Flags for ImGui::BeginCombo() // Flags for ImGui::BeginCombo()
@ -1178,7 +1178,8 @@ enum ImGuiStyleVar_
// Obsolete names (will be removed) // Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiStyleVar_Count_ = ImGuiStyleVar_COUNT, ImGuiStyleVar_ChildWindowRounding = ImGuiStyleVar_ChildRounding , ImGuiStyleVar_Count_ = ImGuiStyleVar_COUNT // [renamed in 1.60]
, ImGuiStyleVar_ChildWindowRounding = ImGuiStyleVar_ChildRounding // [renamed in 1.53]
#endif #endif
}; };
@ -1223,7 +1224,7 @@ enum ImGuiColorEditFlags_
// Obsolete names (will be removed) // Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex , ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69]
#endif #endif
}; };
@ -1244,7 +1245,7 @@ enum ImGuiMouseCursor_
// Obsolete names (will be removed) // Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiMouseCursor_Count_ = ImGuiMouseCursor_COUNT , ImGuiMouseCursor_Count_ = ImGuiMouseCursor_COUNT // [renamed in 1.60]
#endif #endif
}; };
@ -1260,7 +1261,7 @@ enum ImGuiCond_
// Obsolete names (will be removed) // Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiSetCond_Always = ImGuiCond_Always, ImGuiSetCond_Once = ImGuiCond_Once, ImGuiSetCond_FirstUseEver = ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing = ImGuiCond_Appearing , ImGuiSetCond_Always = ImGuiCond_Always, ImGuiSetCond_Once = ImGuiCond_Once, ImGuiSetCond_FirstUseEver = ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing = ImGuiCond_Appearing // [renamed in 1.51]
#endif #endif
}; };
@ -1628,7 +1629,6 @@ namespace ImGui
{ {
// OBSOLETED in 1.71 (from May 2019) // OBSOLETED in 1.71 (from May 2019)
static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); } static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); }
// OBSOLETED in 1.70 (from May 2019) // OBSOLETED in 1.70 (from May 2019)
static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; } static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; }
// OBSOLETED in 1.69 (from Mar 2019) // OBSOLETED in 1.69 (from Mar 2019)
@ -1663,7 +1663,7 @@ namespace ImGui
static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); }
static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); }
} }
typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETE in 1.63 (from Aug 2018): made the names consistent typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent
typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData; typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
#endif #endif
@ -2247,7 +2247,7 @@ struct ImFontAtlas
int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETE 1.67+ typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
#endif #endif
}; };
@ -2301,7 +2301,7 @@ struct ImFont
IMGUI_API void SetFallbackChar(ImWchar c); IMGUI_API void SetFallbackChar(ImWchar c);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
typedef ImFontGlyph Glyph; // OBSOLETE 1.52+ typedef ImFontGlyph Glyph; // OBSOLETED in 1.52+
#endif #endif
}; };

View File

@ -17,9 +17,18 @@
// In this demo code, we frequently we use 'static' variables inside functions. A static variable persist across calls, so it is // In this demo code, we frequently we use 'static' variables inside functions. A static variable persist across calls, so it is
// essentially like a global variable but declared inside the scope of the function. We do this as a way to gather code and data // essentially like a global variable but declared inside the scope of the function. We do this as a way to gather code and data
// in the same place, to make the demo source code faster to read, faster to write, and smaller in size. // in the same place, to make the demo source code faster to read, faster to write, and smaller in size.
// It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant // It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be
// or used in threads. This might be a pattern you will want to use in your code, but most of the real data you would be editing is // reentrant or used in multiple threads. This might be a pattern you will want to use in your code, but most of the real data
// likely going to be stored outside your functions. // you would be editing is likely going to be stored outside your functions.
// The Demo code is this file is designed to be easy to copy-and-paste in into your application!
// Because of this:
// - We never omit the ImGui:: namespace when calling functions, even though most of our code is already in the same namespace.
// - We try to declare static variables in the local scope, as close as possible to the code using them.
// - We never use any of the helpers/facilities used internally by dear imgui, unless it has been exposed in the public API (imgui.h).
// - We never use maths operators on ImVec2/ImVec4. For other imgui sources files, they are provided by imgui_internal.h w/ IMGUI_DEFINE_MATH_OPERATORS,
// for your own sources file they are optional and require you either enable those, either provide your own via IM_VEC2_CLASS_EXTRA in imconfig.h.
// Because we don't want to assume anything about your support of maths operators, we don't use them in imgui_demo.cpp.
/* /*
@ -2108,14 +2117,21 @@ static void ShowDemoWindowLayout()
HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position."); HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position.");
static bool track = true; static bool track = true;
static int track_line = 50, scroll_to_px = 200; static int track_line = 50;
static float scroll_to_off_px = 0.0f;
static float scroll_to_pos_px = 200.0f;
ImGui::Checkbox("Track", &track); ImGui::Checkbox("Track", &track);
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %d"); ImGui::SameLine(140); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %d");
bool scroll_to = ImGui::Button("Scroll To Pos");
ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %d px"); bool scroll_to_off = ImGui::Button("Scroll Offset");
ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off_y", &scroll_to_off_px, 1.00f, 0, 9999, "+%.0f px");
bool scroll_to_pos = ImGui::Button("Scroll To Pos");
ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos_y", &scroll_to_pos_px, 1.00f, 0, 9999, "Y = %.0f px");
ImGui::PopItemWidth(); ImGui::PopItemWidth();
if (scroll_to) if (scroll_to_off || scroll_to_pos)
track = false; track = false;
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
@ -2125,9 +2141,13 @@ static void ShowDemoWindowLayout()
if (i > 0) ImGui::SameLine(); if (i > 0) ImGui::SameLine();
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom"); ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom");
ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(child_w, 200.0f), true);
if (scroll_to) ImGuiWindowFlags child_flags = ImGuiWindowFlags_MenuBar;
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_px, i * 0.25f); ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(child_w, 200.0f), true, child_flags);
if (scroll_to_off)
ImGui::SetScrollY(scroll_to_off_px);
if (scroll_to_pos)
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_pos_px, i * 0.25f);
for (int line = 0; line < 100; line++) for (int line = 0; line < 100; line++)
{ {
if (track && line == track_line) if (track && line == track_line)
@ -2143,7 +2163,7 @@ static void ShowDemoWindowLayout()
float scroll_y = ImGui::GetScrollY(); float scroll_y = ImGui::GetScrollY();
float scroll_max_y = ImGui::GetScrollMaxY(); float scroll_max_y = ImGui::GetScrollMaxY();
ImGui::EndChild(); ImGui::EndChild();
ImGui::Text("%.0f/%0.f", scroll_y, scroll_max_y); ImGui::Text("%.0f/%.0f", scroll_y, scroll_max_y);
ImGui::EndGroup(); ImGui::EndGroup();
} }
ImGui::TreePop(); ImGui::TreePop();
@ -2193,6 +2213,97 @@ static void ShowDemoWindowLayout()
ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta); ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta);
ImGui::EndChild(); ImGui::EndChild();
} }
ImGui::Spacing();
static bool show_horizontal_contents_size_demo_window = false;
ImGui::Checkbox("Show Horizontal contents size demo window", &show_horizontal_contents_size_demo_window);
if (show_horizontal_contents_size_demo_window)
{
static bool show_h_scrollbar = true;
static bool show_button = true;
static bool show_tree_nodes = true;
static bool show_text_wrapped = false;
static bool show_columns = true;
static bool show_tab_bar = true;
static bool show_child = false;
static bool explicit_content_size = false;
static float contents_size_x = 300.0f;
if (explicit_content_size)
ImGui::SetNextWindowContentSize(ImVec2(contents_size_x, 0.0f));
ImGui::Begin("Horizontal contents size demo window", &show_horizontal_contents_size_demo_window, show_h_scrollbar ? ImGuiWindowFlags_HorizontalScrollbar : 0);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 0));
HelpMarker("Test of different widgets react and impact the work rectangle growing when horizontal scrolling is enabled.\n\nUse 'Metrics->Tools->Show windows rectangles' to visualize rectangles.");
ImGui::Checkbox("H-scrollbar", &show_h_scrollbar);
ImGui::Checkbox("Button", &show_button); // Will grow contents size (unless explicitly overwritten)
ImGui::Checkbox("Tree nodes", &show_tree_nodes); // Will grow contents size and display highlight over full width
ImGui::Checkbox("Text wrapped", &show_text_wrapped);// Will grow and use contents size
ImGui::Checkbox("Columns", &show_columns); // Will use contents size
ImGui::Checkbox("Tab bar", &show_tab_bar); // Will use contents size
ImGui::Checkbox("Child", &show_child); // Will grow and use contents size
ImGui::Checkbox("Explicit content size", &explicit_content_size);
ImGui::Text("Scroll %.1f/%.1f %.1f/%.1f", ImGui::GetScrollX(), ImGui::GetScrollMaxX(), ImGui::GetScrollY(), ImGui::GetScrollMaxY());
if (explicit_content_size)
{
ImGui::SameLine();
ImGui::SetNextItemWidth(100);
ImGui::DragFloat("##csx", &contents_size_x);
ImVec2 p = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + 10, p.y + 10), IM_COL32_WHITE);
ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(p.x + contents_size_x - 10, p.y), ImVec2(p.x + contents_size_x, p.y + 10), IM_COL32_WHITE);
ImGui::Dummy(ImVec2(0, 10));
}
ImGui::PopStyleVar(2);
ImGui::Separator();
if (show_button)
{
ImGui::Button("this is a 300-wide button", ImVec2(300, 0));
}
if (show_tree_nodes)
{
bool open = true;
if (ImGui::TreeNode("this is a tree node"))
{
if (ImGui::TreeNode("another one of those tree node..."))
{
ImGui::Text("Some tree contents");
ImGui::TreePop();
}
ImGui::TreePop();
}
ImGui::CollapsingHeader("CollapsingHeader", &open);
}
if (show_text_wrapped)
{
ImGui::TextWrapped("This text should automatically wrap on the edge of the work rectangle.");
}
if (show_columns)
{
ImGui::Columns(4);
for (int n = 0; n < 4; n++)
{
ImGui::Text("Width %.2f", ImGui::GetColumnWidth());
ImGui::NextColumn();
}
ImGui::Columns(1);
}
if (show_tab_bar && ImGui::BeginTabBar("Hello"))
{
if (ImGui::BeginTabItem("OneOneOne")) { ImGui::EndTabItem(); }
if (ImGui::BeginTabItem("TwoTwoTwo")) { ImGui::EndTabItem(); }
if (ImGui::BeginTabItem("ThreeThreeThree")) { ImGui::EndTabItem(); }
if (ImGui::BeginTabItem("FourFourFour")) { ImGui::EndTabItem(); }
ImGui::EndTabBar();
}
if (show_child)
{
ImGui::BeginChild("child", ImVec2(0,0), true);
ImGui::EndChild();
}
ImGui::End();
}
ImGui::TreePop(); ImGui::TreePop();
} }

View File

@ -1327,7 +1327,7 @@ struct IMGUI_API ImGuiWindowTempData
ImVec2 CursorPos; ImVec2 CursorPos;
ImVec2 CursorPosPrevLine; ImVec2 CursorPosPrevLine;
ImVec2 CursorStartPos; // Initial position in client area with padding ImVec2 CursorStartPos; // Initial position in client area with padding
ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Turned into window->SizeContents at the beginning of next frame ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Used to calculate window->ContentSize at the beginning of next frame
ImVec2 CurrLineSize; ImVec2 CurrLineSize;
ImVec2 PrevLineSize; ImVec2 PrevLineSize;
float CurrLineTextBaseOffset; float CurrLineTextBaseOffset;
@ -1415,9 +1415,8 @@ struct IMGUI_API ImGuiWindow
ImVec2 Pos; // Position (always rounded-up to nearest pixel) ImVec2 Pos; // Position (always rounded-up to nearest pixel)
ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeFull; // Size when non collapsed
ImVec2 SizeFullAtLastBegin; // Copy of SizeFull at the end of Begin. This is the reference value we'll use on the next frame to decide if we need scrollbars. ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) from previous frame. Does not include window decoration or window padding.
ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame. FIXME: Include decoration, window title, border, menu, etc. Ideally should remove them from this value? ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize().
ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize(). EXCLUDE decorations. Making this not consistent with the above!
ImVec2 WindowPadding; // Window padding at the time of begin. ImVec2 WindowPadding; // Window padding at the time of begin.
float WindowRounding; // Window rounding at the time of begin. float WindowRounding; // Window rounding at the time of begin.
float WindowBorderSize; // Window border size at the time of begin. float WindowBorderSize; // Window border size at the time of begin.
@ -1425,6 +1424,7 @@ struct IMGUI_API ImGuiWindow
ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID MoveId; // == window->GetID("#MOVE")
ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window) ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
ImVec2 Scroll; ImVec2 Scroll;
ImVec2 ScrollMax;
ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change)
ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
ImVec2 ScrollbarSizes; // Size taken by scrollbars on each axis ImVec2 ScrollbarSizes; // Size taken by scrollbars on each axis
@ -1459,13 +1459,17 @@ struct IMGUI_API ImGuiWindow
ImGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the "DC" variable name. ImGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the "DC" variable name.
ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack
ImRect ClipRect; // Current clipping rectangle. = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2.
ImRect OuterRectClipped; // == WindowRect just after setup in Begin(). == window->Rect() for root window. // The best way to understand what those rectangles are is to use the 'Metrics -> Tools -> Show windows rectangles' viewer.
ImRect InnerRect; // Inner rectangle // The main 'OuterRect', omitted as a field, is window->Rect().
ImRect InnerClipRect; // == InnerRect minus WindowPadding.x, clipped within viewport or parent clip rect. ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window.
ImRect WorkRect; // == InnerRect minus WindowPadding.x ImRect InnerRect; // Inner rectangle (omit title bar, menu bar)
ImRect ContentsRegionRect; // FIXME: This is currently confusing/misleading. Maximum visible content position ~~ Pos + (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect.
ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentsRegionRect over time (from 1.71+ onward).
ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
ImRect ContentsRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on.
ImVec2ih HitTestHoleSize, HitTestHoleOffset; ImVec2ih HitTestHoleSize, HitTestHoleOffset;
int LastFrameActive; // Last frame number the window was Active. int LastFrameActive; // Last frame number the window was Active.
int LastFrameJustFocused; // Last frame number the window was made Focused. int LastFrameJustFocused; // Last frame number the window was made Focused.
float ItemWidthDefault; float ItemWidthDefault;
@ -1631,8 +1635,6 @@ namespace ImGui
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
IMGUI_API void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); IMGUI_API void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x);
IMGUI_API void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); IMGUI_API void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y);
IMGUI_API float GetWindowScrollMaxX(ImGuiWindow* window);
IMGUI_API float GetWindowScrollMaxY(ImGuiWindow* window);
IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow* window); IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow* window);
IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0);
IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0); IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0);

View File

@ -878,7 +878,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa
} }
// Apply scroll // Apply scroll
// It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position // It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position
const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm)); const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm));
*p_scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v)); *p_scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v));
@ -914,22 +914,26 @@ void ImGui::Scrollbar(ImGuiAxis axis)
// Calculate scrollbar bounding box // Calculate scrollbar bounding box
const ImRect outer_rect = window->Rect(); const ImRect outer_rect = window->Rect();
const ImRect inner_rect = window->InnerRect;
const float border_size = window->WindowBorderSize;
const float scrollbar_size = window->ScrollbarSizes[axis ^ 1];
IM_ASSERT(scrollbar_size > 0.0f);
const float other_scrollbar_size = window->ScrollbarSizes[axis]; const float other_scrollbar_size = window->ScrollbarSizes[axis];
ImDrawCornerFlags rounding_corners = (other_scrollbar_size <= 0.0f) ? ImDrawCornerFlags_BotRight : 0; ImDrawCornerFlags rounding_corners = (other_scrollbar_size <= 0.0f) ? ImDrawCornerFlags_BotRight : 0;
ImRect bb; ImRect bb;
if (axis == ImGuiAxis_X) if (axis == ImGuiAxis_X)
{ {
bb.Min = ImVec2(window->InnerRect.Min.x, window->InnerRect.Max.y); bb.Min = ImVec2(inner_rect.Min.x, outer_rect.Max.y - border_size - scrollbar_size);
bb.Max = ImVec2(window->InnerRect.Max.x, outer_rect.Max.y - window->WindowBorderSize); bb.Max = ImVec2(inner_rect.Max.x, outer_rect.Max.y);
rounding_corners |= ImDrawCornerFlags_BotLeft; rounding_corners |= ImDrawCornerFlags_BotLeft;
} }
else else
{ {
bb.Min = ImVec2(window->InnerRect.Max.x, window->InnerRect.Min.y); bb.Min = ImVec2(outer_rect.Max.x - border_size - scrollbar_size, inner_rect.Min.y);
bb.Max = ImVec2(outer_rect.Max.x - window->WindowBorderSize, window->InnerRect.Max.y); bb.Max = ImVec2(outer_rect.Max.x, window->InnerRect.Max.y);
rounding_corners |= ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0; rounding_corners |= ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0;
} }
ScrollbarEx(bb, id, axis, &window->Scroll[axis], window->SizeFull[axis] - other_scrollbar_size, window->SizeContents[axis], rounding_corners); ScrollbarEx(bb, id, axis, &window->Scroll[axis], inner_rect.Max[axis] - inner_rect.Min[axis], window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f, rounding_corners);
} }
void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col)
@ -5161,12 +5165,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
// We vertically grow up to current line height up the typical widget height. // We vertically grow up to current line height up the typical widget height.
const float text_base_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it const float text_base_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2); const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2);
ImRect frame_bb = ImRect(window->DC.CursorPos, ImVec2(GetContentRegionMaxAbs().x, window->DC.CursorPos.y + frame_height)); ImRect frame_bb = ImRect(window->DC.CursorPos, ImVec2(window->WorkRect.Max.x, window->DC.CursorPos.y + frame_height));
if (display_frame) if (display_frame)
{ {
// Framed header expand a little outside the default padding // Framed header expand a little outside the default padding
frame_bb.Min.x -= (float)(int)(window->WindowPadding.x * 0.5f) - 1; frame_bb.Min.x -= (float)(int)(window->WindowPadding.x * 0.5f - 1.0f);
frame_bb.Max.x += (float)(int)(window->WindowPadding.x * 0.5f) - 1; frame_bb.Max.x += (float)(int)(window->WindowPadding.x * 0.5f - 1.0f);
} }
const float text_offset_x = (g.FontSize + (display_frame ? padding.x*3 : padding.x*2)); // Collapser arrow width + Spacing const float text_offset_x = (g.FontSize + (display_frame ? padding.x*3 : padding.x*2)); // Collapser arrow width + Spacing
@ -6360,7 +6364,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
tab_bar->FramePadding = g.Style.FramePadding; tab_bar->FramePadding = g.Style.FramePadding;
// Layout // Layout
ItemSize(ImVec2(tab_bar->OffsetMax, tab_bar->BarRect.GetHeight())); ItemSize(ImVec2(0.0f /*tab_bar->OffsetMax*/, tab_bar->BarRect.GetHeight())); // Don't feed width back
window->DC.CursorPos.x = tab_bar->BarRect.Min.x; window->DC.CursorPos.x = tab_bar->BarRect.Min.x;
// Draw separator // Draw separator
@ -6374,8 +6378,8 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
} }
else else
{ {
const float separator_min_x = tab_bar->BarRect.Min.x - window->WindowPadding.x; const float separator_min_x = tab_bar->BarRect.Min.x - ImFloor(window->WindowPadding.x * 0.5f);
const float separator_max_x = tab_bar->BarRect.Max.x + window->WindowPadding.x; const float separator_max_x = tab_bar->BarRect.Max.x + ImFloor(window->WindowPadding.x * 0.5f);
window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f); window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f);
} }
return true; return true;
@ -6504,7 +6508,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
} }
// Compute width // Compute width
const float width_avail = tab_bar->BarRect.GetWidth(); const float initial_offset_x = 0.0f; // g.Style.ItemInnerSpacing.x;
const float width_avail = ImMax(tab_bar->BarRect.GetWidth() - initial_offset_x, 0.0f);
float width_excess = (width_avail < width_total_contents) ? (width_total_contents - width_avail) : 0.0f; float width_excess = (width_avail < width_total_contents) ? (width_total_contents - width_avail) : 0.0f;
if (width_excess > 0.0f && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown)) if (width_excess > 0.0f && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown))
{ {
@ -6524,7 +6529,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
} }
// Layout all active tabs // Layout all active tabs
float offset_x = 0.0f; float offset_x = initial_offset_x;
tab_bar->OffsetNextTab = offset_x; // This is used by non-reorderable tab bar where the submission order is always honored.
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
{ {
ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
@ -6534,7 +6540,6 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
offset_x += tab->Width + g.Style.ItemInnerSpacing.x; offset_x += tab->Width + g.Style.ItemInnerSpacing.x;
} }
tab_bar->OffsetMax = ImMax(offset_x - g.Style.ItemInnerSpacing.x, 0.0f); tab_bar->OffsetMax = ImMax(offset_x - g.Style.ItemInnerSpacing.x, 0.0f);
tab_bar->OffsetNextTab = 0.0f;
// Horizontal scrolling buttons // Horizontal scrolling buttons
const bool scrolling_buttons = (tab_bar->OffsetMax > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll); const bool scrolling_buttons = (tab_bar->OffsetMax > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll);
@ -6962,7 +6967,10 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
if (want_clip_rect) if (want_clip_rect)
PushClipRect(ImVec2(ImMax(bb.Min.x, tab_bar->BarRect.Min.x), bb.Min.y - 1), ImVec2(tab_bar->BarRect.Max.x, bb.Max.y), true); PushClipRect(ImVec2(ImMax(bb.Min.x, tab_bar->BarRect.Min.x), bb.Min.y - 1), ImVec2(tab_bar->BarRect.Max.x, bb.Max.y), true);
ItemSize(bb, style.FramePadding.y); ImVec2 backup_cursor_max_pos = window->DC.CursorMaxPos;
ItemSize(bb.GetSize(), style.FramePadding.y);
window->DC.CursorMaxPos = backup_cursor_max_pos;
if (!ItemAdd(bb, id)) if (!ItemAdd(bb, id))
{ {
if (want_clip_rect) if (want_clip_rect)