/// <summary>
        /// Performs to the required animation to reset selection on the Selected Visual
        /// </summary>
        private void ResetBannerItems()
        {
            if (_selectedVisual == null)
            {
                return;
            }

            _isCollapsing = true;

            // Get the value to set for the LeftInset of the InsetClip
            float left;

            _selectedVisual.Properties.TryGetScalar("LeftInset", out left);
            _collapseLeftInset.InsertKeyFrame(1f, left);

            // Get the value to set for the RightInset of the InsetClip
            float right;

            _selectedVisual.Properties.TryGetScalar("RightInset", out right);
            _collapseRightInset.InsertKeyFrame(1f, right);

            // Use a scoped batch helper to queue up animations one after the other
            _compositor.CreateScopedBatch(CompositionBatchTypes.Animation,
                                          () =>
            {
                // Collapse the visual
                _selectedVisual.Clip.StartAnimation("RightInset", _collapseInsetClip.Animation);
            },
                                          async() =>
            {
                // If the first visual is selected, then no need to move it to the leftmost
                // position as it is already there.
                if (!ReferenceEquals(_selectedVisual, _fluidItems.Keys.ElementAt(0)))
                {
                    // Move the visual back to its original location in the banner
                    _selectedVisual.Clip.StartAnimation("LeftInset", _collapseLeftInset.Animation);
                    _selectedVisual.Clip.StartAnimation("RightInset", _collapseRightInset.Animation);
                }

                // Fade in the other visuals and scale them to normal size
                foreach (var child in _bgLayer.Children)
                {
                    child.Scale   = Vector3.One;
                    child.Opacity = 1;
                }

                // Delay the exchange, of selected visual, between the top and background layers
                // by the DefaultScaleAnimationDuration so that other visuals in
                // the Banner scale back to normal
                await Task.Delay((int)DefaultScaleAnimationDuration.TotalMilliseconds);

                // Bring the selected visual from top layer to the background layer
                _topLayer.Children.Remove(_selectedVisual);
                _bgLayer.Children.InsertAtTop(_selectedVisual);

                _selectedVisual = null;
                _isCollapsing   = false;

                // Check the current location of the Pointer and whether it is hovering
                // over any of the FluidBanner items
                HandlePointerPosition(GetPointerPosition());
            });
        }
        /// <summary>
        /// Initialize all Composition related stuff here (Compositor, Animations etc)
        /// </summary>
        private void InitializeComposition()
        {
            var rootVisual = ElementCompositionPreview.GetElementVisual(this);

            // Compositor
            _compositor = rootVisual.Compositor;
            // Composition Generator
            _generator = CompositionGeneratorFactory.GetCompositionGenerator(_compositor);

            // Final Value Expressions
            var vector3Expr = _compositor.CreateFinalValueExpression <Vector3>();
            var scalarExpr  = _compositor.CreateFinalValueExpression <float>();

            // Opacity Animation
            var opacityAnimation = _compositor.CreateKeyFrameAnimation <float>()
                                   .HavingDuration(DefaultOpacityAnimationDuration)
                                   .ForTarget(() => rootVisual.Opacity);

            opacityAnimation.InsertExpressionKeyFrame(1f, scalarExpr);

            // Scale Animation
            var scaleAnimation = _compositor.CreateKeyFrameAnimation <Vector3>()
                                 .HavingDuration(DefaultScaleAnimationDuration)
                                 .ForTarget(() => rootVisual.Scale);

            scaleAnimation.InsertExpressionKeyFrame(1f, vector3Expr);

            // ImplicitAnimation
            _implicitAnimationCollection            = _compositor.CreateImplicitAnimationCollection();
            _implicitAnimationCollection["Opacity"] = opacityAnimation.Animation;
            _implicitAnimationCollection["Scale"]   = scaleAnimation.Animation;

            // Expand Animations
            _expandLeftInset = _compositor.CreateKeyFrameAnimation <float>()
                               .HavingDuration(InsetAnimationDuration)
                               .DelayBy(InsetAnimationDelayDuration);

            _expandLeftInset.InsertKeyFrame(1f, 0);

            _expandRightInset = _compositor.CreateKeyFrameAnimation <float>()
                                .HavingDuration(InsetAnimationDuration)
                                .DelayBy(InsetAnimationDelayDuration);

            _expandInsetClip = _compositor.CreateKeyFrameAnimation <float>()
                               .HavingDuration(InsetClipAnimationDuration);

            _expandInsetClip.InsertKeyFrame(1f, 0);

            // Collapse Animations
            _collapseLeftInset = _compositor.CreateKeyFrameAnimation <float>()
                                 .HavingDuration(InsetAnimationDuration);

            _collapseRightInset = _compositor.CreateKeyFrameAnimation <float>()
                                  .HavingDuration(InsetAnimationDuration);

            _collapseInsetClip = _compositor.CreateKeyFrameAnimation <float>()
                                 .HavingDuration(InsetClipAnimationDuration);

            // Root Container
            _rootContainer = _compositor.CreateContainerVisual();

            // Background Layer
            _bgLayer             = _compositor.CreateLayerVisual();
            _bgLayer.Size        = _rootContainer.Size;
            _bgLayer.CenterPoint = new Vector3(_bgLayer.Size * 0.5f, 0);

            // Top Layer
            _topLayer      = _compositor.CreateLayerVisual();
            _topLayer.Size = _rootContainer.Size;

            _rootContainer.Children.InsertAtBottom(_bgLayer);
            _rootContainer.Children.InsertAtTop(_topLayer);

            // Add the rootContainer to the visual tree
            ElementCompositionPreview.SetElementChildVisual(this, _rootContainer);
        }
        /// <summary>
        /// Handles the Arrange pass during Layout
        /// </summary>
        /// <param name="finalSize">Final Size of the control</param>
        /// <returns>Total size occupied by all the Children</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            if ((ItemsSource == null) || !ItemsSource.Any())
            {
                return(finalSize);
            }

            // Resize the rootContainer
            _rootContainer.Size = finalSize.ToVector2();

            var padding = Padding;

            var paddingSize = padding.CollapseThickness();
            var width       = finalSize.Width;
            var height      = finalSize.Height;

            _itemCount = ItemsSource.Count();

            _availableWidth  = (width - paddingSize.Width).Single();
            _availableHeight = (height - paddingSize.Height).Single();
            var gapCount              = _itemCount - 1;
            var totalGap              = (gapCount * ItemGap).Single();
            var availableNonGapWidth  = _availableWidth - totalGap;
            var availableNonGapHeight = _availableHeight;

            _itemWidth    = availableNonGapWidth / _itemCount;
            _itemHeight   = availableNonGapHeight;
            _bannerBounds = new Rect(padding.Left, padding.Top, _availableWidth, _availableHeight);

            // Update Visual sizes and surfaceImages
            var availableSize = new Vector2(_availableWidth, _availableHeight);

            _rootContainer.Size  = availableSize;
            _bgLayer.Size        = availableSize;
            _bgLayer.CenterPoint = new Vector3(_bgLayer.Size * 0.5f, 0);
            _topLayer.Size       = availableSize;

            // Check if any visual is currently selected. If yes then obtain its index.
            // The new visual at that index should be selected and added to the toplayer
            var selectedVisualIndex = -1;

            if (_selectedVisual != null)
            {
                foreach (var item in _fluidItems)
                {
                    selectedVisualIndex++;
                    if (ReferenceEquals(item.Key, _selectedVisual))
                    {
                        break;
                    }
                }
            }

            for (var index = 0; index < _surfaceImages.Count; index++)
            {
                // Get the surfaceImage
                var surfaceImage = _surfaceImages.ElementAt(index);

                // Get the visual corresponding to this surfaceImage
                var itemVisual = _surfaceVisuals[surfaceImage];

                if (itemVisual == null)
                {
                    continue;
                }

                itemVisual.Size        = availableSize;
                itemVisual.CenterPoint = new Vector3(itemVisual.Size * 0.5f, 0);
                var contentVisual = itemVisual.Children.ElementAt(0) as SpriteVisual;
                if (contentVisual == null)
                {
                    continue;
                }

                contentVisual.Size        = availableSize;
                contentVisual.CenterPoint = itemVisual.CenterPoint;
                (contentVisual.Brush as CompositionSurfaceBrush)?.UpdateSurfaceBrushOptions(Stretch, AlignX, AlignY);

                // Calculate the Inset Clip
                var left  = index * (_itemWidth + ItemGap.Single());
                var right = _availableWidth - (left + _itemWidth);
                itemVisual.Properties.InsertScalar("LeftInset", left);
                itemVisual.Properties.InsertScalar("RightInset", right);
                itemVisual.Clip = (index == selectedVisualIndex)
                    ? _compositor.CreateInsetClip(0, 0, 0, 0)
                    : _compositor.CreateInsetClip(left, 0, right, 0);

                // Center Point
                itemVisual.CenterPoint    = new Vector3(left + (_itemWidth / 2f), (float)padding.Top + (_itemHeight / 2f), 0);
                contentVisual.CenterPoint = itemVisual.CenterPoint;

                // Update Fluid Items
                _fluidItems[itemVisual] = new Rect(padding.Left + left, padding.Top, _itemWidth, _itemHeight);
            }

            // Update Animations' keyframes
            _expandRightInset.InsertKeyFrame(1f, _availableWidth - _itemWidth);
            _collapseInsetClip.InsertKeyFrame(1f, _availableWidth - _itemWidth);

            return(finalSize);
        }
        /// <summary>
        /// Initialize all Composition related stuff here (Compositor, Animations etc)
        /// </summary>
        private void InitializeComposition()
        {
            var rootVisual = ElementCompositionPreview.GetElementVisual(this);
            // Compositor
            _compositor = rootVisual.Compositor;
            // Composition Generator
            _generator = CompositionGeneratorFactory.GetCompositionGenerator(_compositor);

            // Final Value Expressions
            var vector3Expr = _compositor.CreateFinalValueExpression<Vector3>();
            var scalarExpr = _compositor.CreateFinalValueExpression<float>();

            // Opacity Animation
            var opacityAnimation = _compositor.CreateKeyFrameAnimation<float>()
                                              .HavingDuration(DefaultOpacityAnimationDuration)
                                              .ForTarget(() => rootVisual.Opacity);
            opacityAnimation.InsertExpressionKeyFrame(1f, scalarExpr);

            // Scale Animation
            var scaleAnimation = _compositor.CreateKeyFrameAnimation<Vector3>()
                                            .HavingDuration(DefaultScaleAnimationDuration)
                                            .ForTarget(() => rootVisual.Scale);
            scaleAnimation.InsertExpressionKeyFrame(1f, vector3Expr);

            // ImplicitAnimation
            _implicitAnimationCollection = _compositor.CreateImplicitAnimationCollection();
            _implicitAnimationCollection["Opacity"] = opacityAnimation.Animation;
            _implicitAnimationCollection["Scale"] = scaleAnimation.Animation;

            // Expand Animations
            _expandLeftInset = _compositor.CreateKeyFrameAnimation<float>()
                                          .HavingDuration(InsetAnimationDuration)
                                          .DelayBy(InsetAnimationDelayDuration);

            _expandLeftInset.InsertKeyFrame(1f, 0);

            _expandRightInset = _compositor.CreateKeyFrameAnimation<float>()
                                           .HavingDuration(InsetAnimationDuration)
                                           .DelayBy(InsetAnimationDelayDuration);

            _expandInsetClip = _compositor.CreateKeyFrameAnimation<float>()
                                          .HavingDuration(InsetClipAnimationDuration);

            _expandInsetClip.InsertKeyFrame(1f, 0);

            // Collapse Animations
            _collapseLeftInset = _compositor.CreateKeyFrameAnimation<float>()
                                            .HavingDuration(InsetAnimationDuration);

            _collapseRightInset = _compositor.CreateKeyFrameAnimation<float>()
                                             .HavingDuration(InsetAnimationDuration);

            _collapseInsetClip = _compositor.CreateKeyFrameAnimation<float>()
                                            .HavingDuration(InsetClipAnimationDuration);

            // Root Container
            _rootContainer = _compositor.CreateContainerVisual();

            // Background Layer
            _bgLayer = _compositor.CreateLayerVisual();
            _bgLayer.Size = _rootContainer.Size;
            _bgLayer.CenterPoint = new Vector3(_bgLayer.Size * 0.5f, 0);

            // Top Layer
            _topLayer = _compositor.CreateLayerVisual();
            _topLayer.Size = _rootContainer.Size;

            _rootContainer.Children.InsertAtBottom(_bgLayer);
            _rootContainer.Children.InsertAtTop(_topLayer);

            // Add the rootContainer to the visual tree
            ElementCompositionPreview.SetElementChildVisual(this, _rootContainer);
        }
