732 lines
25 KiB
C#
732 lines
25 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
namespace UVC.UI.Window.PropertyWindow
|
|
{
|
|
/// <summary>
|
|
/// 속성 데이터를 관리하고, 데이터 변경 시 이벤트를 발생시키는 컨트롤러 클래스입니다.
|
|
/// Model과 View 사이의 중재자 역할을 합니다.
|
|
/// 그룹과 개별 아이템을 혼용하여 사용할 수 있습니다.
|
|
/// </summary>
|
|
public class PropertyWindow : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
private PropertyView _view;
|
|
|
|
#region Internal Data Structures
|
|
|
|
/// <summary>
|
|
/// 통합 엔트리 목록 (그룹과 개별 아이템 혼합 저장)
|
|
/// </summary>
|
|
private readonly List<IPropertyEntry> _entries = new List<IPropertyEntry>();
|
|
|
|
/// <summary>
|
|
/// 빠른 그룹 조회를 위한 인덱스
|
|
/// </summary>
|
|
private readonly Dictionary<string, IPropertyGroup> _groupIndex = new Dictionary<string, IPropertyGroup>();
|
|
|
|
/// <summary>
|
|
/// 빠른 아이템 조회를 위한 인덱스
|
|
/// </summary>
|
|
private readonly Dictionary<string, IPropertyItem> _itemIndex = new Dictionary<string, IPropertyItem>();
|
|
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// 현재 컨트롤러가 관리하는 모든 속성 항목의 목록입니다.
|
|
/// 하위 호환성을 위해 유지됩니다. 그룹에 속한 아이템도 포함됩니다.
|
|
/// </summary>
|
|
public List<IPropertyItem> Properties
|
|
{
|
|
get
|
|
{
|
|
var allItems = new List<IPropertyItem>();
|
|
foreach (var entry in _entries)
|
|
{
|
|
if (entry is IPropertyItem item && item.GroupId == null)
|
|
{
|
|
allItems.Add(item);
|
|
}
|
|
else if (entry is IPropertyGroup group)
|
|
{
|
|
allItems.AddRange(group.Items);
|
|
}
|
|
}
|
|
return allItems;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 정렬된 엔트리 목록을 반환합니다.
|
|
/// </summary>
|
|
public IReadOnlyList<IPropertyEntry> Entries => _entries.OrderBy(e => e.Order).ToList().AsReadOnly();
|
|
|
|
/// <summary>
|
|
/// 모든 그룹의 읽기 전용 목록을 반환합니다.
|
|
/// </summary>
|
|
public IReadOnlyList<IPropertyGroup> Groups => _groupIndex.Values.ToList().AsReadOnly();
|
|
|
|
#endregion
|
|
|
|
#region Events
|
|
|
|
/// <summary>
|
|
/// 속성 값이 변경될 때 발생하는 이벤트입니다.
|
|
/// </summary>
|
|
public event EventHandler<PropertyValueChangedEventArgs>? PropertyValueChanged;
|
|
|
|
/// <summary>
|
|
/// 그룹이 추가되었을 때 발생하는 이벤트입니다.
|
|
/// </summary>
|
|
public event EventHandler<PropertyGroupEventArgs>? GroupAdded;
|
|
|
|
/// <summary>
|
|
/// 그룹이 제거되었을 때 발생하는 이벤트입니다.
|
|
/// </summary>
|
|
public event EventHandler<PropertyGroupEventArgs>? GroupRemoved;
|
|
|
|
/// <summary>
|
|
/// 그룹의 펼침/접힘 상태가 변경되었을 때 발생하는 이벤트입니다.
|
|
/// </summary>
|
|
public event EventHandler<PropertyGroupExpandedEventArgs>? GroupExpandedChanged;
|
|
|
|
/// <summary>
|
|
/// 엔트리가 추가되었을 때 발생하는 이벤트입니다.
|
|
/// </summary>
|
|
public event EventHandler<PropertyEntryEventArgs>? EntryAdded;
|
|
|
|
/// <summary>
|
|
/// 엔트리가 제거되었을 때 발생하는 이벤트입니다.
|
|
/// </summary>
|
|
public event EventHandler<PropertyEntryEventArgs>? EntryRemoved;
|
|
|
|
/// <summary>
|
|
/// 모든 엔트리가 제거되었을 때 발생하는 이벤트입니다.
|
|
/// </summary>
|
|
public event EventHandler? EntriesCleared;
|
|
|
|
#endregion
|
|
|
|
#region Load Methods (기존 호환 + 그룹 + 혼용)
|
|
|
|
/// <summary>
|
|
/// [기존 방식] 그룹 없이 속성 목록을 로드합니다.
|
|
/// 모든 아이템이 flat하게 표시됩니다.
|
|
/// </summary>
|
|
/// <param name="items">표시할 속성 항목들의 목록</param>
|
|
public void LoadProperties(List<IPropertyItem> items)
|
|
{
|
|
Clear();
|
|
if (items != null)
|
|
{
|
|
foreach (var item in items)
|
|
{
|
|
item.GroupId = null; // 그룹 없음 명시
|
|
AddEntryInternal(item);
|
|
}
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// [그룹 방식] 그룹화된 속성 목록을 로드합니다.
|
|
/// </summary>
|
|
/// <param name="groups">표시할 속성 그룹들의 목록</param>
|
|
public void LoadGroupedProperties(List<IPropertyGroup> groups)
|
|
{
|
|
Clear();
|
|
if (groups != null)
|
|
{
|
|
foreach (var group in groups)
|
|
{
|
|
AddEntryInternal(group);
|
|
}
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// [혼용 방식] 그룹과 개별 아이템을 함께 로드합니다.
|
|
/// </summary>
|
|
/// <param name="entries">표시할 엔트리들의 목록 (그룹 또는 아이템)</param>
|
|
public void LoadMixedProperties(List<IPropertyEntry> entries)
|
|
{
|
|
Clear();
|
|
if (entries != null)
|
|
{
|
|
foreach (var entry in entries)
|
|
{
|
|
AddEntryInternal(entry);
|
|
}
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Group Management
|
|
|
|
/// <summary>
|
|
/// 그룹을 추가합니다.
|
|
/// </summary>
|
|
/// <param name="group">추가할 그룹</param>
|
|
public void AddGroup(IPropertyGroup group)
|
|
{
|
|
if (group == null)
|
|
throw new ArgumentNullException(nameof(group));
|
|
|
|
if (_groupIndex.ContainsKey(group.GroupId))
|
|
{
|
|
Debug.LogWarning($"[PropertyWindow] 이미 존재하는 그룹 ID입니다: {group.GroupId}");
|
|
return;
|
|
}
|
|
|
|
AddEntryInternal(group);
|
|
GroupAdded?.Invoke(this, new PropertyGroupEventArgs(group));
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 그룹을 제거합니다.
|
|
/// </summary>
|
|
/// <param name="groupId">제거할 그룹의 ID</param>
|
|
public void RemoveGroup(string groupId)
|
|
{
|
|
if (_groupIndex.TryGetValue(groupId, out var group))
|
|
{
|
|
// 그룹 내 모든 아이템의 GroupId 초기화 및 인덱스에서 제거
|
|
foreach (var item in group.Items)
|
|
{
|
|
item.GroupId = null;
|
|
_itemIndex.Remove(item.Id);
|
|
}
|
|
group.Clear();
|
|
|
|
_groupIndex.Remove(groupId);
|
|
_entries.Remove(group);
|
|
|
|
GroupRemoved?.Invoke(this, new PropertyGroupEventArgs(group));
|
|
Refresh();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 ID의 그룹을 가져옵니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
/// <returns>그룹 또는 null</returns>
|
|
public IPropertyGroup? GetGroup(string groupId)
|
|
{
|
|
_groupIndex.TryGetValue(groupId, out var group);
|
|
return group;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 그룹의 펼침/접힘 상태를 변경합니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
/// <param name="isExpanded">펼침 상태</param>
|
|
public void SetGroupExpanded(string groupId, bool isExpanded)
|
|
{
|
|
if (_groupIndex.TryGetValue(groupId, out var group))
|
|
{
|
|
bool wasExpanded = group.IsExpanded;
|
|
if (wasExpanded != isExpanded)
|
|
{
|
|
group.IsExpanded = isExpanded;
|
|
// 이벤트를 통해 PropertyView.OnGroupExpandedChanged()가 호출되어
|
|
// 부분적으로 UI를 업데이트합니다. 전체 Refresh()는 스크롤 위치를 초기화하므로 호출하지 않습니다.
|
|
GroupExpandedChanged?.Invoke(this, new PropertyGroupExpandedEventArgs(group, wasExpanded, isExpanded));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 그룹의 펼침/접힘 상태를 토글합니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
public void ToggleGroupExpanded(string groupId)
|
|
{
|
|
if (_groupIndex.TryGetValue(groupId, out var group))
|
|
{
|
|
SetGroupExpanded(groupId, !group.IsExpanded);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Property Management
|
|
|
|
/// <summary>
|
|
/// 개별 속성 아이템을 추가합니다 (그룹 없이).
|
|
/// </summary>
|
|
/// <param name="item">추가할 속성 아이템</param>
|
|
public void AddProperty(IPropertyItem item)
|
|
{
|
|
if (item == null)
|
|
throw new ArgumentNullException(nameof(item));
|
|
|
|
item.GroupId = null;
|
|
AddEntryInternal(item);
|
|
EntryAdded?.Invoke(this, new PropertyEntryEventArgs(item));
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 그룹에 속성 아이템을 추가합니다.
|
|
/// 그룹이 없으면 새로 생성합니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
/// <param name="item">추가할 속성 아이템</param>
|
|
/// <param name="groupNameIfNew">그룹이 새로 생성될 경우 사용할 이름 (null이면 groupId 사용)</param>
|
|
public void AddPropertyToGroup(string groupId, IPropertyItem item, string? groupNameIfNew = null)
|
|
{
|
|
if (string.IsNullOrEmpty(groupId))
|
|
throw new ArgumentNullException(nameof(groupId));
|
|
if (item == null)
|
|
throw new ArgumentNullException(nameof(item));
|
|
|
|
if (!_groupIndex.TryGetValue(groupId, out var group))
|
|
{
|
|
// 그룹이 없으면 새로 생성
|
|
group = new PropertyGroup(groupId, groupNameIfNew ?? groupId);
|
|
AddEntryInternal(group);
|
|
GroupAdded?.Invoke(this, new PropertyGroupEventArgs(group));
|
|
}
|
|
|
|
group.AddItem(item);
|
|
_itemIndex[item.Id] = item;
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 속성 아이템을 한번에 그룹에 추가합니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
/// <param name="items">추가할 속성 아이템들</param>
|
|
/// <param name="groupNameIfNew">그룹이 새로 생성될 경우 사용할 이름</param>
|
|
public void AddPropertiesToGroup(string groupId, IEnumerable<IPropertyItem> items, string? groupNameIfNew = null)
|
|
{
|
|
if (string.IsNullOrEmpty(groupId))
|
|
throw new ArgumentNullException(nameof(groupId));
|
|
if (items == null)
|
|
throw new ArgumentNullException(nameof(items));
|
|
|
|
if (!_groupIndex.TryGetValue(groupId, out var group))
|
|
{
|
|
group = new PropertyGroup(groupId, groupNameIfNew ?? groupId);
|
|
AddEntryInternal(group);
|
|
GroupAdded?.Invoke(this, new PropertyGroupEventArgs(group));
|
|
}
|
|
|
|
foreach (var item in items)
|
|
{
|
|
group.AddItem(item);
|
|
_itemIndex[item.Id] = item;
|
|
}
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 속성 아이템을 그룹에서 제거하고 독립 아이템으로 변경합니다.
|
|
/// </summary>
|
|
/// <param name="itemId">아이템 ID</param>
|
|
public void UngroupProperty(string itemId)
|
|
{
|
|
if (_itemIndex.TryGetValue(itemId, out var item) && item.GroupId != null)
|
|
{
|
|
if (_groupIndex.TryGetValue(item.GroupId, out var group))
|
|
{
|
|
group.RemoveItem(itemId);
|
|
}
|
|
item.GroupId = null;
|
|
AddEntryInternal(item); // 독립 엔트리로 추가
|
|
Refresh();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 속성 아이템을 제거합니다.
|
|
/// </summary>
|
|
/// <param name="itemId">제거할 아이템 ID</param>
|
|
public void RemoveProperty(string itemId)
|
|
{
|
|
if (_itemIndex.TryGetValue(itemId, out var item))
|
|
{
|
|
if (item.GroupId != null && _groupIndex.TryGetValue(item.GroupId, out var group))
|
|
{
|
|
group.RemoveItem(itemId);
|
|
}
|
|
else
|
|
{
|
|
_entries.Remove(item);
|
|
}
|
|
|
|
_itemIndex.Remove(itemId);
|
|
EntryRemoved?.Invoke(this, new PropertyEntryEventArgs(item));
|
|
Refresh();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 ID의 속성 아이템을 가져옵니다.
|
|
/// </summary>
|
|
/// <param name="itemId">아이템 ID</param>
|
|
/// <returns>속성 아이템 또는 null</returns>
|
|
public IPropertyItem? GetProperty(string itemId)
|
|
{
|
|
_itemIndex.TryGetValue(itemId, out var item);
|
|
return item;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Clear and Refresh
|
|
|
|
/// <summary>
|
|
/// 모든 엔트리를 제거합니다.
|
|
/// </summary>
|
|
public void Clear()
|
|
{
|
|
foreach (var group in _groupIndex.Values)
|
|
{
|
|
group.Clear();
|
|
}
|
|
_entries.Clear();
|
|
_groupIndex.Clear();
|
|
_itemIndex.Clear();
|
|
EntriesCleared?.Invoke(this, EventArgs.Empty);
|
|
|
|
// View 갱신하여 UI에서도 항목 제거
|
|
Refresh();
|
|
}
|
|
|
|
/// <summary>
|
|
/// View를 갱신합니다.
|
|
/// </summary>
|
|
public void Refresh()
|
|
{
|
|
if (_view != null)
|
|
{
|
|
_view.Initialize(this);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Value Update
|
|
|
|
/// <summary>
|
|
/// 특정 ID를 가진 속성의 값을 업데이트합니다.
|
|
/// 이 메서드는 주로 View에서 사용자 입력이 발생했을 때 호출됩니다.
|
|
/// </summary>
|
|
/// <param name="propertyId">값을 변경할 속성의 고유 ID</param>
|
|
/// <param name="propertyType">속성의 타입</param>
|
|
/// <param name="newValue">새로운 값</param>
|
|
public void UpdatePropertyValue(string propertyId, PropertyType propertyType, object newValue)
|
|
{
|
|
if (!_itemIndex.TryGetValue(propertyId, out var propertyItem))
|
|
{
|
|
Debug.LogError($"[PropertyWindow] ID '{propertyId}'에 해당하는 속성을 찾을 수 없습니다.");
|
|
return;
|
|
}
|
|
|
|
object? oldValue = propertyItem.GetValue();
|
|
|
|
// 값 타입일 때 새 값과 이전 값이 같은지 확인합니다.
|
|
if (oldValue != null && oldValue.GetType().IsValueType && Equals(oldValue, newValue))
|
|
{
|
|
return;
|
|
}
|
|
|
|
propertyItem.SetValue(newValue);
|
|
OnPropertyValueChanged(propertyId, propertyType, oldValue!, newValue);
|
|
}
|
|
|
|
/// <summary>
|
|
/// PropertyValueChanged 이벤트를 안전하게 발생시키는 보호된 가상 메서드입니다.
|
|
/// </summary>
|
|
protected virtual void OnPropertyValueChanged(string propertyId, PropertyType propertyType, object oldValue, object newValue)
|
|
{
|
|
PropertyValueChanged?.Invoke(this, new PropertyValueChangedEventArgs(propertyId, propertyType, oldValue, newValue));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 ID를 가진 속성의 값을 설정합니다.
|
|
/// 이 메서드는 Undo/Redo 시 값을 복원할 때 사용됩니다.
|
|
/// PropertyValueChanged 이벤트를 발생시키지 않습니다.
|
|
/// </summary>
|
|
/// <param name="propertyId">값을 변경할 속성의 고유 ID</param>
|
|
/// <param name="value">새로운 값</param>
|
|
/// <returns>값이 성공적으로 설정되었는지 여부</returns>
|
|
public bool SetPropertyValue(string propertyId, object? value)
|
|
{
|
|
if (!_itemIndex.TryGetValue(propertyId, out var propertyItem))
|
|
{
|
|
Debug.LogWarning($"[PropertyWindow] ID '{propertyId}'에 해당하는 속성을 찾을 수 없습니다.");
|
|
return false;
|
|
}
|
|
|
|
if (value != null)
|
|
{
|
|
propertyItem.SetValue(value);
|
|
|
|
// View에 값 반영 (UI 업데이트)
|
|
if (_view != null)
|
|
{
|
|
_view.UpdatePropertyValue(propertyId, value);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Internal Helpers
|
|
|
|
/// <summary>
|
|
/// 엔트리를 내부 컬렉션에 추가합니다.
|
|
/// </summary>
|
|
private void AddEntryInternal(IPropertyEntry entry)
|
|
{
|
|
if (entry is IPropertyGroup group)
|
|
{
|
|
if (!_groupIndex.ContainsKey(group.GroupId))
|
|
{
|
|
_groupIndex[group.GroupId] = group;
|
|
_entries.Add(group);
|
|
|
|
// 그룹 내 아이템들도 인덱스에 추가
|
|
foreach (var item in group.Items)
|
|
{
|
|
_itemIndex[item.Id] = item;
|
|
}
|
|
}
|
|
}
|
|
else if (entry is IPropertyItem item)
|
|
{
|
|
if (!_itemIndex.ContainsKey(item.Id))
|
|
{
|
|
_itemIndex[item.Id] = item;
|
|
if (item.GroupId == null)
|
|
{
|
|
_entries.Add(item);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Visibility
|
|
|
|
public bool IsVisible => gameObject.activeSelf;
|
|
|
|
public void Show()
|
|
{
|
|
gameObject.SetActive(true);
|
|
}
|
|
|
|
public void Hide()
|
|
{
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
public void ToggleVisibility()
|
|
{
|
|
gameObject.SetActive(!gameObject.activeSelf);
|
|
}
|
|
|
|
public void SetVisibility(bool visible)
|
|
{
|
|
gameObject.SetActive(visible);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Property/Group Visibility
|
|
|
|
/// <summary>
|
|
/// 특정 속성 아이템의 가시성을 설정합니다.
|
|
/// </summary>
|
|
/// <param name="propertyId">속성 아이템의 ID</param>
|
|
/// <param name="visible">가시성 여부</param>
|
|
public void SetPropertyVisibility(string propertyId, bool visible)
|
|
{
|
|
if (_view != null)
|
|
{
|
|
_view.SetPropertyVisibility(propertyId, visible);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 속성 아이템의 가시성을 한번에 설정합니다.
|
|
/// </summary>
|
|
/// <param name="propertyIds">속성 아이템 ID 목록</param>
|
|
/// <param name="visible">가시성 여부</param>
|
|
public void SetPropertiesVisibility(IEnumerable<string> propertyIds, bool visible)
|
|
{
|
|
if (_view != null && propertyIds != null)
|
|
{
|
|
foreach (var propertyId in propertyIds)
|
|
{
|
|
_view.SetPropertyVisibility(propertyId, visible);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 그룹의 가시성을 설정합니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
/// <param name="visible">가시성 여부</param>
|
|
public void SetGroupVisibility(string groupId, bool visible)
|
|
{
|
|
if (_view != null)
|
|
{
|
|
_view.SetGroupVisibility(groupId, visible);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 그룹의 가시성을 한번에 설정합니다.
|
|
/// </summary>
|
|
/// <param name="groupIds">그룹 ID 목록</param>
|
|
/// <param name="visible">가시성 여부</param>
|
|
public void SetGroupsVisibility(IEnumerable<string> groupIds, bool visible)
|
|
{
|
|
if (_view != null && groupIds != null)
|
|
{
|
|
foreach (var groupId in groupIds)
|
|
{
|
|
_view.SetGroupVisibility(groupId, visible);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Property/Group ReadOnly (Enable/Disable)
|
|
|
|
/// <summary>
|
|
/// 특정 속성 아이템의 읽기 전용 상태를 설정합니다.
|
|
/// </summary>
|
|
/// <param name="propertyId">속성 아이템의 ID</param>
|
|
/// <param name="isReadOnly">읽기 전용 여부 (true: 비활성화, false: 활성화)</param>
|
|
public void SetPropertyReadOnly(string propertyId, bool isReadOnly)
|
|
{
|
|
if (_itemIndex.TryGetValue(propertyId, out var item))
|
|
{
|
|
item.IsReadOnly = isReadOnly;
|
|
if (_view != null)
|
|
{
|
|
_view.SetPropertyReadOnly(propertyId, isReadOnly);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 속성 아이템의 활성화 상태를 설정합니다.
|
|
/// SetPropertyReadOnly의 반대 동작입니다.
|
|
/// </summary>
|
|
/// <param name="propertyId">속성 아이템의 ID</param>
|
|
/// <param name="enabled">활성화 여부 (true: 활성화, false: 비활성화)</param>
|
|
public void SetPropertyEnabled(string propertyId, bool enabled)
|
|
{
|
|
SetPropertyReadOnly(propertyId, !enabled);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 속성 아이템의 읽기 전용 상태를 한번에 설정합니다.
|
|
/// </summary>
|
|
/// <param name="propertyIds">속성 아이템 ID 목록</param>
|
|
/// <param name="isReadOnly">읽기 전용 여부</param>
|
|
public void SetPropertiesReadOnly(IEnumerable<string> propertyIds, bool isReadOnly)
|
|
{
|
|
if (propertyIds != null)
|
|
{
|
|
foreach (var propertyId in propertyIds)
|
|
{
|
|
SetPropertyReadOnly(propertyId, isReadOnly);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 속성 아이템의 활성화 상태를 한번에 설정합니다.
|
|
/// </summary>
|
|
/// <param name="propertyIds">속성 아이템 ID 목록</param>
|
|
/// <param name="enabled">활성화 여부</param>
|
|
public void SetPropertiesEnabled(IEnumerable<string> propertyIds, bool enabled)
|
|
{
|
|
SetPropertiesReadOnly(propertyIds, !enabled);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 그룹 내 모든 속성 아이템의 읽기 전용 상태를 설정합니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
/// <param name="isReadOnly">읽기 전용 여부</param>
|
|
public void SetGroupReadOnly(string groupId, bool isReadOnly)
|
|
{
|
|
if (_groupIndex.TryGetValue(groupId, out var group))
|
|
{
|
|
foreach (var item in group.Items)
|
|
{
|
|
item.IsReadOnly = isReadOnly;
|
|
if (_view != null)
|
|
{
|
|
_view.SetPropertyReadOnly(item.Id, isReadOnly);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 그룹 내 모든 속성 아이템의 활성화 상태를 설정합니다.
|
|
/// SetGroupReadOnly의 반대 동작입니다.
|
|
/// </summary>
|
|
/// <param name="groupId">그룹 ID</param>
|
|
/// <param name="enabled">활성화 여부</param>
|
|
public void SetGroupEnabled(string groupId, bool enabled)
|
|
{
|
|
SetGroupReadOnly(groupId, !enabled);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 그룹 내 모든 속성 아이템의 읽기 전용 상태를 한번에 설정합니다.
|
|
/// </summary>
|
|
/// <param name="groupIds">그룹 ID 목록</param>
|
|
/// <param name="isReadOnly">읽기 전용 여부</param>
|
|
public void SetGroupsReadOnly(IEnumerable<string> groupIds, bool isReadOnly)
|
|
{
|
|
if (groupIds != null)
|
|
{
|
|
foreach (var groupId in groupIds)
|
|
{
|
|
SetGroupReadOnly(groupId, isReadOnly);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 여러 그룹 내 모든 속성 아이템의 활성화 상태를 한번에 설정합니다.
|
|
/// </summary>
|
|
/// <param name="groupIds">그룹 ID 목록</param>
|
|
/// <param name="enabled">활성화 여부</param>
|
|
public void SetGroupsEnabled(IEnumerable<string> groupIds, bool enabled)
|
|
{
|
|
SetGroupsReadOnly(groupIds, !enabled);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|