/// <summary>
        /// Scrolls to the desired index, starting from the provided visual item.
        /// </summary>
        /// <param name="item">The visual item to start from.</param>
        /// <param name="to">The target index to scroll to.</param>
        private void ScrollToIndex(LoopingListItem item, int to)
        {
            if (!this.IsInitialized())
            {
                return;
            }

            int from = item.LogicalIndex;

            if (item.LogicalIndex == to)
            {
                this.BringIntoView(to);
                return;
            }

            int indexOffset = Math.Abs(from - to);
            int pivotIndex  = this.logicalCount / 2;
            int sign        = Math.Sign(from - to);

            if (indexOffset > pivotIndex)
            {
                indexOffset = this.logicalCount - indexOffset;
                sign       *= -1;
            }

            double offset = this.visualOffset + (sign * indexOffset * this.itemLength);

            this.scrollState = LoopingPanelScrollState.ScrollingToIndex;
            this.AnimateVerticalOffset(offset);
        }
        /// <summary>
        /// Ensures that the visual item, associated with the specified logical index is currently displayed.
        /// </summary>
        /// <param name="logicalIndex"></param>
        /// <param name="animate">True to perform animated scrolling, false otherwise.</param>
        private void BringIntoView(int logicalIndex, bool animate)
        {
            // no visual children yet
            if (this.items.Count == 0)
            {
                return;
            }

            if (logicalIndex < 0 || logicalIndex >= this.logicalCount)
            {
                return;
            }

            double offset = this.CalculateOffset(logicalIndex);

            if (animate)
            {
                this.scrollState = LoopingPanelScrollState.ScrollingToIndex;
                this.AnimateVerticalOffset(offset);
            }
            else
            {
                this.UpdateWheel(offset, false);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Applies the specified offset as current.
        /// </summary>
        /// <param name="offset">The desired offset.</param>
        /// <param name="duration">The duration of the animation used to apply the offset.</param>
        /// <param name="ease">The easing function that describes animation interpolation.</param>
        internal void SetVerticalOffset(double offset, Duration duration, EasingFunctionBase ease)
        {
            if (!this.IsInitialized())
            {
                return;
            }

            this.scrollState = LoopingPanelScrollState.Scrolling;
            this.AnimateVerticalOffset(duration, ease, offset);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Stops the vertical offset animation (if running).
        /// </summary>
        internal void StopOffsetAnimation(bool raiseCompleted)
        {
            LoopingPanelScrollState currentState = this.scrollState;

            this.scrollState = LoopingPanelScrollState.NotScrolling;
            this.animating   = false;
            this.offsetStoryboard.Stop();

            if (raiseCompleted && currentState != LoopingPanelScrollState.NotScrolling)
            {
                this.OnScrollCompleted(currentState);
            }
        }
Exemplo n.º 5
0
        private void OnOffsetAnimationCompleted(object sender, object args)
        {
            if (this.scrollState == LoopingPanelScrollState.NotScrolling)
            {
                return;
            }

            LoopingPanelScrollState previousState = this.scrollState;

            this.animating = false;
            this.offsetStoryboard.Stop();
            this.OnScrollCompleted(previousState);
        }
Exemplo n.º 6
0
        internal void Scroll(double amount)
        {
            if (!this.IsInitialized())
            {
                return;
            }

            if (this.animating)
            {
                this.StopOffsetAnimation(false);
            }

            this.scrollState = LoopingPanelScrollState.Scrolling;
            this.UpdateWheel(this.visualOffset + amount, false);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Notifies that a scroll operation has completed.
        /// </summary>
        /// <param name="previousState">The state the panel was in before the scrolling ended.</param>
        private void OnScrollCompleted(LoopingPanelScrollState previousState)
        {
            this.scrollState = LoopingPanelScrollState.NotScrolling;

            if (!this.isCentered)
            {
                return;
            }

            if (previousState == LoopingPanelScrollState.Scrolling ||
                previousState == LoopingPanelScrollState.ScrollingToIndex)
            {
                this.CenterMiddleItem(previousState != LoopingPanelScrollState.ScrollingToIndex, true);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Ensures that the visual item, associated with the specified logical index is currently displayed.
        /// </summary>
        /// <param name="logicalIndex">The logical index of the item.</param>
        /// <param name="visualIndex">The visual index of the item.</param>
        /// <param name="animate">True to perform animated scrolling, false otherwise.</param>
        private void BringIntoView(int logicalIndex, int visualIndex, bool animate)
        {
            // no visual children yet
            if (this.items.Count == 0)
            {
                return;
            }

            if (logicalIndex < 0 || logicalIndex >= this.logicalCount)
            {
                return;
            }

            double offset;

            if (this.IsIndexInView(logicalIndex) && visualIndex >= 0)
            {
                offset = this.CalculateVisualOffset(visualIndex, this.visualIndexChain[0]);
            }
            else
            {
                offset = this.CalculateLogicalOffset(logicalIndex, this.topLogicalIndex);
            }

            if (animate)
            {
                this.scrollState = LoopingPanelScrollState.ScrollingToIndex;
                this.AnimateVerticalOffset(offset);
            }
            else
            {
                this.UpdateWheel(offset, false);

                this.UpdateLayout();

                // Force items to be remeasured as occasionalli there is no measure for items and they desapear.
                this.InvalidateMeasure();
            }
        }