2026-05-29 19:54:56 +08:00

212 lines
6.3 KiB
GDScript

class_name SeedBagView
extends RefCounted
const UiMotionScript := preload("res://scripts/ui/common/ui_motion.gd")
const PANEL_HIDDEN_POSITION := Vector2(640.0, 247.0)
const PANEL_VISIBLE_POSITION := Vector2(526.0, 247.0)
const DISMISS_Z_INDEX := 1500
const PANEL_Z_INDEX := 1501
var _owner: Control
var _style_label: Callable
var _get_item_icon_texture: Callable
var _seed_icon_id: Callable
var _on_item_pressed: Callable
var _textures: Dictionary = {}
var _dismiss_button: Button
var _panel: Control
var _list: VBoxContainer
var _mode := "seed"
var _tween: Tween
func setup(options: Dictionary) -> void:
_owner = options.get("owner") as Control
_style_label = options.get("style_label", Callable())
_get_item_icon_texture = options.get("get_item_icon_texture", Callable())
_seed_icon_id = options.get("seed_icon_id", Callable())
_on_item_pressed = options.get("on_item_pressed", Callable())
_textures = options.get("textures", {})
_create_panel()
func open(mode: String, seed_items: Array[Dictionary], fertilizer_items: Array[Dictionary]) -> void:
_mode = mode
show()
render(seed_items, fertilizer_items)
func render(seed_items: Array[Dictionary], fertilizer_items: Array[Dictionary]) -> void:
if _list == null:
return
_clear_children(_list)
var items := seed_items if _mode == "seed" else fertilizer_items
for item in items:
_list.add_child(_create_item(item))
func hide() -> void:
if _panel == null:
return
if _tween != null:
_tween.kill()
if _dismiss_button != null:
_dismiss_button.visible = false
_dismiss_button.disabled = true
_panel.visible = false
func show() -> void:
if _panel == null:
return
if _tween != null:
_tween.kill()
if _dismiss_button != null:
_dismiss_button.visible = true
_dismiss_button.disabled = false
_panel.visible = true
_panel.position = PANEL_HIDDEN_POSITION
_panel.modulate = Color(1.0, 1.0, 1.0, 0.0)
_tween = _owner.create_tween().set_parallel(true)
_tween.tween_property(_panel, "position", PANEL_VISIBLE_POSITION, 0.18).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT)
_tween.tween_property(_panel, "modulate:a", 1.0, 0.12)
func is_visible() -> bool:
return _panel != null and _panel.visible
func mode() -> String:
return _mode
func panel() -> Control:
return _panel
func _create_panel() -> void:
if _owner == null:
return
_create_dismiss_button()
_panel = Control.new()
_panel.name = "SeedBagPanel"
_panel.position = PANEL_VISIBLE_POSITION
_panel.size = Vector2(114.0, 416.0)
_panel.mouse_filter = Control.MOUSE_FILTER_STOP
_panel.z_index = PANEL_Z_INDEX
_panel.visible = false
_owner.add_child(_panel)
var bag_bg := TextureRect.new()
bag_bg.name = "BagBg"
bag_bg.texture = _textures.get("bg")
if bag_bg.texture != null:
bag_bg.size = bag_bg.texture.get_size()
bag_bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
_panel.add_child(bag_bg)
var scroll := ScrollContainer.new()
scroll.name = "SeedScroll"
scroll.position = Vector2(31.0, 28.0)
scroll.size = Vector2(82.0, 362.0)
scroll.follow_focus = true
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
scroll.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
_panel.add_child(scroll)
_list = VBoxContainer.new()
_list.name = "SeedList"
_list.custom_minimum_size = Vector2(87.0, 0.0)
_list.add_theme_constant_override("separation", 0)
scroll.add_child(_list)
func _create_dismiss_button() -> void:
_dismiss_button = Button.new()
_dismiss_button.name = "SeedBagDismissHit"
_dismiss_button.set_anchors_preset(Control.PRESET_FULL_RECT)
_dismiss_button.focus_mode = Control.FOCUS_NONE
_dismiss_button.text = ""
_dismiss_button.mouse_filter = Control.MOUSE_FILTER_STOP
_dismiss_button.z_index = DISMISS_Z_INDEX
_dismiss_button.visible = false
_dismiss_button.disabled = true
UiMotionScript.apply_empty_button_style(_dismiss_button)
_dismiss_button.pressed.connect(hide)
_owner.add_child(_dismiss_button)
func _create_item(item: Dictionary) -> Control:
var holder := Control.new()
holder.name = "BagItem%s" % int(item.get("item_id", 0))
holder.custom_minimum_size = Vector2(74.0, 74.0)
holder.size = Vector2(74.0, 74.0)
var icon := TextureRect.new()
icon.name = "Icon"
icon.texture = _item_texture(item)
icon.position = Vector2.ZERO
icon.size = Vector2(66.0, 58.0)
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
holder.add_child(icon)
var count_label := Label.new()
count_label.name = "Count"
count_label.text = "x%s" % int(item.get("num", 0))
count_label.position = Vector2(31.0, 43.0)
count_label.size = Vector2(41.0, 25.0)
count_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
count_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
count_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
if _style_label.is_valid():
_style_label.call(count_label, 20, Color.html("#7a5838"), 2, Color.WHITE)
holder.add_child(count_label)
var line := TextureRect.new()
line.name = "Line"
line.texture = _textures.get("line")
line.position = Vector2(1.0, 66.0)
if line.texture != null:
line.size = line.texture.get_size()
line.mouse_filter = Control.MOUSE_FILTER_IGNORE
holder.add_child(line)
var hit_button := Button.new()
hit_button.name = "SeedHit"
hit_button.position = Vector2.ZERO
hit_button.size = Vector2(74.0, 74.0)
hit_button.focus_mode = Control.FOCUS_NONE
hit_button.text = ""
UiMotionScript.apply_empty_button_style(hit_button)
hit_button.pressed.connect(func() -> void: _handle_item_pressed(item.duplicate(true)))
hit_button.button_down.connect(func() -> void: UiMotionScript.play_press_scale(_owner, holder))
hit_button.button_up.connect(func() -> void: UiMotionScript.play_release_scale(_owner, holder))
holder.add_child(hit_button)
return holder
func _handle_item_pressed(item: Dictionary) -> void:
if _on_item_pressed.is_valid():
_on_item_pressed.call(item, _mode)
func _item_texture(item: Dictionary) -> Texture2D:
if not _get_item_icon_texture.is_valid():
return null
var icon_id := int(item.get("icon_id", 0))
if icon_id <= 0 and _seed_icon_id.is_valid():
icon_id = int(_seed_icon_id.call(int(item.get("item_id", 0))))
return _get_item_icon_texture.call(icon_id) as Texture2D
func _clear_children(parent: Node) -> void:
if parent == null:
return
for child in parent.get_children():
parent.remove_child(child)
child.queue_free()