85 lines
2.5 KiB
GDScript
85 lines
2.5 KiB
GDScript
@tool
|
|
extends Container
|
|
const Utils = preload("../utils.gd")
|
|
const Dragger = preload("dragger.gd")
|
|
|
|
signal move_requested(from:int, to:int)
|
|
signal delete_requested(index:int)
|
|
signal duplicate_requested(index:int)
|
|
|
|
@onready var _dragger:Dragger = %Dragger
|
|
@onready var _content:Container = %Content
|
|
@onready var _before_indicator:ColorRect = %BeforeIndicator
|
|
@onready var _after_indicator:ColorRect = %AfterIndicator
|
|
@onready var _popup_menu:PopupMenu = %PopupMenu
|
|
|
|
|
|
const ID_DELETE = 2
|
|
const ID_DUPLICATE = 3
|
|
|
|
func _ready():
|
|
_dragger.icon = get_theme_icon("GuiSpinboxUpdown", "EditorIcons")
|
|
_before_indicator.color = get_theme_color("box_selection_stroke_color", "Editor")
|
|
_after_indicator.color = get_theme_color("box_selection_stroke_color", "Editor")
|
|
_before_indicator.visible = false
|
|
_after_indicator.visible = false
|
|
_dragger._parent_array = get_parent()
|
|
_dragger._index = get_index()
|
|
_dragger.pressed.connect(_show_popup_menu)
|
|
|
|
_popup_menu.clear()
|
|
_popup_menu.add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), "Duplicate", ID_DUPLICATE)
|
|
_popup_menu.add_icon_item(get_theme_icon("Remove", "EditorIcons"), "Delete", ID_DELETE)
|
|
_popup_menu.id_pressed.connect(_on_popup_menu_id_pressed)
|
|
|
|
func initialize(content:Control):
|
|
Utils.clear(_content)
|
|
_content.add_child(content)
|
|
|
|
|
|
func _can_drop_data(at_position:Vector2, data) -> bool:
|
|
if data is Dictionary and data.has("parent_array") and data.parent_array == get_parent() and data.index != get_index():
|
|
var height = size.y
|
|
|
|
var is_before = not _is_last_child() or (at_position.y < height/2.0)
|
|
if is_before and data.index == get_index() - 1:
|
|
# don't allow the previous child to be inserted at its
|
|
# own position
|
|
return false
|
|
|
|
_before_indicator.visible = is_before
|
|
_after_indicator.visible = not is_before
|
|
return true
|
|
|
|
return false
|
|
|
|
|
|
func _drop_data(at_position, data):
|
|
var height = size.y
|
|
var is_before = not _is_last_child() or (at_position.y < height/2.0)
|
|
var from = data.index
|
|
var to = get_index() if is_before else get_index() + 1
|
|
move_requested.emit(data.index, to)
|
|
_before_indicator.visible = false
|
|
_after_indicator.visible = false
|
|
|
|
func _is_last_child() -> bool:
|
|
return get_index() == get_parent().get_child_count() - 1
|
|
|
|
|
|
func _on_mouse_exited():
|
|
_before_indicator.visible = false
|
|
_after_indicator.visible = false
|
|
|
|
|
|
func _show_popup_menu():
|
|
_popup_menu.popup(Rect2(get_global_mouse_position(), Vector2.ZERO))
|
|
|
|
|
|
func _on_popup_menu_id_pressed(id:int):
|
|
match id:
|
|
ID_DELETE:
|
|
delete_requested.emit(get_index())
|
|
ID_DUPLICATE:
|
|
duplicate_requested.emit(get_index())
|