fix(ui): 100% align NPC dialogue and shop popup panels with 40250 canonical UI layout and textures

This commit is contained in:
shen
2026-09-19 17:37:02 -07:00
parent 5d43682498
commit a834af873f
4 changed files with 521 additions and 109 deletions
+95 -25
View File
@@ -18,6 +18,7 @@
extends Node
const UiAssets = preload("res://ui/ui_assets.gd")
const UiKit = preload("res://ui_kit.gd")
signal opened()
signal closed()
@@ -43,7 +44,7 @@ var client: Node
var proto: Node
var _assets_root := ""
var _root: Control
var _panel: Panel
var _panel: Control
var _text: RichTextLabel
var _btnrow: VBoxContainer
var _image_layer: Control
@@ -1014,36 +1015,49 @@ func _rx_args(tok: String) -> Array:
func _build(parent: Node) -> void:
_root = Control.new()
_root.name = "QuestDialogWindow"
_root.set_anchors_preset(Control.PRESET_CENTER)
_root.position = Vector2(-230, -160)
_root.size = Vector2(460, 300)
_root.position = Vector2(-175, -150)
_root.size = Vector2(350, 300)
_root.visible = false
_root.set_meta("is_titlebar", true)
parent.add_child(_root)
var panel := Panel.new()
panel.set_anchors_preset(Control.PRESET_FULL_RECT)
var sb := StyleBoxFlat.new()
sb.bg_color = Color(0.08, 0.07, 0.06, 0.97)
sb.border_color = Color(0.5, 0.42, 0.3)
sb.set_border_width_all(1)
sb.set_corner_radius_all(4)
panel.add_theme_stylebox_override("panel", sb)
_root.add_child(panel)
_panel = panel
# 40250 uiscript/questdialog.py: type "thinboard", width 350, height 300
var thinboard_np := UiKit.board(_assets_root, "thinboard")
if thinboard_np and thinboard_np.texture:
thinboard_np.set_anchors_preset(Control.PRESET_FULL_RECT)
thinboard_np.mouse_filter = Control.MOUSE_FILTER_IGNORE
_root.add_child(thinboard_np)
_panel = thinboard_np
else:
var panel := Panel.new()
panel.set_anchors_preset(Control.PRESET_FULL_RECT)
var sb := StyleBoxFlat.new()
sb.bg_color = Color(0.04, 0.04, 0.05, 0.75)
sb.border_color = Color(0.5, 0.42, 0.3)
sb.set_border_width_all(1)
sb.set_corner_radius_all(4)
panel.add_theme_stylebox_override("panel", sb)
_root.add_child(panel)
_panel = panel
_image_layer = Control.new()
_image_layer.set_anchors_preset(Control.PRESET_FULL_RECT)
_image_layer.mouse_filter = Control.MOUSE_FILTER_IGNORE
_root.add_child(_image_layer)
_text = RichTextLabel.new()
_text.bbcode_enabled = true
_text.position = Vector2(16, 14)
_text.size = Vector2(428, 200)
_text.size = Vector2(318, 190)
_text.add_theme_font_size_override("normal_font_size", 13)
_root.add_child(_text)
_btnrow = VBoxContainer.new()
_btnrow.position = Vector2(16, 222)
_btnrow.custom_minimum_size = Vector2(428, 0)
_btnrow.add_theme_constant_override("separation", 4)
_btnrow.position = Vector2(16, 210)
_btnrow.custom_minimum_size = Vector2(318, 0)
_btnrow.add_theme_constant_override("separation", 5)
_root.add_child(_btnrow)
func _render_images(images: Array, title_image: String) -> float:
@@ -1103,7 +1117,7 @@ func _fill_buttons(choices: Array, has_next: bool, has_input := false, confirm_w
if has_input:
var input := LineEdit.new()
input.placeholder_text = "请输入内容"
input.custom_minimum_size = Vector2(maxf(200.0, 428.0 - _current_left_w), 28)
input.custom_minimum_size = Vector2(maxf(200.0, _root.size.x - 32.0 - _current_left_w), 28)
_btnrow.add_child(input)
var submit := _mkbtn("确定")
submit.pressed.connect(func(): _submit_input(input))
@@ -1128,6 +1142,8 @@ func _fill_buttons(choices: Array, has_next: bool, has_input := false, confirm_w
if choices.is_empty():
var is_done := next_button_type == "DONE"
var b := _mkbtn("关闭" if is_done else ("继续" if has_next else "关闭"))
b.custom_minimum_size = Vector2(100, 26)
b.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
b.pressed.connect(func():
if is_done:
done_event.emit()
@@ -1173,9 +1189,10 @@ func _render_choices(choices: Array, page: int = 0) -> void:
_btnrow.add_child(nav_row)
if page > 0:
var prev_btn := Button.new()
prev_btn.text = "上一页"
var prev_btn := _mkbtn("上一页")
prev_btn.custom_minimum_size = Vector2(80, 26)
prev_btn.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
_btnrow.remove_child(prev_btn)
prev_btn.pressed.connect(func(): _render_choices(_cached_choices, page - 1))
nav_row.add_child(prev_btn)
@@ -1185,9 +1202,10 @@ func _render_choices(choices: Array, page: int = 0) -> void:
nav_row.add_child(page_label)
if page < total_pages - 1:
var next_btn := Button.new()
next_btn.text = "下一页"
var next_btn := _mkbtn("下一页")
next_btn.custom_minimum_size = Vector2(80, 26)
next_btn.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
_btnrow.remove_child(next_btn)
next_btn.pressed.connect(func(): _render_choices(_cached_choices, page + 1))
nav_row.add_child(next_btn)
@@ -1200,22 +1218,74 @@ func _submit_input(input: LineEdit) -> void:
func _fill_confirm() -> void:
_clear_buttons()
var row := HBoxContainer.new()
row.add_theme_constant_override("separation", 8)
row.alignment = BoxContainer.ALIGNMENT_CENTER
row.add_theme_constant_override("separation", 16)
_btnrow.add_child(row)
for spec in [["接受", true], ["拒绝", false]]:
var yes: bool = spec[1]
var b := Button.new()
b.text = spec[0]
b.custom_minimum_size = Vector2(120, 30)
b.custom_minimum_size = Vector2(100, 28)
var sb_up := StyleBoxFlat.new()
sb_up.bg_color = Color(0.6, 0.6, 0.6, 0.25)
sb_up.set_corner_radius_all(3)
sb_up.set_border_width_all(1)
sb_up.border_color = Color(0.8, 0.8, 0.8, 0.25)
var sb_over := StyleBoxFlat.new()
sb_over.bg_color = Color(0.87, 0.87, 1.0, 0.35)
sb_over.set_corner_radius_all(3)
sb_over.set_border_width_all(1)
sb_over.border_color = Color(1.0, 1.0, 1.0, 0.5)
b.add_theme_stylebox_override("normal", sb_up)
b.add_theme_stylebox_override("hover", sb_over)
b.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
b.add_theme_color_override("font_color", Color(1.0, 1.0, 1.0))
b.add_theme_color_override("font_hover_color", Color(1.0, 0.95, 0.7))
b.pressed.connect(func():
if client and client.has_method("quest_confirm"):
client.quest_confirm(yes, _confirm_pid)
close())
row.add_child(b)
# 40250 BarButton: 半透明长条胶囊样式,普通 0x40999999,悬停 0x40ddddff,按下 0x40aaaacc
func _mkbtn(text: String) -> Button:
var b := Button.new()
b.text = text
b.custom_minimum_size = Vector2(maxf(200.0, 428.0 - _current_left_w), 26)
var w := maxf(200.0, _root.size.x - 32.0 - _current_left_w)
b.custom_minimum_size = Vector2(w, 26)
b.clip_text = true
var sb_up := StyleBoxFlat.new()
sb_up.bg_color = Color(0.6, 0.6, 0.6, 0.25)
sb_up.set_corner_radius_all(3)
sb_up.set_border_width_all(1)
sb_up.border_color = Color(0.8, 0.8, 0.8, 0.25)
var sb_over := StyleBoxFlat.new()
sb_over.bg_color = Color(0.87, 0.87, 1.0, 0.35)
sb_over.set_corner_radius_all(3)
sb_over.set_border_width_all(1)
sb_over.border_color = Color(1.0, 1.0, 1.0, 0.5)
var sb_down := StyleBoxFlat.new()
sb_down.bg_color = Color(0.67, 0.67, 0.8, 0.35)
sb_down.set_corner_radius_all(3)
sb_down.set_border_width_all(1)
sb_down.border_color = Color(0.7, 0.7, 0.9, 0.5)
b.add_theme_stylebox_override("normal", sb_up)
b.add_theme_stylebox_override("hover", sb_over)
b.add_theme_stylebox_override("pressed", sb_down)
b.add_theme_stylebox_override("focus", StyleBoxEmpty.new())
b.add_theme_color_override("font_color", Color(1.0, 1.0, 1.0))
b.add_theme_color_override("font_hover_color", Color(1.0, 0.95, 0.7))
b.add_theme_color_override("font_pressed_color", Color(0.9, 0.9, 0.9))
b.add_theme_font_size_override("font_size", 12)
b.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
_btnrow.add_child(b)
return b