Files
XRLib/Assets/Scripts/UVC/UI/Tab/TabModel.cs
2025-09-26 12:01:35 +09:00

209 lines
6.9 KiB
C#

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