This repository has been archived on 2025-08-02. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Cryville.EEW.Unity/Assets/Cryville.EEW.Unity/UI/EventOngoingListView.cs

108 lines
3.1 KiB
C#

using Cryville.EEW.Report;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Cryville.EEW.Unity.UI {
class EventOngoingListView : MonoBehaviour {
public static EventOngoingListView Instance { get; private set; }
[SerializeField] EventReportView m_currentView;
[SerializeField] Transform m_listView;
[SerializeField] EventOngoingView m_prefabEventOngoingView;
readonly List<ReportViewModel> _displayingReports = new();
readonly List<EventOngoingView> _displayingViews = new();
public void Add(ReportViewModel e) {
_displayingReports.Add(e);
var child = Instantiate(m_prefabEventOngoingView);
child.SetViewModel(e);
child.transform.SetParent(m_listView, false);
_displayingViews.Add(child);
OnDisplayingViewsChanged();
SwitchTo(_displayingReports.Count - 1);
if (_displayingReports.Count > 1) m_listView.gameObject.SetActive(true);
}
public void Remove(ReportViewModel e) {
int index = _displayingReports.IndexOf(e);
if (index == -1) return;
_displayingReports.RemoveAt(index);
var child = m_listView.GetChild(index);
child.SetParent(null, false);
Destroy(child.gameObject);
_displayingViews.RemoveAt(index);
OnDisplayingViewsChanged();
if (_displayingReports.Count == 0) {
m_currentView.gameObject.SetActive(false);
_index = -1;
}
else {
if (_index > index) --_index;
else if (_index == index) SwitchTo(index % _displayingReports.Count, true);
}
if (_displayingReports.Count <= 1) m_listView.gameObject.SetActive(false);
}
void OnDisplayingViewsChanged() {
_maxBaseDuration = 1;
foreach (var e in _displayingReports) {
float duration = GetBaseDuration(e);
if (duration > _maxBaseDuration)
_maxBaseDuration = duration;
}
}
void Awake() {
if (Instance != null) {
Destroy(this);
throw new InvalidOperationException("Duplicate ongoing list view.");
}
Instance = this;
}
void Start() {
m_currentView.gameObject.SetActive(false);
}
int _index = -1;
float _tickDown;
float _maxBaseDuration;
void Update() {
if (_displayingReports.Count == 0) return;
_tickDown -= Time.deltaTime;
if (_tickDown < 0) {
SwitchTo((_index + 1) % _displayingReports.Count);
}
}
void SwitchTo(int index, bool forced = false) {
if (!forced && _index == index) return;
if (_index < _displayingReports.Count && _index != -1)
_displayingViews[_index].SetCurrent(false);
_index = index;
var e = _displayingReports[index];
m_currentView.SetViewModel(e, true);
_displayingViews[_index].SetCurrent(true);
_tickDown = GetBaseDuration(e) / Math.Min(_maxBaseDuration, 4) * 4;
m_currentView.gameObject.SetActive(true);
Worker.Instance.SetCurrent(e);
}
static float GetBaseDuration(ReportViewModel e) {
return MathF.Exp(Math.Max(-1f, e.Properties.FirstOrDefault()?.Severity ?? -1f) + 1);
}
public void OnItemClicked(ReportViewModel viewModel) {
int index = _displayingReports.IndexOf(viewModel);
if (index == -1) return;
SwitchTo(index);
Worker.Instance.SetSelected(null);
}
}
}