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