From 13fca41c237615fb4c2ed1aa560794c4c7bd5253 Mon Sep 17 00:00:00 2001 From: Tig Date: Thu, 14 Nov 2024 16:46:02 -0700 Subject: [PATCH] Fightin math. --- Terminal.Gui/Drawing/Glyphs.cs | 4 +- Terminal.Gui/View/View.ScrollBars.cs | 210 ++--- Terminal.Gui/Views/ScrollBar/ScrollBar.cs | 431 +++++----- Terminal.Gui/Views/ScrollBar/ScrollSlider.cs | 102 ++- UICatalog/Scenarios/CharacterMap/CharMap.cs | 20 +- UICatalog/Scenarios/ScrollBarDemo.cs | 48 +- UnitTests/Views/ScrollBarTests.cs | 845 +++++++++++++------ UnitTests/Views/ScrollSliderTests.cs | 54 +- 8 files changed, 1061 insertions(+), 653 deletions(-) diff --git a/Terminal.Gui/Drawing/Glyphs.cs b/Terminal.Gui/Drawing/Glyphs.cs index 2cf77699b..c3b72711f 100644 --- a/Terminal.Gui/Drawing/Glyphs.cs +++ b/Terminal.Gui/Drawing/Glyphs.cs @@ -79,10 +79,10 @@ public class GlyphDefinitions /// Continuous block meter segment (e.g. for ). public Rune ContinuousMeterSegment { get; set; } = (Rune)'█'; - /// Stipple pattern (e.g. for ). Default is Light Shade (U+2591) - ░. + /// Stipple pattern (e.g. for ). Default is Light Shade (U+2591) - ░. public Rune Stipple { get; set; } = (Rune)'░'; - /// Diamond (e.g. for . Default is Lozenge (U+25CA) - ◊. + /// Diamond. Default is Lozenge (U+25CA) - ◊. public Rune Diamond { get; set; } = (Rune)'◊'; /// Close. Default is Heavy Ballot X (U+2718) - ✘. diff --git a/Terminal.Gui/View/View.ScrollBars.cs b/Terminal.Gui/View/View.ScrollBars.cs index e56c3d4a8..8dcfe8d92 100644 --- a/Terminal.Gui/View/View.ScrollBars.cs +++ b/Terminal.Gui/View/View.ScrollBars.cs @@ -11,131 +11,131 @@ public partial class View /// private void SetupScrollBars () { - _horizontalScrollBar = new ( - () => - { - var scrollBar = new ScrollBar - { - Orientation = Orientation.Horizontal, - X = 0, - Y = Pos.AnchorEnd (), - Width = Dim.Fill ( - Dim.Func ( - () => - { - if (_verticalScrollBar.IsValueCreated) - { - return _verticalScrollBar.Value.Visible ? 1 : 0; - } + _horizontalScrollBar = new Lazy ( + () => + { + var scrollBar = new ScrollBar + { + Orientation = Orientation.Horizontal, + X = 0, + Y = Pos.AnchorEnd (), + Width = Dim.Fill ( + Dim.Func ( + () => + { + if (_verticalScrollBar.IsValueCreated) + { + return _verticalScrollBar.Value.Visible ? 1 : 0; + } - return 0; - })), - Size = GetContentSize ().Width, - Visible = false - }; + return 0; + })), + ScrollableContentSize = GetContentSize ().Width, + Visible = false + }; - Padding?.Add (scrollBar); + Padding?.Add (scrollBar); - scrollBar.Initialized += (_, _) => - { - Padding!.Thickness = Padding.Thickness with - { - Bottom = scrollBar.Visible ? Padding.Thickness.Bottom + 1 : 0 - }; + scrollBar.Initialized += (_, _) => + { + Padding!.Thickness = Padding.Thickness with + { + Bottom = scrollBar.Visible ? Padding.Thickness.Bottom + 1 : 0 + }; - scrollBar.ContentPositionChanged += (_, args) => - { - Viewport = Viewport with - { - X = Math.Min ( - args.CurrentValue, - GetContentSize ().Width - (Viewport.Width)) - }; - }; + scrollBar.PositionChanged += (_, args) => + { + Viewport = Viewport with + { + X = Math.Min ( + args.CurrentValue, + GetContentSize ().Width - (Viewport.Width)) + }; + }; - scrollBar.VisibleChanged += (_, _) => - { - Padding.Thickness = Padding.Thickness with - { - Bottom = scrollBar.Visible - ? Padding.Thickness.Bottom + 1 - : Padding.Thickness.Bottom - 1 - }; - }; - }; + scrollBar.VisibleChanged += (_, _) => + { + Padding.Thickness = Padding.Thickness with + { + Bottom = scrollBar.Visible + ? Padding.Thickness.Bottom + 1 + : Padding.Thickness.Bottom - 1 + }; + }; + }; - return scrollBar; - }); + return scrollBar; + }); - _verticalScrollBar = new ( - () => - { - var scrollBar = new ScrollBar - { - Orientation = Orientation.Vertical, - X = Pos.AnchorEnd (), - Y = Pos.Func (() => Padding.Thickness.Top), - Height = Dim.Fill ( - Dim.Func ( - () => - { - if (_horizontalScrollBar.IsValueCreated) - { - return _horizontalScrollBar.Value.Visible ? 1 : 0; - } + _verticalScrollBar = new Lazy ( + () => + { + var scrollBar = new ScrollBar + { + Orientation = Orientation.Vertical, + X = Pos.AnchorEnd (), + Y = Pos.Func (() => Padding.Thickness.Top), + Height = Dim.Fill ( + Dim.Func ( + () => + { + if (_horizontalScrollBar.IsValueCreated) + { + return _horizontalScrollBar.Value.Visible ? 1 : 0; + } - return 0; - })), - Size = GetContentSize ().Height, - Visible = false - }; + return 0; + })), + ScrollableContentSize = GetContentSize ().Height, + Visible = false + }; - Padding?.Add (scrollBar); + Padding?.Add (scrollBar); - scrollBar.Initialized += (_, _) => - { - if (Padding is { }) - { - Padding.Thickness = Padding.Thickness with - { - Right = scrollBar.Visible ? Padding.Thickness.Right + 1 : 0 - }; + scrollBar.Initialized += (_, _) => + { + if (Padding is { }) + { + Padding.Thickness = Padding.Thickness with + { + Right = scrollBar.Visible ? Padding.Thickness.Right + 1 : 0 + }; - scrollBar.ContentPositionChanged += (_, args) => - { - Viewport = Viewport with - { - Y = Math.Min (args.CurrentValue, GetContentSize ().Height - (Viewport.Height - 1)) - }; - }; + scrollBar.PositionChanged += (_, args) => + { + Viewport = Viewport with + { + Y = Math.Min (args.CurrentValue, GetContentSize ().Height - (Viewport.Height - 1)) + }; + }; - scrollBar.VisibleChanged += (_, _) => - { - Padding.Thickness = Padding.Thickness with - { - Right = scrollBar.Visible - ? Padding.Thickness.Right + 1 - : Padding.Thickness.Right - 1 - }; - }; - } - }; + scrollBar.VisibleChanged += (_, _) => + { + Padding.Thickness = Padding.Thickness with + { + Right = scrollBar.Visible + ? Padding.Thickness.Right + 1 + : Padding.Thickness.Right - 1 + }; + }; + } + }; - return scrollBar; - }); + return scrollBar; + }); ViewportChanged += (_, _) => { if (_verticalScrollBar.IsValueCreated) { - _verticalScrollBar.Value.ViewportDimension = Viewport.Height; - _verticalScrollBar.Value.ContentPosition = Viewport.Y; + _verticalScrollBar.Value.VisibleContentSize = Viewport.Height; + _verticalScrollBar.Value.Position = Viewport.Y; } if (_horizontalScrollBar.IsValueCreated) { - _horizontalScrollBar.Value.ViewportDimension = Viewport.Width; - _horizontalScrollBar.Value.ContentPosition = Viewport.X; + _horizontalScrollBar.Value.VisibleContentSize = Viewport.Width; + _horizontalScrollBar.Value.Position = Viewport.X; } }; @@ -143,11 +143,11 @@ public partial class View { if (_verticalScrollBar.IsValueCreated) { - _verticalScrollBar.Value.Size = GetContentSize ().Height; + _verticalScrollBar.Value.ScrollableContentSize = GetContentSize ().Height; } if (_horizontalScrollBar.IsValueCreated) { - _horizontalScrollBar.Value.Size = GetContentSize ().Width; + _horizontalScrollBar.Value.ScrollableContentSize = GetContentSize ().Width; } }; } diff --git a/Terminal.Gui/Views/ScrollBar/ScrollBar.cs b/Terminal.Gui/Views/ScrollBar/ScrollBar.cs index 7a37b8d81..5f8a3e49f 100644 --- a/Terminal.Gui/Views/ScrollBar/ScrollBar.cs +++ b/Terminal.Gui/Views/ScrollBar/ScrollBar.cs @@ -38,7 +38,7 @@ public class ScrollBar : View, IOrientation, IDesignable _slider = new () { - ShrinkBy = 2, // For the buttons + SliderPadding = 2, // For the buttons }; _slider.Scrolled += SliderOnScroll; _slider.PositionChanged += SliderOnPositionChanged; @@ -66,13 +66,13 @@ public class ScrollBar : View, IOrientation, IDesignable void OnDecreaseButtonOnAccept (object? s, CommandEventArgs e) { - ContentPosition -= Increment; + Position -= Increment; e.Cancel = true; } void OnIncreaseButtonOnAccept (object? s, CommandEventArgs e) { - ContentPosition += Increment; + Position += Increment; e.Cancel = true; } } @@ -80,54 +80,42 @@ public class ScrollBar : View, IOrientation, IDesignable /// protected override void OnFrameChanged (in Rectangle frame) { + if (Orientation == Orientation.Vertical) + { + _slider.VisibleContentSize = Viewport.Height; + } + else + { + _slider.VisibleContentSize = Viewport.Width ; + } + ShowHide (); } private void ShowHide () { - if (!AutoHide || !IsInitialized) + if (!AutoHide) { return; } if (Orientation == Orientation.Vertical) { - Visible = Frame.Height < Size; + Visible = Frame.Height < ScrollableContentSize; } else { - Visible = Frame.Width < Size; + Visible = Frame.Width < ScrollableContentSize; } + + _slider.Size = CalculateSliderSize (); + _slider.Position = CalculateSliderPosition (_position, NavigationDirection.Forward); } /// protected override void OnSubviewLayout (LayoutEventArgs args) { - _slider.Size = CalculateSliderSize (); - if (Orientation == Orientation.Vertical) - { - _slider.ViewportDimension = Viewport.Height - _slider.ShrinkBy; - } - else - { - _slider.ViewportDimension = Viewport.Width - _slider.ShrinkBy; - } - } - - /// - /// INTERNAL (for unit tests). Calclates the size of the slider based on the Orientation, ViewportDimension, the actual Viewport, and Size. - /// - /// - internal int CalculateSliderSize () - { - if (Size <= 0 || ViewportDimension <= 0) - { - return 1; - } - - int viewport = Orientation == Orientation.Vertical ? Viewport.Height : Viewport.Width; - return (int)Math.Clamp (Math.Floor ((double)ViewportDimension / Size * (viewport - 2)), 1, ViewportDimension); } private void PositionSubviews () @@ -215,12 +203,19 @@ public class ScrollBar : View, IOrientation, IDesignable #endregion - + /// + /// Gets or sets the amount each mouse wheel event will incremenet/decrement the . + /// + /// + /// The default is 1. + /// + public int Increment { get; set; } = 1; + private bool _autoHide = true; /// /// Gets or sets whether will be set to if the dimension of the - /// scroll bar is greater than or equal to . + /// scroll bar is greater than or equal to . /// public bool AutoHide { @@ -251,7 +246,7 @@ public class ScrollBar : View, IOrientation, IDesignable /// /// Gets or sets whether the Scroll will show the percentage the slider - /// takes up within the . + /// takes up within the . /// public bool ShowPercent { @@ -259,61 +254,211 @@ public class ScrollBar : View, IOrientation, IDesignable set => _slider.ShowPercent = value; } - private int? _viewportDimension; + private int? _visibleContentSize; /// - /// Gets or sets the size of the viewport into the content being scrolled, bounded by . + /// Gets or sets the size of the visible viewport into the content being scrolled, bounded by . /// /// /// If not explicitly set, will be the appropriate dimension of the Scroll's Frame. /// - public int ViewportDimension + public int VisibleContentSize { get { - if (_viewportDimension.HasValue) + if (_visibleContentSize.HasValue) { - return _viewportDimension.Value; + return _visibleContentSize.Value; } return Orientation == Orientation.Vertical ? Frame.Height : Frame.Width; } - set => _viewportDimension = value; - } - - private int _size; - - /// - /// Gets or sets the size of the content that can be scrolled. - /// - public int Size - { - get => _size; set { - if (value == _size || value < 0) + _visibleContentSize = value; + _slider.Size = CalculateSliderSize (); + } + } + + private int _scrollableContentSize; + + /// + /// Gets or sets the size of the content that can be scrolled. This is typically set to . + /// + public int ScrollableContentSize + { + get => _scrollableContentSize; + set + { + if (value == _scrollableContentSize || value < 0) { return; } - _size = value; - OnSizeChanged (_size); - SizeChanged?.Invoke (this, new (in _size)); + _scrollableContentSize = value; + _slider.Size = CalculateSliderSize (); + OnSizeChanged (_scrollableContentSize); + ScrollableContentSizeChanged?.Invoke (this, new (in _scrollableContentSize)); SetNeedsLayout (); } } - /// Called when has changed. + /// Called when has changed. protected virtual void OnSizeChanged (int size) { } - /// Raised when has changed. - public event EventHandler>? SizeChanged; + /// Raised when has changed. + public event EventHandler>? ScrollableContentSizeChanged; - #region SliderPosition + #region Position + + private int _position; + + /// + /// Gets or sets the position of the slider relative to . + /// + /// + /// + /// The content position is clamped to 0 and minus . + /// + /// + /// Setting will result in the and + /// events being raised. + /// + /// + public int Position + { + get => _position; + set + { + if (value == _position) + { + return; + } + + // Clamp the value between 0 and Size - VisibleContentSize + int newContentPosition = (int)Math.Clamp (value, 0, Math.Max (0, ScrollableContentSize - VisibleContentSize)); + NavigationDirection direction = newContentPosition >= _position ? NavigationDirection.Forward : NavigationDirection.Backward; + + if (OnPositionChanging (_position, newContentPosition)) + { + return; + } + + CancelEventArgs args = new (ref _position, ref newContentPosition); + PositionChanging?.Invoke (this, args); + + if (args.Cancel) + { + return; + } + + int distance = newContentPosition - _position; + + _position = newContentPosition; + + OnPositionChanged (_position); + PositionChanged?.Invoke (this, new (in _position)); + + OnScrolled (distance); + Scrolled?.Invoke (this, new (in distance)); + + int currentSliderPosition = _slider.Position; + + //_slider.Size = CalculateSliderSize (); + + //int calculatedSliderPosition = CalculateSliderPosition (_position, direction); + + //_slider.MoveToPosition (calculatedSliderPosition); + + _slider.Size = CalculateSliderSize (); + int calculatedSliderPosition = CalculateSliderPosition (_position, direction); + + RaiseSliderPositionChangeEvents (calculatedSliderPosition, currentSliderPosition); + + } + } + + /// + /// Called when is changing. Return true to cancel the change. + /// + protected virtual bool OnPositionChanging (int currentPos, int newPos) { return false; } + + /// + /// Raised when the is changing. Set to + /// to prevent the position from being changed. + /// + public event EventHandler>? PositionChanging; + + /// Called when has changed. + protected virtual void OnPositionChanged (int position) { } + + /// Raised when the has changed. + public event EventHandler>? PositionChanged; + + /// Called when has changed. Indicates how much to scroll. + protected virtual void OnScrolled (int distance) { } + + /// Raised when the has changed. Indicates how much to scroll. + public event EventHandler>? Scrolled; + + + /// + /// INTERNAL API (for unit tests) - Calculates the position within the based on the slider position. + /// + /// + /// Clamps the sliderPosition, ensuring the returned content position is always less than + /// - . + /// + /// + /// + internal int CalculatePosition (int sliderPosition) + { + // Clamp the slider + int clampedSliderPosition = _slider.ClampPosition (sliderPosition); + int scrollBarSize = Orientation == Orientation.Vertical ? Viewport.Height : Viewport.Width; + double pos = (double)(clampedSliderPosition) / + (scrollBarSize - _slider.Size - _slider.SliderPadding) * (ScrollableContentSize - VisibleContentSize); + + if (pos is double.NaN) + { + return 0; + } + double rounded = Math.Ceiling (pos); + + // Clamp between 0 and Size - SliderSize + return (int)Math.Clamp (rounded, 0, Math.Max (0, ScrollableContentSize - _slider.Size)); + } + + #endregion ContentPosition + + + #region Slider Management + + /// + /// INTERNAL (for unit tests). Calculates the size of the slider based on the Orientation, VisibleContentSize, the actual Viewport, and Size. + /// + /// + internal int CalculateSliderSize () + { + int maxSliderSize = (Orientation == Orientation.Vertical ? Viewport.Height : Viewport.Width) - 2; + + if (maxSliderSize < 1 || VisibleContentSize == 0) + { + return 1; + } + + //if (ScrollableContentSize < VisibleContentSize) + //{ + // return maxSliderSize ; + //} + + int size = (int)Math.Clamp (Math.Floor ((double)VisibleContentSize / ScrollableContentSize * (maxSliderSize)), 1, VisibleContentSize); + return Math.Clamp (size, 1, maxSliderSize); + } private void SliderOnPositionChanged (object? sender, EventArgs e) { - if (ViewportDimension == 0) + if (VisibleContentSize == 0) { return; } @@ -325,24 +470,24 @@ public class ScrollBar : View, IOrientation, IDesignable private void SliderOnScroll (object? sender, EventArgs e) { - if (ViewportDimension == 0) + if (VisibleContentSize == 0) { return; } - int calculatedSliderPos = CalculateSliderPosition (_contentPosition, e.CurrentValue >= 0 ? NavigationDirection.Forward : NavigationDirection.Backward); + int calculatedSliderPos = CalculateSliderPosition (_position, e.CurrentValue >= 0 ? NavigationDirection.Forward : NavigationDirection.Backward); int sliderScrolledAmount = e.CurrentValue; - int scrolledAmount = CalculateContentPosition (sliderScrolledAmount); + int scrolledAmount = CalculatePosition (sliderScrolledAmount); RaiseSliderPositionChangeEvents (calculatedSliderPos, _slider.Position); - ContentPosition = _contentPosition + scrolledAmount; + Position = _position + scrolledAmount; } /// /// Gets or sets the position of the start of the Scroll slider, within the Viewport. /// - public int GetSliderPosition () => CalculateSliderPosition (_contentPosition); + public int GetSliderPosition () => CalculateSliderPosition (_position); private void RaiseSliderPositionChangeEvents (int calculatedSliderPosition, int newSliderPosition) { @@ -364,131 +509,27 @@ public class ScrollBar : View, IOrientation, IDesignable /// Raised when the slider position has changed. public event EventHandler>? SliderPositionChanged; - private int CalculateSliderPosition (int contentPosition, NavigationDirection direction = NavigationDirection.Forward) + /// + /// INTERNAL API (for unit tests) - Calculates the position of the slider based on the content position. + /// + /// + /// + /// + internal int CalculateSliderPosition (int contentPosition, NavigationDirection direction = NavigationDirection.Forward) { - if (Size - ViewportDimension == 0) + int scrollBarSize = Orientation == Orientation.Vertical ? Viewport.Height : Viewport.Width; + if (scrollBarSize < 3 || ScrollableContentSize - VisibleContentSize == 0) { return 0; } - int scrollBarSize = Orientation == Orientation.Vertical ? Viewport.Height : Viewport.Width; - double newSliderPosition = (double)contentPosition / (Size - ViewportDimension) * (scrollBarSize - _slider.Size - _slider.ShrinkBy); + double newSliderPosition = (double)(contentPosition - 1) / (ScrollableContentSize - VisibleContentSize) * (scrollBarSize - _slider.Size - _slider.SliderPadding); - return direction == NavigationDirection.Forward ? (int)Math.Floor (newSliderPosition) : (int)Math.Ceiling (newSliderPosition); - } - - /// - /// INTERNAL API (for unit tests) - Calculates the content position based on the slider position. - /// - /// - /// Clamps the sliderPosition, ensuring the returned content position is always less than - /// Size - VieportDimension. - /// - /// - /// - internal int CalculateContentPosition (int sliderPosition) - { - // Clamp the slider - int clampedSliderPosition = _slider.ClampPosition (sliderPosition); - int scrollBarSize = Orientation == Orientation.Vertical ? Viewport.Height : Viewport.Width; - double pos = (double)(clampedSliderPosition) / - (scrollBarSize - _slider.Size - _slider.ShrinkBy) * (Size - ViewportDimension); - double rounded = Math.Round (pos); - - // Clamp between 0 and Size - SliderSize - return (int)Math.Clamp (pos, 0, Math.Max (0, Size - _slider.Size)); + return Math.Clamp (direction == NavigationDirection.Forward ? (int)Math.Floor (newSliderPosition) : (int)Math.Ceiling (newSliderPosition), 0, scrollBarSize - _slider.Size - _slider.SliderPadding); } - #endregion SliderPosition - - #region ContentPosition - - private int _contentPosition; - - /// - /// Gets or sets the position of the slider relative to . - /// - /// - /// - /// The content position is clamped to 0 and minus . - /// - /// - /// Setting will result in the and - /// events being raised. - /// - /// - public int ContentPosition - { - get => _contentPosition; - set - { - if (value == _contentPosition) - { - return; - } - - // Clamp the value between 0 and Size - ViewportDimension - int newContentPosition = (int)Math.Clamp (value, 0, Math.Max (0, Size - ViewportDimension)); - NavigationDirection direction = newContentPosition >= _contentPosition ? NavigationDirection.Forward : NavigationDirection.Backward; - - if (OnContentPositionChanging (_contentPosition, newContentPosition)) - { - return; - } - - CancelEventArgs args = new (ref _contentPosition, ref newContentPosition); - ContentPositionChanging?.Invoke (this, args); - - if (args.Cancel) - { - return; - } - - int distance = newContentPosition - _contentPosition; - - _contentPosition = newContentPosition; - - OnContentPositionChanged (_contentPosition); - ContentPositionChanged?.Invoke (this, new (in _contentPosition)); - - OnScrolled (distance); - Scrolled?.Invoke (this, new (in distance)); - - int currentSliderPosition = _slider.Position; - int calculatedSliderPosition = CalculateSliderPosition (_contentPosition, direction); - - _slider.MoveToPosition (calculatedSliderPosition); - - RaiseSliderPositionChangeEvents (currentSliderPosition, _slider.Position); - - } - } - - /// - /// Called when is changing. Return true to cancel the change. - /// - protected virtual bool OnContentPositionChanging (int currentPos, int newPos) { return false; } - - /// - /// Raised when the is changing. Set to - /// to prevent the position from being changed. - /// - public event EventHandler>? ContentPositionChanging; - - /// Called when has changed. - protected virtual void OnContentPositionChanged (int position) { } - - /// Raised when the has changed. - public event EventHandler>? ContentPositionChanged; - - /// Called when has changed. Indicates how much to scroll. - protected virtual void OnScrolled (int distance) { } - - /// Raised when the has changed. Indicates how much to scroll. - public event EventHandler>? Scrolled; - - #endregion ContentPosition + #endregion Slider Management /// protected override bool OnClearingViewport () @@ -531,38 +572,28 @@ public class ScrollBar : View, IOrientation, IDesignable #if PROPORTIONAL_SCROLL_JUMP // BUGBUG: This logic mostly works to provide a proportional jump. However, the math - // BUGBUG: falls apart in edge cases. Most other scroll bars (e.g. Windows) do not do prooportional + // BUGBUG: falls apart in edge cases. Most other scroll bars (e.g. Windows) do not do proportional // BUGBUG: Thus, this is disabled and we just jump a page each click. // Ratio of the distance to the viewport dimension - double ratio = (double)Math.Abs (distanceFromCenter) / (ViewportDimension); + double ratio = (double)Math.Abs (distanceFromCenter) / (VisibleContentSize); // Jump size based on the ratio and the total content size - int jump = (int)(ratio * (Size - ViewportDimension)); + int jump = (int)(ratio * (Size - VisibleContentSize)); #else - int jump = (ViewportDimension); + int jump = (VisibleContentSize); #endif // Adjust the content position based on the distance if (distanceFromCenter < 0) { - ContentPosition = Math.Max (0, ContentPosition - jump); + Position = Math.Max (0, Position - jump); } else { - ContentPosition = Math.Min (Size - _slider.ViewportDimension, ContentPosition + jump); + Position = Math.Min (ScrollableContentSize - _slider.VisibleContentSize, Position + jump); } return true; } - - - /// - /// Gets or sets the amount each mouse hweel event will incremenet/decrement the . - /// - /// - /// The default is 1. - /// - public int Increment { get; set; } = 1; - /// protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { @@ -580,24 +611,24 @@ public class ScrollBar : View, IOrientation, IDesignable { if (mouseEvent.Flags.HasFlag (MouseFlags.WheeledDown)) { - ContentPosition += Increment; + Position += Increment; } if (mouseEvent.Flags.HasFlag (MouseFlags.WheeledUp)) { - ContentPosition -= Increment; + Position -= Increment; } } else { if (mouseEvent.Flags.HasFlag (MouseFlags.WheeledRight)) { - ContentPosition += Increment; + Position += Increment; } if (mouseEvent.Flags.HasFlag (MouseFlags.WheeledLeft)) { - ContentPosition -= Increment; + Position -= Increment; } } @@ -623,7 +654,7 @@ public class ScrollBar : View, IOrientation, IDesignable Width = 1; Height = Dim.Fill (); - Size = 250; + ScrollableContentSize = 250; return true; } diff --git a/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs b/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs index 7bf313f83..d82082e86 100644 --- a/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs +++ b/Terminal.Gui/Views/ScrollBar/ScrollSlider.cs @@ -40,7 +40,14 @@ public class ScrollSlider : View, IOrientation, IDesignable FrameChanged += (sender, args) => { - + //if (Orientation == Orientation.Vertical) + //{ + // Size = Frame.Height; + //} + //else + //{ + // Size = Frame.Width; + //} }; SubviewLayout += (sender, args) => @@ -49,7 +56,7 @@ public class ScrollSlider : View, IOrientation, IDesignable SubviewsLaidOut += (sender, args) => { - + }; } @@ -85,10 +92,12 @@ public class ScrollSlider : View, IOrientation, IDesignable // Reset opposite dim to Dim.Fill () if (Orientation == Orientation.Vertical) { + Height = Width; Width = Dim.Fill (); } else { + Width = Height; Height = Dim.Fill (); } SetNeedsLayout (); @@ -149,7 +158,7 @@ public class ScrollSlider : View, IOrientation, IDesignable return; } - _size = Math.Clamp (value, 1, ViewportDimension); + _size = Math.Clamp (value, 1, VisibleContentSize); if (Orientation == Orientation.Vertical) @@ -164,32 +173,32 @@ public class ScrollSlider : View, IOrientation, IDesignable } } - private int? _viewportDimension; + private int? _visibleContentSize; /// /// Gets or sets the size of the viewport into the content being scrolled. If not explicitly set, will be the /// greater of 1 and the dimension of the . /// - public int ViewportDimension + public int VisibleContentSize { get { - if (_viewportDimension.HasValue) + if (_visibleContentSize.HasValue) { - return _viewportDimension.Value; + return _visibleContentSize.Value; } return Math.Max (1, Orientation == Orientation.Vertical ? SuperView?.Viewport.Height ?? 2048 : SuperView?.Viewport.Width ?? 2048); } set { - if (value == _viewportDimension) + if (value == _visibleContentSize) { return; } - _viewportDimension = int.Max (1, value); - - if (_position > _viewportDimension - _size) + _visibleContentSize = int.Max (1, value); + + if (_position > _visibleContentSize - _size) { Position = _position; } @@ -229,11 +238,11 @@ public class ScrollSlider : View, IOrientation, IDesignable { if (Orientation == Orientation.Vertical) { - Y = _position + ShrinkBy / 2; + Y = _position + SliderPadding / 2; } else { - X = _position + ShrinkBy / 2; + X = _position + SliderPadding / 2; } } @@ -245,7 +254,7 @@ public class ScrollSlider : View, IOrientation, IDesignable /// internal int ClampPosition (int newPosition) { - return Math.Clamp (newPosition, 0, Math.Max (0, ViewportDimension - Size)); + return Math.Clamp (newPosition, 0, Math.Max (0, VisibleContentSize - SliderPadding - Size)); } private void RaisePositionChangeEvents (int newPosition) @@ -333,7 +342,14 @@ public class ScrollSlider : View, IOrientation, IDesignable ///// private int _lastLocation = -1; - public int ShrinkBy { get; set; } + /// + /// Gets or sets the amount to pad the start and end of the scroll slider. The default is 0. + /// + /// + /// When the scroll slider is used by , which has increment and decrement buttons, the + /// SliderPadding should be set to the size of the buttons (typically 2). + /// + public int SliderPadding { get; set; } /// protected override bool OnMouseEvent (MouseEventArgs mouseEvent) @@ -348,9 +364,9 @@ public class ScrollSlider : View, IOrientation, IDesignable return true; } - int location = (Orientation == Orientation.Vertical ? mouseEvent.Position.Y : mouseEvent.Position.X) + ShrinkBy / 2; - int offset = _lastLocation > -1 ? location - _lastLocation : 0; - int superViewDimension = ViewportDimension; + int location = (Orientation == Orientation.Vertical ? mouseEvent.Position.Y : mouseEvent.Position.X); + int offsetFromLastLocation = _lastLocation > -1 ? location - _lastLocation : 0; + int superViewDimension = VisibleContentSize; if (mouseEvent.IsPressed || mouseEvent.IsReleased) { @@ -364,22 +380,35 @@ public class ScrollSlider : View, IOrientation, IDesignable } else if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)) { + int currentLocation; if (Orientation == Orientation.Vertical) { - Y = Frame.Y + offset < ShrinkBy / 2 - ? ShrinkBy / 2 - : Frame.Y + offset + Frame.Height > superViewDimension - ? Math.Max (superViewDimension - Frame.Height + ShrinkBy, 1) - : Frame.Y + offset; + currentLocation = Frame.Y; } else { - X = Frame.X + offset < ShrinkBy / 2 - ? ShrinkBy / 2 - : Frame.X + offset + Frame.Width > superViewDimension - ? Math.Max (superViewDimension - Frame.Width + ShrinkBy / 2, 1) - : Frame.X + offset; + currentLocation = Frame.X; } + + // location does not account for the ShrinkBy + int sliderLowerBound = SliderPadding / 2; + int sliderUpperBound = superViewDimension - SliderPadding / 2 - Size; + + int newLocation = currentLocation + offsetFromLastLocation; + Position = newLocation; + + //if (location > 0 && location < sliderLowerBound) + //{ + // Position = 0; + //} + //else if (location > sliderUpperBound) + //{ + // Position = superViewDimension - Size; + //} + //else + //{ + // Position = currentLocation + offsetFromLastLocation; + //} } else if (mouseEvent.Flags == MouseFlags.Button1Released) { @@ -400,22 +429,9 @@ public class ScrollSlider : View, IOrientation, IDesignable /// public bool EnableForDesign () { - OrientationChanged += (sender, args) => - { - if (args.CurrentValue == Orientation.Vertical) - { - Width = Dim.Fill (); - Size = 5; - } - else - { - Size = 5; - Height = Dim.Fill (); - } - }; - - Orientation = Orientation.Horizontal; +// Orientation = Orientation.Horizontal; ShowPercent = true; + Size = 5; return true; } diff --git a/UICatalog/Scenarios/CharacterMap/CharMap.cs b/UICatalog/Scenarios/CharacterMap/CharMap.cs index 6497d50d6..8fae22bf4 100644 --- a/UICatalog/Scenarios/CharacterMap/CharMap.cs +++ b/UICatalog/Scenarios/CharacterMap/CharMap.cs @@ -149,7 +149,7 @@ public class CharMap : View, IDesignable Y = Pos.AnchorEnd (), Orientation = Orientation.Horizontal, Width = Dim.Fill (1), - Size = GetContentSize ().Width - RowLabelWidth, + ScrollableContentSize = GetContentSize ().Width - RowLabelWidth, Increment = COLUMN_WIDTH, }; @@ -159,12 +159,12 @@ public class CharMap : View, IDesignable X = Pos.AnchorEnd (), Y = 1, // Header Height = Dim.Fill (Dim.Func (() => Padding.Thickness.Bottom)), - Size = GetContentSize ().Height + ScrollableContentSize = GetContentSize ().Height }; Padding.Add (_vScrollBar, _hScrollBar); - _vScrollBar.ContentPositionChanged += (sender, args) => + _vScrollBar.PositionChanged += (sender, args) => { if (Viewport.Height > 0) { @@ -179,7 +179,7 @@ public class CharMap : View, IDesignable { //ScrollVertical (args.CurrentValue); }; - _hScrollBar.ContentPositionChanged += (sender, args) => + _hScrollBar.PositionChanged += (sender, args) => { if (Viewport.Width > 0) { @@ -234,8 +234,8 @@ public class CharMap : View, IDesignable ScrollHorizontal (newCursor.X - Viewport.Width + 1); } - _vScrollBar.ContentPosition = Viewport.Y; - _hScrollBar.ContentPosition = Viewport.X; + _vScrollBar.Position = Viewport.Y; + _hScrollBar.Position = Viewport.X; } #region Cursor @@ -524,7 +524,7 @@ public class CharMap : View, IDesignable if (e.Flags == MouseFlags.WheeledDown) { ScrollVertical (1); - _vScrollBar.ContentPosition = Viewport.Y; + _vScrollBar.Position = Viewport.Y; e.Handled = true; return; @@ -533,7 +533,7 @@ public class CharMap : View, IDesignable if (e.Flags == MouseFlags.WheeledUp) { ScrollVertical (-1); - _vScrollBar.ContentPosition = Viewport.Y; + _vScrollBar.Position = Viewport.Y; e.Handled = true; return; @@ -542,7 +542,7 @@ public class CharMap : View, IDesignable if (e.Flags == MouseFlags.WheeledRight) { ScrollHorizontal (1); - _hScrollBar.ContentPosition = Viewport.X; + _hScrollBar.Position = Viewport.X; e.Handled = true; return; @@ -551,7 +551,7 @@ public class CharMap : View, IDesignable if (e.Flags == MouseFlags.WheeledLeft) { ScrollHorizontal (-1); - _hScrollBar.ContentPosition = Viewport.X; + _hScrollBar.Position = Viewport.X; e.Handled = true; } } diff --git a/UICatalog/Scenarios/ScrollBarDemo.cs b/UICatalog/Scenarios/ScrollBarDemo.cs index 885513ace..c32e4b0f3 100644 --- a/UICatalog/Scenarios/ScrollBarDemo.cs +++ b/UICatalog/Scenarios/ScrollBarDemo.cs @@ -36,7 +36,7 @@ public class ScrollBarDemo : Scenario { X = Pos.AnchorEnd () - 5, AutoHide = false, - Size = 100, + ScrollableContentSize = 100, //ShowPercent = true }; demoFrame.Add (scrollBar); @@ -52,7 +52,7 @@ public class ScrollBarDemo : Scenario demoFrame.Add (controlledList); // populate the list box with Size items of the form "{n:00000}" - controlledList.SetSource (new ObservableCollection (Enumerable.Range (0, scrollBar.Size).Select (n => $"{n:00000}"))); + controlledList.SetSource (new ObservableCollection (Enumerable.Range (0, scrollBar.ScrollableContentSize).Select (n => $"{n:00000}"))); int GetMaxLabelWidth (int groupId) { @@ -167,7 +167,7 @@ public class ScrollBarDemo : Scenario NumericUpDown scrollSize = new () { - Value = scrollBar.Size, + Value = scrollBar.ScrollableContentSize, X = Pos.Right (lblSize) + 1, Y = Pos.Top (lblSize) }; @@ -182,30 +182,30 @@ public class ScrollBarDemo : Scenario return; } - if (scrollBar.Size != e.NewValue) + if (scrollBar.ScrollableContentSize != e.NewValue) { - scrollBar.Size = e.NewValue; + scrollBar.ScrollableContentSize = e.NewValue; } }; - var lblViewportDimension = new Label + var lblVisibleContentSize = new Label { - Text = "_ViewportDimension::", + Text = "_VisibleContentSize::", TextAlignment = Alignment.End, Y = Pos.Align (Alignment.Start, groupId: 1), Width = Dim.Func (() => GetMaxLabelWidth (1)) }; - demoFrame.Add (lblViewportDimension); + demoFrame.Add (lblVisibleContentSize); - NumericUpDown viewportDimension = new () + NumericUpDown VisibleContentSize = new () { - Value = scrollBar.ViewportDimension, - X = Pos.Right (lblViewportDimension) + 1, - Y = Pos.Top (lblViewportDimension) + Value = scrollBar.VisibleContentSize, + X = Pos.Right (lblVisibleContentSize) + 1, + Y = Pos.Top (lblVisibleContentSize) }; - demoFrame.Add (viewportDimension); + demoFrame.Add (VisibleContentSize); - viewportDimension.ValueChanging += (s, e) => + VisibleContentSize.ValueChanging += (s, e) => { if (e.NewValue < 0) { @@ -214,9 +214,9 @@ public class ScrollBarDemo : Scenario return; } - if (scrollBar.ViewportDimension != e.NewValue) + if (scrollBar.VisibleContentSize != e.NewValue) { - scrollBar.ViewportDimension = e.NewValue; + scrollBar.VisibleContentSize = e.NewValue; } }; @@ -281,12 +281,12 @@ public class ScrollBarDemo : Scenario return; } - if (scrollBar.ContentPosition != e.NewValue) + if (scrollBar.Position != e.NewValue) { - scrollBar.ContentPosition = e.NewValue; + scrollBar.Position = e.NewValue; } - if (scrollBar.ContentPosition != e.NewValue) + if (scrollBar.Position != e.NewValue) { e.Cancel = true; } @@ -351,7 +351,7 @@ public class ScrollBarDemo : Scenario lblScrollFrame.Text = $"Scroll Frame: {scrollBar.Frame.ToString ()}"; lblScrollViewport.Text = $"Scroll Viewport: {scrollBar.Viewport.ToString ()}"; lblScrollContentSize.Text = $"Scroll ContentSize: {scrollBar.GetContentSize ().ToString ()}"; - viewportDimension.Value = scrollBar.ViewportDimension; + VisibleContentSize.Value = scrollBar.VisibleContentSize; }; EventLog eventLog = new () @@ -368,7 +368,7 @@ public class ScrollBarDemo : Scenario void AppOnInitialized (object sender, EventArgs e) { - scrollBar.SizeChanged += (s, e) => + scrollBar.ScrollableContentSizeChanged += (s, e) => { eventLog.Log ($"SizeChanged: {e.CurrentValue}"); @@ -381,7 +381,7 @@ public class ScrollBarDemo : Scenario scrollBar.SliderPositionChanged += (s, e) => { eventLog.Log ($"SliderPositionChanged: {e.CurrentValue}"); - eventLog.Log ($" ContentPosition: {scrollBar.ContentPosition}"); + eventLog.Log ($" ContentPosition: {scrollBar.Position}"); scrollSliderPosition.Text = e.CurrentValue.ToString (); }; @@ -392,7 +392,7 @@ public class ScrollBarDemo : Scenario scrolled.Text = e.CurrentValue.ToString (); }; - scrollBar.ContentPositionChanged += (s, e) => + scrollBar.PositionChanged += (s, e) => { eventLog.Log ($"ContentPositionChanged: {e.CurrentValue}"); scrollContentPosition.Value = e.CurrentValue; @@ -403,7 +403,7 @@ public class ScrollBarDemo : Scenario controlledList.ViewportChanged += (s, e) => { eventLog.Log ($"ViewportChanged: {e.NewViewport.Y}"); - scrollBar.ContentPosition = e.NewViewport.Y; + scrollBar.Position = e.NewViewport.Y; }; } diff --git a/UnitTests/Views/ScrollBarTests.cs b/UnitTests/Views/ScrollBarTests.cs index 2a5982548..bc7cd8ce8 100644 --- a/UnitTests/Views/ScrollBarTests.cs +++ b/UnitTests/Views/ScrollBarTests.cs @@ -3,33 +3,166 @@ using static Unix.Terminal.Delegates; namespace Terminal.Gui.ViewsTests; -public class ScrollBarTests +public class ScrollBarTests (ITestOutputHelper output) { - public ScrollBarTests (ITestOutputHelper output) { _output = output; } - private readonly ITestOutputHelper _output; + [Fact] + public void Constructor_Defaults () + { + var scrollBar = new ScrollBar (); + Assert.False (scrollBar.CanFocus); + Assert.Equal (Orientation.Vertical, scrollBar.Orientation); + Assert.Equal (0, scrollBar.ScrollableContentSize); + Assert.Equal (0, scrollBar.VisibleContentSize); + Assert.Equal (0, scrollBar.GetSliderPosition ()); + Assert.Equal (0, scrollBar.Position); + Assert.True (scrollBar.AutoHide); + } + + #region AutoHide + [Fact] + [AutoInitShutdown] + public void AutoHide_True_Is_Default_CorrectlyHidesAndShows () + { + var super = new Toplevel () + { + Id = "super", + Width = 1, + Height = 20 + }; + + var scrollBar = new ScrollBar + { + ScrollableContentSize = 20, + }; + super.Add (scrollBar); + Assert.True (scrollBar.AutoHide); + Assert.True (scrollBar.Visible); // Before Init + + RunState rs = Application.Begin (super); + + // Should Show + scrollBar.ScrollableContentSize = 21; + Application.RunIteration (ref rs); + Assert.True (scrollBar.Visible); + + // Should Hide + scrollBar.ScrollableContentSize = 10; + Assert.False (scrollBar.Visible); + + super.Dispose (); + } [Fact] [AutoInitShutdown] - public void AutoHideScrollBar_CheckScrollBarVisibility () + public void AutoHide_False_CorrectlyHidesAndShows () { - var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), Size = 30 }; - View scrollBarSuperView = ScrollBarSuperView (); - scrollBarSuperView.Add (scrollBar); - Application.Begin ((scrollBarSuperView.SuperView as Toplevel)!); + var super = new Toplevel () + { + Id = "super", + Width = 1, + Height = 20 + }; + + var scrollBar = new ScrollBar + { + ScrollableContentSize = 20, + AutoHide = false + }; + super.Add (scrollBar); + Assert.False (scrollBar.AutoHide); + Assert.True (scrollBar.Visible); + + RunState rs = Application.Begin (super); + + // Should Hide if AutoSize = true, but should not hide if AutoSize = false + scrollBar.ScrollableContentSize = 10; + Assert.True (scrollBar.Visible); + + super.Dispose (); + } + + [Fact] + [AutoInitShutdown] + public void AutoHide_Change_AutoSize_CorrectlyHidesAndShows () + { + var super = new Toplevel () + { + Id = "super", + Width = 1, + Height = 20 + }; + + var scrollBar = new ScrollBar + { + ScrollableContentSize = 20, + }; + super.Add (scrollBar); + Assert.True (scrollBar.AutoHide); + Assert.True (scrollBar.Visible); // Before Init + + RunState rs = Application.Begin (super); + + Assert.False (scrollBar.Visible); + Assert.Equal (1, scrollBar.Frame.Width); + Assert.Equal (20, scrollBar.Frame.Height); + + scrollBar.ScrollableContentSize = 10; + Application.RunIteration (ref rs); + Assert.False (scrollBar.Visible); + + scrollBar.ScrollableContentSize = 30; + Assert.True (scrollBar.Visible); + + scrollBar.AutoHide = false; + Assert.True (scrollBar.Visible); + + scrollBar.ScrollableContentSize = 10; + Assert.True (scrollBar.Visible); + + super.Dispose (); + } + + [Fact] + [AutoInitShutdown] + public void AutoHide_Change_Size_CorrectlyHidesAndShows () + { + var super = new Toplevel () + { + Id = "super", + Width = 1, + Height = 20 + }; + + var scrollBar = new ScrollBar + { + ScrollableContentSize = 20, + }; + super.Add (scrollBar); + + RunState rs = Application.Begin (super); Assert.Equal (Orientation.Vertical, scrollBar.Orientation); + Assert.Equal (20, scrollBar.VisibleContentSize); //Assert.True (scrollBar.ShowScrollIndicator); - Assert.True (scrollBar.Visible); - Assert.Equal ("Absolute(2)", scrollBar.Width!.ToString ()); - Assert.Equal (2, scrollBar.Viewport.Width); - Assert.Equal ("Fill(Absolute(0))", scrollBar.Height!.ToString ()); - Assert.Equal (25, scrollBar.Viewport.Height); + Assert.False (scrollBar.Visible); + Assert.Equal (1, scrollBar.Frame.Width); + Assert.Equal (20, scrollBar.Frame.Height); - scrollBar.Size = 10; + scrollBar.ScrollableContentSize = 10; + Application.RunIteration (ref rs); //Assert.False (scrollBar.ShowScrollIndicator); Assert.False (scrollBar.Visible); - scrollBar.Size = 30; + scrollBar.ScrollableContentSize = 30; + //Assert.True (scrollBar.ShowScrollIndicator); + Assert.True (scrollBar.Visible); + + scrollBar.ScrollableContentSize = 10; + Application.RunIteration (ref rs); + //Assert.False (scrollBar.ShowScrollIndicator); + Assert.False (scrollBar.Visible); + + scrollBar.ScrollableContentSize = 21; //Assert.True (scrollBar.ShowScrollIndicator); Assert.True (scrollBar.Visible); @@ -37,37 +170,25 @@ public class ScrollBarTests //Assert.True (scrollBar.ShowScrollIndicator); Assert.True (scrollBar.Visible); - scrollBar.Size = 10; + scrollBar.ScrollableContentSize = 10; //Assert.True (scrollBar.ShowScrollIndicator); Assert.True (scrollBar.Visible); - scrollBarSuperView.SuperView!.Dispose (); - } - - - [Fact] - public void Constructor_Defaults () - { - var scrollBar = new ScrollBar (); - Assert.False (scrollBar.CanFocus); - Assert.Equal (Orientation.Vertical, scrollBar.Orientation); - Assert.Equal (0, scrollBar.Size); - Assert.Equal (0, scrollBar.ViewportDimension); - Assert.Equal (0, scrollBar.GetSliderPosition ()); - Assert.Equal (0, scrollBar.ContentPosition); - Assert.True (scrollBar.AutoHide); + super.Dispose (); } + #endregion AutoHide + #region Orientation [Fact] public void OnOrientationChanged_Keeps_Size () { var scroll = new ScrollBar (); scroll.Layout (); - scroll.Size = 1; + scroll.ScrollableContentSize = 1; scroll.Orientation = Orientation.Horizontal; - Assert.Equal (1, scroll.Size); + Assert.Equal (1, scroll.ScrollableContentSize); } [Fact] @@ -84,23 +205,391 @@ public class ScrollBarTests }; super.Add (scrollBar); scrollBar.Layout (); - scrollBar.ContentPosition = 1; + scrollBar.Position = 1; scrollBar.Orientation = Orientation.Horizontal; Assert.Equal (0, scrollBar.GetSliderPosition ()); } + #endregion Orientation + #region Slider + + [Theory] + [InlineData (-1, 10, 1)] + [InlineData (0, 10, 1)] + [InlineData (10, 15, 5)] + [InlineData (10, 5, 8)] + [InlineData (10, 3, 8)] + [InlineData (10, 2, 8)] + [InlineData (10, 1, 8)] + [InlineData (10, 0, 8)] + [InlineData (10, 10, 8)] + [InlineData (10, 20, 4)] + [InlineData (10, 100, 1)] + [InlineData (15, 0, 13)] + [InlineData (15, 1, 13)] + [InlineData (15, 2, 13)] + [InlineData (15, 3, 13)] + [InlineData (15, 5, 13)] + [InlineData (15, 10, 13)] + [InlineData (15, 14, 13)] + [InlineData (15, 15, 13)] + [InlineData (15, 16, 12)] + [InlineData (20, 10, 18)] + [InlineData (100, 10, 98)] + public void CalculateSliderSize_Width_Is_VisibleContentSize_CalculatesCorrectly (int visibleContentSize, int scrollableContentSize, int expectedSliderSize) + { + // Arrange + var scrollBar = new ScrollBar + { + VisibleContentSize = visibleContentSize, + ScrollableContentSize = scrollableContentSize, + Orientation = Orientation.Horizontal // Assuming horizontal for simplicity + }; + scrollBar.Width = visibleContentSize; + + // Act + var sliderSize = scrollBar.CalculateSliderSize (); + + // Assert + Assert.Equal (expectedSliderSize, sliderSize); + } + + [Theory] + // 0123456789 + // - + // ********** + // ◄███► + [InlineData (5, 10, 1, 3)] + + // 01234567890 + // ---------- + // ********** + // ◄██░► + [InlineData (5, 10, 11, 2)] + + + [InlineData (20, 10, 1, 18)] + + //// ◄█░░░░░░░► + //[InlineData (1, 10, 1)] + + //// --------- + //// ◄████░░░░► + //[InlineData (5, 10, 4)] + + //// ---------- + //// ◄███░░░░░► + //[InlineData (5, 11, 3)] + //[InlineData (5, 12, 3)] + //[InlineData (5, 13, 3)] + + //// 012345678901234 + //// -------------- + //// ◄██░░░░░░► + //[InlineData (5, 14, 2)] + //[InlineData (5, 15, 2)] + //[InlineData (5, 16, 2)] + + //// 012345678901234567890 + //// ---------------- + //// ◄██░░░░░░► + //[InlineData (5, 18, 2)] + //[InlineData (5, 19, 2)] + //[InlineData (5, 20, 2)] + + + //// 012345678901234567890 + //// -------------------- + //// ◄█░░░░░░░► + //[InlineData (5, 21, 1)] + //[InlineData (5, 22, 1)] + //[InlineData (5, 23, 1)] + public void CalculateSliderSize_Width_Is_LT_VisibleContentSize_CalculatesCorrectly (int width, int visibleContentSize, int scrollableContentSize, int expectedSliderSize) + { + // Arrange + var scrollBar = new ScrollBar + { + VisibleContentSize = visibleContentSize, + ScrollableContentSize = scrollableContentSize, + Orientation = Orientation.Horizontal // Assuming horizontal for simplicity + }; + scrollBar.Width = width; + + // Act + var sliderSize = scrollBar.CalculateSliderSize (); + + // Assert + Assert.Equal (expectedSliderSize, sliderSize); + } + + + [Theory] + // 0123456789 + // --------- + // ◄█░░░░░░░► + [InlineData (0, 10, 1)] + // ◄█░░░░░░░► + [InlineData (1, 10, 1)] + + // --------- + // ◄████░░░░► + [InlineData (5, 10, 4)] + + // ---------- + // ◄███░░░░░► + [InlineData (5, 11, 3)] + [InlineData (5, 12, 3)] + [InlineData (5, 13, 3)] + + // 012345678901234 + // -------------- + // ◄██░░░░░░► + [InlineData (5, 14, 2)] + [InlineData (5, 15, 2)] + [InlineData (5, 16, 2)] + + // 012345678901234567890 + // ---------------- + // ◄██░░░░░░► + [InlineData (5, 18, 2)] + [InlineData (5, 19, 2)] + [InlineData (5, 20, 2)] + + + // 012345678901234567890 + // -------------------- + // ◄█░░░░░░░► + [InlineData (5, 21, 1)] + [InlineData (5, 22, 1)] + [InlineData (5, 23, 1)] + + public void CalculateSliderSize_Width_Is_GT_VisibleContentSize_CalculatesCorrectly (int visibleContentSize, int scrollableContentSize, int expectedSliderSize) + { + // Arrange + var scrollBar = new ScrollBar + { + VisibleContentSize = visibleContentSize, + ScrollableContentSize = scrollableContentSize, + Orientation = Orientation.Horizontal // Assuming horizontal for simplicity + }; + scrollBar.Width = 10; + + // Act + var sliderSize = scrollBar.CalculateSliderSize (); + + // Assert + Assert.Equal (expectedSliderSize, sliderSize); + } + + [Theory] + // 0123456789 + // --------- + // ◄█► + [InlineData (3, 3, 0, 0)] + [InlineData (3, 3, 1, 0)] + [InlineData (3, 3, 2, 0)] + + // 0123456789 + // --------- + // ◄██► + [InlineData (4, 4, 0, 0)] + [InlineData (4, 4, 1, 0)] + [InlineData (4, 4, 2, 0)] + [InlineData (4, 4, 3, 0)] + [InlineData (4, 4, 4, 0)] + + + // 012345 + // ^---- + // ◄█░► + [InlineData (4, 5, 0, 0)] + // -^--- + // ◄█░► + [InlineData (4, 5, 1, 0)] + // --^-- + // ◄░█► + [InlineData (4, 5, 2, 1)] + // ---^- + // ◄░█► + [InlineData (4, 5, 3, 1)] + // ----^ + // ◄░█► + [InlineData (4, 5, 4, 1)] + + // 01234 + // ^--------- + // ◄█░░► + [InlineData (5, 10, 0, 0)] + // -^-------- + // ◄█░░► + [InlineData (5, 10, 1, 0)] + // --^------- + // ◄█░░► + [InlineData (5, 10, 2, 0)] + // ---^------ + // ◄█░░► + [InlineData (5, 10, 3, 0)] + // ----^---- + // ◄░█░► + [InlineData (5, 10, 4, 1)] + // -----^--- + // ◄░█░► + [InlineData (5, 10, 5, 1)] + // ------^-- + // ◄░░█► + [InlineData (5, 10, 6, 2)] + // ------^-- + // ◄░░█► + [InlineData (5, 10, 7, 2)] + // -------^- + // ◄░░█► + [InlineData (5, 10, 8, 2)] + // --------^ + // ◄░░█► + [InlineData (5, 10, 9, 2)] + + + [InlineData (10, 20, 0, 0)] + [InlineData (10, 20, 1, 0)] + [InlineData (10, 20, 2, 0)] + [InlineData (10, 20, 3, 1)] + [InlineData (10, 20, 4, 2)] + [InlineData (10, 20, 5, 2)] + [InlineData (10, 20, 6, 3)] + [InlineData (10, 20, 7, 4)] + [InlineData (10, 20, 8, 4)] + + public void CalculateSliderPosition_Calculates_Correctly (int visibleContentSize, int scrollableContentSize, int contentPosition, int expectedSliderPosition) + { + // Arrange + var scrollBar = new ScrollBar + { + ScrollableContentSize = scrollableContentSize, + VisibleContentSize = visibleContentSize, + Orientation = Orientation.Horizontal // Assuming horizontal for simplicity + }; + scrollBar.Width = visibleContentSize; + + // Act + var sliderPosition= scrollBar.CalculateSliderPosition (contentPosition, NavigationDirection.Forward); + + // Assert + Assert.Equal (expectedSliderPosition, sliderPosition); + } + + + #endregion Slider + + #region Size + + // TODO: Add tests. + + #endregion Size + + #region Position + + // 012345678901 + // ◄█░░░░░░░░░► + [Theory] + // ◄█► + [InlineData (3, 3, -1, 0)] + [InlineData (3, 3, 0, 0)] + // 012 + // --- + // ◄█► + [InlineData (3, 3, 1, 0)] + [InlineData (3, 3, 2, 0)] + + // ◄██► + [InlineData (4, 2, 1, 0)] + [InlineData (4, 2, 2, 0)] + + // 0123 + // --- + // ◄██► + [InlineData (4, 3, 0, 0)] // scrollBarWidth/VisibleContentSize > size - scrolling doesn't make sense. Size should clamp to scrollSlider.Size. + // ◄██► + [InlineData (4, 3, 1, 0)] + // ◄██► + [InlineData (4, 3, 2, 0)] + + + // 01234 + // ---- + // ◄██► + [InlineData (4, 4, 0, 0)] // scrollBarWidth/VisibleContentSize == size - scrolling doesn't make sense. Size should clamp to scrollSlider.Size. + // ◄██► + [InlineData (4, 4, 1, 0)] + // ◄██► + [InlineData (4, 4, 2, 0)] + + // 012345 + // ◄███► + // ----- + [InlineData (5, 5, 3, 0)] + [InlineData (5, 5, 4, 0)] + + // 0123456 + // ◄██░► + // ^----- + [InlineData (5, 6, 0, 0)] + // ◄░██► + // -^---- + [InlineData (5, 6, 1, 1)] + [InlineData (5, 6, 2, 1)] + + // 012346789 + // ◄█░░► + // ^-------- + [InlineData (5, 10, -1, 0)] + [InlineData (5, 10, 0, 0)] + + // 0123456789 + // ◄░█░► + // --^------- + [InlineData (5, 10, 1, 3)] + + // ◄░░█► + // ----^---- + [InlineData (5, 10, 2, 5)] + + // ◄░░█► + // ------^--- + [InlineData (5, 10, 4, 5)] + + // ◄░████░░░► + // -------------------- + [InlineData (10, 20, 0, 0)] + + public void CalculatePosition_Calculates (int visibleContentSize, int scrollableContentSize, int sliderPosition, int expectedContentPosition) + { + // Arrange + var scrollBar = new ScrollBar + { + VisibleContentSize = visibleContentSize, + ScrollableContentSize = scrollableContentSize, + Orientation = Orientation.Horizontal // Use Horizontal because it's easier to visualize + }; + scrollBar.Frame = new (0, 0, visibleContentSize, 0); + + // Act + var contentPosition = scrollBar.CalculatePosition (sliderPosition); + + // Assert + Assert.Equal (expectedContentPosition, contentPosition); + } [Fact] - public void ContentPosition_Event_Cancelables () + public void Position_Event_Cancelables () { var changingCount = 0; var changedCount = 0; var scrollBar = new ScrollBar { }; - scrollBar.Size = 4; + scrollBar.ScrollableContentSize = 5; scrollBar.Frame = new Rectangle (0, 0, 1, 4); // Needs to be at least 4 for slider to move - scrollBar.ContentPositionChanging += (s, e) => + scrollBar.PositionChanging += (s, e) => { if (changingCount == 0) { @@ -109,79 +598,49 @@ public class ScrollBarTests changingCount++; }; - scrollBar.ContentPositionChanged += (s, e) => changedCount++; + scrollBar.PositionChanged += (s, e) => changedCount++; - scrollBar.ContentPosition = 1; - Assert.Equal (0, scrollBar.ContentPosition); + scrollBar.Position = 1; + Assert.Equal (0, scrollBar.Position); Assert.Equal (1, changingCount); Assert.Equal (0, changedCount); - scrollBar.ContentPosition = 1; - Assert.Equal (1, scrollBar.ContentPosition); + scrollBar.Position = 1; + Assert.Equal (1, scrollBar.Position); Assert.Equal (2, changingCount); Assert.Equal (1, changedCount); } - - - - [Fact (Skip = "Disabled - Will put this feature in View")] - [AutoInitShutdown] - public void KeepContentInAllViewport_True_False () - { - var view = new View { Width = Dim.Fill (), Height = Dim.Fill () }; - view.Padding.Thickness = new (0, 0, 2, 0); - view.SetContentSize (new (view.Viewport.Width, 30)); - var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), Size = view.GetContentSize ().Height }; - scrollBar.SliderPositionChanged += (_, e) => view.Viewport = view.Viewport with { Y = e.CurrentValue }; - view.Padding.Add (scrollBar); - var top = new Toplevel (); - top.Add (view); - Application.Begin (top); - - Assert.False (scrollBar.KeepContentInAllViewport); - scrollBar.KeepContentInAllViewport = true; - Assert.Equal (80, view.Padding.Viewport.Width); - Assert.Equal (25, view.Padding.Viewport.Height); - Assert.Equal (2, scrollBar.Viewport.Width); - Assert.Equal (25, scrollBar.Viewport.Height); - Assert.Equal (30, scrollBar.Size); - - scrollBar.KeepContentInAllViewport = false; - scrollBar.ContentPosition = 50; - Assert.Equal (scrollBar.GetSliderPosition (), scrollBar.Size - 1); - Assert.Equal (scrollBar.GetSliderPosition (), view.Viewport.Y); - Assert.Equal (29, scrollBar.GetSliderPosition ()); - Assert.Equal (29, view.Viewport.Y); - - top.Dispose (); - } + #endregion Position [Fact] - public void Size_Cannot_Be_Negative () + public void ScrollableContentSize_Cannot_Be_Negative () { - var scrollBar = new ScrollBar { Height = 10, Size = -1 }; - Assert.Equal (0, scrollBar.Size); - scrollBar.Size = -10; - Assert.Equal (0, scrollBar.Size); + var scrollBar = new ScrollBar { Height = 10, ScrollableContentSize = -1 }; + Assert.Equal (0, scrollBar.ScrollableContentSize); + scrollBar.ScrollableContentSize = -10; + Assert.Equal (0, scrollBar.ScrollableContentSize); } [Fact] - public void SizeChanged_Event () + public void ScrollableContentSizeChanged_Event () { var count = 0; var scrollBar = new ScrollBar (); - scrollBar.SizeChanged += (s, e) => count++; + scrollBar.ScrollableContentSizeChanged += (s, e) => count++; - scrollBar.Size = 10; - Assert.Equal (10, scrollBar.Size); + scrollBar.ScrollableContentSize = 10; + Assert.Equal (10, scrollBar.ScrollableContentSize); Assert.Equal (1, count); } [Theory] [SetupFakeDriver] - #region Vertical + #region Draw + + + #region Horizontal #region Super 10 - ScrollBar 8 [InlineData ( @@ -235,7 +694,7 @@ public class ScrollBarTests Orientation.Horizontal, @" ┌──────────┐ -│◄░████░░░►│ +│◄████░░░░►│ └──────────┘ ")] @@ -553,9 +1012,9 @@ public class ScrollBarTests │ ░████░░░ │ └──────────┘ ")] - #endregion Vertical + #endregion Horizontal - #region Horizontal + #region Vertical [InlineData ( 1, @@ -659,16 +1118,16 @@ public class ScrollBarTests │ ▼ │ └───┘ ")] - #endregion + #endregion Vertical - public void Draws_Correctly (int superWidth, int superHeight, int contentSize, int contentPosition, Orientation orientation, string expected) + public void Draws_Correctly (int width, int height, int contentSize, int contentPosition, Orientation orientation, string expected) { var super = new Window { Id = "super", - Width = superWidth + 2, - Height = superHeight + 2 + Width = width + 2, + Height = height + 2 }; var scrollBar = new ScrollBar @@ -678,38 +1137,32 @@ public class ScrollBarTests if (orientation == Orientation.Vertical) { - scrollBar.Width = Dim.Fill (); + scrollBar.Width = 1; + scrollBar.Height = height; } else { - scrollBar.Height = Dim.Fill (); + scrollBar.Width = width; + scrollBar.Height = 1; } super.Add (scrollBar); - scrollBar.Size = contentSize; - scrollBar.ContentPosition = contentPosition; + scrollBar.ScrollableContentSize = contentSize; + scrollBar.Position = contentPosition; + + int sliderPos = scrollBar.CalculateSliderPosition (contentPosition, NavigationDirection.Forward); super.BeginInit (); super.EndInit (); super.Layout (); super.Draw (); - _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + _ = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); } + #endregion Draw - private View ScrollBarSuperView () - { - var view = new View - { - Width = Dim.Fill (), - Height = Dim.Fill () - }; + #region Mouse - var top = new Toplevel (); - top.Add (view); - - return view; - } [Theory] @@ -727,7 +1180,7 @@ public class ScrollBarTests { Id = "scrollBar", Orientation = orientation, - Size = 20, + ScrollableContentSize = 20, Increment = increment }; @@ -735,13 +1188,13 @@ public class ScrollBarTests RunState rs = Application.Begin (top); // Scroll to end - scrollBar.ContentPosition = 20; - Assert.Equal (10, scrollBar.ContentPosition); + scrollBar.Position = 20; + Assert.Equal (10, scrollBar.Position); Application.RunIteration (ref rs); Assert.Equal (4, scrollBar.GetSliderPosition ()); - Assert.Equal (10, scrollBar.ContentPosition); - int initialPos = scrollBar.ContentPosition; + Assert.Equal (10, scrollBar.Position); + int initialPos = scrollBar.Position; Application.RaiseMouseEvent (new () { @@ -750,7 +1203,7 @@ public class ScrollBarTests }); Application.RunIteration (ref rs); - Assert.Equal (initialPos - increment, scrollBar.ContentPosition); + Assert.Equal (initialPos - increment, scrollBar.Position); Application.ResetState (true); } @@ -771,7 +1224,7 @@ public class ScrollBarTests { Id = "scrollBar", Orientation = orientation, - Size = 20, + ScrollableContentSize = 20, Increment = increment }; @@ -779,12 +1232,12 @@ public class ScrollBarTests RunState rs = Application.Begin (top); // Scroll to top - scrollBar.ContentPosition = 0; + scrollBar.Position = 0; Application.RunIteration (ref rs); Assert.Equal (0, scrollBar.GetSliderPosition ()); - Assert.Equal (0, scrollBar.ContentPosition); - int initialPos = scrollBar.ContentPosition; + Assert.Equal (0, scrollBar.Position); + int initialPos = scrollBar.Position; Application.RaiseMouseEvent (new () { @@ -793,136 +1246,44 @@ public class ScrollBarTests }); Application.RunIteration (ref rs); - Assert.Equal (initialPos + increment, scrollBar.ContentPosition); + Assert.Equal (initialPos + increment, scrollBar.Position); Application.ResetState (true); } + #endregion Mouse - [Theory] - [InlineData (-1, 10, 1)] - [InlineData (0, 10, 1)] - [InlineData (10, 15, 5)] - [InlineData (10, 5, 10)] - [InlineData (10, 3, 10)] - [InlineData (10, 2, 10)] - [InlineData (10, 1, 10)] - [InlineData (10, 0, 1)] - [InlineData (10, 10, 8)] - [InlineData (10, 20, 4)] - [InlineData (10, 100, 1)] - [InlineData (15, 10, 15)] - [InlineData (15, 0, 1)] - [InlineData (15, 1, 15)] - [InlineData (15, 2, 15)] - [InlineData (15, 3, 15)] - [InlineData (15, 5, 15)] - [InlineData (15, 14, 13)] - [InlineData (15, 15, 13)] - [InlineData (15, 16, 12)] - [InlineData (20, 10, 20)] - [InlineData (100, 10, 100)] - public void CalculateSliderSize_Width_Matches_ViewportDimension (int viewportDimension, int size, int expectedSliderSize) + + + [Fact (Skip = "Disabled - Will put this feature in View")] + [AutoInitShutdown] + public void KeepContentInAllViewport_True_False () { - // Arrange - var scrollBar = new ScrollBar - { - ViewportDimension = viewportDimension, - Size = size, - Orientation = Orientation.Horizontal // Assuming horizontal for simplicity - }; - scrollBar.Width = viewportDimension; // Changing orientation changes Width - scrollBar.BeginInit (); - scrollBar.EndInit (); - scrollBar.Layout (); + var view = new View { Width = Dim.Fill (), Height = Dim.Fill () }; + view.Padding.Thickness = new (0, 0, 2, 0); + view.SetContentSize (new (view.Viewport.Width, 30)); + var scrollBar = new ScrollBar { Width = 2, Height = Dim.Fill (), ScrollableContentSize = view.GetContentSize ().Height }; + scrollBar.SliderPositionChanged += (_, e) => view.Viewport = view.Viewport with { Y = e.CurrentValue }; + view.Padding.Add (scrollBar); + var top = new Toplevel (); + top.Add (view); + Application.Begin (top); - // Act - var sliderSize = scrollBar.CalculateSliderSize (); + Assert.False (scrollBar.KeepContentInAllViewport); + scrollBar.KeepContentInAllViewport = true; + Assert.Equal (80, view.Padding.Viewport.Width); + Assert.Equal (25, view.Padding.Viewport.Height); + Assert.Equal (2, scrollBar.Viewport.Width); + Assert.Equal (25, scrollBar.Viewport.Height); + Assert.Equal (30, scrollBar.ScrollableContentSize); + scrollBar.KeepContentInAllViewport = false; + scrollBar.Position = 50; + Assert.Equal (scrollBar.GetSliderPosition (), scrollBar.ScrollableContentSize - 1); + Assert.Equal (scrollBar.GetSliderPosition (), view.Viewport.Y); + Assert.Equal (29, scrollBar.GetSliderPosition ()); + Assert.Equal (29, view.Viewport.Y); - // Assert - Assert.Equal (expectedSliderSize, sliderSize); + top.Dispose (); } - // 012345678901 - // ◄█░░░░░░░░░► - [Theory] - // ◄█► - [InlineData (3, 3, -1, 0)] - [InlineData (3, 3, 0, 0)] - [InlineData (3, 3, 1, 0)] - [InlineData (3, 3, 2, 0)] - - // ◄██► - [InlineData (4, 2, 1, 0)] - [InlineData (4, 2, 2, 0)] - - // 0123 - // --- - // ◄█░► - [InlineData (4, 3, 0, 0)] - // ◄░█► - [InlineData (4, 3, 1, 1)] - // ◄░█► - [InlineData (4, 3, 2, 1)] - - - // 01234 - // ---- - // ◄█░► - [InlineData (4, 4, 0, 0)] - // ◄░█► - [InlineData (4, 4, 1, 1)] - // ◄░█► - [InlineData (4, 4, 2, 1)] - - // 012345 - // ◄███► - // ----- - [InlineData (5, 5, 3, 0)] - [InlineData (5, 5, 4, 0)] - - // 0123456 - // ◄██░► - // ------ - [InlineData (5, 6, 0, 0)] - [InlineData (5, 6, 1, 1)] - [InlineData (5, 6, 2, 1)] - - // 01234567890 - // ◄█░░░► - // ---------- - [InlineData (5, 10, -1, 0)] - [InlineData (5, 10, 0, 0)] - - // 01234567890 - // ◄░█░░► - // --^------- - [InlineData (5, 10, 1, 2)] - [InlineData (5, 10, 2, 3)] - [InlineData (5, 10, 3, 3)] - [InlineData (5, 10, 4, 3)] - [InlineData (5, 10, 5, 3)] - [InlineData (5, 10, 6, 3)] - [InlineData (5, 10, 7, 3)] - [InlineData (5, 10, 8, 3)] - [InlineData (5, 10, 9, 3)] - [InlineData (5, 10, 10, 3)] - public void CalculateContentPosition_ComprehensiveTests (int viewportDimension, int size, int sliderPosition, int expectedContentPosition) - { - // Arrange - var scrollBar = new ScrollBar - { - ViewportDimension = viewportDimension, - Size = size, - Orientation = Orientation.Horizontal // Assuming horizontal for simplicity - }; - scrollBar.Width = viewportDimension; // Changing orientation changes Width - scrollBar.Layout (); - - // Act - var contentPosition = scrollBar.CalculateContentPosition (sliderPosition); - - // Assert - Assert.Equal (expectedContentPosition, contentPosition); - } } diff --git a/UnitTests/Views/ScrollSliderTests.cs b/UnitTests/Views/ScrollSliderTests.cs index 9f9eb592f..b44101795 100644 --- a/UnitTests/Views/ScrollSliderTests.cs +++ b/UnitTests/Views/ScrollSliderTests.cs @@ -21,7 +21,7 @@ public class ScrollSliderTests (ITestOutputHelper output) Assert.Equal (0, scrollSlider.Frame.X); Assert.Equal (0, scrollSlider.Frame.Y); Assert.Equal (1, scrollSlider.Size); - Assert.Equal (2048, scrollSlider.ViewportDimension); + Assert.Equal (2048, scrollSlider.VisibleContentSize); } [Fact] @@ -46,7 +46,7 @@ public class ScrollSliderTests (ITestOutputHelper output) Assert.Equal (0, scrollSlider.Frame.X); Assert.Equal (0, scrollSlider.Frame.Y); Assert.Equal (1, scrollSlider.Size); - Assert.Equal (10, scrollSlider.ViewportDimension); + Assert.Equal (10, scrollSlider.VisibleContentSize); } //[Fact] @@ -116,12 +116,12 @@ public class ScrollSliderTests (ITestOutputHelper output) [Theory] [CombinatorialData] - public void Size_Clamps_To_ViewportDimensions ([CombinatorialRange (1, 6, 1)] int dimension, [CombinatorialRange (-1, 6, 1)] int sliderSize, Orientation orientation) + public void Size_Clamps_To_VisibleContentSizes ([CombinatorialRange (1, 6, 1)] int dimension, [CombinatorialRange (-1, 6, 1)] int sliderSize, Orientation orientation) { var scrollSlider = new ScrollSlider { Orientation = orientation, - ViewportDimension = dimension, + VisibleContentSize = dimension, Size = sliderSize, }; scrollSlider.Layout (); @@ -132,7 +132,7 @@ public class ScrollSliderTests (ITestOutputHelper output) } [Fact] - public void ViewportDimension_Not_Set_Uses_SuperView () + public void VisibleContentSize_Not_Set_Uses_SuperView () { View super = new () { @@ -146,11 +146,11 @@ public class ScrollSliderTests (ITestOutputHelper output) super.Add (scrollSlider); super.Layout (); - Assert.Equal (5, scrollSlider.ViewportDimension); + Assert.Equal (5, scrollSlider.VisibleContentSize); } [Fact] - public void ViewportDimension_Set_Overrides_SuperView () + public void VisibleContentSize_Set_Overrides_SuperView () { View super = new () { @@ -160,34 +160,34 @@ public class ScrollSliderTests (ITestOutputHelper output) }; var scrollSlider = new ScrollSlider { - ViewportDimension = 10, + VisibleContentSize = 10, }; super.Add (scrollSlider); super.Layout (); - Assert.Equal (10, scrollSlider.ViewportDimension); + Assert.Equal (10, scrollSlider.VisibleContentSize); super.Height = 3; super.Layout (); - Assert.Equal (10, scrollSlider.ViewportDimension); + Assert.Equal (10, scrollSlider.VisibleContentSize); super.Height = 7; super.Layout (); - Assert.Equal (10, scrollSlider.ViewportDimension); + Assert.Equal (10, scrollSlider.VisibleContentSize); } [Theory] [CombinatorialData] - public void ViewportDimensions_Clamps_0_To_Dimension ([CombinatorialRange (0, 10, 1)] int dimension, Orientation orientation) + public void VisibleContentSizes_Clamps_0_To_Dimension ([CombinatorialRange (0, 10, 1)] int dimension, Orientation orientation) { var scrollSlider = new ScrollSlider { Orientation = orientation, - ViewportDimension = dimension, + VisibleContentSize = dimension, }; - Assert.InRange (scrollSlider.ViewportDimension, 1, 10); + Assert.InRange (scrollSlider.VisibleContentSize, 1, 10); View super = new () { @@ -203,16 +203,16 @@ public class ScrollSliderTests (ITestOutputHelper output) super.Add (scrollSlider); super.Layout (); - Assert.InRange (scrollSlider.ViewportDimension, 1, 10); + Assert.InRange (scrollSlider.VisibleContentSize, 1, 10); - scrollSlider.ViewportDimension = dimension; + scrollSlider.VisibleContentSize = dimension; - Assert.InRange (scrollSlider.ViewportDimension, 1, 10); + Assert.InRange (scrollSlider.VisibleContentSize, 1, 10); } [Theory] [CombinatorialData] - public void ClampPosition_WithSuperView_Clamps_To_ViewPort_Minus_Size_If_ViewportDimension_Not_Set ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) + public void ClampPosition_WithSuperView_Clamps_To_ViewPort_Minus_Size_If_VisibleContentSize_Not_Set ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) { View super = new () { @@ -228,7 +228,7 @@ public class ScrollSliderTests (ITestOutputHelper output) super.Add (scrollSlider); super.Layout (); - Assert.Equal(dimension, scrollSlider.ViewportDimension); + Assert.Equal(dimension, scrollSlider.VisibleContentSize); int clampedPosition = scrollSlider.ClampPosition (sliderPosition); @@ -237,7 +237,7 @@ public class ScrollSliderTests (ITestOutputHelper output) [Theory] [CombinatorialData] - public void ClampPosition_WithSuperView_Clamps_To_ViewportDimension_Minus_Size ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) + public void ClampPosition_WithSuperView_Clamps_To_VisibleContentSize_Minus_Size ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) { View super = new () { @@ -248,7 +248,7 @@ public class ScrollSliderTests (ITestOutputHelper output) var scrollSlider = new ScrollSlider { Orientation = orientation, - ViewportDimension = dimension, + VisibleContentSize = dimension, Size = sliderSize, }; super.Add (scrollSlider); @@ -261,12 +261,12 @@ public class ScrollSliderTests (ITestOutputHelper output) [Theory] [CombinatorialData] - public void ClampPosition_NoSuperView_Clamps_To_ViewportDimension_Minus_Size ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) + public void ClampPosition_NoSuperView_Clamps_To_VisibleContentSize_Minus_Size ([CombinatorialRange (10, 10, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) { var scrollSlider = new ScrollSlider { Orientation = orientation, - ViewportDimension = dimension, + VisibleContentSize = dimension, Size = sliderSize, }; @@ -277,12 +277,12 @@ public class ScrollSliderTests (ITestOutputHelper output) [Theory] [CombinatorialData] - public void Position_Clamps_To_ViewportDimension ([CombinatorialRange (0, 5, 1)] int dimension, [CombinatorialRange(1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) + public void Position_Clamps_To_VisibleContentSize ([CombinatorialRange (0, 5, 1)] int dimension, [CombinatorialRange(1, 5, 1)] int sliderSize, [CombinatorialRange (-1, 10, 2)] int sliderPosition, Orientation orientation) { var scrollSlider = new ScrollSlider { Orientation = orientation, - ViewportDimension = dimension, + VisibleContentSize = dimension, Size = sliderSize, Position = sliderPosition }; @@ -318,7 +318,7 @@ public class ScrollSliderTests (ITestOutputHelper output) [Theory] [CombinatorialData] - public void Position_Clamps_To_ViewportDimension_With_SuperView ([CombinatorialRange (0, 5, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-2, 10, 2)] int sliderPosition, Orientation orientation) + public void Position_Clamps_To_VisibleContentSize_With_SuperView ([CombinatorialRange (0, 5, 1)] int dimension, [CombinatorialRange (1, 5, 1)] int sliderSize, [CombinatorialRange (-2, 10, 2)] int sliderPosition, Orientation orientation) { var super = new View { @@ -330,7 +330,7 @@ public class ScrollSliderTests (ITestOutputHelper output) var scrollSlider = new ScrollSlider { Orientation = orientation, - ViewportDimension = dimension, + VisibleContentSize = dimension, Size = sliderSize, Position = sliderPosition };