ComponentList Tab 기능 추가
This commit is contained in:
@@ -26,7 +26,7 @@ namespace UVC.Factory.Tab
|
||||
public void Start()
|
||||
{
|
||||
// 1. TabConfig 설정
|
||||
tabController?.AddTabConfig("Explorer", "탐색기", "Prefabs/UI/Tab/TabContentComponentList", "Prefabs/UI/images/icon_side_tab_explorer_128", "탐색기", true);
|
||||
tabController?.AddTabConfig("Explorer", "탐색기", "Prefabs/UI/Tab/TabContentTabComponentList", "Prefabs/UI/images/icon_side_tab_explorer_128", "탐색기", true);
|
||||
tabController?.AddTabConfig("Library", "라이브러리", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/images/icon_side_tab_library_128", "라이브러리", true);
|
||||
tabController?.AddTabConfig("ResourceExplorer", "자원 탐색기", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/images/icon_side_tab_resource_128", "자원 탐색기", true);
|
||||
tabController?.AddTabConfig("FleetManager", "이동기 관리", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/images/icon_side_tab_fleet_128", "이동기 관리", true);
|
||||
|
||||
@@ -13,12 +13,13 @@ namespace UVC.Factory.Tab
|
||||
public class TabContentComponentList : MonoBehaviour, ITabContent
|
||||
{
|
||||
|
||||
// [SerializeField]는 Unity 에디터의 Inspector 창에서 이 변수를 직접 연결할 수 있게 해줍니다.
|
||||
// 이 창이 실제로 제어할 리스트 UI 컴포넌트를 가리킵니다.
|
||||
[Tooltip("실제 데이터 리스트를 표시하는 ComponentList UI 컴포넌트입니다.")]
|
||||
[SerializeField]
|
||||
protected ComponentList? componentList = null;
|
||||
|
||||
private string category = "ALL";
|
||||
|
||||
/// <summary>
|
||||
/// 이 컴포넌트가 처음 초기화될 때 호출됩니다. (SingletonScene의 일부)
|
||||
/// 'componentList' 변수에 필요한 컴포넌트를 찾아 할당하는 역할을 합니다.
|
||||
@@ -46,6 +47,15 @@ namespace UVC.Factory.Tab
|
||||
// 팩토리 내 모든 객체 정보를 카테고리별로 정렬하여 가져옵니다.
|
||||
var infos = FactoryObjectManager.Instance.GetFactoryObjectInfosByCategory();
|
||||
// 가져온 데이터를 ComponentList 컴포넌트에 전달하여 실제 UI 리스트를 생성하도록 합니다.
|
||||
if (category != "ALL" && infos.ContainsKey(category))
|
||||
{
|
||||
var filteredInfos = new SortedDictionary<string, List<FactoryObjectInfo>>
|
||||
{
|
||||
{ category, infos[category] }
|
||||
};
|
||||
componentList?.SetupData(filteredInfos);
|
||||
return;
|
||||
}
|
||||
componentList?.SetupData(infos);
|
||||
}
|
||||
|
||||
@@ -81,8 +91,7 @@ namespace UVC.Factory.Tab
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
var infos = FactoryObjectManager.Instance.GetFactoryObjectInfosByCategory();
|
||||
componentList?.SetupData(infos);
|
||||
SetupData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -91,7 +100,8 @@ namespace UVC.Factory.Tab
|
||||
/// <param name="data">전달할 데이터 객체</param>
|
||||
public void SetContentData(object? data)
|
||||
{
|
||||
Debug.Log("TabContentComponentList: SetContentData called");
|
||||
Debug.Log($"TabContentComponentList: SetContentData called. data:{data}");
|
||||
category = data as string ?? "ALL";
|
||||
SetupData();
|
||||
}
|
||||
|
||||
|
||||
78
Assets/Scripts/UVC/Factory/Tab/TabContentTabComponentList.cs
Normal file
78
Assets/Scripts/UVC/Factory/Tab/TabContentTabComponentList.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
#nullable enable
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UVC.Factory.Component;
|
||||
using UVC.UI.Tab;
|
||||
|
||||
namespace Assets.Scripts.UVC.Factory.Tab
|
||||
{
|
||||
public class TabContentTabComponentList : MonoBehaviour, ITabContent
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
private TabController? tabController;
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
if (tabController == null)
|
||||
{
|
||||
Debug.LogError("SideTabBar: TabController가 할당되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
var infos = FactoryObjectManager.Instance.GetFactoryObjectInfosByCategory();
|
||||
|
||||
// 1. TabConfig 설정
|
||||
tabController?.AddTabConfig("ALL", "ALL", "Prefabs/UI/Tab/TabContentComponentList", "", "ALL", true);
|
||||
foreach (var info in infos)
|
||||
{
|
||||
//info.Key 카테고리 이름
|
||||
tabController?.AddTabConfig(info.Key, info.Key, "Prefabs/UI/Tab/TabContentComponentList", "", info.Key, true);
|
||||
}
|
||||
|
||||
// 2. 컨트롤러 초기화
|
||||
tabController?.Initialize();
|
||||
|
||||
if (tabController != null)
|
||||
{
|
||||
tabController.OnTabChanged += (index) =>
|
||||
{
|
||||
Debug.Log($"탭이 변경되었습니다: {index}");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 탭 콘텐츠에 데이터를 전달합니다.
|
||||
/// </summary>
|
||||
/// <param name="data">전달할 데이터 객체</param>
|
||||
public void SetContentData(object? data)
|
||||
{
|
||||
Debug.Log("TabContentTabComponentList: SetContentData called");
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 탭 전환 시 데이터가 있는 경우 전달 되는 데이터. SetContentData 이후 호출 됨
|
||||
/// </summary>
|
||||
/// <param name="data">전달할 데이터 객체</param>
|
||||
public void UpdateContentData(object? data)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 닫힐 때 실행되는 로직을 처리합니다.
|
||||
/// </summary>
|
||||
/// <returns>비동기 닫기 작업을 나타내는 <see cref="UniTask"/>입니다.</returns>
|
||||
public UniTask OnCloseAsync()
|
||||
{
|
||||
Debug.Log("TabContentTabComponentList: OnClose called");
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28aaae2c78789f346a82a972ca52d44b
|
||||
@@ -62,7 +62,6 @@ namespace UVC.UI.List.ComponentList
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void OnDestroy()
|
||||
{
|
||||
if (inputField != null)
|
||||
@@ -87,42 +86,68 @@ namespace UVC.UI.List.ComponentList
|
||||
|
||||
if (inputField != null) inputField.text = string.Empty;
|
||||
|
||||
//toggle 않된 카테고리 찾기
|
||||
List<string> notExpendedCategory = new List<string>();
|
||||
if (scrollList.GetDataCount() > 0)
|
||||
{
|
||||
List<InfiniteScrollData> scrollDatalist = scrollList.GetDataList();
|
||||
foreach (var data in scrollDatalist)
|
||||
{
|
||||
if (data is ComponentListItemData itemData && itemData.isCategory)
|
||||
{
|
||||
itemData.OnCategoryExpendAction = null;
|
||||
if (!itemData.isExpanded) notExpendedCategory.Add(itemData.categoryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//transform.SetAsFirstSibling();
|
||||
scrollList.ClearData(); // 스크롤 리스트의 기존 데이터를 모두 비웁니다.
|
||||
|
||||
data?.Clear();
|
||||
if (data != null) data?.Clear();
|
||||
data = new List<ComponentListItemData>();
|
||||
|
||||
// 1. FactoryObjectManager에서 카테고리별로 그룹화된 객체 정보를 가져옵니다.
|
||||
//var infos = FactoryObjectManager.Instance.GetFactoryObjectInfosByCategory();
|
||||
|
||||
//보여주기 용 list
|
||||
List<ComponentListItemData> listData = new List<ComponentListItemData>();
|
||||
|
||||
// 2. 각 카테고리에 대해 루프를 돕니다.
|
||||
foreach (var info in objectsData)
|
||||
{
|
||||
bool isExpended = !notExpendedCategory.Contains(info.Key);
|
||||
// 2-1. 카테고리 아이템 데이터를 추가합니다.
|
||||
data.Add(new ComponentListItemData
|
||||
var categoryData = new ComponentListItemData
|
||||
{
|
||||
isCategory = true,
|
||||
categoryName = info.Key, // 카테고리 이름 (예: "전기 설비")
|
||||
categoryBadgeCount = info.Value.Count, // 해당 카테고리의 항목 수
|
||||
OnCategoryExpendAction = ToggleCategory // 액션 할당
|
||||
});
|
||||
OnCategoryExpendAction = ToggleCategory, // 액션 할당
|
||||
isExpanded = isExpended,
|
||||
};
|
||||
data.Add(categoryData);
|
||||
listData.Add(categoryData);
|
||||
|
||||
|
||||
// 2-2. 해당 카테고리에 속한 모든 일반 항목 데이터를 추가합니다.
|
||||
foreach (var item in info.Value)
|
||||
{
|
||||
data.Add(new ComponentListItemData
|
||||
var itemData = new ComponentListItemData
|
||||
{
|
||||
isCategory = false,
|
||||
generalName = item.Name, // 항목 이름 (예: "분전반")
|
||||
generalOption = item.Floor, // 항목 옵션 (예: "1F")
|
||||
factoryObjectInfo = item // 이 항목이 속한 카테고리 이름 (필터링을 위해 필요)
|
||||
});
|
||||
};
|
||||
data.Add(itemData);
|
||||
//카테고리가 축소된 상태라면, 자식 항목들을 추가하지 않고 다음 카테고리로 넘어갑니다.
|
||||
if (isExpended) listData.Add(itemData);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 완성된 데이터 리스트를 InfiniteScroll에 한 번에 삽입하여 UI를 업데이트합니다.
|
||||
scrollList.InsertData(data.ToArray());
|
||||
scrollList.InsertData(listData.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -134,15 +159,12 @@ namespace UVC.UI.List.ComponentList
|
||||
if (scrollList == null || data == null) return;
|
||||
|
||||
// 1. 현재 스크롤 리스트에서 토글할 카테고리의 인덱스를 찾습니다.
|
||||
int categoryIndex = -1;
|
||||
for (int i = 0; i < scrollList.GetDataCount(); i++)
|
||||
List<InfiniteScrollData> scrollDatalist = scrollList.GetDataList();
|
||||
int categoryIndex = scrollDatalist.FindIndex(0, (item) =>
|
||||
{
|
||||
if (scrollList.GetData(i) == categoryData)
|
||||
{
|
||||
categoryIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item is ComponentListItemData data) return data.categoryName == categoryData.categoryName;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (categoryIndex == -1) return; // 카테고리를 찾지 못하면 중단
|
||||
|
||||
|
||||
@@ -104,6 +104,9 @@ namespace UVC.UI.List.ComponentList
|
||||
// 카테고리 아이템일 경우
|
||||
categoryText.text = itemData.categoryName;
|
||||
categoryBageText.text = itemData.categoryBadgeCount.ToString();
|
||||
|
||||
// 애니메이션을 위해 현재 각도에서 목표 각도로 회전시킵니다.
|
||||
categoryExtendButton.transform.DORotate(new Vector3(0, 0, itemData.isExpanded ? 0 : 90), 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace UVC.UI.Tab
|
||||
[SerializeField] private TabContentConfig[] tabConfigs = new TabContentConfig[0];
|
||||
|
||||
[Tooltip("활성화 탭 버튼을 클릭 시 해당 탭 비활성화 할지 여부")]
|
||||
[SerializeField] private bool closableTab = false;
|
||||
[SerializeField] private bool togglableTab = false;
|
||||
|
||||
// 탭 모델
|
||||
private TabModel? _tabModel;
|
||||
@@ -89,7 +89,7 @@ namespace UVC.UI.Tab
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_tabModel = new TabModel(closableTab);
|
||||
_tabModel = new TabModel(togglableTab);
|
||||
if (initializeOnStart)
|
||||
{
|
||||
Initialize();
|
||||
@@ -153,7 +153,7 @@ namespace UVC.UI.Tab
|
||||
|
||||
// TabView에 설정 전달하여 초기화
|
||||
List<TabContentConfig> allConfigs = GetAllTabConfigs();
|
||||
tabView.InitializeTabs(_tabModel.Tabs, allConfigs, OnTabButtonSelected, closableTab);
|
||||
tabView.InitializeTabs(_tabModel.Tabs, allConfigs, OnTabButtonSelected, togglableTab);
|
||||
|
||||
// 모델 이벤트 구독
|
||||
_tabModel.OnTabChanged += HandleTabChanged;
|
||||
|
||||
@@ -40,11 +40,11 @@ namespace UVC.UI.Tab
|
||||
public event Action<int, object?>? OnTabChanged;
|
||||
|
||||
//활성화 탭 버튼을 클릭 시 해당 탭 비활성화 할지 여부
|
||||
private bool closableTab = false;
|
||||
private bool togglableTab = false;
|
||||
|
||||
public TabModel(bool closableTab = false)
|
||||
public TabModel(bool togglableTab = false)
|
||||
{
|
||||
this.closableTab = closableTab;
|
||||
this.togglableTab = togglableTab;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -56,7 +56,7 @@ namespace UVC.UI.Tab
|
||||
_tabs.Add(tab);
|
||||
|
||||
// 첫 번째 추가된 탭을 기본 활성화 탭으로 설정
|
||||
if (_activeTabIndex == -1 && _tabs.Count == 1 && !closableTab)
|
||||
if (_activeTabIndex == -1 && _tabs.Count == 1 && !togglableTab)
|
||||
{
|
||||
_activeTabIndex = 0;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ namespace UVC.UI.Tab
|
||||
// 같은 탭을 다시 선택한 경우 무시
|
||||
if (_activeTabIndex == tabIndex)
|
||||
{
|
||||
if (!closableTab)
|
||||
if (!togglableTab)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace UVC.UI.Tab
|
||||
|
||||
|
||||
//활성화 탭 버튼을 클릭 시 해당 탭 비활성화 할지 여부
|
||||
private bool closableTab = false;
|
||||
private bool togglableTab = false;
|
||||
|
||||
/// <summary>
|
||||
/// 탭 시스템을 초기화합니다.
|
||||
@@ -59,9 +59,10 @@ namespace UVC.UI.Tab
|
||||
/// <param name="tabs">탭 데이터 목록</param>
|
||||
/// <param name="configs">탭 설정 목록 (TabController에서 전달)</param>
|
||||
/// <param name="onTabSelected">탭 선택 시 호출될 콜백</param>
|
||||
public void InitializeTabs(IReadOnlyList<TabData> tabs, List<TabContentConfig> configs, Action<int> onTabSelected, bool closableTab = false)
|
||||
/// <param name="togglableTab">전체를 비활성화 할 수 있는지</param>
|
||||
public void InitializeTabs(IReadOnlyList<TabData> tabs, List<TabContentConfig> configs, Action<int> onTabSelected, bool togglableTab = false)
|
||||
{
|
||||
this.closableTab = closableTab;
|
||||
this.togglableTab = togglableTab;
|
||||
// 기존 탭 정리
|
||||
ClearTabs();
|
||||
|
||||
@@ -223,7 +224,7 @@ namespace UVC.UI.Tab
|
||||
/// <param name="updateData">업데이트할 데이터 (선택적)</param>
|
||||
public async UniTask UpdateActiveTab(int tabIndex, int prevTabIndex, TabData? tabData, object? updateData = null)
|
||||
{
|
||||
if ((tabIndex < 0 && !closableTab) || tabIndex >= _tabConfigs.Count) return;
|
||||
if ((tabIndex < 0 && !togglableTab) || tabIndex >= _tabConfigs.Count) return;
|
||||
if (tabIndex > -1 && tabData != null)
|
||||
{
|
||||
var config = _tabConfigs[tabIndex];
|
||||
|
||||
@@ -94,8 +94,7 @@ namespace UVC.UI.Window
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
var infos = FactoryObjectManager.Instance.GetFactoryObjectInfosByCategory();
|
||||
componentList?.SetupData(infos);
|
||||
SetupData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace UVC.UI.Window.PropertyWindow
|
||||
// UI를 다시 그리기 전에 기존에 생성된 모든 자식 오브젝트를 삭제합니다.
|
||||
foreach (Transform child in _container)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
DestroyImmediate(child.gameObject);
|
||||
}
|
||||
|
||||
if (_controller == null) return;
|
||||
|
||||
Reference in New Issue
Block a user