Randoloot/scripts/ui/item_drag_overlay.gd
2026-10-17 16:20:14 +02:00

68 lines
2.3 KiB
GDScript

extends CanvasLayer
const ICON_SIZE := Vector2(64, 64)
var _view: PanelContainer
var _picture: TextureRect
var _fallback: Label
var _started_frame := -1
var _pointer_position := Vector2.ZERO
func _ready() -> void:
layer = preload("res://scripts/ui/render_layers.gd").DRAG_PREVIEW
process_mode = Node.PROCESS_MODE_ALWAYS
add_to_group("item_drag_overlay")
_view = PanelContainer.new()
_view.name = "DragIcon"
_view.mouse_filter = Control.MOUSE_FILTER_IGNORE
_view.size = ICON_SIZE
add_child(_view)
_picture = TextureRect.new()
_picture.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
_picture.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
_picture.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS
_picture.mouse_filter = Control.MOUSE_FILTER_IGNORE
_view.add_child(_picture)
_fallback = Label.new()
_fallback.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_fallback.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_fallback.mouse_filter = Control.MOUSE_FILTER_IGNORE
_fallback.add_theme_font_size_override("font_size", 10)
_view.add_child(_fallback)
_view.hide()
func begin_drag(item: ItemInstance) -> void:
_started_frame = Engine.get_process_frames()
_pointer_position = get_viewport().get_mouse_position()
_picture.texture = item.definition.icon
_fallback.text = item.definition.display_name if item.definition.icon == null else ""
_fallback.visible = item.definition.icon == null
var frame := StyleBoxFlat.new()
frame.bg_color = Color(0.025, 0.045, 0.065, 0.8)
frame.border_color = item.get_type_color()
frame.set_border_width_all(1)
frame.set_corner_radius_all(5)
frame.set_content_margin_all(5)
frame.shadow_color = Color(0, 0, 0, 0.45)
frame.shadow_size = 4
_view.add_theme_stylebox_override("panel", frame)
_view.size = ICON_SIZE
_view.show()
_update_position()
func _input(event: InputEvent) -> void:
if _view.visible and (event is InputEventMouseMotion or event is InputEventMouseButton):
_pointer_position = event.position
_update_position()
func _update_position() -> void:
_view.position = _pointer_position - _view.size * 0.5
func _process(_delta: float) -> void:
if not _view.visible:
return
if get_viewport().gui_is_dragging():
_update_position()
elif Engine.get_process_frames() > _started_frame + 1:
_view.hide()
_picture.texture = null