80 lines
2.5 KiB
GDScript
80 lines
2.5 KiB
GDScript
class_name EditorToolbar
|
|
extends HBoxContainer
|
|
## Tool-mode switcher for the in-game editor (docs/architecture/editor.md
|
|
## §7.2 `Toolbar`). Pure UI: it only emits signals: `InGameEditor` decides
|
|
## what to do with them (calling into `EditorCore`/`ToolRegistry`).
|
|
|
|
signal tool_selected(tool_id: String)
|
|
signal undo_pressed
|
|
signal redo_pressed
|
|
|
|
const TOOL_CONFIG := {
|
|
"brush": {"label": "Brush (B)", "tooltip": "Paint solid ground tiles (drag to paint; 0-9 for tile types)"},
|
|
"select": {"label": "Select (V)", "tooltip": "Select and inspect placed objects"},
|
|
"object_place": {"label": "Place (P)", "tooltip": "Place objects from the Palette onto the grid"},
|
|
"erase": {"label": "Erase (X)", "tooltip": "Erase tiles or objects (drag to erase)"},
|
|
}
|
|
|
|
var _tool_buttons: Dictionary = {}
|
|
var _undo_button: Button
|
|
var _redo_button: Button
|
|
|
|
|
|
func _init() -> void:
|
|
name = "EditorToolbar"
|
|
|
|
|
|
func _ready() -> void:
|
|
for tool_id in TOOL_CONFIG:
|
|
var btn := Button.new()
|
|
var cfg: Dictionary = TOOL_CONFIG[tool_id]
|
|
btn.text = cfg["label"]
|
|
btn.tooltip_text = cfg["tooltip"]
|
|
btn.toggle_mode = true
|
|
btn.pressed.connect(_on_tool_button_pressed.bind(tool_id))
|
|
add_child(btn)
|
|
_tool_buttons[tool_id] = btn
|
|
|
|
add_child(VSeparator.new())
|
|
|
|
_undo_button = Button.new()
|
|
_undo_button.text = "Undo (Ctrl+Z)"
|
|
_undo_button.tooltip_text = "Undo last action"
|
|
_undo_button.disabled = true
|
|
_undo_button.pressed.connect(func(): undo_pressed.emit())
|
|
add_child(_undo_button)
|
|
|
|
_redo_button = Button.new()
|
|
_redo_button.text = "Redo (Ctrl+Y)"
|
|
_redo_button.tooltip_text = "Redo last undone action"
|
|
_redo_button.disabled = true
|
|
_redo_button.pressed.connect(func(): redo_pressed.emit())
|
|
add_child(_redo_button)
|
|
|
|
|
|
func _on_tool_button_pressed(tool_id: String) -> void:
|
|
set_active_tool(tool_id)
|
|
tool_selected.emit(tool_id)
|
|
|
|
|
|
## Reflect the active tool in the button states without re-emitting the signal.
|
|
func set_active_tool(tool_id: String) -> void:
|
|
for id in _tool_buttons:
|
|
var btn: Button = _tool_buttons[id]
|
|
var is_active: bool = (str(id) == tool_id)
|
|
btn.button_pressed = is_active
|
|
if is_active:
|
|
btn.add_theme_color_override("font_color", Color(1.0, 0.95, 0.3))
|
|
btn.add_theme_color_override("font_pressed_color", Color(1.0, 0.95, 0.3))
|
|
else:
|
|
btn.remove_theme_color_override("font_color")
|
|
btn.remove_theme_color_override("font_pressed_color")
|
|
|
|
|
|
## Reflect whether undo/redo currently have anything to do.
|
|
func set_history_state(can_undo: bool, can_redo: bool) -> void:
|
|
if _undo_button:
|
|
_undo_button.disabled = not can_undo
|
|
if _redo_button:
|
|
_redo_button.disabled = not can_redo
|