aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.UI.Controls/ScrollingPanel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.UI.Controls/ScrollingPanel.cs')
-rw-r--r--MediaBrowser.UI.Controls/ScrollingPanel.cs404
1 files changed, 0 insertions, 404 deletions
diff --git a/MediaBrowser.UI.Controls/ScrollingPanel.cs b/MediaBrowser.UI.Controls/ScrollingPanel.cs
deleted file mode 100644
index 636661f54..000000000
--- a/MediaBrowser.UI.Controls/ScrollingPanel.cs
+++ /dev/null
@@ -1,404 +0,0 @@
-using System;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Controls.Primitives;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-
-namespace MediaBrowser.UI.Controls
-{
- /// <summary>
- /// This started from:
- /// http://www.switchonthecode.com/tutorials/wpf-tutorial-implementing-iscrollinfo
- /// Then, after implementing this, content was being displayed in stack panel like manner.
- /// I then reviewed the source code of ScrollContentPresenter and updated MeasureOverride and ArrangeOverride to match.
- /// </summary>
- public class ScrollingPanel : Grid, IScrollInfo
- {
- /// <summary>
- /// The infinite size
- /// </summary>
- private static Size InfiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
- /// <summary>
- /// The line size
- /// </summary>
- private const double LineSize = 16;
- /// <summary>
- /// The wheel size
- /// </summary>
- private const double WheelSize = 3 * LineSize;
-
- /// <summary>
- /// The _ offset
- /// </summary>
- private Vector _Offset;
- /// <summary>
- /// The _ extent
- /// </summary>
- private Size _Extent;
- /// <summary>
- /// The _ viewport
- /// </summary>
- private Size _Viewport;
-
- /// <summary>
- /// The _ animation length
- /// </summary>
- private TimeSpan _AnimationLength = TimeSpan.FromMilliseconds(125);
-
- /// <summary>
- /// When overridden in a derived class, measures the size in layout required for child elements and determines a size for the <see cref="T:System.Windows.FrameworkElement" />-derived class.
- /// </summary>
- /// <param name="availableSize">The available size that this element can give to child elements. Infinity can be specified as a value to indicate that the element will size to whatever content is available.</param>
- /// <returns>The size that this element determines it needs during layout, based on its calculations of child element sizes.</returns>
- protected override Size MeasureOverride(Size availableSize)
- {
- if (Children == null || Children.Count == 0)
- {
- return availableSize;
- }
-
- var constraint2 = availableSize;
- if (CanHorizontallyScroll)
- {
- constraint2.Width = double.PositiveInfinity;
- }
- if (CanVerticallyScroll)
- {
- constraint2.Height = double.PositiveInfinity;
- }
-
- var uiElement = Children[0];
-
- uiElement.Measure(constraint2);
- var size = uiElement.DesiredSize;
-
- VerifyScrollData(availableSize, size);
-
- size.Width = Math.Min(availableSize.Width, size.Width);
- size.Height = Math.Min(availableSize.Height, size.Height);
-
- return size;
- }
-
- /// <summary>
- /// Arranges the content of a <see cref="T:System.Windows.Controls.Grid" /> element.
- /// </summary>
- /// <param name="arrangeSize">Specifies the size this <see cref="T:System.Windows.Controls.Grid" /> element should use to arrange its child elements.</param>
- /// <returns><see cref="T:System.Windows.Size" /> that represents the arranged size of this Grid element and its children.</returns>
- protected override Size ArrangeOverride(Size arrangeSize)
- {
- this.VerifyScrollData(arrangeSize, _Extent);
-
- if (this.Children == null || this.Children.Count == 0)
- {
- return arrangeSize;
- }
-
- TranslateTransform trans = null;
-
- var uiElement = Children[0];
-
- var finalRect = new Rect(uiElement.DesiredSize);
-
- // ScrollContentPresenter sets these to 0 - current offset
- // We need to set it to zero in order to make the animation work
- finalRect.X = 0;
- finalRect.Y = 0;
-
- finalRect.Width = Math.Max(finalRect.Width, arrangeSize.Width);
- finalRect.Height = Math.Max(finalRect.Height, arrangeSize.Height);
-
- trans = uiElement.RenderTransform as TranslateTransform;
-
- if (trans == null)
- {
- uiElement.RenderTransformOrigin = new Point(0, 0);
- trans = new TranslateTransform();
- uiElement.RenderTransform = trans;
- }
-
- uiElement.Arrange(finalRect);
-
- trans.BeginAnimation(TranslateTransform.XProperty,
- GetAnimation(0 - HorizontalOffset),
- HandoffBehavior.Compose);
- trans.BeginAnimation(TranslateTransform.YProperty,
- GetAnimation(0 - VerticalOffset),
- HandoffBehavior.Compose);
-
- return arrangeSize;
- }
-
- /// <summary>
- /// Gets the animation.
- /// </summary>
- /// <param name="toValue">To value.</param>
- /// <returns>DoubleAnimation.</returns>
- private DoubleAnimation GetAnimation(double toValue)
- {
- var animation = new DoubleAnimation(toValue, _AnimationLength);
-
- animation.EasingFunction = new ExponentialEase { EasingMode = EasingMode.EaseInOut };
-
- return animation;
- }
-
- #region Movement Methods
- /// <summary>
- /// Scrolls down within content by one logical unit.
- /// </summary>
- public void LineDown()
- { SetVerticalOffset(VerticalOffset + LineSize); }
-
- /// <summary>
- /// Scrolls up within content by one logical unit.
- /// </summary>
- public void LineUp()
- { SetVerticalOffset(VerticalOffset - LineSize); }
-
- /// <summary>
- /// Scrolls left within content by one logical unit.
- /// </summary>
- public void LineLeft()
- { SetHorizontalOffset(HorizontalOffset - LineSize); }
-
- /// <summary>
- /// Scrolls right within content by one logical unit.
- /// </summary>
- public void LineRight()
- { SetHorizontalOffset(HorizontalOffset + LineSize); }
-
- /// <summary>
- /// Scrolls down within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelDown()
- { SetVerticalOffset(VerticalOffset + WheelSize); }
-
- /// <summary>
- /// Scrolls up within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelUp()
- { SetVerticalOffset(VerticalOffset - WheelSize); }
-
- /// <summary>
- /// Scrolls left within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelLeft()
- { SetHorizontalOffset(HorizontalOffset - WheelSize); }
-
- /// <summary>
- /// Scrolls right within content after a user clicks the wheel button on a mouse.
- /// </summary>
- public void MouseWheelRight()
- { SetHorizontalOffset(HorizontalOffset + WheelSize); }
-
- /// <summary>
- /// Scrolls down within content by one page.
- /// </summary>
- public void PageDown()
- { SetVerticalOffset(VerticalOffset + ViewportHeight); }
-
- /// <summary>
- /// Scrolls up within content by one page.
- /// </summary>
- public void PageUp()
- { SetVerticalOffset(VerticalOffset - ViewportHeight); }
-
- /// <summary>
- /// Scrolls left within content by one page.
- /// </summary>
- public void PageLeft()
- { SetHorizontalOffset(HorizontalOffset - ViewportWidth); }
-
- /// <summary>
- /// Scrolls right within content by one page.
- /// </summary>
- public void PageRight()
- { SetHorizontalOffset(HorizontalOffset + ViewportWidth); }
- #endregion
-
- /// <summary>
- /// Gets or sets a <see cref="T:System.Windows.Controls.ScrollViewer" /> element that controls scrolling behavior.
- /// </summary>
- /// <value>The scroll owner.</value>
- /// <returns>A <see cref="T:System.Windows.Controls.ScrollViewer" /> element that controls scrolling behavior. This property has no default value.</returns>
- public ScrollViewer ScrollOwner { get; set; }
-
- /// <summary>
- /// Gets or sets a value that indicates whether scrolling on the horizontal axis is possible.
- /// </summary>
- /// <value><c>true</c> if this instance can horizontally scroll; otherwise, <c>false</c>.</value>
- /// <returns>true if scrolling is possible; otherwise, false. This property has no default value.</returns>
- public bool CanHorizontallyScroll { get; set; }
-
- /// <summary>
- /// Gets or sets a value that indicates whether scrolling on the vertical axis is possible.
- /// </summary>
- /// <value><c>true</c> if this instance can vertically scroll; otherwise, <c>false</c>.</value>
- /// <returns>true if scrolling is possible; otherwise, false. This property has no default value.</returns>
- public bool CanVerticallyScroll { get; set; }
-
- /// <summary>
- /// Gets the vertical size of the extent.
- /// </summary>
- /// <value>The height of the extent.</value>
- /// <returns>A <see cref="T:System.Double" /> that represents, in device independent pixels, the vertical size of the extent.This property has no default value.</returns>
- public double ExtentHeight
- { get { return _Extent.Height; } }
-
- /// <summary>
- /// Gets the horizontal size of the extent.
- /// </summary>
- /// <value>The width of the extent.</value>
- /// <returns>A <see cref="T:System.Double" /> that represents, in device independent pixels, the horizontal size of the extent. This property has no default value.</returns>
- public double ExtentWidth
- { get { return _Extent.Width; } }
-
- /// <summary>
- /// Gets the horizontal offset of the scrolled content.
- /// </summary>
- /// <value>The horizontal offset.</value>
- /// <returns>A <see cref="T:System.Double" /> that represents, in device independent pixels, the horizontal offset. This property has no default value.</returns>
- public double HorizontalOffset
- { get { return _Offset.X; } }
-
- /// <summary>
- /// Gets the vertical offset of the scrolled content.
- /// </summary>
- /// <value>The vertical offset.</value>
- /// <returns>A <see cref="T:System.Double" /> that represents, in device independent pixels, the vertical offset of the scrolled content. Valid values are between zero and the <see cref="P:System.Windows.Controls.Primitives.IScrollInfo.ExtentHeight" /> minus the <see cref="P:System.Windows.Controls.Primitives.IScrollInfo.ViewportHeight" />. This property has no default value.</returns>
- public double VerticalOffset
- { get { return _Offset.Y; } }
-
- /// <summary>
- /// Gets the vertical size of the viewport for this content.
- /// </summary>
- /// <value>The height of the viewport.</value>
- /// <returns>A <see cref="T:System.Double" /> that represents, in device independent pixels, the vertical size of the viewport for this content. This property has no default value.</returns>
- public double ViewportHeight
- { get { return _Viewport.Height; } }
-
- /// <summary>
- /// Gets the horizontal size of the viewport for this content.
- /// </summary>
- /// <value>The width of the viewport.</value>
- /// <returns>A <see cref="T:System.Double" /> that represents, in device independent pixels, the horizontal size of the viewport for this content. This property has no default value.</returns>
- public double ViewportWidth
- { get { return _Viewport.Width; } }
-
- /// <summary>
- /// Forces content to scroll until the coordinate space of a <see cref="T:System.Windows.Media.Visual" /> object is visible.
- /// </summary>
- /// <param name="visual">A <see cref="T:System.Windows.Media.Visual" /> that becomes visible.</param>
- /// <param name="rectangle">A bounding rectangle that identifies the coordinate space to make visible.</param>
- /// <returns>A <see cref="T:System.Windows.Rect" /> that is visible.</returns>
- public Rect MakeVisible(Visual visual, Rect rectangle)
- {
- if (rectangle.IsEmpty || visual == null
- || visual == this || !base.IsAncestorOf(visual))
- { return Rect.Empty; }
-
- rectangle = visual.TransformToAncestor(this).TransformBounds(rectangle);
-
- //rectangle.Inflate(50, 50);
- rectangle.Scale(1.2, 1.2);
-
- Rect viewRect = new Rect(HorizontalOffset,
- VerticalOffset, ViewportWidth, ViewportHeight);
- rectangle.X += viewRect.X;
- rectangle.Y += viewRect.Y;
-
- viewRect.X = CalculateNewScrollOffset(viewRect.Left,
- viewRect.Right, rectangle.Left, rectangle.Right);
- viewRect.Y = CalculateNewScrollOffset(viewRect.Top,
- viewRect.Bottom, rectangle.Top, rectangle.Bottom);
- SetHorizontalOffset(viewRect.X);
- SetVerticalOffset(viewRect.Y);
- rectangle.Intersect(viewRect);
- rectangle.X -= viewRect.X;
- rectangle.Y -= viewRect.Y;
-
- return rectangle;
- }
-
- /// <summary>
- /// Calculates the new scroll offset.
- /// </summary>
- /// <param name="topView">The top view.</param>
- /// <param name="bottomView">The bottom view.</param>
- /// <param name="topChild">The top child.</param>
- /// <param name="bottomChild">The bottom child.</param>
- /// <returns>System.Double.</returns>
- private static double CalculateNewScrollOffset(double topView,
- double bottomView, double topChild, double bottomChild)
- {
- bool offBottom = topChild < topView && bottomChild < bottomView;
- bool offTop = bottomChild > bottomView && topChild > topView;
- bool tooLarge = (bottomChild - topChild) > (bottomView - topView);
-
- if (!offBottom && !offTop)
- { return topView; } //Don't do anything, already in view
-
- if ((offBottom && !tooLarge) || (offTop && tooLarge))
- { return topChild; }
-
- return (bottomChild - (bottomView - topView));
- }
-
- /// <summary>
- /// Verifies the scroll data.
- /// </summary>
- /// <param name="viewport">The viewport.</param>
- /// <param name="extent">The extent.</param>
- protected void VerifyScrollData(Size viewport, Size extent)
- {
- if (double.IsInfinity(viewport.Width))
- { viewport.Width = extent.Width; }
-
- if (double.IsInfinity(viewport.Height))
- { viewport.Height = extent.Height; }
-
- _Extent = extent;
- _Viewport = viewport;
-
- _Offset.X = Math.Max(0,
- Math.Min(_Offset.X, ExtentWidth - ViewportWidth));
- _Offset.Y = Math.Max(0,
- Math.Min(_Offset.Y, ExtentHeight - ViewportHeight));
-
- if (ScrollOwner != null)
- { ScrollOwner.InvalidateScrollInfo(); }
- }
-
- /// <summary>
- /// Sets the amount of horizontal offset.
- /// </summary>
- /// <param name="offset">The degree to which content is horizontally offset from the containing viewport.</param>
- public void SetHorizontalOffset(double offset)
- {
- offset = Math.Max(0,
- Math.Min(offset, ExtentWidth - ViewportWidth));
- if (!offset.Equals(_Offset.X))
- {
- _Offset.X = offset;
- InvalidateArrange();
- }
- }
-
- /// <summary>
- /// Sets the amount of vertical offset.
- /// </summary>
- /// <param name="offset">The degree to which content is vertically offset from the containing viewport.</param>
- public void SetVerticalOffset(double offset)
- {
- offset = Math.Max(0,
- Math.Min(offset, ExtentHeight - ViewportHeight));
- if (!offset.Equals(_Offset.Y))
- {
- _Offset.Y = offset;
- InvalidateArrange();
- }
- }
- }
-}