feat: Add ongoing event list view
This commit is contained in:
69
Assets/Cryville.Common/Unity/Tweener.cs
Normal file
69
Assets/Cryville.Common/Unity/Tweener.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Utils {
|
||||
public class PropertyTweener<T> {
|
||||
readonly Func<T> _getter;
|
||||
readonly Action<T> _setter;
|
||||
readonly Tweener<T> _tweener;
|
||||
public PropertyTweener(Func<T> getter, Action<T> setter, Tweener<T> tweener) {
|
||||
_getter = getter;
|
||||
_setter = setter;
|
||||
_tweener = tweener;
|
||||
}
|
||||
public PropertyTweener<T> Start(T endValue, float duration) {
|
||||
_tweener.Start(_getter(), endValue, duration);
|
||||
return this;
|
||||
}
|
||||
public void Advance(float deltaTime) {
|
||||
_setter(_tweener.Advance(deltaTime));
|
||||
}
|
||||
}
|
||||
public class Tweener<T> {
|
||||
readonly Func<T, T, T> _addition;
|
||||
readonly Func<float, T, T> _multiplication;
|
||||
public Tweener(Func<T, T, T> addition, Func<float, T, T> multiplication) {
|
||||
_addition = addition;
|
||||
_multiplication = multiplication;
|
||||
}
|
||||
public Func<float, float> EasingFunction { get; set; } = EasingFunctions.Linear;
|
||||
public Tweener<T> SetEasingFunction(Func<float, float> easing) {
|
||||
EasingFunction = easing;
|
||||
return this;
|
||||
}
|
||||
|
||||
T _startValue = default;
|
||||
T _endValue = default;
|
||||
float _duration = float.PositiveInfinity;
|
||||
float _time;
|
||||
public Tweener<T> Start(T startValue, T endValue, float duration) {
|
||||
_startValue = startValue;
|
||||
_endValue = endValue;
|
||||
_duration = duration;
|
||||
_time = 0;
|
||||
return this;
|
||||
}
|
||||
public T Advance(float deltaTime) {
|
||||
_time += deltaTime;
|
||||
var ratio = EasingFunction(Math.Clamp(_time / _duration, 0, 1));
|
||||
return _addition(_multiplication(1 - ratio, _startValue), _multiplication(ratio, _endValue));
|
||||
}
|
||||
}
|
||||
public static class Tweeners {
|
||||
public static Tweener<int> Int32 => new((a, b) => a + b, (k, v) => (int)(k * v));
|
||||
public static Tweener<float> Single => new((a, b) => a + b, (k, v) => k * v);
|
||||
public static Tweener<double> Double => new((a, b) => a + b, (k, v) => k * v);
|
||||
public static Tweener<Vector2> Vector2 => new((a, b) => a + b, (k, v) => k * v);
|
||||
public static Tweener<Vector3> Vector3 => new((a, b) => a + b, (k, v) => k * v);
|
||||
public static Tweener<Quaternion> Quaternion => new((a, b) => a * b, (k, v) => UnityEngine.Quaternion.Slerp(UnityEngine.Quaternion.identity, v, k));
|
||||
}
|
||||
public static class EasingFunctions {
|
||||
public static float Linear(float x) => x;
|
||||
public static float InQuad(float x) => x * x;
|
||||
public static float InCubic(float x) => x * x * x;
|
||||
public static float InSine(float x) => 1 - OutSine(1 - x);
|
||||
public static float OutQuad(float x) => 1 - InQuad(1 - x);
|
||||
public static float OutCubic(float x) => 1 - InCubic(1 - x);
|
||||
public static float OutSine(float x) => MathF.Sin(x * MathF.PI / 2);
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville.Common/Unity/Tweener.cs.meta
Normal file
11
Assets/Cryville.Common/Unity/Tweener.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d8c4d69179c5e644bd48565ec4c8258
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -6,18 +6,38 @@ 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);
|
||||
|
||||
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);
|
||||
|
||||
if (_displayingReports.Count == 0) {
|
||||
m_currentView.gameObject.SetActive(false);
|
||||
}
|
||||
@@ -25,8 +45,17 @@ namespace Cryville.EEW.Unity.UI {
|
||||
if (_index > index) --_index;
|
||||
else if (_index == index) SwitchTo(index % _displayingReports.Count);
|
||||
}
|
||||
|
||||
if (_displayingReports.Count <= 1) m_listView.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
void Awake() {
|
||||
if (Instance != null) {
|
||||
Destroy(this);
|
||||
throw new InvalidOperationException("Duplicate ongoing list view.");
|
||||
}
|
||||
Instance = this;
|
||||
}
|
||||
void Start() {
|
||||
m_currentView.gameObject.SetActive(false);
|
||||
}
|
||||
@@ -41,12 +70,20 @@ namespace Cryville.EEW.Unity.UI {
|
||||
}
|
||||
}
|
||||
void SwitchTo(int index) {
|
||||
if (_index < _displayingReports.Count)
|
||||
_displayingViews[_index].SetCurrent(false);
|
||||
_index = index;
|
||||
var e = _displayingReports[index];
|
||||
m_currentView.SetViewModel(e, true);
|
||||
var keyProp = e.Properties.FirstOrDefault();
|
||||
_displayingViews[_index].SetCurrent(true);
|
||||
_tickDown = Math.Max(0, keyProp?.Severity ?? 0) * 4 + 4;
|
||||
m_currentView.gameObject.SetActive(true);
|
||||
}
|
||||
public void SetCurrent(ReportViewModel viewModel) {
|
||||
int index = _displayingReports.IndexOf(viewModel);
|
||||
if (index == -1) return;
|
||||
SwitchTo(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
65
Assets/Cryville.EEW.Unity/UI/EventOngoingView.cs
Normal file
65
Assets/Cryville.EEW.Unity/UI/EventOngoingView.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using Cryville.Common.Unity.UI;
|
||||
using Cryville.EEW.Report;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Utils;
|
||||
using static UnityEditor.Profiling.HierarchyFrameDataView;
|
||||
|
||||
namespace Cryville.EEW.Unity.UI {
|
||||
class EventOngoingView : MonoBehaviour {
|
||||
[SerializeField] Image[] m_reportView;
|
||||
|
||||
[SerializeField] Button m_button;
|
||||
[SerializeField] TMPLocalizedText m_textView;
|
||||
|
||||
[SerializeField] DockOccupiedRatioLayoutGroup m_dockLayoutGroup;
|
||||
|
||||
ReportViewModel _viewModel;
|
||||
|
||||
void SetSeverity(float severity) {
|
||||
var color = SharedSettings.Instance.SeverityColorMapping.From(severity);
|
||||
SetMainColor(color.ToSrgb().ToUnityColor());
|
||||
}
|
||||
protected virtual void SetMainColor(Color color) {
|
||||
foreach (var view in m_reportView)
|
||||
view.color = color;
|
||||
}
|
||||
void SetView(float mainSeverity, string title, string location, CultureInfo culture) {
|
||||
SetSeverity(mainSeverity);
|
||||
SetText(m_textView, string.Format("{0} {1}", title, location), culture);
|
||||
}
|
||||
static void SetText(TMPLocalizedText view, string text, CultureInfo culture) {
|
||||
if (string.IsNullOrWhiteSpace(text)) {
|
||||
view.gameObject.SetActive(false);
|
||||
return;
|
||||
}
|
||||
view.gameObject.SetActive(true);
|
||||
view.SetText(text, culture);
|
||||
}
|
||||
|
||||
public void SetViewModel(ReportViewModel e) {
|
||||
_viewModel = e;
|
||||
SetView(e.Properties.FirstOrDefault()?.Severity ?? -1, e.Title, e.Location, e.Culture);
|
||||
}
|
||||
|
||||
PropertyTweener<float> _dockRatioTweener;
|
||||
void Awake() {
|
||||
_dockRatioTweener = new(() => m_dockLayoutGroup.DockOccupiedRatio, v => m_dockLayoutGroup.DockOccupiedRatio = v, Tweeners.Single);
|
||||
}
|
||||
void Start() {
|
||||
m_button.onClick.AddListener(OnViewClicked);
|
||||
}
|
||||
void OnViewClicked() {
|
||||
EventOngoingListView.Instance.SetCurrent(_viewModel);
|
||||
}
|
||||
void Update() {
|
||||
_dockRatioTweener.Advance(Time.deltaTime);
|
||||
}
|
||||
public void SetCurrent(bool v) {
|
||||
_dockRatioTweener.Start(v ? 1 : 0.75f, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Cryville.EEW.Unity/UI/EventOngoingView.cs.meta
Normal file
11
Assets/Cryville.EEW.Unity/UI/EventOngoingView.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a3acd791541c4345a6a5ca7dfa8f046
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -133,6 +133,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 234130748}
|
||||
- component: {fileID: 234130749}
|
||||
- component: {fileID: 234130750}
|
||||
m_Layer: 5
|
||||
m_Name: Current
|
||||
m_TagString: Untagged
|
||||
@@ -175,9 +176,9 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 6
|
||||
m_Right: 6
|
||||
m_Right: 0
|
||||
m_Top: 6
|
||||
m_Bottom: 6
|
||||
m_Bottom: 0
|
||||
m_ChildAlignment: 0
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 0
|
||||
@@ -185,6 +186,26 @@ MonoBehaviour:
|
||||
m_ChildControlHeight: 1
|
||||
m_ChildScaleWidth: 0
|
||||
m_ChildScaleHeight: 0
|
||||
--- !u!114 &234130750
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 234130747}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreLayout: 0
|
||||
m_MinWidth: -1
|
||||
m_MinHeight: 240
|
||||
m_PreferredWidth: -1
|
||||
m_PreferredHeight: -1
|
||||
m_FlexibleWidth: -1
|
||||
m_FlexibleHeight: -1
|
||||
m_LayoutPriority: 1
|
||||
--- !u!1 &239371813
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -583,11 +604,11 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 0
|
||||
m_Right: 0
|
||||
m_Right: 6
|
||||
m_Top: 0
|
||||
m_Bottom: 0
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 0
|
||||
m_Spacing: 16
|
||||
m_ChildForceExpandWidth: 0
|
||||
m_ChildForceExpandHeight: 0
|
||||
m_ChildControlWidth: 1
|
||||
@@ -608,6 +629,8 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_currentView: {fileID: 8447618677709876516}
|
||||
m_listView: {fileID: 917542012}
|
||||
m_prefabEventOngoingView: {fileID: 7245722805295636253, guid: 2310ef60ea9bf8244bbf5ba373c1de9c, type: 3}
|
||||
--- !u!1 &800505389
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -655,13 +678,14 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 917542012}
|
||||
- component: {fileID: 917542013}
|
||||
- component: {fileID: 917542014}
|
||||
m_Layer: 5
|
||||
m_Name: List
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
m_IsActive: 0
|
||||
--- !u!224 &917542012
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -677,10 +701,10 @@ RectTransform:
|
||||
m_Father: {fileID: 719162187}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 157, y: -176}
|
||||
m_SizeDelta: {x: 314, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &917542013
|
||||
MonoBehaviour:
|
||||
@@ -695,19 +719,39 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Padding:
|
||||
m_Left: 0
|
||||
m_Left: -16
|
||||
m_Right: 0
|
||||
m_Top: 0
|
||||
m_Bottom: 0
|
||||
m_ChildAlignment: 0
|
||||
m_Spacing: 0
|
||||
m_ChildForceExpandWidth: 0
|
||||
m_Spacing: 4
|
||||
m_ChildForceExpandWidth: 1
|
||||
m_ChildForceExpandHeight: 0
|
||||
m_ChildControlWidth: 1
|
||||
m_ChildControlHeight: 1
|
||||
m_ChildScaleWidth: 0
|
||||
m_ChildScaleHeight: 1
|
||||
m_ReverseArrangement: 0
|
||||
--- !u!114 &917542014
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 917542011}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreLayout: 0
|
||||
m_MinWidth: -1
|
||||
m_MinHeight: -1
|
||||
m_PreferredWidth: -1
|
||||
m_PreferredHeight: -1
|
||||
m_FlexibleWidth: 1
|
||||
m_FlexibleHeight: -1
|
||||
m_LayoutPriority: 1
|
||||
--- !u!1 &1345962671
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
790
Assets/Prefabs/UI/Event Ongoing.prefab
Normal file
790
Assets/Prefabs/UI/Event Ongoing.prefab
Normal file
File diff suppressed because it is too large
Load Diff
7
Assets/Prefabs/UI/Event Ongoing.prefab.meta
Normal file
7
Assets/Prefabs/UI/Event Ongoing.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2310ef60ea9bf8244bbf5ba373c1de9c
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user