123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- 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
|