feat: complete mobile UI implementation

This commit is contained in:
shenlei
2026-09-04 19:54:33 +09:00
parent 9a4a044da5
commit b19d5b5dd3
132 changed files with 6643 additions and 180 deletions
+73 -4
View File
@@ -34,6 +34,9 @@ var _sell_mode_button: Button
var _sell_drop_target: Button
var _sell_confirm: ConfirmationDialog
var _buy_confirm: ConfirmationDialog
var _mobile_mode := false
var _mobile_sell_scroll: ScrollContainer
var _mobile_sell_list: VBoxContainer
func setup(m2client: Node, parent: Node, proto_node: Node = null, ilist: RefCounted = null) -> void:
client = m2client
@@ -52,6 +55,14 @@ func setup(m2client: Node, parent: Node, proto_node: Node = null, ilist: RefCoun
func is_open() -> bool:
return _root != null and _root.visible
func set_mobile_mode(enabled: bool) -> void:
_mobile_mode = enabled
if _root and _mobile_mode:
_set_mode(_mode)
func get_mobile_window() -> Control:
return _root
func close() -> void:
_close()
@@ -181,11 +192,15 @@ func _ask_sell_confirmation(payload: Dictionary, amount: int, price: int) -> voi
_sell_confirm = null
dialog.hide()
dialog.queue_free())
_prepare_mobile_confirmation(dialog, "确认出售")
_root.add_child(dialog)
if dialog.is_inside_tree():
dialog.popup_centered()
_popup_confirmation(dialog)
else:
dialog.call_deferred("popup_centered")
if _mobile_mode:
dialog.call_deferred("popup_centered", Vector2i(480, 220))
else:
dialog.call_deferred("popup_centered")
func _play_ui(name: String) -> void:
if audio and audio.has_method("play_ui"):
@@ -201,6 +216,10 @@ func _set_mode(mode: int) -> void:
_sell_drop_target.visible = _mode == 2
if cursor_manager and cursor_manager.has_method("set_cursor"):
cursor_manager.set_cursor(CursorManager.SELL if _mode == 2 else CursorManager.BUY)
if _mobile_sell_scroll:
_mobile_sell_scroll.visible = _mobile_mode and _mode == 2
_grid.visible = not (_mobile_mode and _mode == 2)
_refresh_mobile_sell()
func _name_of(vnum: int) -> String:
if proto and proto.has_method("item"):
@@ -256,6 +275,30 @@ func refresh() -> void:
for slot in SHOP_SLOT_COUNT:
var it: Dictionary = by_pos.get(slot, {})
_grid.add_child(_slot(it, base + slot))
_refresh_mobile_sell()
func _refresh_mobile_sell() -> void:
if not _mobile_mode or _mobile_sell_list == null:
return
for child in _mobile_sell_list.get_children():
child.queue_free()
var inv: Array = client.get_inventory() if client and client.has_method("get_inventory") else []
if inv.is_empty():
var empty := Label.new()
empty.text = "(背包为空)"
_mobile_sell_list.add_child(empty)
return
for item in inv:
var cell := int(item.get("cell", -1))
var vnum := int(item.get("vnum", 0))
if cell < 0 or vnum <= 0:
continue
var button := Button.new()
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
button.text = "%s ×%d · 点击出售" % [_name_of(vnum), int(item.get("count", 1))]
button.custom_minimum_size = Vector2(330, 30)
button.pressed.connect(func(): sell(cell, int(_sell_quantity.value)))
_mobile_sell_list.add_child(button)
func _slot(it: Dictionary, pos: int) -> Button:
var slot := Button.new()
@@ -301,11 +344,29 @@ func _buy_slot(pos: int, item: Dictionary) -> void:
_buy_confirm = null
dialog.hide()
dialog.queue_free())
_prepare_mobile_confirmation(dialog, "确认购买")
_root.add_child(dialog)
if dialog.is_inside_tree():
dialog.popup_centered()
_popup_confirmation(dialog)
else:
dialog.call_deferred("popup_centered")
if _mobile_mode:
dialog.call_deferred("popup_centered", Vector2i(480, 220))
else:
dialog.call_deferred("popup_centered")
func _prepare_mobile_confirmation(dialog: ConfirmationDialog, title: String) -> void:
if not _mobile_mode:
return
dialog.set_meta("mobile_modal", true)
dialog.set_meta("mobile_title", title)
dialog.min_size = Vector2i(480, 220)
dialog.size = Vector2i(480, 220)
func _popup_confirmation(dialog: ConfirmationDialog) -> void:
if _mobile_mode:
dialog.popup_centered(Vector2i(480, 220))
else:
dialog.popup_centered()
func _on_error(kind: String) -> void:
var tbl := {
@@ -395,6 +456,14 @@ func _build(parent: Node) -> void:
_grid.add_theme_constant_override("h_separation", 3)
_grid.add_theme_constant_override("v_separation", 2)
_root.add_child(_grid)
_mobile_sell_scroll = ScrollContainer.new()
_mobile_sell_scroll.position = Vector2(12, 58)
_mobile_sell_scroll.size = Vector2(350, 252)
_mobile_sell_scroll.visible = false
_root.add_child(_mobile_sell_scroll)
_mobile_sell_list = VBoxContainer.new()
_mobile_sell_list.add_theme_constant_override("separation", 4)
_mobile_sell_scroll.add_child(_mobile_sell_list)
var close_btn := Button.new()
close_btn.text = "离开"
close_btn.position = Vector2(300, 360)