diary/user_interface/topic_panel/topic_draggable.gd

153 lines
4.2 KiB
GDScript3
Raw Normal View History

extends Container
class_name TopicDraggable
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
var _in_fit_in_animation = false
var _previous_position
var _offset
func _ready():
pass
func _input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
if event.is_pressed():
if _is_mouse_on_control():
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()
editable.text_edit.select_all()
elif !_in_fit_in_animation:
_set_as_grabbed()
elif editable.edit_mode:
editable.text_edit._confirm()
else:
_fit_in_animation()
topic_feed._shift_hold = false
if event is InputEventMouseMotion:
if topic_feed.currently_grabbed_topic == self:
_move_block(event)
topic_feed.check_all_passings()
if topic_feed._shift_hold and _is_mouse_on_control():
# warning-ignore:return_value_discarded
_set_selection(topic_feed._toggle_selection_result)
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)
editable.rect_position = rect.position
topic_feed.currently_grabbed_topic = self
_previous_position = editable.rect_global_position
_offset = 0
func _fit_in_animation():
_in_fit_in_animation = true
topic_feed.currently_grabbed_topic = null
tween.stop_all()
tween.interpolate_property(self, "global_position",
editable.rect_global_position, rect_global_position,
0.12, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
)
tween.start()
yield(tween, "tween_completed")
editable.set_as_toplevel(false)
rect_min_size.y = 0
editable.rect_position = Vector2.ZERO
_in_fit_in_animation = false
func _move_block(event):
_offset += event.relative.y
editable.set_global_position(_previous_position + Vector2(0.0, _offset))
func _is_mouse_on_control() -> bool:
return get_global_rect().has_point(get_viewport().get_mouse_position())
func set_previous_position():
_previous_position = editable.rect_global_position
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()
)
return true
return false
func setup_tween():
if _previous_position != editable.rect_global_position:
tween.stop_all()
tween.interpolate_property(self, "global_position",
_previous_position, rect_global_position, 0.15,
Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
)
tween.start()
func _set_global_position(value):
editable.set_global_position(value)