Implement Phase 6 features for Stickman Editor
- Updated BUGS.md with new issues related to selection bounding box, touchpad panning speed, and zooming behavior. - Enhanced PROJECT.md with detailed specifications for touchpad controls, recent colors in the color picker, and a status bar for project information. - Modified project.godot to update compatibility version to 4.7. - Added a status bar in stickman_editor.tscn to display cursor coordinates and snap status. - Updated body_part_panel.gd to handle recent colors and cursor detection over drawing areas. - Enhanced stickman_editor.gd to manage cursor coordinates display and recent colors tracking. - Improved whole_stickman_preview.gd to render selection gizmos on top of other parts. - Created master_rig.tscn for the stickman rig structure with bones and IK targets. - Developed master_rig_builder.gd to automate the rig building process with remote transforms and IK modifications.
This commit is contained in:
@@ -73,6 +73,8 @@ const MAX_GRID_SIZE := 100
|
||||
@onready var _error_dialog: AcceptDialog = %ErrorDialog
|
||||
@onready var _grid_config_dialog: ConfirmationDialog = %GridConfigDialog
|
||||
@onready var _grid_size_spin_box: SpinBox = %GridSizeSpinBox
|
||||
@onready var _status_cursor_coords: Label = %CursorCoords
|
||||
@onready var _status_snap_status: Label = %SnapStatus
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Grid / snap state
|
||||
@@ -84,6 +86,9 @@ var _snap_enabled: bool = false
|
||||
# Phase 5: shape clipboard
|
||||
var _shape_clipboard: Dictionary = {}
|
||||
|
||||
# Phase 6: recent colors
|
||||
var _recent_colors: Array[String] = []
|
||||
|
||||
var _edit_menu: PopupMenu
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -98,11 +103,31 @@ func _ready() -> void:
|
||||
_whole_preview.set_body_parts(_collect_all_shape_data())
|
||||
|
||||
_load_settings()
|
||||
_update_snap_status_label()
|
||||
_broadcast_settings()
|
||||
_broadcast_recent_colors()
|
||||
|
||||
if not _grid_config_dialog.confirmed.is_connected(_on_grid_config_confirmed):
|
||||
_grid_config_dialog.confirmed.connect(_on_grid_config_confirmed)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
var mouse_pos := get_global_mouse_position()
|
||||
|
||||
for part_name: String in BODY_PART_NAMES:
|
||||
var panel: BodyPartPanel = _body_part_panels.get(part_name) as BodyPartPanel
|
||||
if panel and panel.is_cursor_over_drawing(mouse_pos):
|
||||
var world_pos := panel.global_to_world(mouse_pos)
|
||||
_status_cursor_coords.text = "X: %d Y: %d" % [int(world_pos.x), int(world_pos.y)]
|
||||
return
|
||||
|
||||
if _whole_preview.is_cursor_over_preview(mouse_pos):
|
||||
var world_pos := _whole_preview.global_to_world(mouse_pos)
|
||||
_status_cursor_coords.text = "X: %d Y: %d" % [int(world_pos.x), int(world_pos.y)]
|
||||
return
|
||||
|
||||
_status_cursor_coords.text = ""
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Menu & Dialog setup
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -162,6 +187,7 @@ func _populate_body_part_panels() -> void:
|
||||
panel.shape_selected.connect(_on_body_part_shape_selected.bind(part_name))
|
||||
panel.shape_copy_requested.connect(_on_shape_copy_requested.bind(part_name))
|
||||
panel.shape_paste_requested.connect(_on_shape_paste_requested.bind(part_name))
|
||||
panel.color_selected.connect(_on_color_selected.bind(part_name))
|
||||
_body_part_panels[part_name] = panel
|
||||
left_col.add_child(panel)
|
||||
|
||||
@@ -173,6 +199,7 @@ func _populate_body_part_panels() -> void:
|
||||
panel.shape_selected.connect(_on_body_part_shape_selected.bind(part_name))
|
||||
panel.shape_copy_requested.connect(_on_shape_copy_requested.bind(part_name))
|
||||
panel.shape_paste_requested.connect(_on_shape_paste_requested.bind(part_name))
|
||||
panel.color_selected.connect(_on_color_selected.bind(part_name))
|
||||
_body_part_panels[part_name] = panel
|
||||
center_col.add_child(panel)
|
||||
|
||||
@@ -201,6 +228,7 @@ func _on_edit_menu_id_pressed(id: int) -> void:
|
||||
_edit_menu.set_item_text(1, _snap_menu_label())
|
||||
_save_settings()
|
||||
_broadcast_settings()
|
||||
_update_snap_status_label()
|
||||
|
||||
|
||||
func _on_edit_menu_about_to_popup() -> void:
|
||||
@@ -448,6 +476,12 @@ func _broadcast_clipboard_state() -> void:
|
||||
(panel as BodyPartPanel).set_has_clipboard(not _shape_clipboard.is_empty())
|
||||
|
||||
|
||||
func _broadcast_recent_colors() -> void:
|
||||
for panel in _body_part_panels.values():
|
||||
if panel is BodyPartPanel:
|
||||
(panel as BodyPartPanel).set_recent_colors(_recent_colors)
|
||||
|
||||
|
||||
func _paste_shape_into_panel(part_name: String, world_pos: Vector2) -> void:
|
||||
if _shape_clipboard.is_empty():
|
||||
return
|
||||
@@ -459,6 +493,18 @@ func _paste_shape_into_panel(part_name: String, world_pos: Vector2) -> void:
|
||||
func _on_shape_paste_requested(world_pos: Vector2, part_name: String) -> void:
|
||||
_paste_shape_into_panel(part_name, world_pos)
|
||||
|
||||
|
||||
func _on_color_selected(color: Color, _part_name: String) -> void:
|
||||
var hex_str := color.to_html()
|
||||
var idx := _recent_colors.find(hex_str)
|
||||
if idx >= 0:
|
||||
_recent_colors.remove_at(idx)
|
||||
_recent_colors.insert(0, hex_str)
|
||||
while _recent_colors.size() > 8:
|
||||
_recent_colors.pop_back()
|
||||
_save_settings()
|
||||
_broadcast_recent_colors()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Phase 3: Settings persistence
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -483,6 +529,15 @@ func _load_settings() -> void:
|
||||
_snap_enabled = bool(d.get("snap_to_grid", false))
|
||||
_grid_size = clampi(_grid_size, MIN_GRID_SIZE, MAX_GRID_SIZE)
|
||||
|
||||
var raw_colors: Variant = d.get("recent_colors", [])
|
||||
if raw_colors is Array:
|
||||
var arr: Array = raw_colors as Array
|
||||
for c in arr:
|
||||
if c is String:
|
||||
_recent_colors.append(c as String)
|
||||
while _recent_colors.size() > 8:
|
||||
_recent_colors.pop_back()
|
||||
|
||||
if _edit_menu:
|
||||
_edit_menu.set_item_text(1, _snap_menu_label())
|
||||
|
||||
@@ -492,6 +547,7 @@ func _save_settings() -> void:
|
||||
"version": SETTINGS_VERSION,
|
||||
"grid_size": _grid_size,
|
||||
"snap_to_grid": _snap_enabled,
|
||||
"recent_colors": _recent_colors,
|
||||
}
|
||||
var file := FileAccess.open(SETTINGS_PATH, FileAccess.WRITE)
|
||||
if file:
|
||||
@@ -511,3 +567,7 @@ func _broadcast_settings() -> void:
|
||||
|
||||
func _snap_menu_label() -> String:
|
||||
return "[√] Snap to Grid" if _snap_enabled else "Snap to Grid"
|
||||
|
||||
|
||||
func _update_snap_status_label() -> void:
|
||||
_status_snap_status.text = "SNAP: ON" if _snap_enabled else "SNAP: OFF"
|
||||
|
||||
Reference in New Issue
Block a user