diff options
Diffstat (limited to 'MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs')
| -rw-r--r-- | MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs | 735 |
1 files changed, 0 insertions, 735 deletions
diff --git a/MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs b/MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs deleted file mode 100644 index e9753ccea..000000000 --- a/MediaBrowser.UI.Controls/VirtualizingWrapPanel.cs +++ /dev/null @@ -1,735 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Controls.Primitives; -using System.Windows.Media; - -namespace MediaBrowser.UI.Controls -{ - /// <summary> - /// http://www.codeproject.com/Articles/75847/Virtualizing-WrapPanel - /// Positions child elements in sequential position from left to right, breaking content - /// to the next line at the edge of the containing box. Subsequent ordering happens - /// sequentially from top to bottom or from right to left, depending on the value of - /// the Orientation property. - /// </summary> - [DefaultProperty("Orientation")] - public class VirtualizingWrapPanel : VirtualizingPanel, IScrollInfo - { - /// <summary> - /// Identifies the ItemHeight dependency property. - /// </summary> - public static readonly DependencyProperty ItemHeightProperty = DependencyProperty.Register("ItemHeight", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(100.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - /// <summary> - /// Identifies the Orientation dependency property. - /// </summary> - public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(VirtualizingWrapPanel), new PropertyMetadata(Orientation.Horizontal, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - /// <summary> - /// Identifies the ItemWidth dependency property. - /// </summary> - public static readonly DependencyProperty ItemWidthProperty = DependencyProperty.Register("ItemWidth", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(100.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - /// <summary> - /// Identifies the ScrollStep dependency property. - /// </summary> - public static readonly DependencyProperty ScrollStepProperty = DependencyProperty.Register("ScrollStep", typeof(double), typeof(VirtualizingWrapPanel), new PropertyMetadata(10.0, new PropertyChangedCallback(VirtualizingWrapPanel.OnAppearancePropertyChanged))); - private bool canHorizontallyScroll; - private bool canVerticallyScroll; - private Size contentExtent = new Size(0.0, 0.0); - private Point contentOffset = default(Point); - private ScrollViewer scrollOwner; - private Size viewport = new Size(0.0, 0.0); - private int previousItemCount; - /// <summary> - /// Gets or sets a value that specifies the height of all items that are - /// contained within a VirtualizingWrapPanel. This is a dependency property. - /// </summary> - public double ItemHeight - { - get - { - return (double)base.GetValue(VirtualizingWrapPanel.ItemHeightProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.ItemHeightProperty, value); - } - } - /// <summary> - /// Gets or sets a value that specifies the width of all items that are - /// contained within a VirtualizingWrapPanel. This is a dependency property. - /// </summary> - public double ItemWidth - { - get - { - return (double)base.GetValue(VirtualizingWrapPanel.ItemWidthProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.ItemWidthProperty, value); - } - } - /// <summary> - /// Gets or sets a value that specifies the dimension in which child - /// content is arranged. This is a dependency property. - /// </summary> - public Orientation Orientation - { - get - { - return (Orientation)base.GetValue(VirtualizingWrapPanel.OrientationProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.OrientationProperty, value); - } - } - /// <summary> - /// Gets or sets a value that indicates whether scrolling on the horizontal axis is possible. - /// </summary> - public bool CanHorizontallyScroll - { - get - { - return this.canHorizontallyScroll; - } - set - { - if (this.canHorizontallyScroll != value) - { - this.canHorizontallyScroll = value; - base.InvalidateMeasure(); - } - } - } - /// <summary> - /// Gets or sets a value that indicates whether scrolling on the vertical axis is possible. - /// </summary> - public bool CanVerticallyScroll - { - get - { - return this.canVerticallyScroll; - } - set - { - if (this.canVerticallyScroll != value) - { - this.canVerticallyScroll = value; - base.InvalidateMeasure(); - } - } - } - /// <summary> - /// Gets or sets a ScrollViewer element that controls scrolling behavior. - /// </summary> - public ScrollViewer ScrollOwner - { - get - { - return this.scrollOwner; - } - set - { - this.scrollOwner = value; - } - } - /// <summary> - /// Gets the vertical offset of the scrolled content. - /// </summary> - public double VerticalOffset - { - get - { - return this.contentOffset.Y; - } - } - /// <summary> - /// Gets the vertical size of the viewport for this content. - /// </summary> - public double ViewportHeight - { - get - { - return this.viewport.Height; - } - } - /// <summary> - /// Gets the horizontal size of the viewport for this content. - /// </summary> - public double ViewportWidth - { - get - { - return this.viewport.Width; - } - } - /// <summary> - /// Gets or sets a value for mouse wheel scroll step. - /// </summary> - public double ScrollStep - { - get - { - return (double)base.GetValue(VirtualizingWrapPanel.ScrollStepProperty); - } - set - { - base.SetValue(VirtualizingWrapPanel.ScrollStepProperty, value); - } - } - /// <summary> - /// Gets the vertical size of the extent. - /// </summary> - public double ExtentHeight - { - get - { - return this.contentExtent.Height; - } - } - /// <summary> - /// Gets the horizontal size of the extent. - /// </summary> - public double ExtentWidth - { - get - { - return this.contentExtent.Width; - } - } - /// <summary> - /// Gets the horizontal offset of the scrolled content. - /// </summary> - public double HorizontalOffset - { - get - { - return this.contentOffset.X; - } - } - /// <summary> - /// Scrolls down within content by one logical unit. - /// </summary> - public void LineDown() - { - this.SetVerticalOffset(this.VerticalOffset + this.ScrollStep); - } - /// <summary> - /// Scrolls left within content by one logical unit. - /// </summary> - public void LineLeft() - { - this.SetHorizontalOffset(this.HorizontalOffset - this.ScrollStep); - } - /// <summary> - /// Scrolls right within content by one logical unit. - /// </summary> - public void LineRight() - { - this.SetHorizontalOffset(this.HorizontalOffset + this.ScrollStep); - } - /// <summary> - /// Scrolls up within content by one logical unit. - /// </summary> - public void LineUp() - { - this.SetVerticalOffset(this.VerticalOffset - this.ScrollStep); - } - /// <summary> - /// Forces content to scroll until the coordinate space of a Visual object is visible. - /// </summary> - public Rect MakeVisible(Visual visual, Rect rectangle) - { - this.MakeVisible(visual as UIElement); - return rectangle; - } - /// <summary> - /// Scrolls down within content after a user clicks the wheel button on a mouse. - /// </summary> - public void MouseWheelDown() - { - this.SetVerticalOffset(this.VerticalOffset + this.ScrollStep); - } - /// <summary> - /// Scrolls left within content after a user clicks the wheel button on a mouse. - /// </summary> - public void MouseWheelLeft() - { - this.SetHorizontalOffset(this.HorizontalOffset - this.ScrollStep); - } - /// <summary> - /// Scrolls right within content after a user clicks the wheel button on a mouse. - /// </summary> - public void MouseWheelRight() - { - this.SetHorizontalOffset(this.HorizontalOffset + this.ScrollStep); - } - /// <summary> - /// Scrolls up within content after a user clicks the wheel button on a mouse. - /// </summary> - public void MouseWheelUp() - { - this.SetVerticalOffset(this.VerticalOffset - this.ScrollStep); - } - /// <summary> - /// Scrolls down within content by one page. - /// </summary> - public void PageDown() - { - this.SetVerticalOffset(this.VerticalOffset + this.ViewportHeight); - } - /// <summary> - /// Scrolls left within content by one page. - /// </summary> - public void PageLeft() - { - this.SetHorizontalOffset(this.HorizontalOffset - this.ViewportHeight); - } - /// <summary> - /// Scrolls right within content by one page. - /// </summary> - public void PageRight() - { - this.SetHorizontalOffset(this.HorizontalOffset + this.ViewportHeight); - } - /// <summary> - /// Scrolls up within content by one page. - /// </summary> - public void PageUp() - { - this.SetVerticalOffset(this.VerticalOffset - this.viewport.Height); - } - /// <summary> - /// Sets the amount of vertical offset. - /// </summary> - public void SetVerticalOffset(double offset) - { - if (offset < 0.0 || this.ViewportHeight >= this.ExtentHeight) - { - offset = 0.0; - } - else - { - if (offset + this.ViewportHeight >= this.ExtentHeight) - { - offset = this.ExtentHeight - this.ViewportHeight; - } - } - this.contentOffset.Y = offset; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// <summary> - /// Sets the amount of horizontal offset. - /// </summary> - public void SetHorizontalOffset(double offset) - { - if (offset < 0.0 || this.ViewportWidth >= this.ExtentWidth) - { - offset = 0.0; - } - else - { - if (offset + this.ViewportWidth >= this.ExtentWidth) - { - offset = this.ExtentWidth - this.ViewportWidth; - } - } - this.contentOffset.X = offset; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// <summary> - /// Note: Works only for vertical. - /// </summary> - internal void PageLast() - { - this.contentOffset.Y = this.ExtentHeight; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// <summary> - /// Note: Works only for vertical. - /// </summary> - internal void PageFirst() - { - this.contentOffset.Y = 0.0; - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - base.InvalidateMeasure(); - } - /// <summary> - /// When items are removed, remove the corresponding UI if necessary. - /// </summary> - /// <param name="sender"></param> - /// <param name="args"></param> - protected override void OnItemsChanged(object sender, ItemsChangedEventArgs args) - { - switch (args.Action) - { - case NotifyCollectionChangedAction.Remove: - case NotifyCollectionChangedAction.Replace: - case NotifyCollectionChangedAction.Move: - base.RemoveInternalChildRange(args.Position.Index, args.ItemUICount); - return; - case NotifyCollectionChangedAction.Reset: - { - ItemsControl itemsControl = ItemsControl.GetItemsOwner(this); - if (itemsControl != null) - { - if (this.previousItemCount != itemsControl.Items.Count) - { - if (this.Orientation == Orientation.Horizontal) - { - this.SetVerticalOffset(0.0); - } - else - { - this.SetHorizontalOffset(0.0); - } - } - this.previousItemCount = itemsControl.Items.Count; - } - return; - } - default: - return; - } - } - /// <summary> - /// Measure the children. - /// </summary> - /// <param name="availableSize">The available size.</param> - /// <returns>The desired size.</returns> - protected override Size MeasureOverride(Size availableSize) - { - this.InvalidateScrollInfo(availableSize); - int firstVisibleIndex; - int lastVisibleIndex; - if (this.Orientation == Orientation.Horizontal) - { - this.GetVerticalVisibleRange(out firstVisibleIndex, out lastVisibleIndex); - } - else - { - this.GetHorizontalVisibleRange(out firstVisibleIndex, out lastVisibleIndex); - } - UIElementCollection children = base.Children; - IItemContainerGenerator generator = base.ItemContainerGenerator; - if (generator != null) - { - GeneratorPosition startPos = generator.GeneratorPositionFromIndex(firstVisibleIndex); - int childIndex = (startPos.Offset == 0) ? startPos.Index : (startPos.Index + 1); - if (childIndex == -1) - { - this.RefreshOffset(); - } - using (generator.StartAt(startPos, GeneratorDirection.Forward, true)) - { - int itemIndex = firstVisibleIndex; - while (itemIndex <= lastVisibleIndex) - { - bool newlyRealized; - UIElement child = generator.GenerateNext(out newlyRealized) as UIElement; - if (newlyRealized) - { - if (childIndex >= children.Count) - { - base.AddInternalChild(child); - } - else - { - base.InsertInternalChild(childIndex, child); - } - generator.PrepareItemContainer(child); - } - if (child != null) - { - child.Measure(new Size(this.ItemWidth, this.ItemHeight)); - } - itemIndex++; - childIndex++; - } - } - this.CleanUpChildren(firstVisibleIndex, lastVisibleIndex); - } - if (IsCloseTo(availableSize.Height, double.PositiveInfinity) || IsCloseTo(availableSize.Width, double.PositiveInfinity)) - { - return base.MeasureOverride(availableSize); - } - - var itemsControl = ItemsControl.GetItemsOwner(this); - var numItems = itemsControl.Items.Count; - - var width = availableSize.Width; - var height = availableSize.Height; - - if (Orientation == Orientation.Vertical) - { - var numRows = Math.Floor(availableSize.Height / ItemHeight); - - height = numRows * ItemHeight; - - var requiredColumns = Math.Ceiling(numItems / numRows); - - width = Math.Min(requiredColumns * ItemWidth, width); - } - else - { - var numColumns = Math.Floor(availableSize.Width / ItemWidth); - - width = numColumns * ItemWidth; - - //if (numItems > 0 && numItems < numColumns) - //{ - // width = Math.Min(numColumns, numItems) * ItemWidth; - //} - - var requiredRows = Math.Ceiling(numItems / numColumns); - - height = Math.Min(requiredRows * ItemHeight, height); - } - - return new Size(width, height); - } - - /// <summary> - /// Arranges the children. - /// </summary> - /// <param name="finalSize">The available size.</param> - /// <returns>The used size.</returns> - protected override Size ArrangeOverride(Size finalSize) - { - bool isHorizontal = this.Orientation == Orientation.Horizontal; - this.InvalidateScrollInfo(finalSize); - int i = 0; - foreach (object item in base.Children) - { - this.ArrangeChild(isHorizontal, finalSize, i++, item as UIElement); - } - return finalSize; - } - private static void OnAppearancePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - UIElement panel = d as UIElement; - if (panel != null) - { - panel.InvalidateMeasure(); - } - } - private void MakeVisible(UIElement element) - { - ItemContainerGenerator generator = base.ItemContainerGenerator.GetItemContainerGeneratorForPanel(this); - if (element != null && generator != null) - { - for (int itemIndex = generator.IndexFromContainer(element); itemIndex == -1; itemIndex = generator.IndexFromContainer(element)) - { - element = element.ParentOfType<UIElement>(); - } - ScrollViewer scrollViewer = element.ParentOfType<ScrollViewer>(); - if (scrollViewer != null) - { - GeneralTransform elementTransform = element.TransformToVisual(scrollViewer); - Rect elementRectangle = elementTransform.TransformBounds(new Rect(new Point(0.0, 0.0), element.RenderSize)); - - if (this.Orientation == Orientation.Horizontal) - { - var padding = ItemHeight / 3; - - if (elementRectangle.Bottom > this.ViewportHeight) - { - this.SetVerticalOffset(this.contentOffset.Y + elementRectangle.Bottom - this.ViewportHeight + padding); - return; - } - if (elementRectangle.Top < 0.0) - { - this.SetVerticalOffset(this.contentOffset.Y + elementRectangle.Top - padding); - return; - } - } - else - { - var padding = ItemWidth / 3; - - if (elementRectangle.Right > this.ViewportWidth) - { - this.SetHorizontalOffset(this.contentOffset.X + elementRectangle.Right - this.ViewportWidth + padding); - return; - } - if (elementRectangle.Left < 0.0) - { - this.SetHorizontalOffset(this.contentOffset.X + elementRectangle.Left - padding); - } - } - } - } - } - private void GetVerticalVisibleRange(out int firstVisibleItemIndex, out int lastVisibleItemIndex) - { - int childrenPerRow = this.GetVerticalChildrenCountPerRow(this.contentExtent); - firstVisibleItemIndex = (int)Math.Floor(this.VerticalOffset / this.ItemHeight) * childrenPerRow; - lastVisibleItemIndex = (int)Math.Ceiling((this.VerticalOffset + this.ViewportHeight) / this.ItemHeight) * childrenPerRow - 1; - this.AdjustVisibleRange(ref firstVisibleItemIndex, ref lastVisibleItemIndex); - } - private void GetHorizontalVisibleRange(out int firstVisibleItemIndex, out int lastVisibleItemIndex) - { - int childrenPerRow = this.GetHorizontalChildrenCountPerRow(this.contentExtent); - firstVisibleItemIndex = (int)Math.Floor(this.HorizontalOffset / this.ItemWidth) * childrenPerRow; - lastVisibleItemIndex = (int)Math.Ceiling((this.HorizontalOffset + this.ViewportWidth) / this.ItemWidth) * childrenPerRow - 1; - this.AdjustVisibleRange(ref firstVisibleItemIndex, ref lastVisibleItemIndex); - } - private void AdjustVisibleRange(ref int firstVisibleItemIndex, ref int lastVisibleItemIndex) - { - firstVisibleItemIndex--; - lastVisibleItemIndex++; - ItemsControl itemsControl = ItemsControl.GetItemsOwner(this); - if (itemsControl != null) - { - if (firstVisibleItemIndex < 0) - { - firstVisibleItemIndex = 0; - } - if (lastVisibleItemIndex >= itemsControl.Items.Count) - { - lastVisibleItemIndex = itemsControl.Items.Count - 1; - } - } - } - private void CleanUpChildren(int minIndex, int maxIndex) - { - UIElementCollection children = base.Children; - IItemContainerGenerator generator = base.ItemContainerGenerator; - for (int i = children.Count - 1; i >= 0; i--) - { - GeneratorPosition pos = new GeneratorPosition(i, 0); - int itemIndex = generator.IndexFromGeneratorPosition(pos); - if (itemIndex < minIndex || itemIndex > maxIndex) - { - generator.Remove(pos, 1); - base.RemoveInternalChildRange(i, 1); - } - } - } - private void ArrangeChild(bool isHorizontal, Size finalSize, int index, UIElement child) - { - if (child == null) - { - return; - } - int count = isHorizontal ? this.GetVerticalChildrenCountPerRow(finalSize) : this.GetHorizontalChildrenCountPerRow(finalSize); - int itemIndex = base.ItemContainerGenerator.IndexFromGeneratorPosition(new GeneratorPosition(index, 0)); - int row = isHorizontal ? (itemIndex / count) : (itemIndex % count); - int column = isHorizontal ? (itemIndex % count) : (itemIndex / count); - Rect rect = new Rect((double)column * this.ItemWidth, (double)row * this.ItemHeight, this.ItemWidth, this.ItemHeight); - if (isHorizontal) - { - rect.Y -= this.VerticalOffset; - } - else - { - rect.X -= this.HorizontalOffset; - } - child.Arrange(rect); - } - private void InvalidateScrollInfo(Size availableSize) - { - ItemsControl ownerItemsControl = ItemsControl.GetItemsOwner(this); - if (ownerItemsControl != null) - { - Size extent = this.GetExtent(availableSize, ownerItemsControl.Items.Count); - if (extent != this.contentExtent) - { - this.contentExtent = extent; - this.RefreshOffset(); - } - if (availableSize != this.viewport) - { - this.viewport = availableSize; - this.InvalidateScrollOwner(); - } - } - } - private void RefreshOffset() - { - if (this.Orientation == Orientation.Horizontal) - { - this.SetVerticalOffset(this.VerticalOffset); - return; - } - this.SetHorizontalOffset(this.HorizontalOffset); - } - private void InvalidateScrollOwner() - { - if (this.ScrollOwner != null) - { - this.ScrollOwner.InvalidateScrollInfo(); - } - } - private Size GetExtent(Size availableSize, int itemCount) - { - if (this.Orientation == Orientation.Horizontal) - { - int childrenPerRow = this.GetVerticalChildrenCountPerRow(availableSize); - return new Size((double)childrenPerRow * this.ItemWidth, this.ItemHeight * Math.Ceiling((double)itemCount / (double)childrenPerRow)); - } - int childrenPerRow2 = this.GetHorizontalChildrenCountPerRow(availableSize); - return new Size(this.ItemWidth * Math.Ceiling((double)itemCount / (double)childrenPerRow2), (double)childrenPerRow2 * this.ItemHeight); - } - private int GetVerticalChildrenCountPerRow(Size availableSize) - { - int childrenCountPerRow; - if (availableSize.Width == double.PositiveInfinity) - { - childrenCountPerRow = base.Children.Count; - } - else - { - childrenCountPerRow = Math.Max(1, (int)Math.Floor(availableSize.Width / this.ItemWidth)); - } - return childrenCountPerRow; - } - private int GetHorizontalChildrenCountPerRow(Size availableSize) - { - int childrenCountPerRow; - if (availableSize.Height == double.PositiveInfinity) - { - childrenCountPerRow = base.Children.Count; - } - else - { - childrenCountPerRow = Math.Max(1, (int)Math.Floor(availableSize.Height / this.ItemHeight)); - } - return childrenCountPerRow; - } - - private static bool IsCloseTo(double value1, double value2) - { - return AreClose(value1, value2); - } - - private static bool AreClose(double value1, double value2) - { - if (value1 == value2) - { - return true; - } - double num = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * 2.2204460492503131E-16; - double num2 = value1 - value2; - return -num < num2 && num > num2; - } - } -}
\ No newline at end of file |
