Complete remaining client gap features

This commit is contained in:
shenlei
2026-09-04 13:25:05 +09:00
parent 13ccb8d02d
commit 9a4a044da5
47 changed files with 6667 additions and 140 deletions
+102 -4
View File
@@ -47,6 +47,9 @@ var _buffers := {} # tab -> Array[String]
var _locale: RefCounted
var _proto: Node
var _fishing_active := false
var _whisper_dialog: Panel
var _whisper_target: LineEdit
var _whisper_message: LineEdit
func setup(m2client: Node, parent: Node, assets_root := "") -> void:
client = m2client
@@ -84,10 +87,19 @@ func focus_input() -> void:
# 预填 "/w <名> " 并聚焦(好友列表点名字时调)。
func start_whisper(name: String) -> void:
if _input:
_input.text = "/w %s " % name
_input.caret_column = _input.text.length()
_input.grab_focus()
if _whisper_dialog == null or name.strip_edges() == "":
return
_whisper_target.text = name.strip_edges()
_whisper_message.clear()
_whisper_dialog.visible = true
if _whisper_message.is_inside_tree():
_whisper_message.grab_focus()
func is_whisper_open() -> bool:
return _whisper_dialog != null and _whisper_dialog.visible
func whisper_target() -> String:
return _whisper_target.text if _whisper_target != null else ""
func is_typing() -> bool:
return _input != null and _input.has_focus()
@@ -152,6 +164,92 @@ func _build(parent: Node) -> void:
_input.add_theme_font_size_override("font_size", 12)
_input.text_submitted.connect(_on_submit)
_root.add_child(_input)
_build_whisper_dialog(parent)
func _build_whisper_dialog(parent: Node) -> void:
# root/game.py 的 OpenWhisperDialog 是独立窗口,不应把私聊目标写回公共
# 聊天输入行。这里用 UiManager 同级的独立 Panel,保留自己的焦点和发送键。
_whisper_dialog = Panel.new()
_whisper_dialog.name = "WhisperDialog"
_whisper_dialog.set_anchors_preset(Control.PRESET_CENTER)
_whisper_dialog.position = Vector2(-170, -82)
_whisper_dialog.size = Vector2(340, 164)
_whisper_dialog.visible = false
_whisper_dialog.mouse_filter = Control.MOUSE_FILTER_STOP
var bg := StyleBoxFlat.new()
bg.bg_color = Color(0.04, 0.05, 0.08, 0.97)
bg.border_color = Color(0.62, 0.36, 0.72, 0.95)
bg.set_border_width_all(1)
bg.set_corner_radius_all(5)
_whisper_dialog.add_theme_stylebox_override("panel", bg)
parent.add_child(_whisper_dialog)
var title := Label.new()
title.text = "私聊"
title.position = Vector2(14, 10)
title.add_theme_font_size_override("font_size", 16)
_whisper_dialog.add_child(title)
var target_label := Label.new()
target_label.text = "对象"
target_label.position = Vector2(14, 45)
_whisper_dialog.add_child(target_label)
_whisper_target = LineEdit.new()
_whisper_target.position = Vector2(66, 41)
_whisper_target.size = Vector2(256, 26)
_whisper_target.editable = false
_whisper_target.mouse_filter = Control.MOUSE_FILTER_IGNORE
_whisper_dialog.add_child(_whisper_target)
var message_label := Label.new()
message_label.text = "内容"
message_label.position = Vector2(14, 80)
_whisper_dialog.add_child(message_label)
_whisper_message = LineEdit.new()
_whisper_message.position = Vector2(66, 76)
_whisper_message.size = Vector2(256, 26)
_whisper_message.placeholder_text = "输入私聊内容"
_whisper_message.text_submitted.connect(_on_whisper_submit)
_whisper_dialog.add_child(_whisper_message)
var cancel := Button.new()
cancel.text = "取消"
cancel.position = Vector2(170, 119)
cancel.size = Vector2(70, 28)
cancel.pressed.connect(_close_whisper)
_whisper_dialog.add_child(cancel)
var send := Button.new()
send.text = "发送"
send.position = Vector2(248, 119)
send.size = Vector2(74, 28)
send.pressed.connect(func(): _on_whisper_submit(_whisper_message.text))
_whisper_dialog.add_child(send)
func _close_whisper() -> void:
if _whisper_dialog:
_whisper_dialog.visible = false
if _whisper_message and _whisper_message.is_inside_tree():
_whisper_message.release_focus()
func _on_whisper_submit(text: String) -> void:
var to := _whisper_target.text.strip_edges() if _whisper_target else ""
var msg := text.strip_edges()
if to == "" or msg == "" or client == null:
return
client.whisper(to, msg)
_append(1, T_WHISPER, "%s: %s" % [to, msg])
_append(0, T_WHISPER, "%s: %s" % [to, msg])
_close_whisper()
func _unhandled_input(event: InputEvent) -> void:
if not is_whisper_open() or not (event is InputEventKey):
return
var key := event as InputEventKey
if not key.pressed:
return
if key.keycode == KEY_ESCAPE:
_close_whisper()
get_viewport().set_input_as_handled()
elif key.keycode not in [KEY_ENTER, KEY_KP_ENTER]:
# 独立私聊窗口打开时,WASD / 快捷栏键不应穿透到世界。
get_viewport().set_input_as_handled()
func _select_tab(i: int) -> void:
_tab = i