/// <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; }
/// <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); }
/// <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); }
/// <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)); }