#nullable enable using System; using System.Collections.Generic; using UnityEngine; namespace UVC.UI.Tab { /// /// 전체 탭 시스템의 데이터를 관리하는 모델 클래스입니다. /// public class TabModel { // 모든 탭 목록 private List _tabs = new List(); // 현재 활성화된 탭의 인덱스 (-1은 활성화된 탭이 없음을 의미) private int _activeTabIndex = -1; private int _prevTabIndex = -1; // 탭 컨텐츠 인스턴스를 저장하는 Dictionary (키: tabID) private Dictionary _contentInstances = new Dictionary(); /// /// 현재 활성화된 탭 인덱스를 가져옵니다. /// public int ActiveTabIndex => _activeTabIndex; /// /// 이전에 선택된 탭 인덱스를 가져옵니다. /// public int PrevTabIndex => _prevTabIndex; /// /// 등록된 모든 탭의 목록을 가져옵니다. /// public IReadOnlyList Tabs => _tabs; /// /// 탭이 변경될 때 발생하는 이벤트입니다. /// public event Action? OnTabChanged; //활성화 탭 버튼을 클릭 시 해당 탭 비활성화 할지 여부 private bool togglableTab = false; public TabModel(bool togglableTab = false) { this.togglableTab = togglableTab; } /// /// 새로운 탭을 모델에 추가합니다. /// /// 추가할 탭 데이터 public void AddTab(TabData tab) { _tabs.Add(tab); // 첫 번째 추가된 탭을 기본 활성화 탭으로 설정 if (_activeTabIndex == -1 && _tabs.Count == 1 && !togglableTab) { _activeTabIndex = 0; } } /// /// 탭 인덱스로 탭을 전환합니다. /// /// 활성화할 탭의 인덱스 /// 탭 전환 시 전달할 데이터 (선택적) public void SwitchToTab(int tabIndex, object? updateData = null) { // 인덱스 범위 확인 if (tabIndex < 0 || tabIndex >= _tabs.Count) { Debug.LogWarning($"잘못된 탭 인덱스: {tabIndex}"); return; } // 같은 탭을 다시 선택한 경우 무시 if (_activeTabIndex == tabIndex) { if (!togglableTab) { return; } else { tabIndex = -1; } } Debug.Log($"탭 전환: {_activeTabIndex} -> {tabIndex}"); _prevTabIndex = _activeTabIndex; // 활성화 탭 인덱스 업데이트 _activeTabIndex = tabIndex; // 이벤트 발생 OnTabChanged?.Invoke(_activeTabIndex, updateData); } /// /// 탭 ID로 탭을 전환합니다. /// /// 활성화할 탭의 ID /// 탭 전환 시 전달할 데이터 (선택적) public void SwitchToTab(string tabID, object? updateData = null) { for (int i = 0; i < _tabs.Count; i++) { if (_tabs[i].tabID == tabID) { SwitchToTab(i, updateData); return; } } Debug.LogWarning($"해당 ID의 탭을 찾을 수 없음: {tabID}"); } /// /// 현재 활성화된 탭 데이터를 반환합니다. /// /// 활성화된 탭 데이터 또는 활성화된 탭이 없는 경우 null public TabData? GetActiveTab() { if (_activeTabIndex >= 0 && _activeTabIndex < _tabs.Count) { return _tabs[_activeTabIndex]; } return null; } /// /// 특정 탭의 contentData를 업데이트합니다. /// /// 업데이트할 탭의 ID /// 새로운 데이터 public void UpdateTabContentData(string tabID, object? newData) { for (int i = 0; i < _tabs.Count; i++) { if (_tabs[i].tabID == tabID) { _tabs[i].contentData = newData; break; } } } /// /// 특정 탭의 contentData를 업데이트합니다. /// /// 업데이트할 탭의 인덱스 /// 새로운 데이터 public void UpdateTabContentData(int tabIndex, object? newData) { if (tabIndex >= 0 && tabIndex < _tabs.Count) { _tabs[tabIndex].contentData = newData; } } /// /// 특정 탭의 컨텐츠 인스턴스를 저장합니다. /// /// 탭 ID /// 인스턴스화된 컨텐츠 GameObject public void SetContentInstance(string tabID, GameObject instance) { if (_contentInstances.ContainsKey(tabID)) { _contentInstances[tabID] = instance; } else { _contentInstances.Add(tabID, instance); } } /// /// 특정 탭의 컨텐츠 인스턴스를 가져옵니다. /// /// 탭 ID /// 컨텐츠 인스턴스 또는 인스턴스가 없는 경우 null public GameObject? GetContentInstance(string tabID) { if (_contentInstances.TryGetValue(tabID, out GameObject instance)) { return instance; } return null; } /// /// 인덱스로 특정 탭의 컨텐츠 인스턴스를 가져옵니다. /// /// 탭 인덱스 /// 컨텐츠 인스턴스 또는 인스턴스가 없는 경우 null public GameObject? GetContentInstance(int tabIndex) { if (tabIndex >= 0 && tabIndex < _tabs.Count) { return GetContentInstance(_tabs[tabIndex].tabID); } return null; } } }