191 lines
6.0 KiB
C#
191 lines
6.0 KiB
C#
#nullable enable
|
|
using System;
|
|
using UnityEngine;
|
|
using UVC.Core;
|
|
using UVC.Studio.Manager;
|
|
using UVC.UI.Commands;
|
|
using UVC.UIToolkit;
|
|
|
|
namespace UVC.Studio.Command
|
|
{
|
|
/// <summary>
|
|
/// PropertyWindow에서 속성 변경 시 사용하는 커맨드 (Undo/Redo 지원)
|
|
/// </summary>
|
|
public class PropertyChangeCommand : IUndoableCommand
|
|
{
|
|
public string Description { get; }
|
|
|
|
private readonly string _propertyId;
|
|
private readonly object? _oldValue;
|
|
private readonly object? _newValue;
|
|
private readonly Action<string, object?>? _applyValueAction;
|
|
|
|
/// <summary>
|
|
/// 생성자
|
|
/// </summary>
|
|
/// <param name="propertyId">속성 ID</param>
|
|
/// <param name="propertyName">속성 이름 (표시용)</param>
|
|
/// <param name="oldValue">이전 값</param>
|
|
/// <param name="newValue">새 값</param>
|
|
/// <param name="applyValueAction">값 적용 함수 (propertyId, value) => void</param>
|
|
public PropertyChangeCommand(
|
|
string propertyId,
|
|
string propertyName,
|
|
object? oldValue,
|
|
object? newValue,
|
|
Action<string, object?>? applyValueAction = null)
|
|
{
|
|
_propertyId = propertyId;
|
|
_oldValue = oldValue;
|
|
_newValue = newValue;
|
|
_applyValueAction = applyValueAction;
|
|
Description = $"속성 변경: {propertyName}";
|
|
}
|
|
|
|
public void Execute(object? parameter = null)
|
|
{
|
|
// 이미 PropertyWindow에서 값이 변경되었으므로
|
|
// 여기서는 추가 작업 없음 (RecordCommand용)
|
|
Debug.Log($"[PropertyChangeCommand] Execute: {_propertyId} = {_newValue}");
|
|
}
|
|
|
|
public void Undo(object? parameter = null)
|
|
{
|
|
_applyValueAction?.Invoke(_propertyId, _oldValue);
|
|
Debug.Log($"[PropertyChangeCommand] Undo: {_propertyId} = {_oldValue}");
|
|
}
|
|
|
|
public void Redo()
|
|
{
|
|
_applyValueAction?.Invoke(_propertyId, _newValue);
|
|
Debug.Log($"[PropertyChangeCommand] Redo: {_propertyId} = {_newValue}");
|
|
}
|
|
|
|
public bool CanMerge(IUndoableCommand other)
|
|
{
|
|
// 같은 속성에 대한 연속 변경은 병합
|
|
return other is PropertyChangeCommand otherCmd &&
|
|
otherCmd._propertyId == _propertyId;
|
|
}
|
|
|
|
public void Merge(IUndoableCommand other)
|
|
{
|
|
// 이 Command의 oldValue는 유지하고
|
|
// newValue만 최신으로 업데이트
|
|
// (불변 객체이므로 실제로는 새 Command 생성 필요하지만
|
|
// 여기서는 병합 시 새 값만 참조)
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Transform 속성 변경 전용 커맨드
|
|
/// Position, Rotation, Scale 변경 시 사용
|
|
/// </summary>
|
|
public class TransformPropertyChangeCommand : IUndoableCommand
|
|
{
|
|
public string Description { get; }
|
|
|
|
private readonly Transform _transform;
|
|
private readonly string _propertyType; // "position", "rotation", "scale"
|
|
private readonly Vector3 _oldValue;
|
|
private readonly Vector3 _newValue;
|
|
|
|
public TransformPropertyChangeCommand(
|
|
Transform transform,
|
|
string propertyType,
|
|
Vector3 oldValue,
|
|
Vector3 newValue)
|
|
{
|
|
_transform = transform;
|
|
_propertyType = propertyType.ToLower();
|
|
_oldValue = oldValue;
|
|
_newValue = newValue;
|
|
|
|
Description = _propertyType switch
|
|
{
|
|
"position" => "위치 변경",
|
|
"rotation" => "회전 변경",
|
|
"scale" => "크기 변경",
|
|
_ => "Transform 변경"
|
|
};
|
|
}
|
|
|
|
public void Execute(object? parameter = null)
|
|
{
|
|
ApplyValue(_newValue);
|
|
}
|
|
|
|
public void Undo(object? parameter = null)
|
|
{
|
|
ApplyValue(_oldValue);
|
|
Debug.Log($"[TransformPropertyChangeCommand] Undo: {_propertyType} = {_oldValue}");
|
|
}
|
|
|
|
public void Redo()
|
|
{
|
|
ApplyValue(_newValue);
|
|
Debug.Log($"[TransformPropertyChangeCommand] Redo: {_propertyType} = {_newValue}");
|
|
}
|
|
|
|
private void ApplyValue(Vector3 value)
|
|
{
|
|
if (_transform == null) return;
|
|
|
|
switch (_propertyType)
|
|
{
|
|
case "position":
|
|
_transform.localPosition = value;
|
|
break;
|
|
case "rotation":
|
|
_transform.localEulerAngles = value;
|
|
break;
|
|
case "scale":
|
|
_transform.localScale = value;
|
|
break;
|
|
}
|
|
|
|
// PropertyWindow UI 업데이트
|
|
UpdatePropertyWindowUI(value);
|
|
|
|
// Gizmo 새로고침
|
|
GizmoUndoBridge.Instance?.RefreshGizmos();
|
|
}
|
|
|
|
/// <summary>
|
|
/// PropertyWindow UI를 업데이트합니다.
|
|
/// </summary>
|
|
private void UpdatePropertyWindowUI(Vector3 value)
|
|
{
|
|
if (InjectorAppContext.Instance == null) return;
|
|
|
|
var propertyWindow = InjectorAppContext.Instance.Get<UTKPropertyTabListWindow>();
|
|
if (propertyWindow == null) return;
|
|
|
|
string propertyId = _propertyType switch
|
|
{
|
|
"position" => "transform_position",
|
|
"rotation" => "transform_rotation",
|
|
"scale" => "transform_scale",
|
|
_ => ""
|
|
};
|
|
|
|
if (!string.IsNullOrEmpty(propertyId))
|
|
{
|
|
propertyWindow.SetPropertyValue(propertyId, value);
|
|
}
|
|
}
|
|
|
|
public bool CanMerge(IUndoableCommand other)
|
|
{
|
|
// PropertyWindow에서의 변경은 각각 독립적인 Undo로 기록
|
|
// (병합하면 중간 상태가 손실됨)
|
|
return false;
|
|
}
|
|
|
|
public void Merge(IUndoableCommand other)
|
|
{
|
|
// 병합하지 않음
|
|
}
|
|
}
|
|
}
|