Topic was automatically imported from the old Question2Answer platform.
Asked By
Fruitdude
Hello,
currently i am trying to scroll trough a list of entries via mousewheel up or down. First i looked for code that would go through the different buttons focus and in the end i found this https://forum.godotengine.org/5990/follow-focus-going-through-entries-inside-scroll-container . Now i can go through the different buttons with the tab key or shitf+tab. But i want to cycle trough them with the mousewheel. I found out that you can simulate a keypress via code https://forum.godotengine.org/53622/how-to-sumalate-a-key-press
The problem here now is that the key can only be pressed once and then never again.
Next problem is that i can’t combine they KEY_SHIFT + KEY_TAB keys so i go to the previous focus.
How can i simulate the keypress so i can use the mousewheel? How do i combine the different keys? Is this even the right approach?
extends VBoxContainer
onready var _scroll_container = get_parent()
onready var button_1 = $Button
func _ready():
button_1.grab_focus()
for child in get_children():
child.connect("focus_entered", self, "_on_focus_change")
func _input(event):
if event is InputEventMouseButton and event.pressed:
if event.button_index == BUTTON_WHEEL_UP :
simulate_keypress_tab_shift()
elif event.button_index == BUTTON_WHEEL_DOWN:
simulate_keypress_tab()
func _on_focus_change():
var focused = get_focus_owner()
var focus_size = focused.rect_size.y
var focus_top = focused.rect_position.y
var scroll_size = _scroll_container.rect_size.y
var scroll_top = _scroll_container.get_v_scroll()
var scroll_bottom = scroll_top + scroll_size - focus_size
if focus_top < scroll_top:
_scroll_container.set_v_scroll(focus_top)
if focus_top > scroll_bottom:
var scroll_offset = scroll_top + focus_top - scroll_bottom
_scroll_container.set_v_scroll(scroll_offset)
func simulate_keypress_tab():
var a = InputEventKey.new()
a.scancode = KEY_TAB
a.pressed = true # change to false to simulate a key release
Input.parse_input_event(a)
func simulate_keypress_tab_shift():
var a = InputEventKey.new()
a.scancode = KEY_SHIFT + KEY_TAB
a.pressed = true # change to false to simulate a key release
Input.parse_input_event(a)
You can map the mousewheel to the ui_up and ui_down Actions. To do that, go to your project settings, second tab (InputMap), locate ui_up and down, and add the right entries with the +.
Alternatively, if you only want the mousewheel to behave like that in some circumstances. You could make two new inputs, Fruit_up and Fruit_down, map them to the wheel, and then listen to them : func _unhandled_input(event): . if event.is_action_pressed("Fruit_up") && time_is_right: . . get_tree().set_input_as_handled() //stop event propagation . . var action := InputEventAction.new() . . action.action = "ui_up" . . action.pressed = true . . Input.parse_input_event(action) . elif event.is_action_pressed("Fruit_down") && time_is_right: . . get_tree().set_input_as_handled() . . var action := InputEventAction.new() . . action.action = "ui_down" . . action.pressed = true . . Input.parse_input_event(action)
With time_is_right being a variable telling you if you want the scrollwheel to handle focus.
i tried binding the mouswheel up/down to the ui_up/down actions at first but sadly that does not work because the mousewheel is never really being pressed. This gets explained in this post i found Wheel Up and Wheel Down "buttons" apparently not working in InputMap · Issue #3340 · godotengine/godot · GitHub
this seem especiall weird to me since you are even allowed to assign the mousewheel up/down to any action but it does not work in the end
the problem more lies in this part of the code. and i don’t know how to do that multiple times. because right now if i press mousewheel down it only executes this func once. what i mean by that is that i can set the focus from button1 to button2 but not from buttton2 to button3. it stops at button2
func simulate_keypress_tab():
var a = InputEventKey.new()
a.scancode = KEY_TAB
a.pressed = true # change to false to simulate a key release
Input.parse_input_event(a)