예제 #1
0
        /// <summary>
        /// Creates the SurfaceImages based on the ItemsSource
        /// </summary>
        /// <returns>Task</returns>
        private async Task CreateSurfaceImagesAsync()
        {
            if (_surfaceImagesCreated)
            {
                return;
            }

            var padding = Padding;

            // Clear previous visuals
            _surfaceVisuals.Clear();
            _fluidItems.Clear();
            _bgLayer.Children.RemoveAll();
            _topLayer.Children.RemoveAll();
            _selectedVisual = null;
            // Dispose the surface images
            for (var i = 0; i < _surfaceImages.Count; i++)
            {
                var surfaceImage = _surfaceImages.ElementAt(i);
                surfaceImage.Dispose();
            }
            _surfaceImages.Clear();

            if ((ItemsSource == null) || !ItemsSource.Any())
            {
                return;
            }

            var options = ImageSurfaceOptions.Default;

            options.SurfaceBackgroundColor = Colors.Transparent;

            var availableSize = new Size(_availableWidth, _availableHeight);

            for (var i = 0; i < ItemsSource.Count(); i++)
            {
                // Create the surface image
                var surfaceImage = await _generator.CreateImageSurfaceAsync(ItemsSource.ElementAt(i), availableSize, options);

                _surfaceImages.Add(surfaceImage);

                // Add a visual for the background
                var containerVisual = _compositor.CreateSpriteVisual();
                containerVisual.Size   = availableSize.ToVector2();
                containerVisual.Brush  = _compositor.CreateColorBrush(ItemBackground);
                containerVisual.Offset = new Vector3((float)padding.Left, (float)padding.Top, 0);

                // Create the visual for the content
                var contentVisual = _compositor.CreateSpriteVisual();
                contentVisual.Size = availableSize.ToVector2();
                var surfaceBrush = _compositor.CreateSurfaceBrush(surfaceImage.Surface);
                surfaceBrush.UpdateSurfaceBrushOptions(Stretch, AlignX, AlignY);
                contentVisual.Brush = surfaceBrush;

                // Calculate the Inset Clip
                var left  = i * (_itemWidth + ItemGap.ToSingle());
                var right = _availableWidth - (left + _itemWidth);
                containerVisual.Properties.InsertScalar("LeftInset", left);
                containerVisual.Properties.InsertScalar("RightInset", right);
                containerVisual.Clip = _compositor.CreateInsetClip(left, 0, right, 0);

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

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

                // Add to Background Layer
                _bgLayer.Children.InsertAtTop(containerVisual);

                // Add Visual to the fluid items
                _fluidItems[containerVisual]  = new Rect(padding.Left + left, padding.Top, _itemWidth, _itemHeight);
                _surfaceVisuals[surfaceImage] = containerVisual;
            }
        }
예제 #2
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);
            }

            // 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).ToSingle();
            _availableHeight = (height - paddingSize.Height).ToSingle();
            var gapCount              = _itemCount - 1;
            var totalGap              = (gapCount * ItemGap).ToSingle();
            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.ToSingle());
                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);
        }