165 lines
4.7 KiB
C#
165 lines
4.7 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using Simulator.Config;
|
|
using Simulator.Data;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UVC.Network;
|
|
|
|
namespace Simulator.UI
|
|
{
|
|
/// <summary>
|
|
/// 시뮬레이션 목록을 표시하는 View 스크립트
|
|
/// UI Prefab의 루트에 붙여서 사용합니다.
|
|
/// </summary>
|
|
public class SimulationListView : MonoBehaviour
|
|
{
|
|
[Header("리스트")]
|
|
[SerializeField] private Transform listContainer;
|
|
[SerializeField] private GameObject rowPrefab;
|
|
|
|
[Header("검색")]
|
|
[SerializeField] private TMP_InputField searchInput;
|
|
|
|
[Header("정보")]
|
|
[SerializeField] private TMP_Text dataCountText;
|
|
|
|
private List<SimulationRowData> allRows = new List<SimulationRowData>();
|
|
private List<SimulationListRowView> rowViews = new List<SimulationListRowView>();
|
|
|
|
private SimulationRowData selectedRow;
|
|
|
|
/// <summary>
|
|
/// 행 선택 시 호출되는 이벤트 (선택된 SimulationRowData 전달)
|
|
/// </summary>
|
|
public event Action<SimulationRowData> OnRowSelected;
|
|
|
|
private void OnEnable()
|
|
{
|
|
FetchSimulationList().Forget();
|
|
}
|
|
|
|
/// <summary>
|
|
/// API에서 시뮬레이션 목록을 가져옵니다.
|
|
/// </summary>
|
|
public async UniTaskVoid FetchSimulationList()
|
|
{
|
|
try
|
|
{
|
|
var response = await HttpRequester.RequestGet<SimulationListResponse>(
|
|
$"{Constants.HTTP_DOMAIN}/simulation/projects", null, null, true);
|
|
|
|
if (response?.data?.rows == null) return;
|
|
|
|
allRows = response.data.rows;
|
|
ApplyFilter();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"시뮬레이션 목록 조회 실패: {e.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 검색 필터를 적용하여 목록을 갱신합니다.
|
|
/// </summary>
|
|
public void ApplyFilter()
|
|
{
|
|
string keyword = searchInput != null ? searchInput.text.Trim() : "";
|
|
|
|
List<SimulationRowData> filtered;
|
|
if (string.IsNullOrEmpty(keyword))
|
|
{
|
|
filtered = allRows;
|
|
}
|
|
else
|
|
{
|
|
filtered = allRows.FindAll(row =>
|
|
row.name != null && row.name.Contains(keyword, StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
|
|
RenderRows(filtered);
|
|
|
|
if (dataCountText != null)
|
|
{
|
|
dataCountText.text = $"검색된 데이터 수: {filtered.Count} / {allRows.Count}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 행 UI를 생성/갱신합니다.
|
|
/// </summary>
|
|
private void RenderRows(List<SimulationRowData> rows)
|
|
{
|
|
// 기존 행 제거
|
|
foreach (var view in rowViews)
|
|
{
|
|
Destroy(view.gameObject);
|
|
}
|
|
rowViews.Clear();
|
|
selectedRow = null;
|
|
|
|
// 새로운 행 생성
|
|
foreach (var row in rows)
|
|
{
|
|
var go = Instantiate(rowPrefab, listContainer);
|
|
var rowView = go.GetComponent<SimulationListRowView>();
|
|
if (rowView != null)
|
|
{
|
|
rowView.SetData(row);
|
|
rowView.OnClicked += OnRowClicked;
|
|
rowViews.Add(rowView);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnRowClicked(SimulationListRowView rowView)
|
|
{
|
|
// 기존 선택 해제
|
|
foreach (var view in rowViews)
|
|
{
|
|
view.SetSelected(false);
|
|
}
|
|
|
|
// 새 선택
|
|
rowView.SetSelected(true);
|
|
selectedRow = rowView.Data;
|
|
OnRowSelected?.Invoke(selectedRow);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 현재 선택된 시뮬레이션 데이터를 반환합니다.
|
|
/// </summary>
|
|
public SimulationRowData GetSelectedRow()
|
|
{
|
|
return selectedRow;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 검색 InputField의 OnValueChanged에 연결할 수 있는 public 메서드
|
|
/// </summary>
|
|
public void OnSearchValueChanged(string value)
|
|
{
|
|
ApplyFilter();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 새로고침 버튼에 연결할 수 있는 public 메서드
|
|
/// </summary>
|
|
public void Refresh()
|
|
{
|
|
FetchSimulationList().Forget();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
foreach (var view in rowViews)
|
|
{
|
|
if (view != null)
|
|
view.OnClicked -= OnRowClicked;
|
|
}
|
|
}
|
|
}
|
|
}
|