VScrollbar - any way to fix the size of the grabber?

I really dont want it to stretch! Cant find the right button to press though…

I am not very well versed in ui.
Does this help?
https://www.reddit.com/r/godot/comments/yvo6zk/scrollbar_customisation/

if you want a static grabber (won’t stretch), then you may need to make use of Vslider along with the scroll container
it can do something like this,
scrolltest
it still needs to calculate the value_changed’s _value from scroll_container’s vscrollbar to Vslider value correctly. try it yourself first…

Thanks - saw that as one of my google results. I think its for Godot 3; there is no NinePatch texture type in the options for the grabber in the theme.
Out of the box, the grabber’s StyleBoxTexture supports a SubRegion Rect on a texture (like an Atlas), but its not NinePatch (more like OnePatch :wink: ); there is only XYWH, no option to specify the quadrants for edges and middle.

If there was, I could potentially see a workaround/hack by making the entire grabber in the “bottom” of the NinePatch and using the top and middle as the vertical stretchy part.

Interesting - thats exactly what I have…

I’m using a ScrollContainer with a GridContainer child that handles laying out the children.

I have a custom theme tres file and I’ve overridden the grabber from a StyleBoxFlat to a StyleBoxTeture, and applied my image from my spritesheet using the Rect Region…

But, for some reason, the grabber is being sized relative to how mcuh scroll there is… in this case there is effectively 2 pages, so the grabber is 50% height of the bar. If I have 3 pages, its 33%.

The ScrollContainer automatically adds a VSlider when it needs it. This is the remote view with the window open:
image

Well… I sort of have a workaround for now, but it smells hacky. Looks like maybe I misunderstood what “grabber” meant and it looks like it is more like a “bar” which gets resized relative to the contents of the ScrollContainer.

I have made a custom script which grabs the _v_scroll node that Godot adds itself, then appends a TextRect icon to it and positions that when the container is scrolled.

But, new problem, “ratio” (or value vs min/max) seems to max out at about 50% when there are two pages.

CleanShot 2024-10-12 at 10.54.32

But it’s closer to 80% when there are 3 pages…

I could do some maths to work around this (I think)… but the odd thing is it seems to track the mouse pointed on scroll, so I think the underlying issue is the ScrollContainer’s maths?

For some reason the 2nd GIF didn’t upload…
CleanShot 2024-10-12 at 10.59.06

In case its of any help to anyone… Simply attach this to the ScrollContainer (or extend it if you need your own additional logic):

extends ScrollContainer

@export var icon : Texture2D
var iconNode : TextureRect

@onready var vsb : VScrollBar = $_v_scroll

func _ready() -> void:
	if vsb:
		iconNode = TextureRect.new()
		iconNode.texture = icon

		vsb.add_child(iconNode)
		vsb.connect("scrolling", _scrolling)

func _scrolling():
	iconNode.position.y = vsb.ratio * vsb.get_size().y

I tried to make it a component, but Godot showed a warning about a ScrollContainer having multiple children.

1 Like

You actually saved my life
very clever thanks!!