示例#5
0
        /// <summary>
        /// Initialize all Composition related stuff here (Compositor, Animations etc)
        /// </summary>
        private void InitializeComposition()
        {
            var rootVisual = ElementCompositionPreview.GetElementVisual(this);

            // Compositor
            _compositor = rootVisual.Compositor;

            // Final Value Expressions
            var vector3Expr = _compositor.CreateFinalValueExpression <Vector3>();
            var scalarExpr  = _compositor.CreateFinalValueExpression <float>();

            // Opacity Animation
            var opacityAnimation = _compositor.CreateKeyFrameAnimation <float>()
                                   .HavingDuration(DefaultOpacityAnimationDuration)
                                   .ForTarget(() => rootVisual.Opacity);

            opacityAnimation.InsertExpressionKeyFrame(1f, scalarExpr);

            // Scale Animation
            var scaleAnimation = _compositor.CreateKeyFrameAnimation <Vector3>()
                                 .HavingDuration(DefaultScaleAnimationDuration)
                                 .ForTarget(() => rootVisual.Scale);

            scaleAnimation.InsertExpressionKeyFrame(1f, vector3Expr);

            // ImplicitAnimation
            _implicitAnimationCollection            = _compositor.CreateImplicitAnimationCollection();
            _implicitAnimationCollection["Opacity"] = opacityAnimation.Animation;
            _implicitAnimationCollection["Scale"]   = scaleAnimation.Animation;

            // Expand Animations
            _expandLeftInset = _compositor.CreateKeyFrameAnimation <float>()
                               .HavingDuration(InsetAnimationDuration)
                               .DelayBy(InsetAnimationDelayDuration);

            _expandLeftInset.InsertKeyFrame(1f, 0);

            _expandRightInset = _compositor.CreateKeyFrameAnimation <float>()
                                .HavingDuration(InsetAnimationDuration)
                                .DelayBy(InsetAnimationDelayDuration);

            _expandInsetClip = _compositor.CreateKeyFrameAnimation <float>()
                               .HavingDuration(InsetClipAnimationDuration);

            _expandInsetClip.InsertKeyFrame(1f, 0);

            // Collapse Animations
            _collapseLeftInset = _compositor.CreateKeyFrameAnimation <float>()
                                 .HavingDuration(InsetAnimationDuration);

            _collapseRightInset = _compositor.CreateKeyFrameAnimation <float>()
                                  .HavingDuration(InsetAnimationDuration);

            _collapseInsetClip = _compositor.CreateKeyFrameAnimation <float>()
                                 .HavingDuration(InsetClipAnimationDuration);

            // Root Container
            _rootContainer = _compositor.CreateContainerVisual();

            // Image Factory
            _imageFactory = CompositionImageFactory.CreateCompositionImageFactory(_compositor);

            // If the ItemsSource has any items then create their corresponding images
            CreateImages();
        }
