Scroll box autoscroll

Hello. By autoscroll I mean hovering over the bottom or top area of a scroll box and having it scroll up or down by a set speed, and stop scrolling when unhovering from those areas.

I’ve tried this with a scroll box and Set Scroll Offset, and it worked alright (I used timers to increase or decrease the offset incrementally), however I couldn’t find a way to set the max scroll offset, so I couldn’t clamp it to only scroll for the contents. It’s kinda hard to explain, but when scrolling down, it’d get to the bottom, then the offset would keep increasing, but nothing would happen visually, so when trying to scroll back up, the offset would decrease, and only when getting back to the point of the last widget in the scroll box will anything happen visually again.

The way I had it set out using the scroll box was a button at the top, and a button at the bottom (not nested inside the scroll box but just sitting on top of it) and would use the hover and unhover events in those buttons to change the scroll offset of the scroll box. Their visibility would get set to collapsed if the scroll offset is = 0, or >= the max scroll offset, the number I couldn’t work out how to get.

Anyway, I’ve tried a new system where I just change the padding of a container holding the scroll box’s contents (no scroll box being used here) in an Overlay when one of the buttons is hovered over, and uses an Animation acting as a Timeline with lerps. This works alright, but would require a lot of additional work to get up to the quality of a default scroll box, like somehow getting the max scroll offset (again, the same problem) and things like that which make this very difficult.

I did try adding all the scroll box’s contents’ sizes (they use size boxes) and padding vertically to get a max scroll offset, but this didn’t work, especially because I’m using a Wrap Box with four items in each row, so I really need to do some sort of For Every 4 Items loop instead for this to really work.

Sorry for the long post, but I’ve been stuck wondering and experimenting with this problem for a long while now, and decided I should ask on the forum as I’m not getting anywhere with it myself.

Theoretically:

The hovering part can be done by overridijg the OnMouseMove Function.
This is triggered every time the mouse moves inside a Widget.

To achive the hovering over top or bottom, you simply ask in the OnMouseMove, if the Mouseposition is < widget top + offset OR > widget height - offset.

When one of these two is true, set an integer to 1 for up or -1 for down.
If both are false, set the integer to 0.

The scrolling runs in the Tick event of the widget.
Simply ask if the scroll integer is != 0.
If false, do nothing.
If true, get the Scrollboxs ScrollOffset, add the scroll integer * a speed float to it, and set the ScrollOffset back.

In order to get the max scroll distance, you need to have a prepass passed, before you can getDesiredSize of a Geometry.

You may want to set the scroll integer to 0, when OnMouseLeave is called.

The max offset (the scroll length) is defined by the content of the scroll box.
Blueprints has the method GetScrollOffsetOfEnd() to get the max offset, did you miss it?

// If the current scroll position <= 0
bool UScrollBoxWidget::IsScrollAtStart() {
	return (MyScrollBox->GetScrollOffset() <= 0.f);
}

// If the current scroll position >= its end position.
bool UScrollBoxWidget::IsScrollAtEnd() {
	return (MyScrollBox->GetScrollOffset() >= MyScrollBox->GetScrollOffsetOfEnd());
}

Hey, I have tried GetScrollOffsetOfEnd, but it didn’t work. I’m assuming this is because the elements in the scroll box are within a Wrap Box as well, so it just takes the default size of that Wrap Box (which is 0 as its contents are created through an array in Blueprints), which obviously then wouldn’t work. If I were to use that then I’d need another way of laying out the contents of the scroll box, which I have just thought of using horizontal boxes stacked in the scroll box, but then there’d be the case of creating each horizontal box and having them hold four items each.

I’ve tried implementing this, however I’m not sure what you mean by “widget top” or “offset”. Are they both floats?

I use a vertical box in my scrollbox widget and it works just fine using GetScrollOffsetOfEnd().
Better try experimenting if the problem lies with the wrapbox and if so replace it with a widget which is calculated properly.

I would use another container, but I need the Wrap Box specifically for the wrapping, unless another widget which works with GetScrollOffsetOfEnd can function similarly. Maybe even just horizontal boxes, but I’m not sure how they’d be created for every four items in an array.

This rather crude sketch shows the kind of thing I’m going for.

To me this looks like a grid. I only use wrapping with text. You can combine that with a scalebox as well to keep the fit.

To perform an action every X times in a loop you can use modulo (%):

Blueprint Modulo

C++ Modulo

I’m saying that I’m using a Wrap Box because each new widget item that’s created gets added horizontally to it, then wraps to a new line when it gets to the end of the container. Using a grid would required a new row to be made every 4 items, which might as well just have horizontal boxes at that point.

How would I use that in a For Each Loop (as that is how I am creating the items and adding them to a Wrap Box)? This kind of programming isn’t my strong point at all.

This is the explanation of how modulo works:

WTF Is? Modulus in Unreal Engine 4

You use the for loop index against modulo, if the remainder == 0 you perform an action.

That works amazingly! Thanks a ton!