feat: complete mobile UI implementation

This commit is contained in:
shenlei
2026-09-04 19:54:33 +09:00
parent 9a4a044da5
commit b19d5b5dd3
132 changed files with 6643 additions and 180 deletions
+46 -2
View File
@@ -26,6 +26,10 @@ var _sel := -1
var _cube_slots: Dictionary = {} # cube index:int -> inventory cell:int
var _craft_in_flight := false
var _cube_npc_vnum := 0
var _mobile_mode := false
var _box: VBoxContainer
var _recipe_scroll: ScrollContainer
var _material_scroll: ScrollContainer
func setup(m2client: Node, parent: Node, proto_node: Node = null) -> void:
client = m2client
@@ -45,6 +49,13 @@ func setup(m2client: Node, parent: Node, proto_node: Node = null) -> void:
func is_open() -> bool:
return _root != null and _root.visible
func get_mobile_window() -> Control:
return _root
func set_mobile_mode(enabled: bool) -> void:
_mobile_mode = enabled
_apply_mobile_layout()
func close() -> void:
if _root:
_root.visible = false
@@ -65,6 +76,7 @@ func _on_open(npc_vnum: int) -> void:
_cube_slots.clear()
_craft_in_flight = false
_cube_npc_vnum = npc_vnum
_apply_mobile_layout()
_root.visible = true
_title.text = "제작 (Cube) · NPC #%d" % npc_vnum
_status.text = ""
@@ -262,6 +274,31 @@ func _lbl(t: String, sz: int) -> Label:
l.add_theme_font_size_override("font_size", sz)
return l
func _apply_mobile_layout() -> void:
if _root == null or _box == null:
return
if _mobile_mode:
# Recipe selection and material/source-bag selection remain side by side
# in landscape. Both columns scroll independently so the craft action
# stays reachable when a recipe has many material alternatives.
_root.size = Vector2(720, 380)
_root.position = Vector2(-360, -190)
_box.position = Vector2(16, 48)
_box.size = Vector2(688, 318)
_box.custom_minimum_size = Vector2(688, 318)
_recipe_scroll.custom_minimum_size = Vector2(248, 254)
_material_scroll.custom_minimum_size = Vector2(430, 254)
_mat.custom_minimum_size = Vector2(414, 254)
else:
_root.size = Vector2(400, 380)
_root.position = Vector2(-200, -190)
_box.position = Vector2(16, 14)
_box.size = Vector2(368, 350)
_box.custom_minimum_size = Vector2(368, 350)
_recipe_scroll.custom_minimum_size = Vector2(180, 250)
_material_scroll.custom_minimum_size = Vector2(178, 250)
_mat.custom_minimum_size = Vector2(178, 250)
func _build(parent: Node) -> void:
_root = Panel.new()
_root.set_anchors_preset(Control.PRESET_CENTER)
@@ -270,7 +307,8 @@ func _build(parent: Node) -> void:
_root.size = Vector2(400, 380)
_root.visible = false
parent.add_child(_root)
var box := VBoxContainer.new()
_box = VBoxContainer.new()
var box := _box
box.position = Vector2(16, 14)
box.custom_minimum_size = Vector2(368, 0)
box.add_theme_constant_override("separation", 6)
@@ -281,15 +319,20 @@ func _build(parent: Node) -> void:
split.add_theme_constant_override("separation", 10)
box.add_child(split)
var lsc := ScrollContainer.new()
_recipe_scroll = lsc
lsc.custom_minimum_size = Vector2(180, 250)
split.add_child(lsc)
_list = VBoxContainer.new()
_list.add_theme_constant_override("separation", 3)
lsc.add_child(_list)
_material_scroll = ScrollContainer.new()
_material_scroll.custom_minimum_size = Vector2(178, 250)
_material_scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
split.add_child(_material_scroll)
_mat = VBoxContainer.new()
_mat.custom_minimum_size = Vector2(178, 250)
_mat.add_theme_constant_override("separation", 3)
split.add_child(_mat)
_material_scroll.add_child(_mat)
_status = _lbl("", 12)
_status.add_theme_color_override("font_color", Color(1, 0.9, 0.5))
box.add_child(_status)
@@ -320,3 +363,4 @@ func _build(parent: Node) -> void:
client.cube_close()
_root.visible = false)
brow.add_child(close)
_apply_mobile_layout()