Example #1
0
        /// <summary>
        /// Arrange Phase
        /// </summary>
        /// <param name="finalSize">Final Size inside which the panel and its children must be arranged</param>
        /// <returns>Size consumed by the panel</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            var cellSize = new Size(ItemWidth, ItemHeight);

            if ((finalSize.Width < 0.0d) || (finalSize.Width.IsZero())
                || (finalSize.Height < 0.0d) || (finalSize.Height.IsZero()))
            {
                finalSize = cellSize;
            }

            _panelSize = finalSize;

            if (!FluidItems.Any())
            {
                return finalSize;
            }

            // Calculate how many unit cells can fit in the given width (or height) when the 
            // Orientation is Horizontal (or Vertical)
            _cellsPerLine = CalculateCellsPerLine(finalSize, cellSize, Orientation);
            // Convert the children's dimensions from Size to BitSize
            var childData = FluidItems.ToDictionary(child => child, child => new BitSize
            {
                Width = Math.Max(1, (int)Math.Floor((child.DesiredSize.Width / cellSize.Width) + 0.5)),
                Height = Math.Max(1, (int)Math.Floor((child.DesiredSize.Height / cellSize.Height) + 0.5))
            }).ToList();

            // If all the children have the same size as the cellSize then use optimized code
            // when a child is being dragged
            _isOptimized = !childData.Any(c => (c.Value.Width != 1) || (c.Value.Height != 1));

            // Calculate matrix dimensions
            var matrixWidth = 0;
            var matrixHeight = 0;
            if (Orientation == Orientation.Horizontal)
            {
                // If the maximum width required by a child is more than the calculated cellsPerLine, then
                // the matrix width should be the maximum width of that child
                matrixWidth = Math.Max(childData.Max(s => s.Value.Width), _cellsPerLine);
                // For purpose of calculating the true size of the panel, the height of the matrix must
                // be set to the cumulative height of all the children
                matrixHeight = childData.Sum(s => s.Value.Height);
            }
            else
            {
                // For purpose of calculating the true size of the panel, the width of the matrix must
                // be set to the cumulative width of all the children
                matrixWidth = childData.Sum(s => s.Value.Width);
                // If the maximum height required by a child is more than the calculated cellsPerLine, then
                // the matrix height should be the maximum height of that child
                matrixHeight = Math.Max(childData.Max(s => s.Value.Height), _cellsPerLine);
            }

            // Create FluidBitMatrix to calculate the size required by the panel
            var matrix = new FluidBitMatrix(matrixHeight, matrixWidth, Orientation);

            var startIndex = 0L;
            _bounds.Clear();

            foreach (var child in childData)
            {
                var location = matrix.FindRegion(startIndex, child.Value.Width, child.Value.Height);
                if (location.IsValid())
                {
                    // Set the bits
                    matrix.SetRegion(location, child.Value.Width, child.Value.Height);
                    // Arrange the child
                    child.Key.Arrange(new Rect(0, 0, child.Key.DesiredSize.Width, child.Key.DesiredSize.Height));
                    // Convert MatrixCell location to actual location
                    var pos = new Point(location.Col * cellSize.Width, location.Row * cellSize.Height);
                    _bounds[child.Key] = new Rect(pos, child.Key.DesiredSize);

                    if (child.Key != _dragElement)
                    {
                        // Animate the child to the new location
                        CreateTransitionAnimation(child.Key, pos);
                    }
                }

                // Update the startIndex so that the next child occupies a location the same (or greater)
                // row and/or column as this child
                if (!OptimizeChildPlacement)
                {
                    startIndex = (Orientation == Orientation.Horizontal) ? location.Row : location.Col;
                }
            }

            return finalSize;
        }
