Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Smooth Scrolling #7348

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

astharoth-tlotb
Copy link

@astharoth-tlotb astharoth-tlotb commented Feb 24, 2024

Feature: Smooth scrolling

This capture was with smooth at 20.0f which is so higher but just to demonstrate how it works.

smoothscroll

ImGuiStyleVar_ScrollSmooth float added.
Default value: 1.0 = means no smooth scrolling
Values over 1.0 = starts to smooth the scroll.

Code in the demo added. Same example as the verticaller scrollers but with smooth activated.

MouseWheel and others like SetScrollHereY continue setting ScrollTarget
SetScrollX/SetScrollY/GetScrollX/GetScrollY and scroll bar widget works against a new value in ImWindow "ScrollExpected"

Function CalcNextScrollFromScrollTargetAndClamp now applies the smooth scrolling no matter if it comes from "ScrollExpected" or "ScrollTarget".

The formula is pretty simple. Is frame bounded and no time bounded but as counter part it is only one new style var and one new var in ImWindow, nothing else. Simple and small change.

… of smoothness (by default disabled).Included example in demo

New feature: Smooth Scrolling
@ocornut
Copy link
Owner

ocornut commented Feb 26, 2024

Hello,
Thanks for the PR.
I only gave a skim to this but some thoughts:

  • I believe the smoothing logic is framerate dependent, and won't work the same at all depending on framerate.
  • I don't know how this would behave when used with a mouse submitting smooth scroll values sequence.
  • I believe potentially a scroll triggered from an API would want to configure this (some API call may want the smooth or follow user style/configuration, while for some other API calls it might be unacceptable to have the smoothing), so it may need accounting for that. Ditto, I think applying it on user-triggered mouse wheeling might need to be optional or more thoughts.

I don't have many concrete actions to suggest, but I believe this may need further thought.
(Linking to #2675 for info)

@astharoth-tlotb
Copy link
Author

astharoth-tlotb commented Feb 26, 2024

Hi Omar!

Smoothing logic is frame dependent yes. I added that way to avoid add more variables into the window structure.

[Frame dependent]
But if we want the feature to be time dependent I can modify it in such way (so, count on me to have smooth scrolling on ImGui). It could be achieved by , for example, some bezier, saving the starting/ending and starting time, with the delta is enough to fetch the intermediate points and we can achieve nice animations (scroll faster / slowly / bouncing a bit on top & bottom, etc. )
Right now is a quick and simple animation with increasing / decreasing velocity. Nothing else.

[Mouse with high resolution / smoother values]
Tried with one Corsair M65RGB and one Logitech MX Anywhere 2. No problems. In fact, mouse wheel events interacts with the ScrollTarget variable (increasing or decreasing the target) and later the target is applied into ScrollExpected so the behavior for the input is the same, smoothness is only applied to the last step (to modify what should be visible, that is, the Scroll var in window)

[API]
That's why I added the style var "ImGuiStyleVar_ScrollSmooth". If you set it to 1.0f (the default) there is no smoothness at all. Any value higher than 1.0f starts adding smoothness. It could be pushed and be independent for controls/windows that display scrollbars. In addition, functions that works with the new Window variable can be modified to do not use it if ScrollSmooth = 1.0f just to avoid all the smoothness code (it can be added, not present on my PR)

If you prefer to keep the system intact if the style var is 1.0f i can modify the PR for that.
If you prefer to have it time dependent to behave exactly the same no matter the frame rate i can modify the PR for that.

Just ask :)

@ocornut
Copy link
Owner

ocornut commented Feb 26, 2024

Smoothing logic is frame dependent yes.

Then it's incorrect/buggy! Of course things needs to behave more or less the same no matter the framerate, some users are running 15 hz some are running 240 hz or unthrolled.
Whatever alternative solution is used need to take account for change of scroll target while an ongoin smooth is running.

[API] That's why I added the style var "ImGuiStyleVar_ScrollSmooth". If you set it to 1.0f (the default) there is no smoothness at all. Any value higher than 1.0f starts adding smoothness. It could be pushed and be independent for controls/windows that display scrollbars.

This is not what I meant. When you do an API call, e.g. SetScrollXXXX() you may want to control whether smoothing is acceptable or if the caller needs immediate application. For example when a window reappear with a new focused item, you don't want smoothing. This would require a rework of scrolling API to expose flags. There's already some WIP work using ImGuiScrollFlags in imgui_internal.h and those would need to be progressively extended to more API. I don't expect you to make those changes fully, but we need to design ahead.

@astharoth-tlotb
Copy link
Author

astharoth-tlotb commented Feb 26, 2024

Got it.

Requirements: It should be time bounded.
Optionally: User may define the time between start and end points
Optionally: User may define the scrolling curve
Requirement: Scrolling functions should expose a flag to define immediate or smooth behavior. By default immediate.
Requirement: Window (and eligible controls that may expose a scrollbar) should have a flag to configure the scrollbar in immediate or smooth scrolling. By default immediate.

Functions:
SetScrollX and SetScrollY for current window used "Scroll" var directly.
SetScrollX and SetScrollY for specific window used "ScrollTarget" var.
SetScrollFromPosX and SetScrollFromPosXY (for current and specific window) used "ScrollTarget" var
SetScrollHereX and SetScrollHereY used SetScrollFromPosN -> used "ScrollTarget" var
ScrollToRect and ScrollToItem should be reviewed.
MouseWheel interactions with "ScrollTarget" should be configured in immediate or smooth as well.

Let me take a look into the new flags / the req list.

You can forget / close this PR but I'll not delete it since maybe is useful for someone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants