diff --git a/imgui.cpp b/imgui.cpp index 4c8812bc..3851108a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4747,16 +4747,6 @@ ImVec2 ImGui::CalcWindowExpectedSize(ImGuiWindow* window) return CalcSizeAfterConstraint(window, CalcSizeAutoFit(window, size_contents)); } -float ImGui::GetWindowScrollMaxX(ImGuiWindow* window) -{ - return ImMax(0.0f, window->ContentSize.x + window->WindowPadding.x * 2.0f - window->InnerRect.GetWidth()); -} - -float ImGui::GetWindowScrollMaxY(ImGuiWindow* window) -{ - return ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight()); -} - static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges) { ImGuiContext& g = *GImGui; @@ -4780,8 +4770,8 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool s scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); if (!window->Collapsed && !window->SkipItems) { - scroll.x = ImMin(scroll.x, ImGui::GetWindowScrollMaxX(window)); - scroll.y = ImMin(scroll.y, ImGui::GetWindowScrollMaxY(window)); + scroll.x = ImMin(scroll.x, window->ScrollMax.x); + scroll.y = ImMin(scroll.y, window->ScrollMax.y); } return scroll; } @@ -5470,10 +5460,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Lock window rounding for the frame (so that altering them doesn't cause inconsistencies) window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; - // 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) bool want_focus = false; if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) @@ -5538,6 +5524,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - window->WindowBorderSize); window->InnerClipRect.ClipWithFull(host_rect); + // 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 // Setup draw list and outer clipping rectangle @@ -5619,7 +5617,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; 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.NavLayerActiveMaskNext = 0x00; window->DC.MenuBarAppending = false; @@ -6687,22 +6685,26 @@ void ImGui::SetCursorScreenPos(const ImVec2& pos) float ImGui::GetScrollX() { - return GImGui->CurrentWindow->Scroll.x; + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Scroll.x; } float ImGui::GetScrollY() { - return GImGui->CurrentWindow->Scroll.y; + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Scroll.y; } float ImGui::GetScrollMaxX() { - return GetWindowScrollMaxX(GImGui->CurrentWindow); + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ScrollMax.x; } float ImGui::GetScrollMaxY() { - return GetWindowScrollMaxY(GImGui->CurrentWindow); + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ScrollMax.y; } void ImGui::SetScrollX(float scroll_x) @@ -9906,7 +9908,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) (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_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("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); diff --git a/imgui_internal.h b/imgui_internal.h index 87a2598e..8faaa026 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1262,6 +1262,7 @@ struct IMGUI_API ImGuiWindow ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window) 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 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 @@ -1450,8 +1451,6 @@ namespace ImGui IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); IMGUI_API void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); 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 void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0);