From fb410463e6a27c4486ac262c3f246543154a49e0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 20 Sep 2024 18:40:32 +0200 Subject: [PATCH] Scrollbar: added io.ConfigScrollbarScrollByPage setting. (#8002, #7328) --- docs/CHANGELOG.txt | 5 +++-- imgui.cpp | 1 + imgui.h | 1 + imgui_demo.cpp | 2 ++ imgui_internal.h | 4 ++-- imgui_widgets.cpp | 7 ++++--- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 99ca1f13476a..fac869de69a9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,8 +43,9 @@ Breaking changes: Other changes: -- Scrollbar: Shift+Click always use absolute positionning scroll (which was the default - before 1.90.8). (#8002, #7328) +- Scrollbar: Shift+Click scroll to clicked location (pre-1.90.8 default). (#8002, #7328) +- Scrollbar: added io.ConfigScrollbarScrollByPage setting (default to true). (#8002, #7328) + Set io.ConfigScrollbarScrollByPage=false to enforce always scrolling to clicked location. - Backends: SDL3: Update for API changes: SDL_bool removal. SDL_INIT_TIMER removal. diff --git a/imgui.cpp b/imgui.cpp index 4b9daf9d2a74..bbe78dc54ad4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1394,6 +1394,7 @@ ImGuiIO::ImGuiIO() ConfigDragClickToInputText = false; ConfigWindowsResizeFromEdges = true; ConfigWindowsMoveFromTitleBarOnly = false; + ConfigScrollbarScrollByPage = true; ConfigMemoryCompactTimer = 60.0f; ConfigDebugIsDebuggerPresent = false; ConfigDebugHighlightIdConflicts = true; diff --git a/imgui.h b/imgui.h index a2aab8a63608..b97a4097e820 100644 --- a/imgui.h +++ b/imgui.h @@ -2250,6 +2250,7 @@ struct ImGuiIO bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar. + bool ConfigScrollbarScrollByPage; // = true // Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location. float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. // Inputs Behaviors diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 5eb64e4702cf..c2d110dd15c9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -539,6 +539,8 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges); ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback."); ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly); + ImGui::Checkbox("io.ConfigScrollbarScrollByPage", &io.ConfigScrollbarScrollByPage); + ImGui::SameLine(); HelpMarker("Enable scrolling page by page when clicking outside the scrollbar grab.\nWhen disabled, always scroll to clicked location.\nWhen enabled, Shift+Click scrolls to clicked location."); ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors); ImGui::SameLine(); HelpMarker("Swap Cmd<>Ctrl keys, enable various MacOS style behaviors."); ImGui::Text("Also see Style->Rendering for rendering options."); diff --git a/imgui_internal.h b/imgui_internal.h index 14b56e8a0f30..664648427989 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2259,8 +2259,8 @@ struct ImGuiContext ImGuiComboPreviewData ComboPreviewData; ImRect WindowResizeBorderExpectedRect; // Expected border rect, switch to relative edit if moving bool WindowResizeRelativeMode; - short ScrollbarSeekMode; // 0: relative, -1/+1: prev/next page. - float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? + short ScrollbarSeekMode; // 0: scroll to clicked location, -1/+1: prev/next page. + float ScrollbarClickDeltaToGrabCenter; // When scrolling to mouse location: distance between mouse and center of grab box, normalized in parent space. float SliderGrabClickOffset; float SliderCurrentAccum; // Accumulated slider delta when using navigation controls. bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it? diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e50452eb63dc..91328d211fed 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -999,9 +999,10 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 const int held_dir = (clicked_v_norm < grab_v_norm) ? -1 : (clicked_v_norm > grab_v_norm + grab_h_norm) ? +1 : 0; if (g.ActiveIdIsJustActivated) { - // On initial click calculate the distance between mouse and the center of the grab - g.ScrollbarSeekMode = g.IO.KeyShift ? 0 : (short)held_dir; - g.ScrollbarClickDeltaToGrabCenter = (g.ScrollbarSeekMode == 0 && !g.IO.KeyShift) ? clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f : 0.0f; + // On initial click when held_dir == 0 (clicked over grab): calculate the distance between mouse and the center of the grab + const bool scroll_to_clicked_location = (g.IO.ConfigScrollbarScrollByPage == false || g.IO.KeyShift || held_dir == 0); + g.ScrollbarSeekMode = scroll_to_clicked_location ? 0 : (short)held_dir; + g.ScrollbarClickDeltaToGrabCenter = (held_dir == 0 && !g.IO.KeyShift) ? clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f : 0.0f; } // Apply scroll (p_scroll_v will generally point on one member of window->Scroll)