#nullable enable using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.EventSystems; using UVC.Core; using UVC.Factory; namespace UVC.UI.Window.PropertyWindow { /// /// 속성 데이터를 관리하고, 데이터 변경 시 이벤트를 발생시키는 컨트롤러 클래스입니다. /// Model과 View 사이의 중재자 역할을 합니다. /// public class PropertyWindow: SingletonScene, IPointerEnterHandler, IPointerExitHandler { [SerializeField] private PropertyView _view; /// /// 현재 컨트롤러가 관리하는 모든 속성 항목의 목록입니다. /// public List Properties { get; private set; } = new List(); /// /// 속성 값이 변경될 때 발생하는 이벤트입니다. /// View는 이 이벤트를 구독하여 UI를 업데이트할 수 있습니다. /// public event EventHandler? PropertyValueChanged; /// /// 새로운 속성 목록을 로드하고 초기화합니다. /// /// 표시할 속성 항목들의 목록 public void LoadProperties(List items) { Properties = items ?? new List(); // 필요하다면 여기서 추가적인 초기화 로직을 수행할 수 있습니다. if(_view != null) _view.Initialize(this); } /// /// 특정 ID를 가진 속성의 값을 업데이트합니다. /// 이 메서드는 주로 View에서 사용자 입력이 발생했을 때 호출됩니다. /// /// 값을 변경할 속성의 고유 ID /// 속성의 타입 /// 새로운 값 public void UpdatePropertyValue(string propertyId, PropertyType propertyType, object newValue) { // ID에 해당하는 속성을 찾습니다. var propertyItem = Properties.FirstOrDefault(p => p.Id == propertyId); if (propertyItem == null) { // 해당 ID의 속성이 없으면 오류를 기록하고 반환합니다. UnityEngine.Debug.LogError($"[PropertyWindow] ID '{propertyId}'에 해당하는 속성을 찾을 수 없습니다."); return; } // 이전 값을 저장합니다. object oldValue = propertyItem.GetValue(); // 값 타입일 때 새 값과 이전 값이 같은지 확인합니다. 참조 타입은 PropertyUI에서 필터링 (불필요한 이벤트 발생 방지) if (oldValue.GetType().IsValueType && Equals(oldValue, newValue)) { return; } // 속성 객체의 값을 새로운 값으로 설정합니다. propertyItem.SetValue(newValue); // 값이 변경되었음을 알리는 이벤트를 발생시킵니다. OnPropertyValueChanged(propertyId, propertyType, oldValue, newValue); } /// /// PropertyValueChanged 이벤트를 안전하게 발생시키는 보호된 가상 메서드입니다. /// /// 변경된 속성 ID /// 이전 값 /// 새로운 값 protected virtual void OnPropertyValueChanged(string propertyId, PropertyType propertyType, object oldValue, object newValue) { // 이벤트 핸들러가 등록되어 있는지 확인하고 이벤트를 발생시킵니다. PropertyValueChanged?.Invoke(this, new PropertyValueChangedEventArgs(propertyId, propertyType, oldValue, newValue)); } public bool IsVisible() { return gameObject.activeSelf; } public void Show() { gameObject.SetActive(true); } public void Hide() { gameObject.SetActive(false); } /// /// 마우스 포인터가 이 UI 요소의 영역 안으로 들어왔을 때 호출됩니다. /// UI와 상호작용하는 동안 3D 뷰의 카메라가 움직이지 않도록 컨트롤러를 비활성화합니다. /// public virtual void OnPointerEnter(PointerEventData eventData) { FactoryCameraController.Instance.Enable = false; // 카메라 컨트롤러 비활성화 } /// /// 마우스 포인터가 이 UI 요소의 영역 밖으로 나갔을 때 호출됩니다. /// 카메라 컨트롤을 다시 활성화하여 3D 뷰를 조작할 수 있도록 합니다. /// public virtual void OnPointerExit(PointerEventData eventData) { FactoryCameraController.Instance.Enable = true; // 카메라 컨트롤러 활성화 } } }