Smooth scrolling list control with ContainerControls

Recently I implemented NSCollectionViewControlMBS control for Xojo to have a grid of items based on container controls. But a few days ago we had the need for having just a few containers to scroll on a window in Xojo. You may start to implement this in Xojo with a scrollbar and then move in the ValueChanged the containers up/down as needed. Quickly you may realize you need a wrapping container to clip the scrolling ones properly. But if you loop over containers and change their Top property to move them around, you may quickly see the scrolling not be smooth. We needed something better.


Since macOS comes with a NSScrollView class, I wanted to use that to push the job of scrolling and redrawing to the OS itself. So we have a Xojo managed inner and outer ContainerControl and slide our NSScrollViewMBS object between. We put all item containers on the inner ContainerControl, so Xojo may not know about the scrolling and just sees a big container in a smaller one. We configure the scroll view with a vertical scrollbar, some bezel around and a reasonable page scroll value.

When we try this setup, we can scroll smoothly and with mouse wheel support. We get the elastic scrolling with bouncing on the ends (can be disabled). This is fantastic and very smooth.

You may ask about Windows and Linux. Well, this may also be doable, but then with a regular Scrollbar itself. It may be tricky to get the redraw stuff smooth and avoid flicker. But well, I made an example for that, too. Tested on Windows and seems to work mostly with scrollbar controls. Since we only move the inner container up and down and let the container do clipping, it seems to work well with not much flicker.

And once I had that, I merged the two examples into one. Please try it soon as part of the examples coming with MBS Xojo Plugins in version 21.2 or later. If you have feedback and improvements, feel free to send them back to us, so we can merge your changes into our example.

2 Likes

Stupid question: what is the name of the example?

/MacControls/ContainerControl List

2 Likes

The scrollbar looks pretty weird. Normal scrolling:

Now I mouse over the scrollbar:

Why do you use the following code with the width of the scrollbar:

innerContainer.EmbedWithin(Self, 0, 0, Me.Width - VScrollBar.width, Me.Height)

Thanks to Apple’s insane invisible-until-used scrollbars they usually don’t have any width.

Feel free to change it.
The scrollbar should be visible always in my opinion, but maybe I forgot to configure that.

1 Like

I removed the “- VScrollBar.width” and the VScrollbar completely. However, the scrollbar still has the odd behaviour. I also think that the scrollbar should be always visible. But it isn’t. Can you fix the scrollbar behaviour?

VScrollBar is for windows.

In Open event, you can change

innerContainer.EmbedWithin(Self, 0, 0, Me.Width - VScrollBar.width, Me.Height)

to this to reduce the right spacing:

innerContainer.EmbedWithin(Self, 0, 0, Me.Width, Me.Height)

and for the scrollbar to be permanent, we need this:

ScrollView.verticalScroller.scrollerStyle = NSScrollerMBS.NSScrollerStyleLegacy

I’ve already removed VScrollbar. I don’t want the legacy style. Instead I want the modern scrollbar all over. How do I achieve this?

Don’t set the legacy style.
And change the Me.Width - VScrollBar.width to Me.Width for the width.

Ich habe das schon gemacht. Aber die Scrollbar sieht immer noch suboptimal aus, wenn ich drĂĽbergehe. Wie bekomme ich das weg?

I may not know the answer.

Too bad. As the example is now it’s not usable on macOS.