dcockerham
Topic Author
Posts: 11
Joined: 10 Apr 2021, 00:44

ScrollChanged event missing the timing for ongoing scroll?

02 Sep 2022, 00:53

We have a custom ScrollViewer (inherited from Noesis::Scrollviewer) that's designed to accelerate over time as the user continues to scroll (allowing them to quickly scroll to the bottom of a long list if they hold down the right joystick of the controller). However, while our implementation was originally functioning as intended, it has recently been behaving oddly, and we were wondering if there might be a recent change to the Noesis::ScrollViewer that might be causing this.

The issue seems to be a matter of missed timing. When the user holds down the joystick, it triggers OnMouseWheelExternal(), which applies a flat change via ScrollToVerticalOffset(). This change then sets off the ScrollChanged() event, which is where we apply our custom logic, adding an additional push via another call to ScrollToVerticalOffset() (we have a check to make sure that this doesn't trigger itself again). However, it seems that, before this new vertical value is applied, OnMouseWheelExternal() is called again, and performs its operation upon the OLD vertical offset value instead of the new value that we should have after the ScrollChanged() event. Because of this, the only time that the accelerated scrolling is applied is when the joystick is released, as there finally isn't an OnMouseWheelExternal() call to overwrite our adjusted scrolling. Is this sort of timing an expected result?

This is the code for the OnMouseWheelExternal() call:
void AcceleratedScrollViewer::OnMouseWheelExternal(float wheelRotation, Noesis::Orientation orientation)
{
    if (orientation == Noesis::Orientation::Orientation_Vertical)
    {
        ScrollToVerticalOffset(GetVerticalOffset() - wheelRotation / 3.0f);
    }

    if (orientation == Noesis::Orientation::Orientation_Horizontal)
    {
        ScrollToHorizontalOffset(GetHorizontalOffset() - wheelRotation / 3.0f);
    }
}
Our response to the ScollChanged() event is a bit more complicated, but this is the gist of it:
this->ScrollChanged() += [this](BaseComponent* /* sender */, const ScrollChangedEventArgs& args) {
    /* calculations and other works happen */
    ScrollToVerticalOffset(GetVerticalOffset() + scrollIncrement);
};
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: ScrollChanged event missing the timing for ongoing scroll?

02 Sep 2022, 12:23

There was a recent change in ScrollViewer to fix a problem with circular loops in the ScrollChanged event. Now the event is not immediately raised in ScrollViewer::ArrangeOverride, but executed at the end of the layout, as it happens in WPF too.

But looking at the ScrollViewer code and the scenario you are describing it seems we introduced a new issue. Could you please report it in our bugtracker, we'll fix it for the next release and I'll send you a patch for you to test.
 
dcockerham
Topic Author
Posts: 11
Joined: 10 Apr 2021, 00:44

Re: ScrollChanged event missing the timing for ongoing scroll?

02 Sep 2022, 23:24

Thanks! I've added it to the bug tracker.
https://www.noesisengine.com/bugs/view.php?id=2408
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: ScrollChanged event missing the timing for ongoing scroll?

05 Sep 2022, 12:09

Thank you, will work on this for the next release.
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: ScrollChanged event missing the timing for ongoing scroll?

07 Sep 2022, 12:08

Hi, we have fixed the problem with changesets 11589 and 11590.
Could you please confirm on your side that the issue is solved?

Who is online

Users browsing this forum: No registered users and 11 guests