|
|
|
@ -59,6 +59,22 @@ namespace Avalonia.Controls |
|
|
|
o => o.Viewport, |
|
|
|
(o, v) => o.Viewport = v); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="LargeChange"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly DirectProperty<ScrollViewer, Size> LargeChangeProperty = |
|
|
|
AvaloniaProperty.RegisterDirect<ScrollViewer, Size>( |
|
|
|
nameof(LargeChange), |
|
|
|
o => o.LargeChange); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="SmallChange"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly DirectProperty<ScrollViewer, Size> SmallChangeProperty = |
|
|
|
AvaloniaProperty.RegisterDirect<ScrollViewer, Size>( |
|
|
|
nameof(SmallChange), |
|
|
|
o => o.SmallChange); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the HorizontalScrollBarMaximum property.
|
|
|
|
/// </summary>
|
|
|
|
@ -149,9 +165,15 @@ namespace Avalonia.Controls |
|
|
|
nameof(VerticalScrollBarVisibility), |
|
|
|
ScrollBarVisibility.Auto); |
|
|
|
|
|
|
|
internal const double DefaultSmallChange = 16; |
|
|
|
|
|
|
|
private IDisposable _childSubscription; |
|
|
|
private ILogicalScrollable _logicalScrollable; |
|
|
|
private Size _extent; |
|
|
|
private Vector _offset; |
|
|
|
private Size _viewport; |
|
|
|
private Size _largeChange; |
|
|
|
private Size _smallChange = new Size(DefaultSmallChange, DefaultSmallChange); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes static members of the <see cref="ScrollViewer"/> class.
|
|
|
|
@ -228,6 +250,16 @@ namespace Avalonia.Controls |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the large (page) change value for the scroll viewer.
|
|
|
|
/// </summary>
|
|
|
|
public Size LargeChange => _largeChange; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the small (line) change value for the scroll viewer.
|
|
|
|
/// </summary>
|
|
|
|
public Size SmallChange => _smallChange; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the horizontal scrollbar visibility.
|
|
|
|
/// </summary>
|
|
|
|
@ -246,22 +278,6 @@ namespace Avalonia.Controls |
|
|
|
set { SetValue(VerticalScrollBarVisibilityProperty, value); } |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Scrolls to the top-left corner of the content.
|
|
|
|
/// </summary>
|
|
|
|
public void ScrollToHome() |
|
|
|
{ |
|
|
|
Offset = new Vector(double.NegativeInfinity, double.NegativeInfinity); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Scrolls to the bottom-left corner of the content.
|
|
|
|
/// </summary>
|
|
|
|
public void ScrollToEnd() |
|
|
|
{ |
|
|
|
Offset = new Vector(double.NegativeInfinity, double.PositiveInfinity); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a value indicating whether the viewer can scroll horizontally.
|
|
|
|
/// </summary>
|
|
|
|
@ -347,6 +363,22 @@ namespace Avalonia.Controls |
|
|
|
/// <inheritdoc/>
|
|
|
|
IControl IScrollAnchorProvider.CurrentAnchor => null; // TODO: Implement
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Scrolls to the top-left corner of the content.
|
|
|
|
/// </summary>
|
|
|
|
public void ScrollToHome() |
|
|
|
{ |
|
|
|
Offset = new Vector(double.NegativeInfinity, double.NegativeInfinity); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Scrolls to the bottom-left corner of the content.
|
|
|
|
/// </summary>
|
|
|
|
public void ScrollToEnd() |
|
|
|
{ |
|
|
|
Offset = new Vector(double.NegativeInfinity, double.PositiveInfinity); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the value of the HorizontalScrollBarVisibility attached property.
|
|
|
|
/// </summary>
|
|
|
|
@ -397,6 +429,22 @@ namespace Avalonia.Controls |
|
|
|
// TODO: Implement
|
|
|
|
} |
|
|
|
|
|
|
|
protected override bool RegisterContentPresenter(IContentPresenter presenter) |
|
|
|
{ |
|
|
|
_childSubscription?.Dispose(); |
|
|
|
_childSubscription = null; |
|
|
|
|
|
|
|
if (base.RegisterContentPresenter(presenter)) |
|
|
|
{ |
|
|
|
_childSubscription = Presenter? |
|
|
|
.GetObservable(ContentPresenter.ChildProperty) |
|
|
|
.Subscribe(ChildChanged); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
internal static Vector CoerceOffset(Size extent, Size viewport, Vector offset) |
|
|
|
{ |
|
|
|
var maxX = Math.Max(extent.Width - viewport.Width, 0); |
|
|
|
@ -431,6 +479,28 @@ namespace Avalonia.Controls |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void ChildChanged(IControl child) |
|
|
|
{ |
|
|
|
if (_logicalScrollable is object) |
|
|
|
{ |
|
|
|
_logicalScrollable.ScrollInvalidated -= LogicalScrollInvalidated; |
|
|
|
_logicalScrollable = null; |
|
|
|
} |
|
|
|
|
|
|
|
if (child is ILogicalScrollable logical) |
|
|
|
{ |
|
|
|
_logicalScrollable = logical; |
|
|
|
logical.ScrollInvalidated += LogicalScrollInvalidated; |
|
|
|
} |
|
|
|
|
|
|
|
CalculatedPropertiesChanged(); |
|
|
|
} |
|
|
|
|
|
|
|
private void LogicalScrollInvalidated(object sender, EventArgs e) |
|
|
|
{ |
|
|
|
CalculatedPropertiesChanged(); |
|
|
|
} |
|
|
|
|
|
|
|
private void ScrollBarVisibilityChanged(AvaloniaPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
var wasEnabled = !ScrollBarVisibility.Disabled.Equals(e.OldValue); |
|
|
|
@ -465,6 +535,17 @@ namespace Avalonia.Controls |
|
|
|
RaisePropertyChanged(VerticalScrollBarMaximumProperty, 0, VerticalScrollBarMaximum); |
|
|
|
RaisePropertyChanged(VerticalScrollBarValueProperty, 0, VerticalScrollBarValue); |
|
|
|
RaisePropertyChanged(VerticalScrollBarViewportSizeProperty, 0, VerticalScrollBarViewportSize); |
|
|
|
|
|
|
|
if (_logicalScrollable?.IsLogicalScrollEnabled == true) |
|
|
|
{ |
|
|
|
SetAndRaise(SmallChangeProperty, ref _smallChange, _logicalScrollable.ScrollSize); |
|
|
|
SetAndRaise(LargeChangeProperty, ref _largeChange, _logicalScrollable.PageScrollSize); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
SetAndRaise(SmallChangeProperty, ref _smallChange, new Size(DefaultSmallChange, DefaultSmallChange)); |
|
|
|
SetAndRaise(LargeChangeProperty, ref _largeChange, Viewport); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected override void OnKeyDown(KeyEventArgs e) |
|
|
|
|