Implement speech style toolbar live-edit refinements and whole speech show controls

- Added a new specification for the speech style toolbar live-edit, detailing immediate style application, scoped effect demonstration, and hover feedback.
- Introduced refinements to the speech style toolbar, including improved chooser sizing, exclusive stage editing during speech composition, and removal of redundant controls.
- Documented new stage controls for managing how the whole speech shows, including options for bubble arrangement, word appearance, and bubble motion.
- Created a new log file for speech padding syntax to track engine versioning.
This commit is contained in:
2026-10-03 14:49:22 -04:00
parent 6a1359f244
commit 6666173c4f
42 changed files with 9163 additions and 165 deletions
+12 -21
View File
@@ -13,6 +13,7 @@ const ACTION_REGISTRY := preload("res://scripts/action_registry.gd")
signal committed(action: Dictionary)
signal cancelled()
signal target_requested()
signal speech_requested(initial: Dictionary)
var _mode: String = "new"
var _initial: Dictionary = {}
@@ -74,6 +75,9 @@ func open_edit(action: Dictionary, show_reactive_options: bool = false) -> void:
_mode = "edit"
_initial = action.duplicate(true)
var type := String(action.get("type", "walk_to"))
if type == "speak":
speech_requested.emit(_initial.duplicate(true))
return
_has_target = action.has("target") and action["target"] is Vector2
_target_pos = action.get("target", Vector2.ZERO) if _has_target else Vector2.ZERO
_prop_target_id = String(action.get("target_prop_id", ""))
@@ -202,6 +206,9 @@ func _current_type() -> String:
func _on_type_selected(_index: int) -> void:
if _current_type() == "speak":
speech_requested.emit(_initial.duplicate(true))
return
_rebuild_params(_current_type())
@@ -264,23 +271,9 @@ func _rebuild_params(type: String) -> void:
throw_row.add_child(_set_target_btn)
_update_throw_target_label()
"speak":
var tlabel := Label.new()
tlabel.text = "Text:"
_params_box.add_child(tlabel)
_text_edit = LineEdit.new()
_text_edit.placeholder_text = "Say something…"
_text_edit.text = String(_initial.get("text", ""))
_params_box.add_child(_text_edit)
var dlabel := Label.new()
dlabel.text = "Duration (s):"
_params_box.add_child(dlabel)
_duration_spin = _make_duration_spin(float(_initial.get("duration", 2.0)))
_params_box.add_child(_duration_spin)
if _show_reactive_options and ACTION_REGISTRY.is_overlay_eligible(type):
_stop_current_check = CheckBox.new()
_stop_current_check.text = "Stop what he's doing?"
_stop_current_check.button_pressed = bool(_initial.get("stop_current", false))
_params_box.add_child(_stop_current_check)
var speech_label := Label.new()
speech_label.text = "Opening the comic speech composer…"
_params_box.add_child(speech_label)
"wait":
var wlabel := Label.new()
wlabel.text = "Duration (s):"
@@ -349,10 +342,8 @@ func _on_ok_pressed() -> void:
return
action["target_position"] = _throw_target_pos
"speak":
action["text"] = _text_edit.text if _text_edit != null else ""
action["duration"] = _duration_spin.value if _duration_spin != null else 2.0
if _show_reactive_options and _stop_current_check != null:
action["stop_current"] = _stop_current_check.button_pressed
speech_requested.emit(_initial.duplicate(true))
return
"wait":
action["duration"] = _duration_spin.value if _duration_spin != null else 1.0
committed.emit(action)