Files

155 lines
4.8 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MobileMenuDrawer —— compact two-level menu for the top-right menu button.
#
# The drawer only routes actions. Feature nodes remain the owners of data,
# server state and permission checks.
extends Control
const TouchButton := preload("res://ui/mobile/mobile_touch_button.gd")
signal item_selected(category: String, item: String)
signal opened
signal closed
const CATEGORIES := ["社交", "成长", "活动", "商业", "系统"]
const ITEMS := {
"社交": ["聊天", "好友", "公会", "情侣", "观战"],
"成长": ["精炼", "龙魂", "Cube 制作"],
"活动": ["副本", "钓鱼"],
"商业": ["商店", "商城", "交易", "私人商店", "仓库", "兑换"],
"系统": ["系统设置", "游戏设置", "帮助", "选择角色", "登出", "退出游戏"],
}
var _backdrop: ColorRect
var _panel: Panel
var _category_row: HBoxContainer
var _item_scroll: ScrollContainer
var _items: VBoxContainer
var _title: Label
var _hint: Label
var _active_category := "社交"
func setup() -> void:
set_anchors_preset(Control.PRESET_FULL_RECT)
mouse_filter = Control.MOUSE_FILTER_IGNORE
_build()
visible = false
func is_open() -> bool:
return visible
func toggle() -> void:
if visible:
close()
else:
open()
func open() -> void:
if visible:
return
visible = true
_refresh_items()
opened.emit()
func close() -> void:
if not visible:
return
visible = false
closed.emit()
func _build() -> void:
_backdrop = ColorRect.new()
_backdrop.color = Color(0.01, 0.02, 0.035, 0.38)
_backdrop.set_anchors_preset(Control.PRESET_FULL_RECT)
_backdrop.mouse_filter = Control.MOUSE_FILTER_STOP
_backdrop.gui_input.connect(func(event: InputEvent):
if event is InputEventScreenTouch and not event.pressed:
close()
elif event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
close())
add_child(_backdrop)
_panel = Panel.new()
_panel.set_anchors_preset(Control.PRESET_TOP_RIGHT)
_panel.position = Vector2(-366, 72)
_panel.size = Vector2(350, 300)
_panel.mouse_filter = Control.MOUSE_FILTER_STOP
_panel.add_theme_stylebox_override("panel", _panel_style())
add_child(_panel)
_title = Label.new()
_title.position = Vector2(18, 13)
_title.add_theme_font_size_override("font_size", 18)
_title.add_theme_color_override("font_color", Color(0.95, 0.82, 0.52))
_panel.add_child(_title)
var close_button := TouchButton.new()
close_button.setup("×", Color(0.6, 0.75, 0.96, 0.9))
close_button.set_rect_style()
close_button.position = Vector2(310, 7)
close_button.size = Vector2(32, 32)
close_button.custom_minimum_size = Vector2(32, 32)
close_button.pressed.connect(close)
_panel.add_child(close_button)
_category_row = HBoxContainer.new()
_category_row.position = Vector2(14, 48)
_category_row.size = Vector2(322, 38)
_category_row.add_theme_constant_override("separation", 4)
_panel.add_child(_category_row)
for category in CATEGORIES:
var button := TouchButton.new()
button.setup(category, Color(0.45, 0.7, 0.95, 0.9))
button.set_rect_style()
button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
button.custom_minimum_size = Vector2(0, 36)
var selected: String = String(category)
button.pressed.connect(func():
_active_category = selected
_refresh_items())
_category_row.add_child(button)
_item_scroll = ScrollContainer.new()
_item_scroll.position = Vector2(16, 96)
_item_scroll.size = Vector2(318, 160)
_item_scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
_item_scroll.mouse_filter = Control.MOUSE_FILTER_STOP
_panel.add_child(_item_scroll)
_items = VBoxContainer.new()
_items.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_items.add_theme_constant_override("separation", 5)
_item_scroll.add_child(_items)
_hint = Label.new()
_hint.position = Vector2(18, 264)
_hint.size = Vector2(314, 26)
_hint.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_hint.add_theme_font_size_override("font_size", 11)
_hint.add_theme_color_override("font_color", Color(0.66, 0.72, 0.8))
_panel.add_child(_hint)
func _refresh_items() -> void:
if _panel == null:
return
_title.text = _active_category
_hint.text = "功能入口仍受当前场景和服务器状态限制。"
for child in _items.get_children():
child.queue_free()
for item in ITEMS.get(_active_category, []):
var button := TouchButton.new()
button.setup(" " + String(item), Color(0.42, 0.65, 0.9, 0.8))
button.set_rect_style()
button.custom_minimum_size = Vector2(0, 34)
var selected: String = String(item)
button.pressed.connect(func(): item_selected.emit(_active_category, selected))
_items.add_child(button)
func _panel_style() -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = Color(0.045, 0.065, 0.1, 0.96)
style.border_color = Color(0.52, 0.68, 0.9, 0.82)
style.set_border_width_all(1)
style.set_corner_radius_all(12)
style.shadow_color = Color(0, 0, 0, 0.45)
style.shadow_size = 12
return style