netfishing/ui/components/bubble_menu/bag_item_sprite.gd

129 lines
3.4 KiB
GDScript3
Raw Normal View History

class_name BagItemSprite
extends ItemDragSource
signal drag_started
signal drag_finished
@onready var _visual_root: Control = %VisualRoot
@onready var _item_texture: TextureRect = %ItemTexture
@onready var _quantity_badge: PanelContainer = %QuantityBadge
@onready var _quantity_label: Label = %QuantityLabel
@onready var _compatibility_marker: Label = %CompatibilityMarker
var _motion_phase: float = 0.0
var _depth_scale: float = 1.0
var _selected: bool = false
var _hovered: bool = false
var _dragging: bool = false
func _ready() -> void:
mouse_entered.connect(_set_hovered.bind(true))
mouse_exited.connect(_set_hovered.bind(false))
focus_entered.connect(_refresh_style)
focus_exited.connect(_refresh_style)
resized.connect(_update_visual_pivot)
_update_visual_pivot()
_apply_quantity_style()
_refresh_style()
func configure_item(
new_item_id: StringName,
new_item_name: String,
new_icon: Texture2D,
quantity: int,
hotbar_compatible: bool,
phase: float,
depth_scale: float,
) -> void:
setup(new_item_id, new_item_name, new_icon)
_item_texture.texture = new_icon
_quantity_label.text = "×%d" % quantity
_quantity_badge.visible = quantity > 1
_compatibility_marker.visible = not hotbar_compatible
_motion_phase = phase
_depth_scale = depth_scale
func set_selected(selected: bool) -> void:
_selected = selected
_refresh_style()
func advance_presentation(elapsed: float, motion_enabled: bool) -> void:
if not motion_enabled or _dragging:
return
var bob: float = sin(elapsed * TAU / 7.4 + _motion_phase) * 0.9
var tilt: float = sin(
elapsed * TAU / 10.2 + _motion_phase * 1.29
) * 0.014
_visual_root.position = Vector2(0.0, bob)
_visual_root.rotation = tilt
var emphasis: float = 1.04 if _hovered or has_focus() else 1.0
_visual_root.scale = Vector2.ONE * _depth_scale * emphasis
func _get_drag_data(at_position: Vector2) -> Variant:
var payload: Variant = super(at_position)
if payload != null:
_dragging = true
drag_started.emit()
return payload
func _notification(what: int) -> void:
if what == NOTIFICATION_DRAG_END and _dragging:
_dragging = false
drag_finished.emit()
func _has_point(point: Vector2) -> bool:
var radius: Vector2 = size * Vector2(0.46, 0.42)
if radius.x <= 0.0 or radius.y <= 0.0:
return false
var normalized: Vector2 = (point - size * 0.5) / radius
return normalized.length_squared() <= 1.0
func _set_hovered(hovered: bool) -> void:
_hovered = hovered
_refresh_style()
func _update_visual_pivot() -> void:
_visual_root.pivot_offset = size * 0.5
func _refresh_style() -> void:
var style := StyleBoxFlat.new()
style.bg_color = (
UtilityPageStyle.OCEAN_SELECTED
if _selected else Color(UtilityPageStyle.OCEAN_FIELD, 0.48)
)
if _selected:
style.bg_color = UtilityPageStyle.OCEAN_SELECTED
if has_focus():
style.bg_color = UtilityPageStyle.OCEAN_BUTTON_HOVER
elif _hovered:
style.bg_color = Color(UtilityPageStyle.OCEAN_PANEL_MID, 0.88)
style.set_border_width_all(0)
style.set_corner_radius_all(64)
for state: StringName in [
&"normal",
&"hover",
&"focus",
&"pressed",
]:
add_theme_stylebox_override(state, style)
func _apply_quantity_style() -> void:
var style := StyleBoxFlat.new()
style.bg_color = UtilityPageStyle.OCEAN_SELECTED
style.set_border_width_all(0)
style.set_corner_radius_all(18)
style.content_margin_left = 5.0
style.content_margin_right = 5.0
_quantity_badge.add_theme_stylebox_override("panel", style)