diff --git a/scenes/ui/build_drawer.gd b/scenes/ui/build_drawer.gd index b53c32c..33b0721 100644 --- a/scenes/ui/build_drawer.gd +++ b/scenes/ui/build_drawer.gd @@ -14,12 +14,14 @@ class_name BuildDrawer extends CanvasLayer # ── layout constants ───────────────────────────────────────────────────────── const LAYER_ORDER: int = 16 +const PANEL_HEIGHT: int = 280 # fixed tray height — same for every tab const BTN_SIZE: int = 72 # preferred hit area for build buttons const FAB_SIZE: int = 48 # floating action button (open trigger) const TAB_HEIGHT: int = 36 const LABEL_HEIGHT: int = 18 const SECTION_HEADER_HEIGHT: int = 20 -const FLOW_COLS: int = 5 # buttons per row in the flow grid +const SECTION_COLS: int = 3 # buttons per row inside one Build-tab section +const FLOW_COLS: int = 5 # buttons per row in plain (non-sectioned) tabs # ── tab indices ────────────────────────────────────────────────────────────── const TAB_DESIGNATE: int = 0 @@ -100,20 +102,13 @@ func _build_ui() -> void: _fab.pressed.connect(toggle) root.add_child(_fab) - # Panel — auto-sized, anchored to the bottom-center of the screen. - # Width hugs the grid contents; height hugs the active tab's contents. + # Panel — full-width tray, anchored to the bottom of the screen. Fixed + # height so switching tabs doesn't change the panel's footprint. _panel = PanelContainer.new() _panel.name = "BuildPanel" - _panel.anchor_left = 0.5 - _panel.anchor_right = 0.5 - _panel.anchor_top = 1.0 - _panel.anchor_bottom = 1.0 - _panel.offset_left = 0 - _panel.offset_right = 0 - _panel.offset_top = 0 - _panel.offset_bottom = -8 # small gap from bottom edge - _panel.grow_horizontal = Control.GROW_DIRECTION_BOTH - _panel.grow_vertical = Control.GROW_DIRECTION_BEGIN + _panel.set_anchors_preset(Control.PRESET_BOTTOM_WIDE) + _panel.offset_top = -PANEL_HEIGHT + _panel.offset_bottom = 0 root.add_child(_panel) var vbox := VBoxContainer.new() @@ -192,62 +187,67 @@ func _build_designate_tab() -> Control: func _build_build_tab() -> Control: - var box := VBoxContainer.new() - box.name = "BuildTab" - box.add_theme_constant_override("separation", 4) + # Build tab is a row of three section columns (Structures | Furniture | + # Production), each its own header + grid. Side-by-side layout fills the + # wide tray horizontally instead of pushing it taller. + var row := HBoxContainer.new() + row.name = "BuildTab" + row.add_theme_constant_override("separation", 14) - # Structures — walls, floors, doors. - _add_section_header(box, Strings.t(&"ui.build_drawer.section.structures")) - var structures := _make_flow_grid() - box.add_child(structures) - _add_tool_btn(structures, Strings.t(&"tool.build_wall_stone"), &"build_wall_stone", + # Structures — walls, floors, door. + var st := _make_section_column(Strings.t(&"ui.build_drawer.section.structures")) + var st_grid := st.get_child(1) as GridContainer + _add_tool_btn(st_grid, Strings.t(&"tool.build_wall_stone"), &"build_wall_stone", func() -> void: _activate_wall(&"stone")) - _add_tool_btn(structures, Strings.t(&"tool.build_wall_wood"), &"build_wall_wood", + _add_tool_btn(st_grid, Strings.t(&"tool.build_wall_wood"), &"build_wall_wood", func() -> void: _activate_wall(&"wood")) - _add_tool_btn(structures, Strings.t(&"tool.build_floor_wood"), &"build_floor_wood", - func() -> void: _activate_floor(&"wood")) - _add_tool_btn(structures, Strings.t(&"tool.build_floor_stone"), &"build_floor_stone", - func() -> void: _activate_floor(&"stone")) - _add_tool_btn(structures, Strings.t(&"tool.build_door"), &"build_door", + _add_tool_btn(st_grid, Strings.t(&"tool.build_door"), &"build_door", func() -> void: _activate(&"build_door", &"", Strings.t(&"tool.build_door"))) + _add_tool_btn(st_grid, Strings.t(&"tool.build_floor_wood"), &"build_floor_wood", + func() -> void: _activate_floor(&"wood")) + _add_tool_btn(st_grid, Strings.t(&"tool.build_floor_stone"), &"build_floor_stone", + func() -> void: _activate_floor(&"stone")) + row.add_child(st) + row.add_child(VSeparator.new()) # Furniture — crate, bed, torch. - _add_section_header(box, Strings.t(&"ui.build_drawer.section.furniture")) - var furniture := _make_flow_grid() - box.add_child(furniture) - _add_tool_btn(furniture, Strings.t(&"tool.build_crate"), &"build_crate", + var fu := _make_section_column(Strings.t(&"ui.build_drawer.section.furniture")) + var fu_grid := fu.get_child(1) as GridContainer + _add_tool_btn(fu_grid, Strings.t(&"tool.build_crate"), &"build_crate", func() -> void: _activate(&"build_crate", &"", Strings.t(&"tool.build_crate"))) - _add_tool_btn(furniture, Strings.t(&"tool.build_bed"), &"build_bed", + _add_tool_btn(fu_grid, Strings.t(&"tool.build_bed"), &"build_bed", func() -> void: _activate(&"build_bed", &"", Strings.t(&"tool.build_bed"))) - _add_tool_btn(furniture, Strings.t(&"tool.build_torch"), &"build_torch", + _add_tool_btn(fu_grid, Strings.t(&"tool.build_torch"), &"build_torch", func() -> void: _activate(&"build_torch", &"", Strings.t(&"tool.build_torch"))) + row.add_child(fu) + row.add_child(VSeparator.new()) # Production — workbenches + quarry. - _add_section_header(box, Strings.t(&"ui.build_drawer.section.production")) - var production := _make_flow_grid() - box.add_child(production) - _add_tool_btn(production, Strings.t(&"tool.workbench_carpenter"), + var pr := _make_section_column(Strings.t(&"ui.build_drawer.section.production")) + var pr_grid := pr.get_child(1) as GridContainer + _add_tool_btn(pr_grid, Strings.t(&"tool.workbench_carpenter"), &"build_workbench_carpenter", func() -> void: _activate(&"build_workbench_carpenter", &"", Strings.t(&"tool.workbench_carpenter"))) - _add_tool_btn(production, Strings.t(&"tool.workbench_smelter"), + _add_tool_btn(pr_grid, Strings.t(&"tool.workbench_smelter"), &"build_workbench_smelter", func() -> void: _activate(&"build_workbench_smelter", &"", Strings.t(&"tool.workbench_smelter"))) - _add_tool_btn(production, Strings.t(&"tool.workbench_millstone"), + _add_tool_btn(pr_grid, Strings.t(&"tool.workbench_millstone"), &"build_workbench_millstone", func() -> void: _activate(&"build_workbench_millstone", &"", Strings.t(&"tool.workbench_millstone"))) - _add_tool_btn(production, Strings.t(&"tool.workbench_hearth"), + _add_tool_btn(pr_grid, Strings.t(&"tool.workbench_hearth"), &"build_workbench_hearth", func() -> void: _activate(&"build_workbench_hearth", &"", Strings.t(&"tool.workbench_hearth"))) - _add_tool_btn(production, Strings.t(&"tool.workbench_cremation_pyre"), + _add_tool_btn(pr_grid, Strings.t(&"tool.workbench_cremation_pyre"), &"build_workbench_cremation_pyre", func() -> void: _activate(&"build_workbench_cremation_pyre", &"", Strings.t(&"tool.workbench_cremation_pyre"))) # Quarry — must be painted on a stone outcrop (BigRockNode); world.gd # rejects placements on plain ground. - _add_tool_btn(production, Strings.t(&"tool.paint_quarry"), + _add_tool_btn(pr_grid, Strings.t(&"tool.paint_quarry"), &"paint_quarry", func() -> void: _activate(&"paint_quarry", &"", Strings.t(&"tool.paint_quarry"))) + row.add_child(pr) - return box + return row func _build_stockpile_tab() -> Control: @@ -301,9 +301,13 @@ func _make_flow_grid() -> GridContainer: return g -## Small section-header label between groups in the Build tab. Drawn in the -## panel's dark border colour so it reads as a divider rather than a button. -func _add_section_header(box: Control, title: String) -> void: +## One vertical section of the Build tab: header label on top, fixed-column +## button grid below. Returns the column (child 0 = label, child 1 = grid) +## so callers can populate the grid with `_add_tool_btn`. +func _make_section_column(title: String) -> VBoxContainer: + var col := VBoxContainer.new() + col.add_theme_constant_override("separation", 4) + var lbl := Label.new() lbl.text = title lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT @@ -311,7 +315,15 @@ func _add_section_header(box: Control, title: String) -> void: lbl.add_theme_color_override("font_color", MedievalTheme.C_PANEL_DARK) lbl.add_theme_font_size_override("font_size", 13) lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE - box.add_child(lbl) + col.add_child(lbl) + + var grid := GridContainer.new() + grid.columns = SECTION_COLS + grid.add_theme_constant_override("h_separation", 6) + grid.add_theme_constant_override("v_separation", 6) + col.add_child(grid) + + return col const _THUMB_SCRIPT: Script = preload("res://scenes/ui/build_drawer_thumb.gd")