init
This commit is contained in:
+102
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
using Com.ForbiddenByte.OSA.CustomParams;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.CustomAdapters.DateTimePicker
|
||||
{
|
||||
/// <summary>Implementing multiple adapters to get a generic picker which returns a <see cref="DateTime"/> object</summary>
|
||||
public class DateTimePickerAdapter : OSA<MyParams, MyItemViewsHolder>
|
||||
{
|
||||
public int SelectedValue { get; private set; }
|
||||
public event Action<int> OnSelectedValueChanged;
|
||||
|
||||
|
||||
#region OSA implementation
|
||||
/// <inheritdoc/>
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (!IsInitialized)
|
||||
return;
|
||||
|
||||
if (VisibleItemsCount == 0)
|
||||
return;
|
||||
|
||||
int middleVHIndex = VisibleItemsCount / 2;
|
||||
var middleVH = GetItemViewsHolder(middleVHIndex);
|
||||
|
||||
var prevValue = SelectedValue;
|
||||
SelectedValue = _Params.GetItemValueAtIndex(middleVH.ItemIndex);
|
||||
middleVH.background.CrossFadeColor(_Params.selectedColor, .1f, false, false);
|
||||
|
||||
for (int i = 0; i < VisibleItemsCount; ++i)
|
||||
{
|
||||
if (i != middleVHIndex)
|
||||
GetItemViewsHolder(i).background.CrossFadeColor(_Params.nonSelectedColor, .1f, false, false);
|
||||
}
|
||||
|
||||
if (prevValue != SelectedValue && OnSelectedValueChanged != null)
|
||||
OnSelectedValueChanged(SelectedValue);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override MyItemViewsHolder CreateViewsHolder(int itemIndex)
|
||||
{
|
||||
var instance = new MyItemViewsHolder();
|
||||
instance.Init(_Params.ItemPrefab, _Params.Content, itemIndex);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void UpdateViewsHolder(MyItemViewsHolder newOrRecycled) { newOrRecycled.titleText.text = _Params.GetItemValueAtIndex(newOrRecycled.ItemIndex) + ""; }
|
||||
#endregion
|
||||
|
||||
void ChangeItemsCountWithChecks(int newCount)
|
||||
{
|
||||
int min = 4;
|
||||
if (newCount < min)
|
||||
newCount = min;
|
||||
|
||||
ResetItems(newCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable] // serializable, so it can be shown in inspector
|
||||
public class MyParams : BaseParamsWithPrefab
|
||||
{
|
||||
public int startItemNumber = 0;
|
||||
public int increment = 1;
|
||||
public Color selectedColor, nonSelectedColor;
|
||||
|
||||
/// <summary>The value of each item is calculated dynamically using its <paramref name="index"/>, <see cref="startItemNumber"/> and the <see cref="increment"/></summary>
|
||||
/// <returns>The item's value (the displayed number)</returns>
|
||||
public int GetItemValueAtIndex(int index) { return startItemNumber + increment * index; }
|
||||
}
|
||||
|
||||
|
||||
public class MyItemViewsHolder : BaseItemViewsHolder
|
||||
{
|
||||
public Image background;
|
||||
public Text titleText;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void CollectViews()
|
||||
{
|
||||
base.CollectViews();
|
||||
|
||||
background = root.GetComponent<Image>();
|
||||
titleText = root.GetComponentInChildren<Text>();
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1cc6a6937df8c046943043e53538154
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using frame8.Logic.Misc.Other.Extensions;
|
||||
using Com.ForbiddenByte.OSA.Core;
|
||||
|
||||
namespace Com.ForbiddenByte.OSA.CustomAdapters.DateTimePicker
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementing multiple adapters to get a generic picker which returns a <see cref="DateTime"/> object.
|
||||
/// There are 2 ways of using this script: either simply call <see cref="Show(Action{DateTime})"/>
|
||||
/// or drag and drop the prefab from /Resources/Com.ForbiddenByte.OSA/DateTimePickerDialog into your scene and subscribe to <see cref="OnDateSelected"/>
|
||||
/// </summary>
|
||||
public class DateTimePickerDialog : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
bool _AutoInit = false;
|
||||
[SerializeField]
|
||||
bool _DisplaySelectedDateAsShort = false;
|
||||
[SerializeField]
|
||||
bool _DisplaySelectedTimeAsShort = false;
|
||||
[Tooltip("If true, animations won't be affected by Time.timeScale")]
|
||||
[SerializeField]
|
||||
bool _UseUnscaledTime = true;
|
||||
|
||||
public event Action<DateTime> OnDateSelected;
|
||||
|
||||
public DateTimePickerAdapter DayAdapter { get; private set; }
|
||||
public DateTimePickerAdapter MonthAdapter { get; private set; }
|
||||
public DateTimePickerAdapter YearAdapter { get; private set; }
|
||||
|
||||
public DateTimePickerAdapter HourAdapter { get; private set; }
|
||||
public DateTimePickerAdapter MinuteAdapter { get; private set; }
|
||||
public DateTimePickerAdapter SecondAdapter { get; private set; }
|
||||
|
||||
public DateTime SelectedValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return new DateTime(
|
||||
YearAdapter.SelectedValue, MonthAdapter.SelectedValue, DayAdapter.SelectedValue,
|
||||
HourAdapter.SelectedValue, MinuteAdapter.SelectedValue, SecondAdapter.SelectedValue
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const float SCROLL_DURATION1 = .2f;
|
||||
const float SCROLL_DURATION2 = .35f;
|
||||
const float SCROLL_DURATION3 = .5f;
|
||||
const float ANIM_DURATION = .25f;
|
||||
const float DEFAULT_WIDTH = 660f, DEFAULT_HEIGHT = DEFAULT_WIDTH / 2;
|
||||
|
||||
float AnimElapsedTime01 { get { float t = Mathf.Clamp01((Time - _AnimStartTime) / ANIM_DURATION); return t * t * t * t; } }
|
||||
//Vector3 AnimCurrentScale { get { return Vector3.Lerp(_AnimStart, _AnimEnd, AnimElapsedTime01); } }
|
||||
float AnimCurrentFloat { get { return Mathf.Lerp(_AnimStart, _AnimEnd, AnimElapsedTime01); } }
|
||||
|
||||
float Time { get { return _UseUnscaledTime ? UnityEngine.Time.unscaledTime : UnityEngine.Time.time; } }
|
||||
|
||||
Transform _DatePanel, _TimePanel;
|
||||
Text _SelectedDateText, _SelectedTimeText;
|
||||
bool _Initialized;
|
||||
DateTime? _DateToInitWith;
|
||||
bool _Animating;
|
||||
//Vector3 _AnimStart, _AnimEnd;
|
||||
float _AnimStart, _AnimEnd;
|
||||
float _AnimStartTime;
|
||||
Action _ActionOnAnimDone;
|
||||
CanvasGroup _CanvasGroup;
|
||||
DateTimePickerAdapter[] _AllAdapters = new DateTimePickerAdapter[6];
|
||||
|
||||
|
||||
public static DateTimePickerDialog Show(Action<DateTime> onSelected)
|
||||
{
|
||||
return Show(DateTime.Now, onSelected);
|
||||
}
|
||||
|
||||
public static DateTimePickerDialog Show(Action<DateTime> onSelected, string prefabPathInResources)
|
||||
{
|
||||
return Show(DateTime.Now, onSelected, prefabPathInResources);
|
||||
}
|
||||
|
||||
public static DateTimePickerDialog Show(DateTime startingDate, Action<DateTime> onSelected)
|
||||
{
|
||||
return Show(startingDate, onSelected, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||
}
|
||||
|
||||
public static DateTimePickerDialog Show(DateTime startingDate, Action<DateTime> onSelected, string prefabPathInResources)
|
||||
{
|
||||
return Show(startingDate, onSelected, DEFAULT_WIDTH, DEFAULT_HEIGHT, prefabPathInResources);
|
||||
}
|
||||
|
||||
public static DateTimePickerDialog Show(DateTime startingDate, Action<DateTime> onSelected, float width, float height)
|
||||
{
|
||||
var prefabPathInResources = OSAConst.OSA_PATH_IN_RESOURCES + "/" + typeof(DateTimePickerDialog).Name;
|
||||
return Show(startingDate, onSelected, width, height, prefabPathInResources);
|
||||
}
|
||||
|
||||
public static DateTimePickerDialog Show(DateTime startingDate, Action<DateTime> onSelected, float width, float height, string prefabPathInResources)
|
||||
{
|
||||
var go = Resources.Load<GameObject>(prefabPathInResources);
|
||||
var picker = (Instantiate(go) as GameObject).GetComponent<DateTimePickerDialog>();
|
||||
var c = FindObjectOfType<Canvas>();
|
||||
if (!c)
|
||||
throw new OSAException(typeof(DateTimePickerDialog).Name + ": no Canvas was found in the scene");
|
||||
var canvasRT = c.transform as RectTransform;
|
||||
var rt = (picker.transform as RectTransform);
|
||||
rt.SetParent(canvasRT, false);
|
||||
rt.SetAsLastSibling();
|
||||
picker._DateToInitWith = startingDate;
|
||||
if (onSelected != null)
|
||||
picker.OnDateSelected += onSelected;
|
||||
|
||||
rt.SetInsetAndSizeFromParentEdgeWithCurrentAnchors(RectTransform.Edge.Left, (canvasRT.rect.width - width) / 2, width);
|
||||
rt.SetInsetAndSizeFromParentEdgeWithCurrentAnchors(RectTransform.Edge.Top, (canvasRT.rect.height - height) / 2, height);
|
||||
|
||||
return picker;
|
||||
}
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
_CanvasGroup = GetComponent<CanvasGroup>();
|
||||
_CanvasGroup.alpha = 0f;
|
||||
_AnimEnd = 1f;
|
||||
_AnimStartTime = Time;
|
||||
_Animating = true;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
var adaptersTR = transform.Find("Adapters");
|
||||
_DatePanel = adaptersTR.Find("Date");
|
||||
_DatePanel.GetComponentAtPath("SelectedIndicatorText", out _SelectedDateText);
|
||||
int i = 0;
|
||||
_AllAdapters[i++] = DayAdapter = _DatePanel.GetComponentAtPath<DateTimePickerAdapter>("Panel/Day");
|
||||
_AllAdapters[i++] = MonthAdapter = _DatePanel.GetComponentAtPath<DateTimePickerAdapter>("Panel/Month");
|
||||
_AllAdapters[i++] = YearAdapter = _DatePanel.GetComponentAtPath<DateTimePickerAdapter>("Panel/Year");
|
||||
_TimePanel = adaptersTR.Find("Time");
|
||||
_TimePanel.GetComponentAtPath("SelectedIndicatorText", out _SelectedTimeText);
|
||||
_AllAdapters[i++] = HourAdapter = _TimePanel.GetComponentAtPath<DateTimePickerAdapter>("Panel/Hour");
|
||||
_AllAdapters[i++] = MinuteAdapter = _TimePanel.GetComponentAtPath<DateTimePickerAdapter>("Panel/Minute");
|
||||
_AllAdapters[i++] = SecondAdapter = _TimePanel.GetComponentAtPath<DateTimePickerAdapter>("Panel/Second");
|
||||
|
||||
for (i = 0; i < _AllAdapters.Length; ++i)
|
||||
_AllAdapters[i].Parameters.UseUnscaledTime = _UseUnscaledTime;
|
||||
|
||||
if (_AutoInit)
|
||||
ExecuteAfter(.2f, AutoInit);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (_Animating)
|
||||
{
|
||||
//transform.localScale = AnimCurrentFloat;
|
||||
_CanvasGroup.alpha = AnimCurrentFloat;
|
||||
|
||||
if (AnimElapsedTime01 == 1f)
|
||||
{
|
||||
_Animating = false;
|
||||
if (_ActionOnAnimDone != null)
|
||||
_ActionOnAnimDone();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_Initialized)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var current = SelectedValue;
|
||||
_SelectedDateText.text = _DisplaySelectedDateAsShort ? current.ToShortDateString() : current.ToLongDateString();
|
||||
_SelectedTimeText.text = _DisplaySelectedTimeAsShort ? current.ToShortTimeString() : current.ToLongTimeString();
|
||||
}
|
||||
catch /*(Exception e)*/{
|
||||
//Debug.Log(e + "\n"+YearAdapter.SelectedValue + "," + MonthAdapter.SelectedValue + "," + DayAdapter.SelectedValue + "," +
|
||||
//HourAdapter.SelectedValue + "," + MinuteAdapter.SelectedValue + "," + SecondAdapter.SelectedValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitWithNow() { InitWithDate(DateTime.Now); }
|
||||
|
||||
public void InitWithDate(DateTime dateTime)
|
||||
{
|
||||
StopAnimations();
|
||||
_DateToInitWith = null;
|
||||
UnregisterAutoCorrection();
|
||||
|
||||
int doneNum = 0;
|
||||
int targetDone = 2;
|
||||
Action onDone = () =>
|
||||
{
|
||||
if (++doneNum == targetDone)
|
||||
{
|
||||
_Initialized = true;
|
||||
RegisterAutoCorrection();
|
||||
}
|
||||
};
|
||||
|
||||
//Func<float, bool> onProgress = p01 =>
|
||||
//{
|
||||
// if (p01 == 1f)
|
||||
// {
|
||||
// if (++doneNum == targetDone)
|
||||
// {
|
||||
// _Initialized = true;
|
||||
// RegisterAutoCorrection();
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
//};
|
||||
|
||||
YearAdapter.ResetItems(3000);
|
||||
YearAdapter.SmoothScrollTo(dateTime.Year - 1, SCROLL_DURATION1, .5f, .5f);
|
||||
MonthAdapter.ResetItems(12);
|
||||
MonthAdapter.SmoothScrollTo(dateTime.Month - 1, SCROLL_DURATION2, .5f, .5f);
|
||||
DayAdapter.ResetItems(DateTime.DaysInMonth(dateTime.Year, dateTime.Month));
|
||||
//DayAdapter.SmoothScrollTo(dateTime.Day - 1, SCROLL_DURATION3, .5f, .5f, onProgress, null, true);
|
||||
DayAdapter.SmoothScrollTo(dateTime.Day - 1, SCROLL_DURATION3, .5f, .5f, null, onDone, true);
|
||||
|
||||
SecondAdapter.ResetItems(60);
|
||||
SecondAdapter.SmoothScrollTo(dateTime.Second, SCROLL_DURATION1, .5f, .5f);
|
||||
MinuteAdapter.ResetItems(60);
|
||||
MinuteAdapter.SmoothScrollTo(dateTime.Minute, SCROLL_DURATION2, .5f, .5f);
|
||||
HourAdapter.ResetItems(24);
|
||||
//HourAdapter.SmoothScrollTo(dateTime.Hour, SCROLL_DURATION3, .5f, .5f, onProgress, true);
|
||||
HourAdapter.SmoothScrollTo(dateTime.Hour, SCROLL_DURATION3, .5f, .5f, null, onDone, true);
|
||||
}
|
||||
|
||||
public void ReturnCurrent()
|
||||
{
|
||||
//_AnimStart = Vector3.one;
|
||||
//_AnimEnd = Vector3.zero;
|
||||
_AnimStart = _CanvasGroup.alpha;
|
||||
_AnimEnd = 0f;
|
||||
_AnimStartTime = Time;
|
||||
_Animating = true;
|
||||
|
||||
_ActionOnAnimDone = () =>
|
||||
{
|
||||
_ActionOnAnimDone = null;
|
||||
if (OnDateSelected != null)
|
||||
OnDateSelected(SelectedValue);
|
||||
|
||||
Destroy(gameObject);
|
||||
};
|
||||
}
|
||||
|
||||
void AutoInit()
|
||||
{
|
||||
_DateToInitWith = _DateToInitWith ?? DateTime.Now;
|
||||
InitWithDate(_DateToInitWith.Value);
|
||||
}
|
||||
|
||||
void UnregisterAutoCorrection()
|
||||
{
|
||||
YearAdapter.OnSelectedValueChanged -= OnYearChanged;
|
||||
MonthAdapter.OnSelectedValueChanged -= OnMonthChanged;
|
||||
}
|
||||
|
||||
void RegisterAutoCorrection()
|
||||
{
|
||||
YearAdapter.OnSelectedValueChanged += OnYearChanged;
|
||||
MonthAdapter.OnSelectedValueChanged += OnMonthChanged;
|
||||
}
|
||||
|
||||
void OnYearChanged(int year) { OnMonthChanged(MonthAdapter.SelectedValue); }
|
||||
|
||||
void OnMonthChanged(int month)
|
||||
{
|
||||
var selectedDay = DayAdapter.SelectedValue;
|
||||
int newDaysInMonth = DateTime.DaysInMonth(YearAdapter.SelectedValue, month);
|
||||
if (newDaysInMonth == DayAdapter.GetItemsCount())
|
||||
return;
|
||||
DayAdapter.ResetItems(newDaysInMonth);
|
||||
DayAdapter.ScrollTo(Math.Min(newDaysInMonth, selectedDay) - 1, .5f, .5f);
|
||||
}
|
||||
|
||||
void StopAnimations()
|
||||
{
|
||||
foreach (var adapter in _AllAdapters)
|
||||
{
|
||||
if (adapter)
|
||||
adapter.CancelAllAnimations();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ExecuteAfter(float seconds, Action action) { StartCoroutine(ExecuteAfterCoroutine(seconds, action)); }
|
||||
IEnumerator ExecuteAfterCoroutine(float seconds, Action action)
|
||||
{
|
||||
if (seconds > 0f)
|
||||
{
|
||||
yield return null;
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (_UseUnscaledTime)
|
||||
yield return new WaitForSecondsRealtime(seconds);
|
||||
else
|
||||
yield return new WaitForSeconds(seconds);
|
||||
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67c05838ffd5f8849ad61288be5e976f
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
Reference in New Issue
Block a user