mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Fightin math.
This commit is contained in:
@@ -79,10 +79,10 @@ public class GlyphDefinitions
|
||||
/// <summary>Continuous block meter segment (e.g. for <see cref="ProgressBar"/>).</summary>
|
||||
public Rune ContinuousMeterSegment { get; set; } = (Rune)'█';
|
||||
|
||||
/// <summary>Stipple pattern (e.g. for <see cref="ScrollBarView"/>). Default is Light Shade (U+2591) - ░.</summary>
|
||||
/// <summary>Stipple pattern (e.g. for <see cref="ScrollBar"/>). Default is Light Shade (U+2591) - ░.</summary>
|
||||
public Rune Stipple { get; set; } = (Rune)'░';
|
||||
|
||||
/// <summary>Diamond (e.g. for <see cref="ScrollBarView"/>. Default is Lozenge (U+25CA) - ◊.</summary>
|
||||
/// <summary>Diamond. Default is Lozenge (U+25CA) - ◊.</summary>
|
||||
public Rune Diamond { get; set; } = (Rune)'◊';
|
||||
|
||||
/// <summary>Close. Default is Heavy Ballot X (U+2718) - ✘.</summary>
|
||||
|
||||
@@ -11,131 +11,131 @@ public partial class View
|
||||
/// </summary>
|
||||
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<ScrollBar> (
|
||||
() =>
|
||||
{
|
||||
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<ScrollBar> (
|
||||
() =>
|
||||
{
|
||||
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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <inheritdoc/>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL (for unit tests). Calclates the size of the slider based on the Orientation, ViewportDimension, the actual Viewport, and Size.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount each mouse wheel event will incremenet/decrement the <see cref="Position"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default is 1.
|
||||
/// </remarks>
|
||||
public int Increment { get; set; } = 1;
|
||||
|
||||
private bool _autoHide = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether <see cref="View.Visible"/> will be set to <see langword="false"/> if the dimension of the
|
||||
/// scroll bar is greater than or equal to <see cref="Size"/>.
|
||||
/// scroll bar is greater than or equal to <see cref="ScrollableContentSize"/>.
|
||||
/// </summary>
|
||||
public bool AutoHide
|
||||
{
|
||||
@@ -251,7 +246,7 @@ public class ScrollBar : View, IOrientation, IDesignable
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the Scroll will show the percentage the slider
|
||||
/// takes up within the <see cref="Size"/>.
|
||||
/// takes up within the <see cref="ScrollableContentSize"/>.
|
||||
/// </summary>
|
||||
public bool ShowPercent
|
||||
{
|
||||
@@ -259,61 +254,211 @@ public class ScrollBar : View, IOrientation, IDesignable
|
||||
set => _slider.ShowPercent = value;
|
||||
}
|
||||
|
||||
private int? _viewportDimension;
|
||||
private int? _visibleContentSize;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the viewport into the content being scrolled, bounded by <see cref="Size"/>.
|
||||
/// Gets or sets the size of the visible viewport into the content being scrolled, bounded by <see cref="ScrollableContentSize"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If not explicitly set, will be the appropriate dimension of the Scroll's Frame.
|
||||
/// </remarks>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the content that can be scrolled.
|
||||
/// </summary>
|
||||
public int Size
|
||||
{
|
||||
get => _size;
|
||||
set
|
||||
{
|
||||
if (value == _size || value < 0)
|
||||
_visibleContentSize = value;
|
||||
_slider.Size = CalculateSliderSize ();
|
||||
}
|
||||
}
|
||||
|
||||
private int _scrollableContentSize;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the content that can be scrolled. This is typically set to <see cref="View.GetContentSize()"/>.
|
||||
/// </summary>
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Called when <see cref="Size"/> has changed. </summary>
|
||||
/// <summary>Called when <see cref="ScrollableContentSize"/> has changed. </summary>
|
||||
protected virtual void OnSizeChanged (int size) { }
|
||||
|
||||
/// <summary>Raised when <see cref="Size"/> has changed.</summary>
|
||||
public event EventHandler<EventArgs<int>>? SizeChanged;
|
||||
/// <summary>Raised when <see cref="ScrollableContentSize"/> has changed.</summary>
|
||||
public event EventHandler<EventArgs<int>>? ScrollableContentSizeChanged;
|
||||
|
||||
#region SliderPosition
|
||||
#region Position
|
||||
|
||||
private int _position;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position of the slider relative to <see cref="ScrollableContentSize"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The content position is clamped to 0 and <see cref="ScrollableContentSize"/> minus <see cref="VisibleContentSize"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Setting will result in the <see cref="PositionChanging"/> and <see cref="PositionChanged"/>
|
||||
/// events being raised.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
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<int> 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when <see cref="Position"/> is changing. Return true to cancel the change.
|
||||
/// </summary>
|
||||
protected virtual bool OnPositionChanging (int currentPos, int newPos) { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the <see cref="Position"/> is changing. Set <see cref="CancelEventArgs.Cancel"/> to
|
||||
/// <see langword="true"/> to prevent the position from being changed.
|
||||
/// </summary>
|
||||
public event EventHandler<CancelEventArgs<int>>? PositionChanging;
|
||||
|
||||
/// <summary>Called when <see cref="Position"/> has changed.</summary>
|
||||
protected virtual void OnPositionChanged (int position) { }
|
||||
|
||||
/// <summary>Raised when the <see cref="Position"/> has changed.</summary>
|
||||
public event EventHandler<EventArgs<int>>? PositionChanged;
|
||||
|
||||
/// <summary>Called when <see cref="Position"/> has changed. Indicates how much to scroll.</summary>
|
||||
protected virtual void OnScrolled (int distance) { }
|
||||
|
||||
/// <summary>Raised when the <see cref="Position"/> has changed. Indicates how much to scroll.</summary>
|
||||
public event EventHandler<EventArgs<int>>? Scrolled;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API (for unit tests) - Calculates the position within the <see cref="ScrollableContentSize"/> based on the slider position.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Clamps the sliderPosition, ensuring the returned content position is always less than
|
||||
/// <see cref="ScrollableContentSize"/> - <see cref="VisibleContentSize"/>.
|
||||
/// </remarks>
|
||||
/// <param name="sliderPosition"></param>
|
||||
/// <returns></returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL (for unit tests). Calculates the size of the slider based on the Orientation, VisibleContentSize, the actual Viewport, and Size.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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<int> e)
|
||||
{
|
||||
if (ViewportDimension == 0)
|
||||
if (VisibleContentSize == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -325,24 +470,24 @@ public class ScrollBar : View, IOrientation, IDesignable
|
||||
|
||||
private void SliderOnScroll (object? sender, EventArgs<int> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position of the start of the Scroll slider, within the Viewport.
|
||||
/// </summary>
|
||||
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
|
||||
/// <summary>Raised when the slider position has changed.</summary>
|
||||
public event EventHandler<EventArgs<int>>? SliderPositionChanged;
|
||||
|
||||
private int CalculateSliderPosition (int contentPosition, NavigationDirection direction = NavigationDirection.Forward)
|
||||
/// <summary>
|
||||
/// INTERNAL API (for unit tests) - Calculates the position of the slider based on the content position.
|
||||
/// </summary>
|
||||
/// <param name="contentPosition"></param>
|
||||
/// <param name="direction"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// INTERNAL API (for unit tests) - Calculates the content position based on the slider position.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Clamps the sliderPosition, ensuring the returned content position is always less than
|
||||
/// Size - VieportDimension.
|
||||
/// </remarks>
|
||||
/// <param name="sliderPosition"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position of the slider relative to <see cref="Size"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The content position is clamped to 0 and <see cref="Size"/> minus <see cref="ViewportDimension"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Setting will result in the <see cref="ContentPositionChanging"/> and <see cref="ContentPositionChanged"/>
|
||||
/// events being raised.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
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<int> 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when <see cref="ContentPosition"/> is changing. Return true to cancel the change.
|
||||
/// </summary>
|
||||
protected virtual bool OnContentPositionChanging (int currentPos, int newPos) { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the <see cref="ContentPosition"/> is changing. Set <see cref="CancelEventArgs.Cancel"/> to
|
||||
/// <see langword="true"/> to prevent the position from being changed.
|
||||
/// </summary>
|
||||
public event EventHandler<CancelEventArgs<int>>? ContentPositionChanging;
|
||||
|
||||
/// <summary>Called when <see cref="ContentPosition"/> has changed.</summary>
|
||||
protected virtual void OnContentPositionChanged (int position) { }
|
||||
|
||||
/// <summary>Raised when the <see cref="ContentPosition"/> has changed.</summary>
|
||||
public event EventHandler<EventArgs<int>>? ContentPositionChanged;
|
||||
|
||||
/// <summary>Called when <see cref="ContentPosition"/> has changed. Indicates how much to scroll.</summary>
|
||||
protected virtual void OnScrolled (int distance) { }
|
||||
|
||||
/// <summary>Raised when the <see cref="ContentPosition"/> has changed. Indicates how much to scroll.</summary>
|
||||
public event EventHandler<EventArgs<int>>? Scrolled;
|
||||
|
||||
#endregion ContentPosition
|
||||
#endregion Slider Management
|
||||
|
||||
/// <inheritdoc/>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount each mouse hweel event will incremenet/decrement the <see cref="ContentPosition"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default is 1.
|
||||
/// </remarks>
|
||||
public int Increment { get; set; } = 1;
|
||||
|
||||
/// <inheritdoc/>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 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 <see cref="View.SuperView"/>.
|
||||
/// </summary>
|
||||
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
|
||||
/// <returns></returns>
|
||||
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
|
||||
///// <inheritdoc/>
|
||||
private int _lastLocation = -1;
|
||||
|
||||
public int ShrinkBy { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the amount to pad the start and end of the scroll slider. The default is 0.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When the scroll slider is used by <see cref="ScrollBar"/>, which has increment and decrement buttons, the
|
||||
/// SliderPadding should be set to the size of the buttons (typically 2).
|
||||
/// </remarks>
|
||||
public int SliderPadding { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
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
|
||||
/// <inheritdoc/>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<string> (Enumerable.Range (0, scrollBar.Size).Select (n => $"{n:00000}")));
|
||||
controlledList.SetSource (new ObservableCollection<string> (Enumerable.Range (0, scrollBar.ScrollableContentSize).Select (n => $"{n:00000}")));
|
||||
|
||||
int GetMaxLabelWidth (int groupId)
|
||||
{
|
||||
@@ -167,7 +167,7 @@ public class ScrollBarDemo : Scenario
|
||||
|
||||
NumericUpDown<int> 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<int> viewportDimension = new ()
|
||||
NumericUpDown<int> 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user