示例#6
0
        /// <summary>
        /// Handles the Arrange pass during Layout
        /// </summary>
        /// <param name="finalSize">Final Size of the control</param>
        /// <returns>Total size occupied by all the Children</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            if ((ItemsSource == null) || (!ItemsSource.Any()))
            {
                return(finalSize);
            }

            var padding     = Padding;
            var paddingSize = padding.CollapseThickness();
            var width       = finalSize.Width;
            var height      = finalSize.Height;
            var itemCount   = ItemsSource.Count();

            _availableWidth  = (width - paddingSize.Width).Single();
            _availableHeight = (height - paddingSize.Height).Single();
            var gapCount              = itemCount - 1;
            var totalGap              = (gapCount * ItemGap).Single();
            var availableNonGapWidth  = _availableWidth - totalGap;
            var availableNonGapHeight = _availableHeight;

            _itemWidth    = availableNonGapWidth / itemCount;
            _itemHeight   = availableNonGapHeight;
            _bannerBounds = new Rect(padding.Left, padding.Top, _availableWidth, _availableHeight);

            // Check if any visual is currently selected. If yes then obtain its index.
            // The new visual at that index should be selected and added to the toplayer
            var selectedVisualIndex = -1;

            if (_selectedVisual != null)
            {
                foreach (var item in _fluidItems)
                {
                    selectedVisualIndex++;
                    if (ReferenceEquals(item.Key, _selectedVisual))
                    {
                        break;
                    }
                }
            }

            // Clear previous visuals
            _fluidItems.Clear();
            _rootContainer.Children.RemoveAll();
            _rootContainer.Size = finalSize.ToVector2();

            // Background Layer
            _bgLayer      = _compositor.CreateLayerVisual();
            _bgLayer.Size = _rootContainer.Size;
            _rootContainer.Children.InsertAtBottom(_bgLayer);
            _bgLayer.CenterPoint = new Vector3(_bgLayer.Size * 0.5f, 0);

            // Top Layer
            _topLayer      = _compositor.CreateLayerVisual();
            _topLayer.Size = _rootContainer.Size;
            _rootContainer.Children.InsertAtTop(_topLayer);

            // Create Visuals
            for (var i = 0; i < itemCount; i++)
            {
                // Add a visual for the background
                var bgVisual = _compositor.CreateSpriteVisual();
                bgVisual.Size  = new Vector2(_availableWidth, _availableHeight);
                bgVisual.Brush = _compositor.CreateColorBrush(ItemBackground);

                // Create the visual for the content
                var contentVisual = _compositor.CreateSpriteVisual();
                contentVisual.Offset = Vector3.Zero;
                contentVisual.Size   = new Vector2(_availableWidth, _availableHeight);

                // Load image from the Uri
                contentVisual.Brush = _compositor.CreateSurfaceBrush(_images.ElementAt(i).Surface);

                // Create the container for the content
                var container = _compositor.CreateContainerVisual();
                container.Offset = new Vector3((float)padding.Left, (float)padding.Top, 0);
                container.Size   = new Vector2(_availableWidth, _availableHeight);

                // Calculate the Inset Clip
                var left  = i * (_itemWidth + ItemGap.Single());
                var right = _availableWidth - (left + _itemWidth);
                container.Properties.InsertScalar("LeftInset", left);
                container.Properties.InsertScalar("RightInset", right);
                // If the current value of 'i' same as the index of the previously selected visual
                // then the InsetClip value should be appropriately set
                container.Clip = (i == selectedVisualIndex) ?
                                 _compositor.CreateInsetClip(0, 0, 0, 0) : _compositor.CreateInsetClip(left, 0, right, 0);

                // Center Point
                container.CenterPoint            = new Vector3(left + (_itemWidth / 2f), (float)padding.Top + (_itemHeight / 2f), 0);
                contentVisual.CenterPoint        = container.CenterPoint;
                container.ImplicitAnimations     = _implicitAnimationCollection;
                contentVisual.ImplicitAnimations = _implicitAnimationCollection;

                // Set the container content
                container.Children.InsertAtTop(contentVisual);
                container.Children.InsertAtBottom(bgVisual);

                // Is the current value of 'i' same as the index of the previously selected visual
                if (i == selectedVisualIndex)
                {
                    // Add to the Top Layer
                    _topLayer.Children.InsertAtTop(container);
                    _selectedVisual = container;
                }
                else
                {
                    // Add to Background Layer
                    _bgLayer.Children.InsertAtTop(container);
                }

                // Add Visual to the fluid items
                _fluidItems[container] = new Rect(padding.Left + left, padding.Top, _itemWidth, _itemHeight);
            }

            // If there was a previously selected visual then Scale back
            // and fade the other visuals in the banner
            if (selectedVisualIndex > -1)
            {
                //
                foreach (var child in _bgLayer.Children)
                {
                    child.Scale   = new Vector3(ScaleDownFactor, ScaleDownFactor, 1);
                    child.Opacity = TargetOpacity;
                }
            }

            // Update Animations' keyframes
            _expandRightInset.InsertKeyFrame(1f, _availableWidth - _itemWidth);
            _collapseInsetClip.InsertKeyFrame(1f, _availableWidth - _itemWidth);

            // Add the rootContainer to the visual tree
            ElementCompositionPreview.SetElementChildVisual(this, _rootContainer);

            return(base.ArrangeOverride(finalSize));
        }