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: begin_icon(item.definition.icon, item.get_type_color(), item.definition.display_name) func begin_icon(texture: Texture2D, accent: Color, caption: String = "") -> void: _started_frame = Engine.get_process_frames() _pointer_position = get_viewport().get_mouse_position() _picture.texture = texture _fallback.text = caption if texture == null else "" _fallback.visible = texture == null var frame := StyleBoxFlat.new() frame.bg_color = Color(0.025, 0.045, 0.065, 0.8) frame.border_color = accent 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