class_name HomeDecorToolbar extends PanelContainer signal placement_mode_requested(mode: int) signal rotate_requested signal store_requested signal cancel_requested var _mode_button: Button var _selection_label: Label var _rotate_button: Button var _store_button: Button var _clear_button: Button var _mode: PlayerHomeState.PlacementMode = PlayerHomeState.PlacementMode.GRID var _interactive: bool = true var _selection_active: bool = false func _ready() -> void: _build_ui() hide() func set_active(active: bool) -> void: if visible == active: return visible = active func set_interactive(interactive: bool) -> void: _interactive = interactive _refresh_button_interactivity() func set_mode(mode: PlayerHomeState.PlacementMode) -> void: _mode = mode if _mode_button != null: _mode_button.text = ( "grid" if mode == PlayerHomeState.PlacementMode.GRID else "free" ) _mode_button.tooltip_text = "placement mode: %s" % _mode_button.text func set_selection(instance_id: String, display_name: String = "") -> void: var selected: bool = not instance_id.is_empty() _selection_active = selected if _selection_label != null: _selection_label.text = ( "selected: %s" % display_name if selected else "use held decor to place; click or drag to edit" ) _refresh_button_interactivity() func report_status(message: String) -> void: if _selection_label != null: _selection_label.text = message func _build_ui() -> void: set_anchors_preset(Control.PRESET_TOP_RIGHT) offset_left = -500.0 offset_top = 0.0 offset_right = 0.0 offset_bottom = 106.0 custom_minimum_size = Vector2(500.0, 0.0) z_index = 85 mouse_filter = Control.MOUSE_FILTER_STOP var panel_style: StyleBoxFlat = UtilityPageStyle.panel_style() panel_style.set_corner_radius_all(10) panel_style.content_margin_left = 6.0 panel_style.content_margin_top = 6.0 panel_style.content_margin_right = 6.0 panel_style.content_margin_bottom = 6.0 add_theme_stylebox_override("panel", panel_style) var margin := MarginContainer.new() for side: StringName in [ &"margin_left", &"margin_top", &"margin_right", &"margin_bottom", ]: margin.add_theme_constant_override(side, 6) add_child(margin) var layout := VBoxContainer.new() layout.add_theme_constant_override("separation", 5) margin.add_child(layout) var row := HBoxContainer.new() row.add_theme_constant_override("separation", 5) layout.add_child(row) var title := Label.new() title.text = "decor" title.custom_minimum_size = Vector2(70.0, 46.0) title.vertical_alignment = VERTICAL_ALIGNMENT_CENTER title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER title.add_theme_font_size_override("font_size", 19) row.add_child(title) _mode_button = _add_tool_button(row, "grid", "switch placement mode", 82.0) _mode_button.pressed.connect(_toggle_mode) _rotate_button = _add_tool_button(row, "rotate", "rotate selected decor", 92.0) _rotate_button.pressed.connect(rotate_requested.emit) _store_button = _add_tool_button(row, "pack", "pack selected decor", 82.0) _store_button.pressed.connect(store_requested.emit) _clear_button = _add_tool_button(row, "clear", "clear selection", 82.0) _clear_button.pressed.connect(cancel_requested.emit) _selection_label = Label.new() _selection_label.text = "use held decor to place; click or drag to edit" _selection_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART _selection_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _selection_label.add_theme_font_size_override("font_size", 15) layout.add_child(_selection_label) _refresh_button_interactivity() func _add_tool_button( parent: Container, button_text: String, button_tooltip: String, minimum_width: float, ) -> Button: var button := Button.new() button.text = button_text button.tooltip_text = button_tooltip button.accessibility_name = button_tooltip button.custom_minimum_size = Vector2(minimum_width, 46.0) button.size_flags_horizontal = Control.SIZE_EXPAND_FILL UtilityPageStyle.apply_ocean_button(button) for style_name: StringName in [ &"normal", &"hover", &"pressed", &"focus", &"disabled", ]: var existing: StyleBox = button.get_theme_stylebox(style_name) var rounded := existing.duplicate() as StyleBoxFlat if rounded == null: continue rounded.set_corner_radius_all(20) button.add_theme_stylebox_override(style_name, rounded) parent.add_child(button) return button func _refresh_button_interactivity() -> void: if _mode_button != null: _mode_button.disabled = not _interactive if _rotate_button != null: _rotate_button.disabled = not _interactive or not _selection_active if _store_button != null: _store_button.disabled = not _interactive or not _selection_active if _clear_button != null: _clear_button.disabled = not _interactive or not _selection_active func _toggle_mode() -> void: _mode = ( PlayerHomeState.PlacementMode.FREE if _mode == PlayerHomeState.PlacementMode.GRID else PlayerHomeState.PlacementMode.GRID ) set_mode(_mode) placement_mode_requested.emit(int(_mode))