Example #2
0
        /// <summary>
        /// Arrange Phase
        /// </summary>
        /// <param name="finalSize">Final Size inside which the panel and its children must be arranged</param>
        /// <returns>Size consumed by the panel</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            var cellSize = new Size(ItemWidth, ItemHeight);

            if ((finalSize.Width < 0.0d) || (finalSize.Width.IsZero()) ||
                (finalSize.Height < 0.0d) || (finalSize.Height.IsZero()))
            {
                finalSize = cellSize;
            }

            _panelSize = finalSize;

            if (!FluidItems.Any())
            {
                return(finalSize);
            }

            // Calculate how many unit cells can fit in the given width (or height) when the
            // Orientation is Horizontal (or Vertical)
            _cellsPerLine = CalculateCellsPerLine(finalSize, cellSize, Orientation);
            // Convert the children's dimensions from Size to BitSize
            var childData = FluidItems.ToDictionary(child => child, child => new BitSize
            {
                Width  = Math.Max(1, (int)Math.Floor((child.DesiredSize.Width / cellSize.Width) + 0.5)),
                Height = Math.Max(1, (int)Math.Floor((child.DesiredSize.Height / cellSize.Height) + 0.5))
            }).ToList();

            // If all the children have the same size as the cellSize then use optimized code
            // when a child is being dragged
            _isOptimized = !childData.Any(c => (c.Value.Width != 1) || (c.Value.Height != 1));

            // Calculate matrix dimensions
            var matrixWidth  = 0;
            var matrixHeight = 0;

            if (Orientation == Orientation.Horizontal)
            {
                // If the maximum width required by a child is more than the calculated cellsPerLine, then
                // the matrix width should be the maximum width of that child
                matrixWidth = Math.Max(childData.Max(s => s.Value.Width), _cellsPerLine);
                // For purpose of calculating the true size of the panel, the height of the matrix must
                // be set to the cumulative height of all the children
                matrixHeight = childData.Sum(s => s.Value.Height);
            }
            else
            {
                // For purpose of calculating the true size of the panel, the width of the matrix must
                // be set to the cumulative width of all the children
                matrixWidth = childData.Sum(s => s.Value.Width);
                // If the maximum height required by a child is more than the calculated cellsPerLine, then
                // the matrix height should be the maximum height of that child
                matrixHeight = Math.Max(childData.Max(s => s.Value.Height), _cellsPerLine);
            }

            // Create FluidBitMatrix to calculate the size required by the panel
            var matrix = new FluidBitMatrix(matrixHeight, matrixWidth, Orientation);

            var startIndex = 0L;

            _bounds.Clear();

            foreach (var child in childData)
            {
                var location = matrix.FindRegion(startIndex, child.Value.Width, child.Value.Height);
                if (location.IsValid())
                {
                    // Set the bits
                    matrix.SetRegion(location, child.Value.Width, child.Value.Height);
                    // Arrange the child
                    child.Key.Arrange(new Rect(0, 0, child.Key.DesiredSize.Width, child.Key.DesiredSize.Height));
                    // Convert MatrixCell location to actual location
                    var pos = new Point(location.Col * cellSize.Width, location.Row * cellSize.Height);
                    _bounds[child.Key] = new Rect(pos, child.Key.DesiredSize);

                    if (child.Key != _dragElement)
                    {
                        // Animate the child to the new location
                        CreateTransitionAnimation(child.Key, pos);
                    }
                }

                // Update the startIndex so that the next child occupies a location the same (or greater)
                // row and/or column as this child
                if (!OptimizeChildPlacement)
                {
                    startIndex = (Orientation == Orientation.Horizontal) ? location.Row : location.Col;
                }
            }

            return(finalSize);
        }
Example #3
0
        /// <summary>
        /// Measure Phase
        /// </summary>
        /// <param name="availableSize">Available Size</param>
        /// <returns>Size required by the panel</returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            var availableItemSize = new Size(Double.PositiveInfinity, Double.PositiveInfinity);

            // Iterate through all the UIElements in the Children collection
            for (var i = 0; i < Children.Count; i++)
            {
                var child = Children[i];
                if (child == null)
                    continue;

                // Ask the child how much size it needs
                child.Measure(availableItemSize);
                // Check if the child is already added to the fluidElements collection
                if (FluidItems.Contains(child))
                    continue;

                // Add the child to the fluidElements collection
                FluidItems.Add(child);
                // Initialize its RenderTransform
                child.RenderTransform = CreateTransform(-ItemWidth, -ItemHeight, NORMAL_SCALE, NORMAL_SCALE);
            }

            var cellSize = new Size(ItemWidth, ItemHeight);

            if ((availableSize.Width < 0.0d) || (availableSize.Width.IsZero())
                || (availableSize.Height < 0.0d) || (availableSize.Height.IsZero())
                || !FluidItems.Any())
                return cellSize;

            // Calculate how many unit cells can fit in the given width (or height) when the 
            // Orientation is Horizontal (or Vertical)
            _cellsPerLine = CalculateCellsPerLine(availableSize, cellSize, Orientation);
            // Convert the children's dimensions from Size to BitSize
            var childData = FluidItems.Select(child => new BitSize
            {
                Width = Math.Max(1, (int)Math.Floor((child.DesiredSize.Width / cellSize.Width) + 0.5)),
                Height = Math.Max(1, (int)Math.Floor((child.DesiredSize.Height / cellSize.Height) + 0.5))
            }).ToList();
             
            // If all the children have the same size as the cellSize then use optimized code
            // when a child is being dragged
            _isOptimized = !childData.Any(c => (c.Width != 1) || (c.Height != 1));

            var matrixWidth = 0;
            var matrixHeight = 0;
            if (Orientation == Orientation.Horizontal)
            {
                // If the maximum width required by a child is more than the calculated cellsPerLine, then
                // the matrix width should be the maximum width of that child
                matrixWidth = Math.Max(childData.Max(s => s.Width), _cellsPerLine);
                // For purpose of calculating the true size of the panel, the height of the matrix must
                // be set to the cumulative height of all the children
                matrixHeight = childData.Sum(s => s.Height);
            }
            else
            {
                // For purpose of calculating the true size of the panel, the width of the matrix must
                // be set to the cumulative width of all the children
                matrixWidth = childData.Sum(s => s.Width);
                // If the maximum height required by a child is more than the calculated cellsPerLine, then
                // the matrix height should be the maximum height of that child
                matrixHeight = Math.Max(childData.Max(s => s.Height), _cellsPerLine);
            }

            // Create FluidBitMatrix to calculate the size required by the panel
            var matrix = new FluidBitMatrix(matrixHeight, matrixWidth, Orientation);

            var startIndex = 0L;

            foreach (var child in childData)
            {
                var location = matrix.FindRegion(startIndex, child.Width, child.Height);
                if (location.IsValid())
                {
                    matrix.SetRegion(location, child.Width, child.Height);
                }

                // Update the startIndex so that the next child occupies a location the same (or greater)
                // row and/or column as this child
                if (!OptimizeChildPlacement)
                {
                    startIndex = (Orientation == Orientation.Horizontal) ? location.Row : location.Col;
                }
            }

            var matrixSize = matrix.GetFilledMatrixDimensions();

            return new Size(matrixSize.Width * cellSize.Width, matrixSize.Height * cellSize.Height);
        }
