123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using UnityEngine;
- using UnityEngine.Events;
- using UnityEngine.Serialization;
- using UnityEngine.UI;
- namespace Bitsplash.DatePicker
- {
- [ExecuteInEditMode]
- public partial class DatePickerContent : MonoBehaviour , IDatePickerSettingsItem
- {
- [SerializeField]
- [HideInInspector]
- private bool isOpen;
- const int RowCount = 6;
- const int ColumnCount = 7;
- [FormerlySerializedAs("FirstDayOfWeek")]
- [SerializeField]
- [Tooltip("the first day of the week for the content")]
- private DayOfWeek firstDayOfWeek = DayOfWeek.Sunday;
- [FormerlySerializedAs("RightToLeft")]
- [SerializeField]
- private bool rightToLeft = false;
- [FormerlySerializedAs("BottomToTop")]
- [SerializeField]
- private bool bottomToTop = false;
- [FormerlySerializedAs("CellPrefab")]
- [SerializeField]
- [Tooltip("drag a cell template here to use it with the datepicker")]
- private DatePickerCell cellPrefab = null;
- [FormerlySerializedAs("SelectionMode")]
- [SerializeField]
- [Tooltip("single,range and multiple selection types. ")]
- private SelectionType selectionMode;
- [FormerlySerializedAs("AllowEmptySelection")]
- [SerializeField]
- private bool allowEmptySelection = false;
- [SerializeField]
- private DateTime startDate = new DateTime(1960,1,1);
- [SerializeField]
- private DateTime endDate = new DateTime(2030, 12, 31);
- void ValidateYear()
- {
- if (endDate < startDate)
- endDate = startDate;
- mMonthFirst = new DateTime(mMonthFirst.Year, mMonthFirst.Month, 1);
- if(mMonthFirst > endDate)
- {
- mMonthFirst = new DateTime(endDate.Year, endDate.Month, 1);
- }
- if(mMonthFirst < startDate)
- {
- mMonthFirst = new DateTime(startDate.Year, startDate.Month, 1);
- }
- }
- public DateTime StartDate
- {
- get { return startDate; }
- set
- {
- startDate = value.Date;
- ValidateYear();
- Invalidate();
- OnSettingsChanged();
- }
- }
- public DateTime EndDate
- {
- get { return endDate; }
- set
- {
- endDate = value.Date;
- ValidateYear();
- Invalidate();
- OnSettingsChanged();
- }
- }
- /// <summary>
- /// the first day of the week for the date picker
- /// </summary>
- public DayOfWeek FirstDayOfWeek
- {
- get { return firstDayOfWeek; }
- set
- {
- firstDayOfWeek = value;
- OnSettingsChanged();
- }
- }
- /// <summary>
- /// set the date picker to right to left mode
- /// </summary>
- public bool RightToLeft
- {
- get { return rightToLeft; }
- set
- {
- rightToLeft = value;
- OnSettingsChanged();
- }
- }
- /// <summary>
- /// show days from bottom to top instead of top to bottom
- /// </summary>
- public bool BottomToTop
- {
- get { return bottomToTop; }
- set
- {
- bottomToTop = value;
- OnSettingsChanged();
- }
- }
- //public DatePickerCell CellPrefab
- //{
- // get { return cellPrefab; }
- // set
- // {
- // cellPrefab = value;
- // }
- //}
- /// <summary>
- /// set the selection mode for the date picker. Single ,Range or Multiple
- /// </summary>
- public SelectionType SelectionMode
- {
- get { return selectionMode; }
- set
- {
- selectionMode = value;
- OnSettingsChanged();
- }
- }
- /// <summary>
- /// allows selection of the date picker to be empty
- /// </summary>
- public bool AllowEmptySelection
- {
- get { return allowEmptySelection; }
- set
- {
- allowEmptySelection = value;
- OnSettingsChanged();
- }
- }
- /// <summary>
- /// used for internal purpose
- /// </summary>
- public event Action SettingsChanged;
- /// <summary>
- /// currently the displayed month and year
- /// </summary>
- DateTime mMonthFirst = DateTime.Today;
- /// <summary>
- /// genearted cells
- /// </summary>
- DatePickerCell[] mCells;
- /// <summary>
- /// the selection collection object for the content
- /// </summary>
- DatePickerCollection mSelection = new DatePickerCollection();
- /// <summary>
- /// a date to cell map for quick lookup
- /// </summary>
- Dictionary<DateTime, DatePickerCell> mDateToCell = new Dictionary<DateTime, DatePickerCell>();
- /// <summary>
- /// an input delegation for the date picker
- /// </summary>
- DatePickerInput mDatePickerInput;
- /// <summary>
- /// true if the datepicker should be recreated
- /// </summary>
- bool mInvalidated = true;
- /// <summary>
- /// This event triggers when the use navigates the datepicker
- /// </summary>
- public UnityEvent OnDisplayChanged;
- /// <summary>
- /// this event triggers when the date selection has changed
- /// </summary>
- public UnityEvent OnSelectionChanged;
- /// <summary>
- /// the date picker selection collection. Use this object to change and query the current date selection
- /// </summary>
- public DatePickerCollection Selection { get { return mSelection; } }
- void EnsureInput()
- {
- mDatePickerInput = GetComponent<DatePickerInput>();
- if (mDatePickerInput == null)
- mDatePickerInput = gameObject.AddComponent<DatePickerStandardInput>();
- }
- /// <summary>
- /// the currently displayed date in the datepicker
- /// </summary>
- public DateTime DisplayDate { get { return mMonthFirst; } }
- /// <summary>
- /// sets the month and year being displayed in the date picker.
- /// </summary>
- /// <param name="year"></param>
- /// <param name="month"></param>
- public void SetMonthAndYear(int year,int month)
- {
- FillCells(new DateTime(year, month, 1));
- }
- /// <summary>
- /// sets the year being displayed in the date picker
- /// </summary>
- /// <param name="year"></param>
- public void SetYear(int year)
- {
- FillCells(new DateTime(year, mMonthFirst.Month, 1));
- }
- /// <summary>
- /// sets the month being displayed in the date picker
- /// </summary>
- /// <param name="month"></param>
- public void SetMonth(int month)
- {
- FillCells(new DateTime(mMonthFirst.Year,month, 1));
- }
- /// <summary>
- /// used internally
- /// </summary>
- public string EditorTitle { get {return "Board"; } }
- /// <summary>
- /// used internally
- /// </summary>
- public int Order { get { return 0; } }
- /// <summary>
- /// advances the display by 1 year
- /// </summary>
- public void NextYear()
- {
- FillCells(mMonthFirst.AddYears(1));
- }
- void OnSettingsChanged()
- {
- if (SettingsChanged != null)
- SettingsChanged();
- }
- /// <summary>
- /// retracts the display by 1 year
- /// </summary>
- public void PrevYear()
- {
- FillCells(mMonthFirst.AddYears(-1));
- }
- /// <summary>
- /// advances the display by 1 month
- /// </summary>
- public void NextMonth()
- {
- FillCells(mMonthFirst.AddMonths(1));
- }
- /// <summary>
- /// retracts the display by 1 month
- /// </summary>
- public void PrevMonth()
- {
- FillCells(mMonthFirst.AddMonths(-1));
- }
- public virtual string DateToString(DateTime date)
- {
- return date.Day.ToString();
- }
- void GenerateCells()
- {
- Clear();
- if (cellPrefab == null)
- return;
- mCells = new DatePickerCell[((int)RowCount) * ((int)ColumnCount)];
- float ColumnSize = 1f / ColumnCount;
- float RowSize = 1f / RowCount;
- for(float i=0; i<RowCount; i++)
- {
- float startY = i / RowCount;
- if (BottomToTop == false)
- startY = 1f - startY - RowSize;
- float endY = startY + RowSize;
- for (float j=0; j<ColumnCount; j++)
- {
- float startX = j / ColumnCount;
- if (RightToLeft)
- startX = 1f - startX - ColumnSize;
- float endX = startX + ColumnSize;
- GameObject newObj = GameObject.Instantiate(cellPrefab.gameObject, transform);
- CommonMethods.SafeDestroy(newObj.GetComponent<DatePickerCellTemplate>());
- CommonMethods.HideObject(newObj);
- newObj.name = String.Format("day_{0}_{1}", j, i);
- newObj.SetActive(true);
- CommonMethods.EnsureComponent<IDateTimeItem>(newObj);
- var rect = newObj.GetComponent<RectTransform>();
- rect.anchorMin = new Vector2(startX, startY);
- rect.anchorMax = new Vector2(endX, endY);
- rect.anchoredPosition = new Vector2(0f, 0f);
- rect.sizeDelta = new Vector2(0f, 0f);
- int childIndex = (int)(i * ColumnCount + j);
- childIndex = (int)(i * ColumnCount + j);
- mCells[childIndex] = newObj.GetComponent<DatePickerCell>();
- var addon = CommonMethods.EnsureComponent<CellAddon>(newObj);
- addon.SetParent(this, childIndex);
- }
- }
- FillCells(mMonthFirst);
- }
- DateTime MonthFromDate(DateTime date)
- {
- return new DateTime(date.Year, date.Month, 1);
- }
- DatePickerCell getCell(int day,int week)
- {
- return mCells[week * ColumnCount + day];
- }
-
- void FillCells(DateTime monthFirst)
- {
- monthFirst = monthFirst.Date;
- mMonthFirst = monthFirst;
- ValidateYear();
- if (mCells == null)
- return;
- monthFirst = mMonthFirst;
- int monthDayOfWeek = (int)monthFirst.DayOfWeek;
- int span = monthDayOfWeek - (int)FirstDayOfWeek;
- if (span < 0)
- span += 7;
- DateTime startFrom = (monthFirst - TimeSpan.FromDays(span)).Date;
- DateTime endIn = startFrom + TimeSpan.FromDays(RowCount * ColumnCount);
- DateTime monthLast = monthFirst + TimeSpan.FromDays(DateTime.DaysInMonth(monthFirst.Year, monthFirst.Month) - 1);
- DateTime current = startFrom;
- mDateToCell.Clear();
- for (int i=0; i<mCells.Length; i++)
- {
- mCells[i].DayValue = current;
- mCells[i].SetText(DateToString(current));
- bool cellenabled = true;
- if (current < monthFirst || current > monthLast || current < startDate || current > endDate)
- cellenabled = false;
- mCells[i].SetInitialSettings(cellenabled, false);
- mDateToCell[current.Date] = mCells[i];
- current += TimeSpan.FromDays(1);
- }
- RefreshSelection();
- if (OnDisplayChanged != null)
- OnDisplayChanged.Invoke();
- }
- protected void Clear()
- {
- IDateTimeItem[] children = GetComponentsInChildren<IDateTimeItem>();
- for (int i = 0; i < children.Length; ++i)
- {
- if (children[i] != null)
- {
- if (children[i].gameObject.GetComponentInParent<DatePickerContent>() != this)
- continue;
- if (children[i].gameObject != gameObject)
- CommonMethods.SafeDestroy(children[i].gameObject);
- }
- }
- }
- public void Invalidate()
- {
- mInvalidated = true;
- }
- void HookEvents()
- {
- ((IDatePickerCollectionPrivate)mSelection).SelectionModified -= DatePicker_SelectionModified;
- ((IDatePickerCollectionPrivate)mSelection).SelectionModified += DatePicker_SelectionModified;
- }
- private void DatePicker_SelectionModified()
- {
- RaiseSelectionChanged();
- }
- public void Start()
- {
- HookEvents();
- EnsureInput();
- GenerateCells();
- // if (AllowEmptySelection == false)
- // SelectOne(DateTime.Today);
- }
- public void Update()
- {
- if(AllowEmptySelection != ((IDatePickerCollectionPrivate)mSelection).AllowEmpty)
- ((IDatePickerCollectionPrivate)mSelection).AllowEmpty = AllowEmptySelection;
- UpdateSelection();
- if(mInvalidated)
- {
- GenerateCells();
- mInvalidated = false;
- }
- }
- public void OnValidate()
- {
- ValidateYear();
- OnSettingsChanged();
- Invalidate();
- }
- /// <summary>
- /// retrives the underlaying gameobject specified by dateTime. If the dateTime is not currently displayed , null is returned
- /// </summary>
- /// <param name="dateTime"></param>
- /// <returns></returns>
- public DatePickerCell GetCellObjectByDate(DateTime dateTime)
- {
- DatePickerCell res = null;
- if (mDateToCell.TryGetValue(dateTime.Date, out res))
- return res;
- return null;
- }
- }
- }
|