feat: complete mobile UI implementation
This commit is contained in:
+107
-4
@@ -50,6 +50,8 @@ var _fishing_active := false
|
||||
var _whisper_dialog: Panel
|
||||
var _whisper_target: LineEdit
|
||||
var _whisper_message: LineEdit
|
||||
var _mobile_mode := false
|
||||
var _tab_row: HBoxContainer
|
||||
|
||||
func setup(m2client: Node, parent: Node, assets_root := "") -> void:
|
||||
client = m2client
|
||||
@@ -85,6 +87,29 @@ func focus_input() -> void:
|
||||
if _input:
|
||||
_input.grab_focus()
|
||||
|
||||
func set_mobile_mode(enabled: bool) -> void:
|
||||
_mobile_mode = enabled
|
||||
if _root:
|
||||
_apply_mobile_layout()
|
||||
_apply_mobile_whisper_layout()
|
||||
if enabled and _root:
|
||||
# Chat is an on-demand full-screen page on mobile; the landscape HUD has
|
||||
# no permanent bottom chat strip.
|
||||
_root.visible = false
|
||||
|
||||
func close() -> void:
|
||||
if _root:
|
||||
_root.visible = false
|
||||
_close_whisper()
|
||||
|
||||
func get_mobile_windows() -> Array[Control]:
|
||||
var result: Array[Control] = []
|
||||
if _root:
|
||||
result.append(_root)
|
||||
if _whisper_dialog:
|
||||
result.append(_whisper_dialog)
|
||||
return result
|
||||
|
||||
# 预填 "/w <名> " 并聚焦(好友列表点名字时调)。
|
||||
func start_whisper(name: String) -> void:
|
||||
if _whisper_dialog == null or name.strip_edges() == "":
|
||||
@@ -130,9 +155,9 @@ func _build(parent: Node) -> void:
|
||||
panel.add_theme_stylebox_override("panel", sb)
|
||||
_root.add_child(panel)
|
||||
|
||||
var tabrow := HBoxContainer.new()
|
||||
tabrow.position = Vector2(6, 4)
|
||||
_root.add_child(tabrow)
|
||||
_tab_row = HBoxContainer.new()
|
||||
_tab_row.position = Vector2(6, 4)
|
||||
_root.add_child(_tab_row)
|
||||
for i in TABS.size():
|
||||
var b := Button.new()
|
||||
b.text = TABS[i]
|
||||
@@ -141,7 +166,7 @@ func _build(parent: Node) -> void:
|
||||
b.add_theme_font_size_override("font_size", 11)
|
||||
var idx := i
|
||||
b.pressed.connect(func(): _select_tab(idx))
|
||||
tabrow.add_child(b)
|
||||
_tab_row.add_child(b)
|
||||
_tab_btns.append(b)
|
||||
|
||||
for i in TABS.size():
|
||||
@@ -165,6 +190,84 @@ func _build(parent: Node) -> void:
|
||||
_input.text_submitted.connect(_on_submit)
|
||||
_root.add_child(_input)
|
||||
_build_whisper_dialog(parent)
|
||||
_apply_mobile_layout()
|
||||
_apply_mobile_whisper_layout()
|
||||
|
||||
func _apply_mobile_layout() -> void:
|
||||
if _root == null:
|
||||
return
|
||||
if not _mobile_mode:
|
||||
_root.set_anchors_preset(Control.PRESET_BOTTOM_LEFT)
|
||||
_root.position = Vector2(12, -232)
|
||||
_root.size = Vector2(460, 220)
|
||||
if _tab_row:
|
||||
_tab_row.position = Vector2(6, 4)
|
||||
for rt in _log.values():
|
||||
(rt as RichTextLabel).position = Vector2(6, 30)
|
||||
(rt as RichTextLabel).size = Vector2(448, 158)
|
||||
if _input:
|
||||
_input.position = Vector2(6, 192)
|
||||
_input.size = Vector2(448, 24)
|
||||
return
|
||||
# One landscape page with a large text area and a keyboard-friendly input
|
||||
# row. The HUD remains clear until the player explicitly opens chat.
|
||||
_root.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
||||
_root.position = Vector2.ZERO
|
||||
_root.size = Vector2(760, 340)
|
||||
_root.set_meta("mobile_title", "聊天")
|
||||
if _tab_row:
|
||||
_tab_row.position = Vector2(14, 48)
|
||||
_tab_row.size = Vector2(732, 40)
|
||||
_tab_row.add_theme_constant_override("separation", 6)
|
||||
for child in _tab_row.get_children():
|
||||
child.custom_minimum_size = Vector2(112, 38)
|
||||
child.add_theme_font_size_override("font_size", 12)
|
||||
for rt in _log.values():
|
||||
(rt as RichTextLabel).position = Vector2(14, 94)
|
||||
(rt as RichTextLabel).size = Vector2(732, 190)
|
||||
(rt as RichTextLabel).add_theme_font_size_override("normal_font_size", 14)
|
||||
if _input:
|
||||
_input.position = Vector2(14, 294)
|
||||
_input.size = Vector2(732, 38)
|
||||
_input.add_theme_font_size_override("font_size", 13)
|
||||
|
||||
func _apply_mobile_whisper_layout() -> void:
|
||||
if _whisper_dialog == null:
|
||||
return
|
||||
if not _mobile_mode:
|
||||
_whisper_dialog.set_anchors_preset(Control.PRESET_CENTER)
|
||||
_whisper_dialog.position = Vector2(-170, -82)
|
||||
_whisper_dialog.size = Vector2(340, 164)
|
||||
return
|
||||
_whisper_dialog.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
||||
_whisper_dialog.position = Vector2.ZERO
|
||||
_whisper_dialog.size = Vector2(480, 260)
|
||||
_whisper_dialog.set_meta("mobile_title", "私聊")
|
||||
var title := _whisper_dialog.get_child(0) as Label
|
||||
if title:
|
||||
title.position = Vector2(18, 50)
|
||||
title.add_theme_font_size_override("font_size", 15)
|
||||
var target_label := _whisper_dialog.get_child(1) as Label
|
||||
if target_label:
|
||||
target_label.position = Vector2(18, 94)
|
||||
var message_label := _whisper_dialog.get_child(3) as Label
|
||||
if message_label:
|
||||
message_label.position = Vector2(18, 148)
|
||||
if _whisper_target:
|
||||
_whisper_target.position = Vector2(86, 90)
|
||||
_whisper_target.size = Vector2(370, 42)
|
||||
if _whisper_message:
|
||||
_whisper_message.position = Vector2(86, 144)
|
||||
_whisper_message.size = Vector2(370, 42)
|
||||
_whisper_message.virtual_keyboard_type = LineEdit.KEYBOARD_TYPE_DEFAULT
|
||||
var cancel := _whisper_dialog.get_node_or_null("Button") as Button
|
||||
var send := _whisper_dialog.get_node_or_null("Button2") as Button
|
||||
if cancel:
|
||||
cancel.position = Vector2(174, 202)
|
||||
cancel.size = Vector2(130, 44)
|
||||
if send:
|
||||
send.position = Vector2(316, 202)
|
||||
send.size = Vector2(130, 44)
|
||||
|
||||
func _build_whisper_dialog(parent: Node) -> void:
|
||||
# root/game.py 的 OpenWhisperDialog 是独立窗口,不应把私聊目标写回公共
|
||||
|
||||
Reference in New Issue
Block a user