示例#1
0
        public void Clear()
        {
            // Don't remove cards, but clear out their data
            for (int i = 0; i < _carouselCards.Count; i++)
            {
                IActivityViewModelBase card = _carouselCards[i];

                card.Clear();
                if (_verticalMode)
                {
                    MonoBehaviour cardBehavior = (card as MonoBehaviour);
                    Vector3       position     = cardBehavior.transform.localPosition;
                    position.y = -i * ((cardBehavior.GetComponent <Collider>() as BoxCollider).size.y + _cardPadding);
                    cardBehavior.transform.localPosition = position;
                }
            }

            // Old cached card data now too
            _cardCache.Clear();

            // Also clear out any date labels
            DateListItem[] dateLabels = transform.GetComponentsInChildren <DateListItem>();
            dateLabels.ToList().ForEach(x => Destroy(x.gameObject));
            ScrollView.ResetPosition();
        }
示例#2
0
        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);
        }
示例#3
0
        private void CreateCards(int desiredCount)
        {
            // Start where we left off. I.e. if we have 2 (indices 0 and 1), we start at 2 and go to 4, adding 3 (for a total of 5). :D
            float offset        = (_verticalMode ? (-160f - _cardPadding) : (540f + _cardPadding)) * (_carouselCards.Count);
            int   cap           = Mathf.Min(desiredCount, _carouselLengthMax);
            int   olderSiblings = _scrollObject.transform.childCount;

            // SUCH HACK: track the active status of the scroll object and restore it after we add cards. It needs to be active while adding.
            bool scrollActiveStatus = _scrollObject.active;

            _scrollObject.SetActive(true);

            GameObject cardPrefabToMake = Resources.Load(_cardPrefabPath + (!_verticalMode ? _activityCardPrefabName : _activityCellPrefabName)) as GameObject;

            for (int i = 0; i < cap; i++)
            {
                GameObject newCard = NGUITools.AddChild(_scrollObject, cardPrefabToMake);
                newCard.name = "Card_" + (i + olderSiblings).ToString();

                if (0f == dragDistanceThreshold)
                {
                    BoxCollider col = newCard.GetComponent <BoxCollider>();
                    dragDistanceThreshold = col.bounds.size.x * 0.33f;
                }

                UIDragScrollView dragScrollView = newCard.GetComponent <UIDragScrollView>();
                dragScrollView.scrollView = ScrollView;

                IActivityViewModelBase cardScript = newCard.GetComponent(typeof(IActivityViewModelBase)) as IActivityViewModelBase;
                if (null != cardScript)
                {
                    _carouselCards.Add(cardScript);
                }

                Transform newCardTrans = newCard.transform;
                Vector3   localPos     = newCardTrans.localPosition;
                if (!_verticalMode)
                {
                    localPos.x = offset;
                }
                else
                {
                    localPos.y = offset;
                }
                newCardTrans.localPosition = localPos;

                offset += (_verticalMode ? -160f - _cardPadding : 540f + _cardPadding);
                if (_carouselCards.Count == _carouselLengthMax)
                {
                    break;
                }
            }

            if (_verticalMode)
            {
                RepositionPadding();
                _carouselLength    = _carouselCards.Count;
                _carouselLengthMax = Mathf.Max(_carouselLength, _carouselLengthMax);
            }
            else
            {
                _carouselLength = Mathf.Min(_carouselCards.Count, _carouselLengthMax);
            }

            _scrollObject.SetActive(scrollActiveStatus);
        }