디자인 적용
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
#nullable enable
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace UVC.UI.Tab
|
||||
{
|
||||
/// <summary>
|
||||
@@ -12,5 +14,11 @@ namespace UVC.UI.Tab
|
||||
/// </summary>
|
||||
/// <param name="data">전달할 데이터 객체</param>
|
||||
void SetContentData(object? data);
|
||||
|
||||
/// <summary>
|
||||
/// 닫힐 때 실행되는 로직을 처리합니다.
|
||||
/// </summary>
|
||||
/// <returns>비동기 닫기 작업을 나타내는 <see cref="UniTask"/>입니다.</returns>
|
||||
UniTask OnCloseAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UVC.Extention;
|
||||
|
||||
namespace UVC.UI.Tab
|
||||
{
|
||||
@@ -23,11 +24,17 @@ namespace UVC.UI.Tab
|
||||
[Tooltip("탭 배경 이미지 컴포넌트")]
|
||||
[SerializeField] private Image? background;
|
||||
|
||||
[Tooltip("탭이 활성화되었을 때의 색상")]
|
||||
[SerializeField] private Color? activeColor;// = Color.white;
|
||||
[Tooltip("탭이 활성화되었을 때의 배경 색상")]
|
||||
[SerializeField] private Color activeColor = Color.white;
|
||||
|
||||
[Tooltip("탭이 비활성화되었을 때의 색상")]
|
||||
[SerializeField] private Color? inactiveColor;// = new Color(0.8f, 0.8f, 0.8f);
|
||||
[Tooltip("탭이 비활성화되었을 때의 배경 색상")]
|
||||
[SerializeField] private Color inactiveColor = Color.gray;
|
||||
|
||||
[Tooltip("탭이 활성화되었을 때의 배경 색상")]
|
||||
[SerializeField] private Color activeTextColor = Color.black;
|
||||
|
||||
[Tooltip("탭이 비활성화되었을 때의 배경 색상")]
|
||||
[SerializeField] private Color inactiveTextColor = Color.white;
|
||||
|
||||
private int _tabIndex;
|
||||
private Action<int>? _onTabSelected;
|
||||
@@ -40,7 +47,10 @@ namespace UVC.UI.Tab
|
||||
|
||||
// 버튼 클릭 이벤트 연결
|
||||
if (button != null)
|
||||
{
|
||||
button.onClick.AddListener(OnButtonClick);
|
||||
button.transition = Selectable.Transition.None; // 버튼의 전환 효과를 비활성화
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -48,9 +58,9 @@ namespace UVC.UI.Tab
|
||||
/// </summary>
|
||||
/// <param name="index">탭 인덱스</param>
|
||||
/// <param name="tabName">탭 이름</param>
|
||||
/// <param name="icon">탭 아이콘</param>
|
||||
/// <param name="iconpath">탭 아이콘 경로</param>
|
||||
/// <param name="onSelectedCallback">탭 선택 시 호출될 콜백</param>
|
||||
public void Setup(int index, string tabName, Sprite? icon, Action<int> onSelectedCallback)
|
||||
public void Setup(int index, string tabName, string iconpath, Action<int> onSelectedCallback)
|
||||
{
|
||||
_tabIndex = index;
|
||||
_onTabSelected = onSelectedCallback;
|
||||
@@ -62,9 +72,9 @@ namespace UVC.UI.Tab
|
||||
// 탭 아이콘 설정
|
||||
if (tabIcon != null)
|
||||
{
|
||||
if (icon != null)
|
||||
if (!iconpath.IsNullOrEmpty())
|
||||
{
|
||||
tabIcon.sprite = icon;
|
||||
tabIcon.sprite = iconpath.LoadResource<Sprite>();
|
||||
tabIcon.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
@@ -81,18 +91,24 @@ namespace UVC.UI.Tab
|
||||
public void SetActive(bool isActive)
|
||||
{
|
||||
// 배경 색상 변경
|
||||
if (background != null && activeColor.HasValue && inactiveColor.HasValue)
|
||||
if (background != null)
|
||||
{
|
||||
background.color = isActive ? activeColor.Value : inactiveColor.Value;
|
||||
background.color = isActive ? activeColor : inactiveColor;
|
||||
}
|
||||
else if(button != null)
|
||||
{
|
||||
button.image.color = isActive ? button.colors.pressedColor : button.colors.normalColor;
|
||||
}
|
||||
|
||||
if(tabIcon != null)
|
||||
{
|
||||
tabIcon.color = isActive ? activeTextColor : inactiveTextColor;
|
||||
}
|
||||
|
||||
// 텍스트 스타일 변경
|
||||
if (tabText != null) {
|
||||
tabText.fontStyle = isActive ? FontStyles.Bold : FontStyles.Normal;
|
||||
tabText.color = isActive ? activeTextColor : inactiveTextColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +121,7 @@ namespace UVC.UI.Tab
|
||||
// 게임 오브젝트가 제거될 때 이벤트 리스너 제거
|
||||
private void OnDestroy()
|
||||
{
|
||||
_onTabSelected = null;
|
||||
if (button != null)
|
||||
button.onClick.RemoveListener(OnButtonClick);
|
||||
}
|
||||
|
||||
@@ -12,16 +12,16 @@ namespace UVC.UI.Tab
|
||||
public string tabID = "";
|
||||
public string tabName = "";
|
||||
public string contentPath = "";
|
||||
public Sprite? tabIcon = null;
|
||||
public string tabIconPath = "";
|
||||
public bool useLazyLoading = false;
|
||||
public object? initialData = null;
|
||||
|
||||
public TabContentConfig(string id, string name, string path, Sprite? icon = null, bool lazy = false, object? data = null)
|
||||
public TabContentConfig(string id, string name, string path, string iconPath = "", bool lazy = false, object? data = null)
|
||||
{
|
||||
tabID = id;
|
||||
tabName = name;
|
||||
contentPath = path;
|
||||
tabIcon = icon;
|
||||
tabIconPath = iconPath;
|
||||
useLazyLoading = lazy;
|
||||
initialData = data;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#nullable enable
|
||||
using Cysharp.Threading.Tasks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@@ -101,7 +102,7 @@ namespace UVC.UI.Tab
|
||||
/// <summary>
|
||||
/// 코드에서 탭 설정을 추가합니다.
|
||||
/// </summary>
|
||||
public bool AddTabConfig(string id, string name, string path, Sprite? icon = null, object? data = null, bool useLazyLoading = false)
|
||||
public bool AddTabConfig(string id, string name, string path, string iconPath = "", object? data = null, bool useLazyLoading = false)
|
||||
{
|
||||
if (_isInitialized)
|
||||
{
|
||||
@@ -109,7 +110,7 @@ namespace UVC.UI.Tab
|
||||
return false;
|
||||
}
|
||||
|
||||
var config = new TabContentConfig(id, name, path, icon, useLazyLoading, data);
|
||||
var config = new TabContentConfig(id, name, path, iconPath, useLazyLoading, data);
|
||||
_additionalTabConfigs.Add(config);
|
||||
return true;
|
||||
}
|
||||
@@ -182,7 +183,7 @@ namespace UVC.UI.Tab
|
||||
config.tabID,
|
||||
config.tabName,
|
||||
config.contentPath,
|
||||
config.tabIcon,
|
||||
config.tabIconPath,
|
||||
config.initialData
|
||||
));
|
||||
}
|
||||
@@ -207,10 +208,12 @@ namespace UVC.UI.Tab
|
||||
if (activeTabData == null) return;
|
||||
|
||||
// TabView에 탭 변경 전달
|
||||
tabView.UpdateActiveTab(newTabIndex, activeTabData);
|
||||
tabView.UpdateActiveTab(newTabIndex, _tabModel.PrevTabIndex, activeTabData).ContinueWith(() =>
|
||||
{
|
||||
// 외부 이벤트 발생
|
||||
OnTabChanged?.Invoke(newTabIndex);
|
||||
});
|
||||
|
||||
// 외부 이벤트 발생
|
||||
OnTabChanged?.Invoke(newTabIndex);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace UVC.UI.Tab
|
||||
public string tabID; // 탭 고유 식별자
|
||||
public string tabName; // 탭 표시 이름
|
||||
public string contentPath; // 탭 내용을 담고 있는 Prefab 경로 (Resources 폴더 기준)
|
||||
public Sprite? tabIcon; // 탭 아이콘 (선택사항, null 가능)
|
||||
public string tabIconPath; // 탭 아이콘 (선택사항, null 가능)
|
||||
public object? contentData; // 탭 콘텐츠에 전달할 데이터 객체 (null 가능)
|
||||
|
||||
// 프리팹 경로로 초기화하는 생성자
|
||||
@@ -23,14 +23,14 @@ namespace UVC.UI.Tab
|
||||
/// <param name="id">탭의 고유 식별자 (예: "inventory", "settings")</param>
|
||||
/// <param name="name">탭의 표시 이름 (예: "인벤토리", "설정")</param>
|
||||
/// <param name="path">탭 컨텐츠 프리팹의 리소스 경로 (예: "Prefabs/UI/InventoryTab")</param>
|
||||
/// <param name="icon">탭 아이콘 이미지 (선택사항)</param>
|
||||
/// <param name="iconPath">탭 아이콘 이미지 리소스 경로(선택사항)</param>
|
||||
/// <param name="data">탭 컨텐츠에 전달할 초기 데이터 (선택사항)</param>
|
||||
public TabData(string id, string name, string path, Sprite? icon = null, object? data = null)
|
||||
public TabData(string id, string name, string path, string iconPath = "", object? data = null)
|
||||
{
|
||||
tabID = id;
|
||||
tabName = name;
|
||||
contentPath = path;
|
||||
tabIcon = icon;
|
||||
tabIconPath = iconPath;
|
||||
contentData = data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace UVC.UI.Tab
|
||||
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>();
|
||||
@@ -23,6 +24,11 @@ namespace UVC.UI.Tab
|
||||
/// </summary>
|
||||
public int ActiveTabIndex => _activeTabIndex;
|
||||
|
||||
/// <summary>
|
||||
/// 이전에 선택된 탭 인덱스를 가져옵니다.
|
||||
/// </summary>
|
||||
public int PrevTabIndex => _prevTabIndex;
|
||||
|
||||
/// <summary>
|
||||
/// 등록된 모든 탭의 목록을 가져옵니다.
|
||||
/// </summary>
|
||||
@@ -66,6 +72,8 @@ namespace UVC.UI.Tab
|
||||
{
|
||||
return;
|
||||
}
|
||||
Debug.Log($"탭 전환: {_activeTabIndex} -> {tabIndex}");
|
||||
_prevTabIndex = _activeTabIndex;
|
||||
|
||||
// 활성화 탭 인덱스 업데이트
|
||||
_activeTabIndex = tabIndex;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#nullable enable
|
||||
using Cysharp.Threading.Tasks;
|
||||
using NUnit.Framework.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UVC.UI.Tab
|
||||
@@ -195,7 +198,7 @@ namespace UVC.UI.Tab
|
||||
}
|
||||
|
||||
// 탭 버튼 설정
|
||||
tabButton.Setup(index, tabData.tabName, tabData.tabIcon, OnTabButtonClicked);
|
||||
tabButton.Setup(index, tabData.tabName, tabData.tabIconPath, OnTabButtonClicked);
|
||||
_tabButtons.Add(tabButton);
|
||||
}
|
||||
|
||||
@@ -212,11 +215,11 @@ namespace UVC.UI.Tab
|
||||
/// 필요한 경우 컨텐츠를 로드합니다.
|
||||
/// </summary>
|
||||
/// <param name="tabIndex">활성화할 탭 인덱스</param>
|
||||
/// <param name="prevTabIndex">현재 활성화 된 탭 인덱스. 없으면 -1</param>
|
||||
/// <param name="tabData">탭 데이터</param>
|
||||
public void UpdateActiveTab(int tabIndex, TabData tabData)
|
||||
public async UniTask UpdateActiveTab(int tabIndex, int prevTabIndex, TabData tabData)
|
||||
{
|
||||
if (tabIndex < 0 || tabIndex >= _tabConfigs.Count) return;
|
||||
|
||||
var config = _tabConfigs[tabIndex];
|
||||
|
||||
// 컨텐츠가 아직 로드되지 않은 경우 로드
|
||||
@@ -243,6 +246,17 @@ namespace UVC.UI.Tab
|
||||
}
|
||||
}
|
||||
|
||||
//현재 활성화 된 탭의 컨텐츠가 있다면 OnClose 호출
|
||||
if (prevTabIndex > -1)
|
||||
{
|
||||
GameObject? contentInstance = _allContentInstances[prevTabIndex];
|
||||
if (contentInstance != null)
|
||||
{
|
||||
ITabContent? tabContent = contentInstance.GetComponent<ITabContent>();
|
||||
if (tabContent != null) await tabContent.OnCloseAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// 모든 컨텐츠 비활성화
|
||||
foreach (var content in _allContentInstances)
|
||||
{
|
||||
@@ -257,11 +271,8 @@ namespace UVC.UI.Tab
|
||||
activeContent.SetActive(true);
|
||||
|
||||
// 데이터 업데이트
|
||||
if (tabData.contentData != null)
|
||||
{
|
||||
ITabContent? tabContent = activeContent.GetComponent<ITabContent>();
|
||||
tabContent?.SetContentData(tabData.contentData);
|
||||
}
|
||||
ITabContent? tabContent = activeContent.GetComponent<ITabContent>();
|
||||
tabContent?.SetContentData(tabData.contentData);
|
||||
}
|
||||
|
||||
// 탭 버튼 상태 업데이트
|
||||
@@ -476,6 +487,20 @@ namespace UVC.UI.Tab
|
||||
|
||||
// 설정 클리어
|
||||
_tabConfigs.Clear();
|
||||
|
||||
_onTabButtonClicked = null;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
// 탭과 관련된 모든 리소스를 정리합니다.
|
||||
ClearTabs();
|
||||
// ContentLoader가 있다면 정리
|
||||
if (contentLoader != null)
|
||||
{
|
||||
contentLoader.ClearLazyContents();
|
||||
contentLoader = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user