2022-05-14 20:51:48 +02:00
extends Container
class_name TopicDraggable
2022-05-21 14:56:02 +02:00
const SCROLL_SPEED = 25.0
2022-05-14 20:51:48 +02:00
onready var topic_feed : VBoxContainer = get_node ( " .. " )
onready var scroll_container : ScrollContainer = get_node ( " ../.. " )
onready var v_scroll : VScrollBar = get_node ( " ../../_v_scroll " )
onready var editable = get_node ( " TopicEditable " )
onready var tween = get_node ( " Tween " )
var global_position setget _set_global_position
2022-05-21 14:56:02 +02:00
var local_position setget _set_local_position
2022-05-14 20:51:48 +02:00
var _in_fit_in_animation = false
2022-05-21 14:56:02 +02:00
var _previous_global_position
var _previous_scroll
2022-05-14 20:51:48 +02:00
var _offset
2022-05-21 14:56:02 +02:00
var _something_passed = false
2022-05-14 20:51:48 +02:00
func _ready ( ) :
pass
2022-05-21 14:56:02 +02:00
func _gui_input ( event ) :
if event is InputEventMouseButton and event . button_index == BUTTON_LEFT :
if event . is_pressed ( ) :
if event . shift :
topic_feed . _toggle_selection_result = _set_selection ( null )
topic_feed . _shift_hold = true
else :
_deselect_all ( )
if not editable . edit_mode :
if event . doubleclick :
editable . _enable_edit_mode ( )
editable . text_edit . grab_focus ( )
yield ( get_tree ( ) , " idle_frame " )
editable . text_edit . select_all ( )
elif ! _in_fit_in_animation :
_set_as_grabbed ( )
2022-05-14 20:51:48 +02:00
func _input ( event ) :
if event is InputEventMouseButton and event . button_index == BUTTON_LEFT :
if event . is_pressed ( ) :
2022-05-21 14:56:02 +02:00
if ! _is_mouse_on_topic ( ) and editable . edit_mode :
2022-05-14 20:51:48 +02:00
editable . text_edit . _confirm ( )
else :
2022-05-21 14:56:02 +02:00
if _is_grabbed ( ) :
_fit_in_animation ( )
2022-05-14 20:51:48 +02:00
topic_feed . _shift_hold = false
if event is InputEventMouseMotion :
2022-05-21 14:56:02 +02:00
if _is_grabbed ( ) :
2022-05-14 20:51:48 +02:00
_move_block ( event )
topic_feed . check_all_passings ( )
2022-05-21 14:56:02 +02:00
if topic_feed . _shift_hold and _is_mouse_on_topic ( ) :
2022-05-14 20:51:48 +02:00
# warning-ignore:return_value_discarded
_set_selection ( topic_feed . _toggle_selection_result )
2022-05-21 14:56:02 +02:00
if event is InputEventMouseButton :
if _is_grabbed ( ) :
var scroll_value = 0.0
if event . button_index == BUTTON_WHEEL_UP :
scroll_value = - SCROLL_SPEED
elif event . button_index == BUTTON_WHEEL_DOWN :
scroll_value = SCROLL_SPEED
if scroll_value != 0.0 :
scroll_container . scroll_vertical += scroll_value
_previous_scroll = scroll_container . scroll_vertical
topic_feed . check_all_passings ( )
2022-05-14 20:51:48 +02:00
func _set_selection ( to ) - > bool :
# If 'to' is null, selection is toggled.
if topic_feed . selected_topics . has ( self ) and to != true :
topic_feed . selected_topics . erase ( self )
editable . _update_color ( )
return false
elif ! topic_feed . selected_topics . has ( self ) and to != false :
topic_feed . selected_topics . append ( self )
editable . _update_color ( )
return true
else :
return topic_feed . selected_topics . has ( self )
func _deselect_all ( ) :
topic_feed . selected_topics . clear ( )
topic_feed . update_all_colors ( )
func _set_as_grabbed ( ) :
var rect = editable . get_global_rect ( )
rect_min_size . y = editable . rect_size . y
editable . set_as_toplevel ( true )
2022-05-21 14:56:02 +02:00
editable . mouse_filter = MOUSE_FILTER_IGNORE
2022-05-14 20:51:48 +02:00
editable . rect_position = rect . position
topic_feed . currently_grabbed_topic = self
2022-05-21 14:56:02 +02:00
_previous_global_position = editable . rect_global_position
_previous_scroll = scroll_container . scroll_vertical
2022-05-14 20:51:48 +02:00
_offset = 0
2022-05-21 14:56:02 +02:00
_move_block ( InputEventMouseMotion . new ( ) )
2022-05-14 20:51:48 +02:00
func _fit_in_animation ( ) :
_in_fit_in_animation = true
topic_feed . currently_grabbed_topic = null
2022-05-21 14:56:02 +02:00
var overhead = _topic_overhead ( rect_global_position . y )
var from = editable . rect_global_position
var to
if overhead > 0.0 :
var sc_rect = scroll_container . get_global_rect ( )
to = Vector2 (
sc_rect . position . x ,
sc_rect . end . y - rect_size . y
)
elif overhead < 0.0 :
to = scroll_container . rect_global_position
else :
to = rect_global_position - Vector2 ( 0.0 , overhead )
2022-05-14 20:51:48 +02:00
tween . stop_all ( )
tween . interpolate_property ( self , " global_position " ,
2022-05-21 14:56:02 +02:00
from , to ,
2022-05-14 20:51:48 +02:00
0.12 , Tween . TRANS_LINEAR , Tween . EASE_IN_OUT
)
2022-05-21 14:56:02 +02:00
if overhead != 0.0 :
tween . interpolate_property ( scroll_container , " scroll_vertical " ,
scroll_container . scroll_vertical , scroll_container . scroll_vertical + overhead ,
0.12 , Tween . TRANS_LINEAR , Tween . EASE_IN_OUT
)
2022-05-14 20:51:48 +02:00
tween . start ( )
2022-05-21 14:56:02 +02:00
2022-05-14 20:51:48 +02:00
yield ( tween , " tween_completed " )
editable . set_as_toplevel ( false )
2022-05-21 14:56:02 +02:00
editable . mouse_filter = MOUSE_FILTER_PASS
2022-05-14 20:51:48 +02:00
rect_min_size . y = 0
editable . rect_position = Vector2 . ZERO
_in_fit_in_animation = false
func _move_block ( event ) :
_offset += event . relative . y
2022-05-21 14:56:02 +02:00
var virtual_position = _previous_global_position + Vector2 ( 0.0 , _offset )
var overhead = _topic_overhead ( virtual_position . y )
virtual_position . y -= overhead
if get_index ( ) == topic_feed . get_child_count ( ) - 2 :
if virtual_position . y > rect_global_position . y :
virtual_position . y = rect_global_position . y
_set_global_position ( virtual_position )
scroll_container . scroll_vertical = _previous_scroll + overhead
2022-05-14 20:51:48 +02:00
2022-05-21 14:56:02 +02:00
# How much topic is out of scroll_container bounds.
func _topic_overhead ( y_pos ) :
var scroll_rect = scroll_container . get_global_rect ( )
scroll_rect . size . y -= editable . rect_size . y
var overhead = 0
# Higher?
if y_pos < scroll_rect . position . y :
overhead = y_pos - scroll_rect . position . y
# Lower?
if y_pos > scroll_rect . end . y :
overhead = y_pos - scroll_rect . end . y
return overhead
func _is_mouse_on_topic ( ) - > bool :
var on_topic = get_global_rect ( ) . has_point ( get_global_mouse_position ( ) )
return _is_mouse_on_topic_feed ( ) and on_topic
func _is_mouse_on_topic_feed ( ) - > bool :
return scroll_container . get_global_rect ( ) . has_point ( get_global_mouse_position ( ) )
func _is_grabbed ( ) - > bool :
return topic_feed . currently_grabbed_topic == self
2022-05-14 20:51:48 +02:00
func set_previous_position ( ) :
2022-05-21 14:56:02 +02:00
_previous_global_position = editable . rect_global_position
2022-05-14 20:51:48 +02:00
func check_for_passing ( ) - > bool :
var dragged : TopicDraggable = topic_feed . currently_grabbed_topic
if dragged == self or dragged == null :
return false
var dir = sign ( dragged . get_index ( ) - get_index ( ) )
var self_rect = get_global_rect ( )
var self_half_size = self_rect . size . y * 0.5
# Center line.
var self_coll_line = self_rect . position . y + self_half_size
var dragged_rect = dragged . editable . get_global_rect ( )
var dragged_half_size = dragged_rect . size . y * 0.5
var dragged_half_pos = dragged_rect . position . y + dragged_half_size
# Top or bottom line, depending on if moved up or down.
var dragged_coll_line = dragged_half_pos + dragged_half_size * - dir
# +1 if dragged_coll_line is below; -1 if above.
var coll_dir = sign ( self_coll_line - dragged_coll_line )
if coll_dir == dir :
topic_feed . set_all_previous_positions ( )
topic_feed . move_child (
topic_feed . currently_grabbed_topic ,
get_index ( )
)
2022-05-21 14:56:02 +02:00
_something_passed = true
Data . topics . dirty_flag = true
2022-05-14 20:51:48 +02:00
return true
return false
func setup_tween ( ) :
2022-05-21 14:56:02 +02:00
if _something_passed :
var _previous_local_position = _previous_global_position - rect_global_position
2022-05-14 20:51:48 +02:00
tween . stop_all ( )
2022-05-21 14:56:02 +02:00
tween . interpolate_property ( self , " local_position " ,
_previous_local_position , Vector2 . ZERO , 0.15 ,
2022-05-14 20:51:48 +02:00
Tween . TRANS_LINEAR , Tween . EASE_IN_OUT
)
tween . start ( )
2022-05-21 14:56:02 +02:00
_something_passed = false
yield ( tween , " tween_completed " )
2022-05-14 20:51:48 +02:00
func _set_global_position ( value ) :
editable . set_global_position ( value )
2022-05-21 14:56:02 +02:00
func _set_local_position ( value ) :
editable . rect_position = value