godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Add Setting to allow ScrollContainers to continue Accepting Input even if the Top/Bottom of their Content is reached #2122

Open Arecher opened 3 years ago

Arecher commented 3 years ago

Describe the project you are working on

Attempting to use a ScrollContainer, to show it's limitations, in my opinion. As I said I would do in (#2119)

Describe the problem or limitation you are having in your project

The ScrollContainer currently automatically stops accepting input ( accept_input ) if you have scrolled to the Top/Bottom of the content. This means it gets passed through the tree, onto possible new ScrollContainers. Although this is intuitive to some users/players, it feel horrible to others.

pass_scrollinput Using the scrollwheel to scroll, as soon as the edge of the content/scrollbar is reached, the ScrollContainer stops accepting the input events, and therefore passes them to the ScrollContainer higher in the Scene Tree. Meaning the bigger ScrollContainer will keep scrolling.

It should be an exposed option/setting instead. That way you can choose whether you want to have ScrollContainers continue to accept any 'scroll' input events, even if they have reached the top/bottom of their content.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

This is probably best as a Project Setting, since it should most likely be a unified behaviour for all ScrollContainers.

In my custom-made ScrollContainer, I made it a GameSetting, to allow users to adjust it for themselves.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The Project Setting should determine whether ScrollContainers stop accepting input events when they have reached the top/bottom of their content.

The current behaviour should remain default though. I personally think it makes sense, but I ran into a few people that hated this behaviour.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not that I know of.

Is there a reason why this should be core and not an add-on in the asset library?

Core: Addition to functionality of ScrollContainers

Calinou commented 3 years ago

This sounds like overscroll-behavior in CSS, which is being implemented in Web browsers as of writing.

paper42 commented 10 months ago

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not that I know of.

You can attach this script to the ScrollContainer, it will manually mark scroll events as handled.

extends ScrollContainer

# ScrollContainer stops marking scroll events as handled once it is at the end of the list,
# this code overrides this behavior
# it has to be _input and not _unhandled_input because input can be consumed by the child
# potential issue: if there is another UI element on top of this element, mouse wheel events in that
# area will still be marked as handled when they shouldn't be
func _unhandled_input(event):
    # mouse wheel events
    if event is InputEventMouseButton \
        and event.button_index in [MOUSE_BUTTON_WHEEL_DOWN, MOUSE_BUTTON_WHEEL_UP]:
        # check if mouse is inside ScrollContainer
        var rect = get_global_rect()
        if event.position.x >= rect.position.x \
            and event.position.x <= rect.position.x + rect.size.x \
            and event.position.y >= rect.position.y \
            and event.position.y <= rect.position.y + rect.size.y:
            # set input as handled
            get_viewport().set_input_as_handled()