SpyrexDE / SmoothScroll

Addon for the Godot Game Engine that adds a SmoothScrollContainer.
https://spyrexde.github.io/SmoothScroll/
MIT License
132 stars 10 forks source link

Overdrag triggering constantly when middle mousebutton pressed to the side #55

Open SpyrexDE opened 2 months ago

SpyrexDE commented 2 months ago

When holding down the middle mouse button in one direction this unpleasant behavior occurs: godot2 The desired behaviour would be for the content to stay in the slightly over-dragged position as long as the button is pressed, instead of snapping back.

HaroldLever commented 2 months ago

Do you mean touch pad gesture? If so, the scrolling gesture is just to emulate wheel buttons event, plus a factor according to gesture movement. It is not very likely to achieve what you said "stay in the slightly over-dragged position as long as the button is pressed, instead of snapping back.", as it is the same case as keeping scrolling to go out of boundary using mouse wheel button. This issue is probably similar to #40 . There is no way in Godot to recognize whether input event mouse wheel buttons or touch pad gestures.

I think multiplying a factor might alleviate the problem, although it still exists.

MOUSE_BUTTON_WHEEL_XXXX:
    if event.pressed:
        last_scroll_type = SCROLL_TYPE.WHEEL
        if event.shift_pressed or not should_scroll_vertical():
            if should_scroll_horizontal():
                # velocity.x -= speed
                velocity.x -= speed * event.factor
        else:
            if should_scroll_vertical():
                # velocity.y -= speed
                velocity.y -= speed  * event.factor
        scroll_damper = wheel_scroll_damper
        kill_scroll_to_tweens()

[Edit] Ahh, I see, mac. Sadly I haven't got the chance to use it. Try to print input event, I guess it sends scroll button event, which suits the case I mention above.

SpyrexDE commented 2 months ago

Do you mean touch pad gesture? If so, the scrolling gesture is just to emulate wheel buttons event, plus a factor according to gesture movement. It is not very likely to achieve what you said "stay in the slightly over-dragged position as long as the button is pressed, instead of snapping back.", as it is the same case as keeping scrolling to go out of boundary using mouse wheel button. This issue is probably similar to https://github.com/SpyrexDE/SmoothScroll/issues/40 . There is no way in Godot to recognize whether input event mouse wheel buttons or touch pad gestures.

I was already aware of that but what I described is present with just a real mouse and pressing the middle mouse button to the left or right. I think that's something that could be checked easily due to being a physical button emitting the same signals as any other mouse button.

Ahh, I see, mac. Sadly I haven't got the chance to use it. Try to print input event, I guess it sends scroll button event, which suits the case I mention above.

The gif was recorded on a Windows 10 PC.

HaroldLever commented 2 months ago

That's weird. Pressing middle mouse button does not do anything when I test it on my device.

https://github.com/SpyrexDE/SmoothScroll/assets/80692930/62d96ef6-4f36-4631-be96-d0a4047c118a

I wonder what I misunderstand.

SpyrexDE commented 2 months ago

Not every mouse is capable of this but this image shows what I mean: image

HaroldLever commented 2 months ago

Could you record a video of printing input event, it might help out to figure out the problem.

SpyrexDE commented 2 months ago

MOUSE_BUTTON_WHEEL_LEFT prints

InputEventMouseButton: button_index=6, mods=none, pressed=false, canceled=false, position=((734, 327)), button_mask=0, double_click=false

MOUSE_BUTTON_WHEEL_RIGHT prints

InputEventMouseButton: button_index=7, mods=none, pressed=true, canceled=false, position=((734, 327)), button_mask=64, double_click=false

godot3

HaroldLever commented 2 months ago

I think my guess is correct. The special buttons on your mouse send wheel button left/right events frequently to emulate horizontal scrolling. It is the same as you scroll wheel buttons vertically by multiple times. That might not be a bug, it is how it work.

SpyrexDE commented 2 months ago

The difference between those two mouse buttons is that for every wheel up/down event you have to actuate the mouse wheel. The wheel left/right controls for horizontal scrolling should behave differently because in most programs you just keep the wheel pressed in one direction to scroll at a constant speed and it stops when it hits the content end.

In the following demo, I only use my middle wheel button to scroll. While this does not have any over-drag functionality, I suppose we could implement that too by using the buttons' pressed and released events instead of just the pressed signal that is being fired frequently by Godot when holding down a button.

https://github.com/SpyrexDE/SmoothScroll/assets/57133330/c64ceeae-782f-45c5-abba-ad73bedfa16f

Demo from this codepen: https://codepen.io/nadeen/pen/ZEQYbeL

HaroldLever commented 2 months ago

I suppose we could implement that too by using the buttons' pressed and released events.

I 'm quite doubtful if we could know when horizontal scroll button is pressed or released, as you can see:

image

Godot send both pressed and not pressed event at the same time.

I guess you want velocity.x = speed rather than velocity.x += speed? I 'm curious if there are some mouses that can scroll in any direction. image

Would that change break these mouses' experience?

SpyrexDE commented 2 months ago

I think such mice are quite uncommon and shouldn't be minded until someone requests it.

I 'm quite doubtful if we could know when horizontal scroll button is pressed or released, as you can see Godot send both pressed and not pressed event at the same time.

I think that's a bug in Godot, or at least a missing feature probably due to Godot handling scroll down/up events the same as scroll right/left.

Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) works perfectly fine while Input.is_mouse_button_pressed(MOUSE_BUTTON_WHEEL_LEFT) is never returning true.

I'm probably gonna open a new issue in the Godot repository for that.

https://github.com/godotengine/godot/issues/91025