forked from datawhale/whale-town-front
合并主场景和个人小屋
This commit is contained in:
@@ -102,9 +102,7 @@ func _ready():
|
||||
_setup_controllers() # 初始化控制器
|
||||
_connect_signals() # 连接信号
|
||||
_setup_ui() # 设置UI初始状态
|
||||
|
||||
print("认证场景视图已加载")
|
||||
|
||||
|
||||
# 测试网络连接
|
||||
auth_manager.test_network_connection()
|
||||
|
||||
@@ -329,6 +327,8 @@ func _on_login_enter(_text: String):
|
||||
|
||||
# 登录成功处理
|
||||
func _on_controller_login_success(username: String) -> void:
|
||||
_release_focus_owner()
|
||||
|
||||
# 清空表单
|
||||
login_username.text = ""
|
||||
login_password.text = ""
|
||||
@@ -341,11 +341,18 @@ func _on_controller_login_success(username: String) -> void:
|
||||
var token: String = auth_manager.get_access_token()
|
||||
if not token.is_empty():
|
||||
ChatManager.set_game_token(token)
|
||||
print("✅ 已设置 ChatManager token: ", token.substr(0, 20) + "...")
|
||||
|
||||
# 同时设置 LocationManager token(用于位置同步)
|
||||
LocationManager.set_auth_token(token)
|
||||
|
||||
# 发送登录成功信号给上层
|
||||
login_success.emit(username)
|
||||
|
||||
func _release_focus_owner() -> void:
|
||||
var focus_owner: Control = get_viewport().gui_get_focus_owner()
|
||||
if is_instance_valid(focus_owner):
|
||||
focus_owner.release_focus()
|
||||
|
||||
# 登录失败处理
|
||||
func _on_controller_login_failed(_message: String):
|
||||
# 登录失败时不需要额外处理,Toast已经显示了错误信息
|
||||
@@ -399,9 +406,9 @@ func _on_controller_form_validation_failed(field: String, message: String):
|
||||
register_confirm.grab_focus()
|
||||
|
||||
# 网络状态变化处理
|
||||
func _on_controller_network_status_changed(network_connected: bool, message: String):
|
||||
func _on_controller_network_status_changed(_network_connected: bool, _message: String):
|
||||
# 可以在这里添加网络状态指示器
|
||||
print("网络状态: ", "连接" if network_connected else "断开", " - ", message)
|
||||
pass
|
||||
|
||||
# 按钮状态变化处理
|
||||
func _on_controller_button_state_changed(button_name: String, is_loading: bool, text: String):
|
||||
|
||||
9
scenes/ui/ChatBubble.gd
Normal file
9
scenes/ui/ChatBubble.gd
Normal file
@@ -0,0 +1,9 @@
|
||||
extends Control
|
||||
|
||||
@onready var label = $PanelContainer/Label
|
||||
|
||||
func set_text(text):
|
||||
label.text = text
|
||||
# Destroy after 5 seconds
|
||||
await get_tree().create_timer(5.0).timeout
|
||||
queue_free()
|
||||
1
scenes/ui/ChatBubble.gd.uid
Normal file
1
scenes/ui/ChatBubble.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b4aorojcbwkmb
|
||||
42
scenes/ui/ChatBubble.tscn
Normal file
42
scenes/ui/ChatBubble.tscn
Normal file
@@ -0,0 +1,42 @@
|
||||
[gd_scene load_steps=3 format=3]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b4aorojcbwkmb" path="res://scenes/ui/ChatBubble.gd" id="1_script"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bubble_modern"]
|
||||
bg_color = Color(1, 1, 1, 0.9)
|
||||
corner_radius_top_left = 5
|
||||
corner_radius_top_right = 5
|
||||
corner_radius_bottom_right = 5
|
||||
corner_radius_bottom_left = 5
|
||||
shadow_color = Color(0, 0, 0, 0.2)
|
||||
shadow_size = 2
|
||||
|
||||
[node name="ChatBubble" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 7
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -75.0
|
||||
offset_top = -60.0
|
||||
offset_right = 75.0
|
||||
offset_bottom = -20.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_bubble_modern")
|
||||
|
||||
[node name="Label" type="Label" parent="PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.1, 0.1, 0.1, 1)
|
||||
theme_override_font_sizes/font_size = 8
|
||||
text = "..."
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
autowrap_mode = 3
|
||||
custom_minimum_size = Vector2(150, 0)
|
||||
@@ -100,7 +100,7 @@ func _exit_tree() -> void:
|
||||
# 处理全局输入
|
||||
func _input(event: InputEvent) -> void:
|
||||
# 检查是否按下 Enter 键
|
||||
if event is InputEventKey and event.keycode == KEY_ENTER:
|
||||
if event is InputEventKey and event.pressed and not event.echo and (event.keycode == KEY_ENTER or event.keycode == KEY_KP_ENTER):
|
||||
_handle_enter_pressed()
|
||||
|
||||
# 处理 Enter 键按下
|
||||
@@ -153,22 +153,22 @@ func _release_input_focus() -> void:
|
||||
|
||||
# 显示聊天框
|
||||
func show_chat() -> void:
|
||||
if _is_chat_visible:
|
||||
return
|
||||
|
||||
_is_chat_visible = true
|
||||
chat_panel.show()
|
||||
if is_instance_valid(chat_panel):
|
||||
chat_panel.show()
|
||||
|
||||
# 停止隐藏计时器
|
||||
_stop_hide_timer()
|
||||
|
||||
# 隐藏聊天框
|
||||
func hide_chat() -> void:
|
||||
if not _is_chat_visible:
|
||||
return
|
||||
|
||||
_is_chat_visible = false
|
||||
chat_panel.hide()
|
||||
_is_typing = false
|
||||
if is_instance_valid(chat_panel):
|
||||
chat_panel.hide()
|
||||
|
||||
if is_instance_valid(chat_input) and chat_input.has_focus():
|
||||
chat_input.release_focus()
|
||||
|
||||
# 停止隐藏计时器
|
||||
_stop_hide_timer()
|
||||
@@ -185,13 +185,17 @@ func _create_hide_timer() -> void:
|
||||
func _start_hide_timer() -> void:
|
||||
if _is_typing:
|
||||
return # 输入时不隐藏
|
||||
if not is_instance_valid(_hide_timer):
|
||||
return
|
||||
if not _hide_timer.is_inside_tree():
|
||||
return
|
||||
|
||||
_stop_hide_timer() # 先停止之前的计时器
|
||||
_hide_timer.start()
|
||||
|
||||
# 停止隐藏倒计时
|
||||
func _stop_hide_timer() -> void:
|
||||
if _hide_timer:
|
||||
if is_instance_valid(_hide_timer) and _hide_timer.is_inside_tree():
|
||||
_hide_timer.stop()
|
||||
|
||||
# 隐藏计时器超时
|
||||
@@ -219,6 +223,8 @@ func _on_input_focus_entered() -> void:
|
||||
# 输入框失去焦点
|
||||
func _on_input_focus_exited() -> void:
|
||||
_is_typing = false
|
||||
if not is_inside_tree():
|
||||
return
|
||||
# 开始 5 秒倒计时
|
||||
if not _is_chat_visible:
|
||||
return
|
||||
@@ -284,7 +290,7 @@ func _on_chat_error(data: Dictionary) -> void:
|
||||
var error_code: String = data.get("error_code", "")
|
||||
var message: String = data.get("message", "")
|
||||
|
||||
print("❌ ChatUI 错误: [", error_code, "] ", message)
|
||||
push_error("ChatUI: [%s] %s" % [error_code, message])
|
||||
|
||||
# 处理连接状态变化
|
||||
func _on_connection_state_changed(data: Dictionary) -> void:
|
||||
|
||||
156
scenes/ui/NoticeDialog.gd
Normal file
156
scenes/ui/NoticeDialog.gd
Normal file
@@ -0,0 +1,156 @@
|
||||
extends CanvasLayer
|
||||
|
||||
@onready var content_label = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer/TextPanel/ContentLabel
|
||||
@onready var prev_btn = $CenterContainer/PanelContainer/VBoxContainer/Footer/PrevButton
|
||||
@onready var next_btn = $CenterContainer/PanelContainer/VBoxContainer/Footer/NextButton
|
||||
@onready var dots_container = $CenterContainer/PanelContainer/VBoxContainer/Footer/DotsContainer
|
||||
@onready var content_container = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer
|
||||
|
||||
# Mock Data
|
||||
var pages = [
|
||||
{
|
||||
"text": "欢迎来到 [color=#3399ff]Datawhale Town[/color]!\n\n这里是开源学习者的家园。在这里,我们一同探索知识,分享成长。\n\n[center]🐋[/center]",
|
||||
# 使用社区图片作为封面
|
||||
"image_path": "res://assets/sprites/environment/community_512_512.png",
|
||||
"image_color": Color(0.9, 0.9, 0.9) # 保留作为后备选项
|
||||
},
|
||||
{
|
||||
"text": "最新活动:\n\n- 镇长刚刚搬进来了,就在喷泉左边。\n- 欢迎板已经设立,查看最新动态。\n- 玩家名字现在显示在头顶了!",
|
||||
# 使用喷泉图片对应"喷泉左边"的描述
|
||||
"image_path": "res://assets/sprites/environment/fountain_256_192.png",
|
||||
"image_color": Color(0.8, 0.9, 0.8)
|
||||
},
|
||||
{
|
||||
"text": "操作提示:\n\n- 按 [color=#ffaa00]F[/color] 键可以与物体互动。\n- 在下方输入框输入文字并在气泡中显示。\n- 点击右下角按钮发送聊天。",
|
||||
# 使用公告板图片对应"操作提示"
|
||||
"image_path": "res://assets/sprites/environment/board.png",
|
||||
"image_color": Color(0.9, 0.8, 0.8)
|
||||
}
|
||||
]
|
||||
|
||||
var current_page = 0
|
||||
var tween: Tween
|
||||
var mock_pages = []
|
||||
|
||||
func _ready():
|
||||
# Pause the game
|
||||
get_tree().paused = true
|
||||
|
||||
$CenterContainer/PanelContainer/VBoxContainer/Header/RightContainer/CloseButton.pressed.connect(_on_close_pressed)
|
||||
prev_btn.pressed.connect(_on_prev_pressed)
|
||||
next_btn.pressed.connect(_on_next_pressed)
|
||||
|
||||
# Network Integration - Use direct callback for better error handling
|
||||
# Short timeout (2.0s) so mock data appears quickly if server is down
|
||||
NetworkManager.get_request("/notices", _on_notices_response, 2.0)
|
||||
|
||||
# Initial Setup (with generic "Loading" state)
|
||||
mock_pages = pages.duplicate(true)
|
||||
pages = [{"text": "[center]Loading notices...[/center]", "image_color": Color(0.9, 0.9, 0.9)}]
|
||||
_setup_dots()
|
||||
_update_ui(false)
|
||||
|
||||
func _on_notices_response(success: bool, data: Dictionary, _error_info: Dictionary):
|
||||
var new_pages = []
|
||||
if success and data.has("data") and data["data"] is Array:
|
||||
new_pages = data["data"]
|
||||
|
||||
if new_pages.is_empty():
|
||||
pages = mock_pages
|
||||
else:
|
||||
pages = new_pages
|
||||
# Handle color strings from JSON if necessary
|
||||
for p in pages:
|
||||
if p.has("image_color") and p["image_color"] is String:
|
||||
p["image_color"] = Color(p["image_color"])
|
||||
|
||||
current_page = 0
|
||||
_setup_dots()
|
||||
_update_ui(true)
|
||||
|
||||
|
||||
func _setup_dots():
|
||||
for child in dots_container.get_children():
|
||||
child.queue_free()
|
||||
|
||||
for i in range(pages.size()):
|
||||
var dot = ColorRect.new()
|
||||
dot.custom_minimum_size = Vector2(10, 10) # Base size
|
||||
dots_container.add_child(dot)
|
||||
|
||||
func _update_ui(animate: bool = true):
|
||||
if pages.is_empty():
|
||||
return
|
||||
|
||||
# Update Buttons
|
||||
prev_btn.disabled = (current_page == 0)
|
||||
next_btn.disabled = (current_page == pages.size() - 1)
|
||||
|
||||
# Update Dots Logic
|
||||
var dots = dots_container.get_children()
|
||||
for i in range(dots.size()):
|
||||
if i == current_page:
|
||||
dots[i].color = Color(0.2, 0.2, 0.2, 1) # Dark Active
|
||||
dots[i].custom_minimum_size = Vector2(12, 12) # Active Slightly Larger
|
||||
else:
|
||||
dots[i].color = Color(0.8, 0.8, 0.8, 1) # Light Inactive
|
||||
dots[i].custom_minimum_size = Vector2(10, 10)
|
||||
|
||||
# Update Content
|
||||
if animate:
|
||||
_animate_content_change()
|
||||
else:
|
||||
_set_content_immediate()
|
||||
|
||||
@onready var image_rect = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer/ImagePanel/ImageRect
|
||||
@onready var image_label = $CenterContainer/PanelContainer/VBoxContainer/ContentContainer/ImagePanel/ImageLabel
|
||||
|
||||
func _set_content_immediate():
|
||||
var page = pages[current_page]
|
||||
content_label.text = page.get("text", "")
|
||||
|
||||
if page.has("image_path") and page["image_path"] != "":
|
||||
var path = page["image_path"]
|
||||
if ResourceLoader.exists(path):
|
||||
image_rect.texture = load(path)
|
||||
image_label.visible = false
|
||||
else:
|
||||
image_rect.texture = null
|
||||
image_label.visible = true
|
||||
image_label.text = "Image Not Found"
|
||||
else:
|
||||
image_rect.texture = null
|
||||
image_label.visible = true
|
||||
image_label.text = "No Image"
|
||||
|
||||
|
||||
|
||||
func _animate_content_change():
|
||||
if tween and tween.is_valid():
|
||||
tween.kill()
|
||||
|
||||
tween = create_tween()
|
||||
|
||||
# Fade Out
|
||||
tween.tween_property(content_container, "modulate:a", 0.0, 0.15)
|
||||
|
||||
# Callback to change text
|
||||
tween.tween_callback(self._set_content_immediate)
|
||||
|
||||
# Fade In
|
||||
tween.tween_property(content_container, "modulate:a", 1.0, 0.15)
|
||||
|
||||
func _on_prev_pressed():
|
||||
if current_page > 0:
|
||||
current_page -= 1
|
||||
_update_ui()
|
||||
|
||||
func _on_next_pressed():
|
||||
if current_page < pages.size() - 1:
|
||||
current_page += 1
|
||||
_update_ui()
|
||||
|
||||
func _on_close_pressed():
|
||||
# Unpause the game
|
||||
get_tree().paused = false
|
||||
queue_free()
|
||||
1
scenes/ui/NoticeDialog.gd.uid
Normal file
1
scenes/ui/NoticeDialog.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cxi5rchnmk07p
|
||||
20
scenes/ui/WelcomeDialog.gd
Normal file
20
scenes/ui/WelcomeDialog.gd
Normal file
@@ -0,0 +1,20 @@
|
||||
extends CanvasLayer
|
||||
|
||||
func _ready():
|
||||
# Connect close button (X)
|
||||
var header_close = find_child("CloseButton", true, false)
|
||||
if header_close:
|
||||
header_close.pressed.connect(_on_close_pressed)
|
||||
|
||||
# Connect Start button
|
||||
var start_btn = find_child("StartButton", true, false)
|
||||
if start_btn:
|
||||
start_btn.pressed.connect(_on_close_pressed)
|
||||
|
||||
func _on_close_pressed():
|
||||
queue_free()
|
||||
|
||||
func _input(event):
|
||||
# Allow ESC to close
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
queue_free()
|
||||
1
scenes/ui/WelcomeDialog.gd.uid
Normal file
1
scenes/ui/WelcomeDialog.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cu6x4dxhsylw2
|
||||
132
scenes/ui/notice_dialog.tscn
Normal file
132
scenes/ui/notice_dialog.tscn
Normal file
@@ -0,0 +1,132 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://rdmro1jxs6ga"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cxi5rchnmk07p" path="res://scenes/ui/NoticeDialog.gd" id="1_script"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_rounded"]
|
||||
bg_color = Color(0.95, 0.95, 0.95, 1)
|
||||
corner_radius_top_left = 16
|
||||
corner_radius_top_right = 16
|
||||
corner_radius_bottom_right = 16
|
||||
corner_radius_bottom_left = 16
|
||||
shadow_color = Color(0, 0, 0, 0.2)
|
||||
shadow_size = 8
|
||||
|
||||
[node name="NoticeDialog" type="CanvasLayer"]
|
||||
process_mode = 3
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="Dimmer" type="ColorRect" parent="."]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0, 0, 0, 0.5)
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="."]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="CenterContainer"]
|
||||
custom_minimum_size = Vector2(480, 420)
|
||||
layout_mode = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_rounded")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 12
|
||||
|
||||
[node name="HeaderSpacer" type="Control" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 4)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Header" type="HBoxContainer" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="LeftSpacer" type="Control" parent="CenterContainer/PanelContainer/VBoxContainer/Header"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Title" type="Label" parent="CenterContainer/PanelContainer/VBoxContainer/Header"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.2, 0.2, 0.2, 1)
|
||||
theme_override_font_sizes/font_size = 22
|
||||
text = "公告板"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="RightContainer" type="HBoxContainer" parent="CenterContainer/PanelContainer/VBoxContainer/Header"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
alignment = 2
|
||||
|
||||
[node name="CloseButton" type="Button" parent="CenterContainer/PanelContainer/VBoxContainer/Header/RightContainer"]
|
||||
custom_minimum_size = Vector2(32, 32)
|
||||
layout_mode = 2
|
||||
text = "X"
|
||||
flat = true
|
||||
|
||||
[node name="RightMargin" type="Control" parent="CenterContainer/PanelContainer/VBoxContainer/Header/RightContainer"]
|
||||
custom_minimum_size = Vector2(8, 0)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ContentContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="ImagePanel" type="PanelContainer" parent="CenterContainer/PanelContainer/VBoxContainer/ContentContainer"]
|
||||
custom_minimum_size = Vector2(0, 200)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ImageRect" type="TextureRect" parent="CenterContainer/PanelContainer/VBoxContainer/ContentContainer/ImagePanel"]
|
||||
layout_mode = 2
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="ImageLabel" type="Label" parent="CenterContainer/PanelContainer/VBoxContainer/ContentContainer/ImagePanel"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
|
||||
text = "Image Placeholder"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="TextPanel" type="MarginContainer" parent="CenterContainer/PanelContainer/VBoxContainer/ContentContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/margin_left = 16
|
||||
theme_override_constants/margin_right = 16
|
||||
|
||||
[node name="ContentLabel" type="RichTextLabel" parent="CenterContainer/PanelContainer/VBoxContainer/ContentContainer/TextPanel"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/default_color = Color(0.3, 0.3, 0.3, 1)
|
||||
theme_override_font_sizes/normal_font_size = 16
|
||||
bbcode_enabled = true
|
||||
text = "Announcement Content..."
|
||||
|
||||
[node name="Footer" type="HBoxContainer" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 48)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 20
|
||||
alignment = 1
|
||||
|
||||
[node name="PrevButton" type="Button" parent="CenterContainer/PanelContainer/VBoxContainer/Footer"]
|
||||
custom_minimum_size = Vector2(40, 40)
|
||||
layout_mode = 2
|
||||
text = "<"
|
||||
|
||||
[node name="DotsContainer" type="HBoxContainer" parent="CenterContainer/PanelContainer/VBoxContainer/Footer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
alignment = 1
|
||||
|
||||
[node name="NextButton" type="Button" parent="CenterContainer/PanelContainer/VBoxContainer/Footer"]
|
||||
custom_minimum_size = Vector2(40, 40)
|
||||
layout_mode = 2
|
||||
text = ">"
|
||||
|
||||
[node name="BottomSpacer" type="Control" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 4)
|
||||
layout_mode = 2
|
||||
117
scenes/ui/welcome_dialog.tscn
Normal file
117
scenes/ui/welcome_dialog.tscn
Normal file
@@ -0,0 +1,117 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://d8mam0n1a3b5"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cu6x4dxhsylw2" path="res://scenes/ui/WelcomeDialog.gd" id="1_vs5b1"]
|
||||
[ext_resource type="Texture2D" uid="uid://v7loa3smfkrd" path="res://assets/materials/WelcomeBoard.png" id="2_dy5hw"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_card"]
|
||||
bg_color = Color(1, 1, 1, 1)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
shadow_color = Color(0, 0, 0, 0.2)
|
||||
shadow_size = 10
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_btn_rounded"]
|
||||
bg_color = Color(0.95, 0.95, 0.95, 1)
|
||||
border_width_left = 1
|
||||
border_width_top = 1
|
||||
border_width_right = 1
|
||||
border_width_bottom = 1
|
||||
corner_radius_top_left = 20
|
||||
corner_radius_top_right = 20
|
||||
corner_radius_bottom_right = 20
|
||||
corner_radius_bottom_left = 20
|
||||
|
||||
[node name="WelcomeDialog" type="CanvasLayer"]
|
||||
script = ExtResource("1_vs5b1")
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="."]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0, 0, 0, 0.4)
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="."]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="CenterContainer"]
|
||||
custom_minimum_size = Vector2(400, 350)
|
||||
layout_mode = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_card")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 10
|
||||
|
||||
[node name="Header" type="HBoxContainer" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="Spacer" type="Control" parent="CenterContainer/PanelContainer/VBoxContainer/Header"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Title" type="Label" parent="CenterContainer/PanelContainer/VBoxContainer/Header"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "欢迎来到 Datawhale Town!"
|
||||
|
||||
[node name="Spacer2" type="Control" parent="CenterContainer/PanelContainer/VBoxContainer/Header"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="CloseButton" type="Button" parent="CenterContainer/PanelContainer/VBoxContainer/Header"]
|
||||
custom_minimum_size = Vector2(30, 30)
|
||||
layout_mode = 2
|
||||
text = "X"
|
||||
flat = true
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="LogoContainer" type="CenterContainer" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="CenterContainer/PanelContainer/VBoxContainer/LogoContainer"]
|
||||
custom_minimum_size = Vector2(300, 100)
|
||||
layout_mode = 2
|
||||
texture = ExtResource("2_dy5hw")
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="BodyText" type="Label" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.3, 0.3, 0.3, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "连接·共生·见证
|
||||
Datawhale Town —— 学习者的赛博家园与精神坐标。
|
||||
✨ 实时广场:看大家都在学什么。
|
||||
🏠 个人空间:展示你的学习笔记与作品。
|
||||
🤝 开源营地:更有氛围的组队学习体验。"
|
||||
horizontal_alignment = 1
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="Spacer3" type="Control" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ActionContainer" type="CenterContainer" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="StartButton" type="Button" parent="CenterContainer/PanelContainer/VBoxContainer/ActionContainer"]
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_styles/normal = SubResource("StyleBoxFlat_btn_rounded")
|
||||
text = "开始探索"
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/PanelContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
Reference in New Issue
Block a user