private void _PopulateInternal(List <BaseCardData> cardList) { if (_clearOnRepopulate) { Clear(); } // If this is a vertical list, show all items. Else parse out only today's items. if (_verticalMode) { _cardCache = cardList; ClampCarouselCards(_cardCache.Count, true); } else { bool receivingSponsors = cardList.Any(x => null != x as SponsorDataModel); if (receivingSponsors) { _cardCache.AddRange(cardList); } else { List <BaseCardData> toAdd = cardList.FindAll(x => { if (x.dateTime == DateTime.MinValue) { x.ParseDateString(); } DateTime lowerBound = (0 == DayIndex ? DateTime.Now : DateTime.Today); return(x.dateTime >= lowerBound.AddDays(DayIndex) && x.dateTime < DateTime.Today.AddDays(DayIndex + 1)); } ); _DistanceSort(toAdd); _cardCache.AddRange(toAdd); ClampCarouselCards(_cardCache.Count, true); } // Regardless, now sort such that sponsors appear once every five activities. // Grab all sponsors first if there are any List <BaseCardData> currentSponsors = _cardCache.FindAll(x => null != x as SponsorDataModel); foreach (BaseCardData bcd in currentSponsors) { _cardCache.Remove(bcd); } if (currentSponsors.Count != 0) { if (_cardCache.Count >= 5) { int s = 0; int a = 5; while (a < _cardCache.Count) { _cardCache.Insert(a, currentSponsors[s % currentSponsors.Count]); a += 6; s++; } } else if (_cardCache.Count > 0 && _cardCache.Count < 5) { _cardCache.Add(currentSponsors[UnityEngine.Random.Range(0, currentSponsors.Count)]); } else { _cardCache.AddRange(currentSponsors); } ClampCarouselCards(_cardCache.Count, true); } } DateTime lastDate = DateTime.MinValue; int i = 0; float dateLabelOffset = 0f; for ( ; i < _cardCache.Count && i < _carouselCards.Count; i++) { if (!_carouselCards[i].IsPopulated() || null != _cardCache[i] as ActivityDataModel) { _carouselCards[i].Populate(_cardCache[i], _onCardClickedDelegate, _allowRecommending); if (_verticalMode) { // Move this card further down if we inserted date labels earlier in the list MonoBehaviour cardBehavior = _carouselCards[i] as MonoBehaviour; Vector3 newCardPosition = cardBehavior.transform.localPosition; newCardPosition.y -= dateLabelOffset; cardBehavior.transform.localPosition = newCardPosition; // Insert date fillers every unique day if (_cardCache[i].dateTime.Day != lastDate.Day || _cardCache[i].dateTime.Month != lastDate.Month || _cardCache[i].dateTime.Year != lastDate.Year) { lastDate = _cardCache[i].dateTime; float additionalOffset = (cardBehavior.GetComponent <Collider>() as BoxCollider).size.y + _cardPadding; dateLabelOffset += additionalOffset; newCardPosition = cardBehavior.transform.localPosition; Vector3 dateLabelPosition = newCardPosition; newCardPosition.y -= additionalOffset; cardBehavior.transform.localPosition = newCardPosition; // Check if there's already a date label for this date. DateListItem[] dateLabels = ScrollView.transform.GetComponentsInChildren <DateListItem>(); if (!dateLabels.ToList().Exists(x => x.dateTime == lastDate)) { GameObject dateListItemPrefab = (GameObject)Resources.Load(_cardPrefabPath + "DateListItem"); GameObject dateListItem = NGUITools.AddChild(ScrollView.gameObject, dateListItemPrefab); DateListItem dliScript = dateListItem.GetComponent <DateListItem>(); UIDragScrollView dateDragScrollView = dateListItem.GetComponent <UIDragScrollView>(); dateDragScrollView.scrollView = ScrollView; // Relative day (yesterday/today/tomorrow) DateTime now = DateTime.Now; DateTime yesterday = DateTime.Now.AddDays(-1); DateTime tomorrow = DateTime.Now.AddDays(1); if (lastDate.Date == now.Date) { dliScript.dayLabel.text = "TODAY"; } else if (lastDate.Date == yesterday.Date) { dliScript.dayLabel.text = "YESTERDAY"; } else if (lastDate.Date == tomorrow.Date) { dliScript.dayLabel.text = "TOMORROW"; } else { dliScript.dayLabel.text = lastDate.DayOfWeek.ToString().ToUpper(); } dliScript.dateLabel.text = lastDate.ToString("M"); dliScript.dateTime = lastDate; dateListItem.transform.localPosition = dateLabelPosition; } } } } } RepositionPadding(); VisibleCardIndexMin = 0; VisibleCardIndexMax = i - 1; }
public void OnScrollViewDragFinished() { dragEndPosition = ScrollView.transform.position; Transform newCenterTarget = null; if (!_verticalMode) { Vector2 drag = dragEndPosition - dragStartPosition; dragStartPosition = dragEndPosition = Vector3.zero; float sqrDragDistance = Vector3.SqrMagnitude(drag); if (sqrDragDistance > dragDistanceThreshold * dragDistanceThreshold || sqrDragDistance / ((Time.time - dragStartTime) / 1.5) > dragDistanceThreshold * dragDistanceThreshold) { // We dragged far enough: try centering on the next card in this direction. if (null == CenterOnChild.centeredObject) { newCenterTarget = CenterOnChild.DetermineCenterTarget(); } else { float dot = Vector3.Dot(drag, Vector3.right); int newIndex = (int)(CenterCardIndex - Mathf.Sign(dot)); if (newIndex >= 0 && newIndex < _carouselCards.Count) { newCenterTarget = (_carouselCards[newIndex] as MonoBehaviour).transform; } else { newCenterTarget = CenterOnChild.centeredObject.transform; } } } } if (null == newCenterTarget) { // Try recentering on centered object, if it exists if (_verticalMode) { newCenterTarget = CenterOnChild.DetermineCenterTarget(); } else { if (null != CenterOnChild.centeredObject) { CenterOnChild.Recenter(); } else { Debug.LogError("CardCarousel: centered on null"); } return; } } DateListItem dli = newCenterTarget.GetComponent <DateListItem>(); Transform nearestToDateLabel = null; int newTargetIndex = -1; if (null != dli) { // Make sure we still recycle the cards if we center on a date label // Find the nearest card in the direction we came from Vector3 deltaScroll = dli.transform.localPosition - _prevCenterTarget.transform.localPosition; RaycastHit[] hits = Physics.RaycastAll(dli.transform.position, -deltaScroll); if (null != hits && hits.Length > 0) { // Pull out only cards, so no date labels List <RaycastHit> hitList = hits.ToList().FindAll(x => null == x.collider.gameObject.GetComponent <DateListItem>()); // Sort by closest hitList.Sort((a, b) => a.distance.CompareTo(b.distance)); // Grab the first (closest) Transform closest = hitList[0].collider.transform; if (null == closest) { return; } Debug.LogWarning("Found " + closest.name); newTargetIndex = _carouselCards.FindIndex(x => (x as MonoBehaviour).transform == closest); } } else if (!_verticalMode) { CenterOnChild.CenterOn(newCenterTarget); } if (newTargetIndex < 0) { newTargetIndex = _carouselCards.FindIndex(x => (x as MonoBehaviour).transform == newCenterTarget); } if (0 > newTargetIndex) { return; } if (_verticalMode) { _prevCenterTarget = newCenterTarget; } int halfCarouselLength = _carouselLength / 2; int numCardsToMove = newTargetIndex - halfCarouselLength; CenterCardIndex = newTargetIndex; if (0 == numCardsToMove) { return; } // Slide the visible indices over an equal amount. // Clamp the number of cards moved if it would push us out of bounds. int oldMin = VisibleCardIndexMin; VisibleCardIndexMin = Mathf.Clamp(VisibleCardIndexMin + numCardsToMove, 0, _cardCache.Count - _carouselLength); int diff = VisibleCardIndexMin - oldMin; numCardsToMove = diff; VisibleCardIndexMax = Mathf.Clamp(VisibleCardIndexMax + numCardsToMove, _carouselLength - 1, _cardCache.Count - 1); int positiveEdge = numCardsToMove < 0 ? 0 : _carouselCards.Count; int negativeEdge = numCardsToMove < 0 ? _carouselCards.Count : 0; int negativeIndex = negativeEdge - (negativeEdge == _carouselLength ? 1 : 0); int positiveIndex = positiveEdge - (positiveEdge == _carouselLength ? 1 : 0); for (int i = 0; i < Mathf.Abs(numCardsToMove); i++) { IActivityViewModelBase movedCard = _carouselCards[negativeIndex]; IActivityViewModelBase edgeCard = _carouselCards[positiveIndex]; DateTime lastDate = DateTime.MinValue; if (_verticalMode) { lastDate = (edgeCard as ActivityTableCellViewModel).data.dateTime.Date; } int indexToPopulate = (numCardsToMove > 0 ? VisibleCardIndexMax - (numCardsToMove - 1 - i) : VisibleCardIndexMin + (Mathf.Abs(numCardsToMove) - 1 - i)); movedCard.Clear(); movedCard.Populate(_cardCache[indexToPopulate], _onCardClickedDelegate, _allowRecommending); DateTime newDate = _cardCache[indexToPopulate].dateTime.Date; Vector3 newPosition = (edgeCard as MonoBehaviour).transform.localPosition; if (_verticalMode) { float singleCardOffset = ((edgeCard as MonoBehaviour).GetComponent <Collider>() as BoxCollider).size.y + _cardPadding; newPosition.y -= (numCardsToMove > 0 ? 1 : -1) * singleCardOffset; if (lastDate != newDate) { // If we're moving positive, it's the newDate. Else it's lastDate. DateTime dateToShow = (numCardsToMove > 0 ? newDate : lastDate); Vector3 dateListItemPosition = newPosition; newPosition.y -= (numCardsToMove > 0 ? 1 : -1) * singleCardOffset; // Check if there's already a date label for this date. DateListItem[] dateLabels = ScrollView.transform.GetComponentsInChildren <DateListItem>(); var dateLabel = dateLabels.ToList().Find(x => x.dateTime.Date == dateToShow); if (dateLabel == null) { // Now at the singleCardOffset position, spawn a date label. GameObject dateListItemPrefab = (GameObject)Resources.Load(_cardPrefabPath + "DateListItem"); GameObject dateListItem = NGUITools.AddChild(ScrollView.gameObject, dateListItemPrefab); DateListItem dliScript = dateListItem.GetComponent <DateListItem>(); UIDragScrollView dateDragScrollView = dateListItem.AddComponent <UIDragScrollView>(); dateDragScrollView.scrollView = ScrollView; // Still respect relative dates DateTime now = DateTime.Now; DateTime yesterday = DateTime.Now.AddDays(-1); DateTime tomorrow = DateTime.Now.AddDays(1); if (dateToShow.Date == now.Date) { dliScript.dayLabel.text = "TODAY"; } else if (dateToShow.Date == yesterday.Date) { dliScript.dayLabel.text = "YESTERDAY"; } else if (dateToShow.Date == tomorrow.Date) { dliScript.dayLabel.text = "TOMORROW"; } else { dliScript.dayLabel.text = dateToShow.DayOfWeek.ToString().ToUpper(); } dliScript.dateLabel.text = dateToShow.ToString("M"); dliScript.dateTime = dateToShow.Date; dateListItem.gameObject.transform.localPosition = dateListItemPosition; } } } else { newPosition.x += (numCardsToMove > 0 ? 1 : -1) * (((edgeCard as MonoBehaviour).GetComponent <Collider>() as BoxCollider).size.x + _cardPadding); } (movedCard as MonoBehaviour).transform.localPosition = newPosition; _carouselCards.Insert(positiveEdge, movedCard); _carouselCards.RemoveAt(negativeEdge); } if (null != dli) { return; } CenterCardIndex = _carouselCards.FindIndex(x => (x as MonoBehaviour).transform == newCenterTarget); }
public string GetRowStyle(DateListItem date) => (!string.IsNullOrEmpty(date.Themes), date.TransferredDate == Today) switch