fix(editor): move build stamp to bottom, expand palette list, add hover feedback and instructions
checkpoint / checkpoint (push) Successful in 6m5s

This commit is contained in:
2026-09-16 12:21:39 +00:00
parent 42520b33d5
commit 73172b1e28
6 changed files with 195 additions and 28 deletions
+70 -2
View File
@@ -34,6 +34,7 @@ var _viewport: EditorViewport
var _close_button: Button
var _save_button: Button
var _save_status_label: Label
var _instruction_label: Label
## Save-path state (world_persistence_impl.md §8.1/§8.2), set via
## `setup_persistence()`. `_save_service == null` means there is nothing to
@@ -66,11 +67,16 @@ func setup_persistence(save_service: ChunkSaveService, world_id: String, room_sl
_base_revision = base_revision
if _save_button != null:
_save_button.disabled = false
_save_button.tooltip_text = "Save chunk changes to backend (Ctrl+S)"
func _ready() -> void:
_build_ui()
_refresh_history_buttons()
if core.tools.get_active_tool_id() == "select" and core.model.payload.objects.is_empty():
core.tools.set_active_tool("brush")
_toolbar.set_active_tool("brush")
_update_instruction()
func _build_ui() -> void:
@@ -98,14 +104,21 @@ func _build_ui() -> void:
_save_button = Button.new()
_save_button.text = "Save (Ctrl+S)"
_save_button.disabled = (_save_service == null)
_save_button.tooltip_text = "Save changes to server (Ctrl+S)" if _save_service != null else "Saving not available in scratch mode"
_save_button.pressed.connect(_on_save_pressed)
top_bar.add_child(_save_button)
_close_button = Button.new()
_close_button.text = "Close (F2)"
_close_button.text = "Close (F2 / Esc)"
_close_button.tooltip_text = "Exit build mode and return to game"
_close_button.pressed.connect(_on_close_pressed)
top_bar.add_child(_close_button)
_instruction_label = Label.new()
_instruction_label.add_theme_font_size_override("font_size", 13)
_instruction_label.add_theme_color_override("font_color", Color(0.75, 0.92, 1.0))
root_vbox.add_child(_instruction_label)
_save_status_label = Label.new()
_save_status_label.autowrap_mode = TextServer.AUTOWRAP_WORD
_save_status_label.visible = false
@@ -124,13 +137,15 @@ func _build_ui() -> void:
viewport_scroll.add_child(_viewport)
var sidebar := VBoxContainer.new()
sidebar.custom_minimum_size = Vector2(240, 0)
sidebar.custom_minimum_size = Vector2(260, 0)
body.add_child(sidebar)
_palette = PalettePanel.new()
_palette.size_flags_vertical = Control.SIZE_EXPAND_FILL
sidebar.add_child(_palette)
_inspector = InspectorPanel.new()
_inspector.size_flags_vertical = Control.SIZE_EXPAND_FILL
sidebar.add_child(_inspector)
_viewport.setup(core, 0)
@@ -166,16 +181,34 @@ func _unhandled_key_input(event: InputEvent) -> void:
core.delete_object(core.selection.get_selected())
_on_edit_applied()
get_viewport().set_input_as_handled()
elif key.keycode == KEY_B and not key.ctrl_pressed:
_on_tool_selected("brush")
_toolbar.set_active_tool("brush")
get_viewport().set_input_as_handled()
elif key.keycode == KEY_V and not key.ctrl_pressed:
_on_tool_selected("select")
_toolbar.set_active_tool("select")
get_viewport().set_input_as_handled()
elif key.keycode == KEY_P and not key.ctrl_pressed:
_on_tool_selected("object_place")
_toolbar.set_active_tool("object_place")
get_viewport().set_input_as_handled()
elif key.keycode == KEY_X and not key.ctrl_pressed:
_on_tool_selected("erase")
_toolbar.set_active_tool("erase")
get_viewport().set_input_as_handled()
func _on_tool_selected(tool_id: String) -> void:
core.tools.set_active_tool(tool_id)
_update_instruction()
func _on_palette_object_selected(catalog_id: String) -> void:
_viewport.pending_catalog_id = catalog_id
core.tools.set_active_tool("object_place")
_toolbar.set_active_tool("object_place")
_update_instruction()
func _on_inspector_delete_requested(object_id: String) -> void:
@@ -197,10 +230,45 @@ func _on_edit_applied() -> void:
_viewport.queue_redraw()
_inspector.show_object(core.selection.get_selected())
_refresh_history_buttons()
_update_instruction()
func _on_selection_changed(object_id: String) -> void:
_inspector.show_object(object_id)
_update_instruction()
func _update_instruction() -> void:
if _instruction_label == null:
return
var active_id := core.tools.get_active_tool_id()
match active_id:
"brush":
_instruction_label.text = "Tool: [ Brush ] — Left-click and drag on grid squares to paint ground tiles. (Keys 0-9 pick tile type)"
"object_place":
var name := _viewport.pending_catalog_id
if core.catalog != null:
var e := core.catalog.resolve(name)
if e.has("display_name"):
name = str(e["display_name"])
if name == "":
_instruction_label.text = "Tool: [ Place ] — Select an item in the Palette on the right, then click on the grid squares to place."
else:
_instruction_label.text = "Tool: [ Place: %s ] — Click any grid square to place '%s'." % [name, name]
"select":
if core.selection.has_selection():
var sel_id := core.selection.get_selected()
var obj := core.model.find_object(sel_id)
var dname := sel_id
if obj != null and obj.properties is Dictionary and obj.properties.has("display_name"):
dname = "%s (%s)" % [obj.properties["display_name"], sel_id]
_instruction_label.text = "Tool: [ Select ] — Selected '%s'. Edit in the Inspector on the right, or press Delete to remove." % dname
else:
_instruction_label.text = "Tool: [ Select ] — Click on a placed object on the grid to inspect it, or switch to Brush/Place to build."
"erase":
_instruction_label.text = "Tool: [ Erase ] — Left-click and drag on grid squares to erase painted tiles or delete objects."
_:
_instruction_label.text = "Tool: [ %s ]" % active_id
func _refresh_history_buttons() -> void: