pir-serious-game-ethics/addons/dialogic/Editor/TimelineEditor/TimelineArea.gd

139 lines
3.6 KiB
GDScript

tool
extends ScrollContainer
var _drag_drop_indicator = null
# store last attempts since godot sometimes misses drop events
var _is_drag_receiving = false
var _last_event_button_drop_attempt = ''
var _mouse_exited = false
func _ready():
connect("mouse_entered", self, '_on_mouse_entered')
connect("mouse_exited", self, '_on_mouse_exited')
connect("gui_input", self, '_on_gui_input')
func can_drop_data(position, data):
if (data != null and data is Dictionary and data.has("source")):
if (data["source"] == "EventButton"):
# position drop indicator
_set_indicator_position(position)
_is_drag_receiving = true
_last_event_button_drop_attempt = data["event_name"]
return true
_remove_drop_indicator()
return false
func cancel_drop():
_is_drag_receiving = false
_last_event_button_drop_attempt = ''
_remove_drop_indicator()
pass
func drop_data(position, data):
# todo, getting timeline like this is prone to fail someday
var timeline_editor = get_parent()
# add event
if (data["source"] == "EventButton"):
var piece = timeline_editor.create_event(data["event_name"])
if (piece != null and _drag_drop_indicator != null):
var parent = piece.get_parent()
if (parent != null):
parent.remove_child(piece)
parent.add_child_below_node(_drag_drop_indicator, piece)
timeline_editor.indent_events()
# @todo _select_item seems to be a "private" function
# maybe expose it as "public" or add a public helper function
# to TimelineEditor.gd
timeline_editor._select_item(piece)
_is_drag_receiving = false
_last_event_button_drop_attempt = ''
_remove_drop_indicator()
func _on_mouse_exited():
_mouse_exited = true
func _on_mouse_entered():
_mouse_exited = false
func _input(event):
if (event is InputEventMouseButton and is_visible_in_tree() and event.button_index == BUTTON_LEFT):
if (_mouse_exited and _is_drag_receiving):
cancel_drop()
func _on_gui_input(event):
# godot sometimes misses drop events
if (event is InputEventMouseButton and event.button_index == BUTTON_LEFT):
if (_is_drag_receiving):
if (_last_event_button_drop_attempt != ''):
drop_data(Vector2.ZERO, { "source": "EventButton", "event_name": _last_event_button_drop_attempt} )
_is_drag_receiving = false
_remove_drop_indicator()
pass
func _create_drop_indicator():
_remove_drop_indicator()
var timeline = get_child(0)
if (timeline == null):
return
var indicator = ColorRect.new()
indicator.name = "DropIndicator"
indicator.rect_size.y = 100
indicator.rect_min_size.y = 100
indicator.color = Color(0.35, 0.37, 0.44) # default editor light blue
indicator.mouse_filter = MOUSE_FILTER_IGNORE
# add indent node like the other scene nodes have
var indent = Control.new()
indent.rect_min_size.x = 25
indent.visible = false
indent.name = "Indent"
indicator.add_child(indent)
var label = Label.new()
label.text = "Drop here"
indicator.add_child(label)
timeline.add_child(indicator)
_drag_drop_indicator = indicator
func _remove_drop_indicator():
if (_drag_drop_indicator != null):
_drag_drop_indicator.get_parent().remove_child(_drag_drop_indicator)
_drag_drop_indicator.queue_free()
_drag_drop_indicator = null
func _set_indicator_position(position):
var timeline = get_child(0)
if (timeline == null):
return
if (_drag_drop_indicator == null):
_create_drop_indicator()
var highest_index = 0
var index = 0
for child in timeline.get_children():
if child.get_local_mouse_position().y > 0 and index > highest_index:
highest_index = index
index += 1
if (_drag_drop_indicator.is_inside_tree()):
timeline.move_child(_drag_drop_indicator, max(0, highest_index))
pass