Example #4
0
        /// <summary>
        /// Measure Phase
        /// </summary>
        /// <param name="availableSize">Available Size</param>
        /// <returns>Size required by the panel</returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            var availableItemSize = new Size(Double.PositiveInfinity, Double.PositiveInfinity);

            // Iterate through all the UIElements in the Children collection
            for (var i = 0; i < Children.Count; i++)
            {
                var child = Children[i];
                if (child == null)
                {
                    continue;
                }

                // Ask the child how much size it needs
                child.Measure(availableItemSize);
                // Check if the child is already added to the fluidElements collection
                if (FluidItems.Contains(child))
                {
                    continue;
                }

                // Add the child to the fluidElements collection
                FluidItems.Add(child);
                // Initialize its RenderTransform
                child.RenderTransform = CreateTransform(-ItemWidth, -ItemHeight, NORMAL_SCALE, NORMAL_SCALE);
            }

            var cellSize = new Size(ItemWidth, ItemHeight);

            if ((availableSize.Width < 0.0d) || (availableSize.Width.IsZero()) ||
                (availableSize.Height < 0.0d) || (availableSize.Height.IsZero()) ||
                !FluidItems.Any())
            {
                return(cellSize);
            }

            // Calculate how many unit cells can fit in the given width (or height) when the
            // Orientation is Horizontal (or Vertical)
            _cellsPerLine = CalculateCellsPerLine(availableSize, cellSize, Orientation);
            // Convert the children's dimensions from Size to BitSize
            var childData = FluidItems.Select(child => new BitSize
            {
                Width  = Math.Max(1, (int)Math.Floor((child.DesiredSize.Width / cellSize.Width) + 0.5)),
                Height = Math.Max(1, (int)Math.Floor((child.DesiredSize.Height / cellSize.Height) + 0.5))
            }).ToList();

            // If all the children have the same size as the cellSize then use optimized code
            // when a child is being dragged
            _isOptimized = !childData.Any(c => (c.Width != 1) || (c.Height != 1));

            var matrixWidth  = 0;
            var matrixHeight = 0;

            if (Orientation == Orientation.Horizontal)
            {
                // If the maximum width required by a child is more than the calculated cellsPerLine, then
                // the matrix width should be the maximum width of that child
                matrixWidth = Math.Max(childData.Max(s => s.Width), _cellsPerLine);
                // For purpose of calculating the true size of the panel, the height of the matrix must
                // be set to the cumulative height of all the children
                matrixHeight = childData.Sum(s => s.Height);
            }
            else
            {
                // For purpose of calculating the true size of the panel, the width of the matrix must
                // be set to the cumulative width of all the children
                matrixWidth = childData.Sum(s => s.Width);
                // If the maximum height required by a child is more than the calculated cellsPerLine, then
                // the matrix height should be the maximum height of that child
                matrixHeight = Math.Max(childData.Max(s => s.Height), _cellsPerLine);
            }

            // Create FluidBitMatrix to calculate the size required by the panel
            var matrix = new FluidBitMatrix(matrixHeight, matrixWidth, Orientation);

            var startIndex = 0L;

            foreach (var child in childData)
            {
                var location = matrix.FindRegion(startIndex, child.Width, child.Height);
                if (location.IsValid())
                {
                    matrix.SetRegion(location, child.Width, child.Height);
                }

                // Update the startIndex so that the next child occupies a location the same (or greater)
                // row and/or column as this child
                if (!OptimizeChildPlacement)
                {
                    startIndex = (Orientation == Orientation.Horizontal) ? location.Row : location.Col;
                }
            }

            var matrixSize = matrix.GetFilledMatrixDimensions();

            return(new Size(matrixSize.Width * cellSize.Width, matrixSize.Height * cellSize.Height));
        }