Quantcast
Channel: Recent Gists from assertchris
Viewing all articles
Browse latest Browse all 30

iOS-like scroll picker container for text selection

$
0
0
ScrollPicker.gd
extends ScrollContainer
class_name GameScrollPicker
export (Array, String) var items := [] setget set_items
export (Resource) var label_theme
export var label_height := 50
onready var _items := $Items as VBoxContainer
func set_items(items : Array) -> void:
for i in range(2):
var label = create_label('')
_items.add_child(label)
for i in items.size():
var label = create_label(items[i])
_items.add_child(label)
for i in range(1):
var label = create_label('')
_items.add_child(label)
func create_label(text : String) -> Label:
var label = Label.new()
label.text = text
label.theme = label_theme
label.align = label.ALIGN_CENTER
label.valign = label.VALIGN_CENTER
label.rect_min_size = Vector2(0, label_height)
return label
func _process(_delta: float) -> void:
if not label_height:
return
rect_min_size = Vector2(0, label_height * 5)
for child in _items.get_children():
if child.rect_position.y == scroll_vertical + (label_height * 2):
child.modulate.a = 1.0
elif child.rect_position.y == scroll_vertical + (label_height * 1) or child.rect_position.y == scroll_vertical + (label_height * 3):
child.modulate.a = 0.5
else:
child.modulate.a = 0.1
"""
Original: https://github.com/godotengine/godot/issues/21137
Helper Script for ScrollContainer to let them scroll with InputListeners inside.
Buttons inside should react to release, in order to be not activated during scroll.
Does not work with Touch Screen Buttons as they handle the input before.
"""
export (Vector2) var delta_for_swipe := Vector2(8, 8)
var look_for_swipe := false
var swiping := false
var swipe_start : Vector2
var swipe_mouse_start : Vector2
var swipe_mouse_times := []
var swipe_mouse_positions := []
var tween : Tween
func _input(ev) -> void:
if !is_visible_in_tree():
return
if ev is InputEventScreenDrag and swiping:
accept_event()
return
if ev is InputEventMouseButton:
if ev.pressed and get_viewport_transform().xform(get_global_rect()).has_point(ev.global_position):
look_for_swipe = true
swipe_mouse_start = ev.global_position
elif swiping:
swipe_mouse_times.append(OS.get_ticks_msec())
swipe_mouse_positions.append(ev.global_position)
var source := Vector2(get_h_scroll(), get_v_scroll())
var idx := swipe_mouse_times.size() - 1
var now := OS.get_ticks_msec()
var cutoff := now - 100
for i in range(swipe_mouse_times.size() - 1, -1, -1):
if swipe_mouse_times[i] >= cutoff:
idx = i
else: break
var flick_start : Vector2 = swipe_mouse_positions[idx]
var flick_dur := min(0.3, (ev.global_position - flick_start).length() / 1000)
if flick_dur > 0.0:
tween = Tween.new()
add_child(tween)
var delta : Vector2 = ev.global_position - flick_start
var target := source - delta * flick_dur * 15.0
tween.interpolate_method(self, 'set_h_scroll', source.x, stepify(target.x, label_height), flick_dur, Tween.TRANS_LINEAR, Tween.EASE_OUT)
tween.interpolate_method(self, 'set_v_scroll', source.y, stepify(target.y, label_height), flick_dur, Tween.TRANS_LINEAR, Tween.EASE_OUT)
tween.interpolate_callback(tween, flick_dur, 'queue_free')
tween.start()
swiping = false
swipe_mouse_times = []
swipe_mouse_positions = []
else:
look_for_swipe = false
if ev is InputEventMouseMotion:
if look_for_swipe:
var delta = ev.global_position - swipe_mouse_start
if abs(delta.x) > delta_for_swipe.x or abs(delta.y) > delta_for_swipe.y:
swiping = true
look_for_swipe = false
swipe_start = Vector2(get_h_scroll(), get_v_scroll())
swipe_mouse_start = ev.global_position
swipe_mouse_times = [OS.get_ticks_msec()]
swipe_mouse_positions = [swipe_mouse_start]
if is_instance_valid(tween) and tween is Tween:
tween.stop_all()
if swiping:
var delta : Vector2 = ev.global_position - swipe_mouse_start
set_h_scroll(stepify(swipe_start.x - delta.x, label_height))
set_v_scroll(stepify(swipe_start.y - delta.y, label_height))
swipe_mouse_times.append(OS.get_ticks_msec())
swipe_mouse_positions.append(ev.global_position)
ev.position = Vector2.ZERO

Viewing all articles
Browse latest Browse all 30

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>