コード例 #1
0
ファイル: FluidWrapPanel.cs プロジェクト: danartri/PanoBeam
        /// <summary>
        /// Handler for the event when the user drags the dragElement.
        /// </summary>
        /// <param name="child">UIElement being dragged</param>
        /// <param name="position">Position where the user clicked w.r.t. the UIElement being dragged</param>
        /// <param name="positionInParent">Position where the user clicked w.r.t. the FluidWrapPanel (the parentFWPanel of the UIElement being dragged</param>
        internal async Task FluidDragAsync(UIElement child, Point position, Point positionInParent)
        {
            if ((child == null) || (!IsComposing) || (_dragElement == null))
            {
                return;
            }

            // Call the event handler core on the Dispatcher. (Improves efficiency!)
            await Dispatcher.InvokeAsync(() =>
            {
                _dragElement.RenderTransform = CreateTransform(positionInParent.X - _dragStartPoint.X,
                                                               positionInParent.Y - _dragStartPoint.Y,
                                                               DragScale,
                                                               DragScale);

                // Get the index in the fluidElements list corresponding to the current mouse location
                var currentPt = positionInParent;
                var index     = GetIndexFromPoint(currentPt, _dragElement, FluidItems);

                //if (index == _originalDragIndex)
                //    return;

                Debug.WriteLine(
                    $"Current Pt: {currentPt.ToString()} OldIndex: {FluidItems.IndexOf(_dragElement)} NewIndex: {index}");
                // If no valid cell index is obtained, add the child to the end of the
                // fluidElements list.
                if ((index == -1) || (index >= FluidItems.Count))
                {
                    index = FluidItems.Count - 1;
                }

                var element = FluidItems[index];

                if (_dragElement == element)
                {
                    _lastExchangeElement = null;
                    return;
                }

                if (element == _lastExchangeElement)
                {
                    return;
                }

                _lastExchangeElement = element;
                var dragCellIndex    = FluidItems.IndexOf(_dragElement);
                FluidItems.RemoveAt(dragCellIndex);
                FluidItems.Insert(index, _dragElement);
                Debug.WriteLine("Invalidating");
                InvalidateVisual();
            });
        }
コード例 #2
0
ファイル: FluidWrapPanel.cs プロジェクト: tablesmit/wpfspark
 /// <summary>
 /// Removes all the children from the FluidWrapPanel
 /// </summary>
 private void ClearItemsSource()
 {
     FluidItems.Clear();
     Children.Clear();
 }
コード例 #3
0
ファイル: FluidWrapPanel.cs プロジェクト: tablesmit/wpfspark
        /// <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);
        }
コード例 #4
0
ファイル: FluidWrapPanel.cs プロジェクト: tablesmit/wpfspark
        /// <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));
        }