зеркало из https://github.com/AvaloniaUI/Avalonia.git
Simplified TextBox scrolling.
This commit is contained in:
Родитель
542e81d129
Коммит
39691aecc3
|
@ -71,7 +71,7 @@
|
|||
<Compile Include="ItemsPanelTemplate.cs" />
|
||||
<Compile Include="Presenters\ItemsPresenter.cs" />
|
||||
<Compile Include="Panel.cs" />
|
||||
<Compile Include="Primitives\IScrollInfo.cs" />
|
||||
<Compile Include="Primitives\ScrollBarVisibility.cs" />
|
||||
<Compile Include="Primitives\Track.cs" />
|
||||
<Compile Include="Primitives\Thumb.cs" />
|
||||
<Compile Include="RequestBringIntoViewEventArgs.cs" />
|
||||
|
|
|
@ -36,8 +36,6 @@ namespace Perspex.Controls.Presenters
|
|||
|
||||
public ScrollContentPresenter()
|
||||
{
|
||||
this.GetObservable(ContentProperty).Subscribe(this.ContentChanged);
|
||||
|
||||
this.AddHandler(
|
||||
Control.RequestBringIntoViewEvent,
|
||||
new EventHandler<RequestBringIntoViewEventArgs>(this.BringIntoViewRequested));
|
||||
|
@ -145,21 +143,5 @@ namespace Perspex.Controls.Presenters
|
|||
|
||||
this.Offset = offset;
|
||||
}
|
||||
|
||||
private void ContentChanged(object content)
|
||||
{
|
||||
var scrollInfo = content as IScrollInfo;
|
||||
|
||||
if (this.contentBindings != null)
|
||||
{
|
||||
this.contentBindings.Dispose();
|
||||
this.contentBindings = null;
|
||||
}
|
||||
|
||||
if (scrollInfo != null)
|
||||
{
|
||||
this.contentBindings = this.Bind(CanScrollHorizontallyProperty, scrollInfo.CanScrollHorizontally);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Perspex.Controls
|
|||
using Perspex.Media;
|
||||
using Perspex.Threading;
|
||||
|
||||
public class TextPresenter : TextBlock, IScrollInfo
|
||||
public class TextPresenter : TextBlock
|
||||
{
|
||||
public static readonly PerspexProperty<bool> AcceptsReturnProperty =
|
||||
TextBox.AcceptsReturnProperty.AddOwner<TextPresenter>();
|
||||
|
@ -97,16 +97,6 @@ namespace Perspex.Controls
|
|||
get { return base.FormattedText; }
|
||||
}
|
||||
|
||||
IObservable<bool> IScrollInfo.CanScrollHorizontally
|
||||
{
|
||||
get { return this.canScrollHorizontally; }
|
||||
}
|
||||
|
||||
IObservable<bool> IScrollInfo.IsHorizontalScrollBarVisible
|
||||
{
|
||||
get { return Observable.Never<bool>().StartWith(false); }
|
||||
}
|
||||
|
||||
public int GetCaretIndex(Point point)
|
||||
{
|
||||
var hit = this.FormattedText.HitTestPoint(point);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="IScrollInfo.cs" company="Steven Kirk">
|
||||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Perspex.Controls.Primitives
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Allows the child of a <see cref="ScrollViewer"/> to communicate with the scroll viewer.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that this interface has a different purpose to IScrollInfo in WPF! I would give it
|
||||
/// a different name, but it does what it suggests - give information about the scrolling
|
||||
/// requirements of a control.
|
||||
/// </remarks>
|
||||
public interface IScrollInfo
|
||||
{
|
||||
IObservable<bool> CanScrollHorizontally { get; }
|
||||
|
||||
IObservable<bool> IsHorizontalScrollBarVisible { get; }
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
namespace Perspex.Controls.Primitives
|
||||
{
|
||||
using System;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
|
||||
public class ScrollBar : TemplatedControl
|
||||
|
@ -23,6 +24,9 @@ namespace Perspex.Controls.Primitives
|
|||
public static readonly PerspexProperty<double> ViewportSizeProperty =
|
||||
PerspexProperty.Register<ScrollBar, double>("ViewportSize", defaultValue: double.NaN);
|
||||
|
||||
public static readonly PerspexProperty<ScrollBarVisibility> VisibilityProperty =
|
||||
PerspexProperty.Register<ScrollBar, ScrollBarVisibility>("Visibility");
|
||||
|
||||
public static readonly PerspexProperty<Orientation> OrientationProperty =
|
||||
PerspexProperty.Register<ScrollBar, Orientation>("Orientation");
|
||||
|
||||
|
@ -32,6 +36,17 @@ namespace Perspex.Controls.Primitives
|
|||
Control.PseudoClass(OrientationProperty, x => x == Orientation.Vertical, ":vertical");
|
||||
}
|
||||
|
||||
public ScrollBar()
|
||||
{
|
||||
var isVisible = Observable.Merge(
|
||||
this.GetObservable(MinimumProperty).Select(_ => Unit.Default),
|
||||
this.GetObservable(MaximumProperty).Select(_ => Unit.Default),
|
||||
this.GetObservable(ViewportSizeProperty).Select(_ => Unit.Default),
|
||||
this.GetObservable(VisibilityProperty).Select(_ => Unit.Default))
|
||||
.Select(_ => this.CalculateIsVisible());
|
||||
this.Bind(IsVisibleProperty, isVisible, BindingPriority.Style);
|
||||
}
|
||||
|
||||
public double Minimum
|
||||
{
|
||||
get { return this.GetValue(MinimumProperty); }
|
||||
|
@ -56,6 +71,12 @@ namespace Perspex.Controls.Primitives
|
|||
set { this.SetValue(ViewportSizeProperty, value); }
|
||||
}
|
||||
|
||||
public ScrollBarVisibility Visibility
|
||||
{
|
||||
get { return this.GetValue(VisibilityProperty); }
|
||||
set { this.SetValue(VisibilityProperty, value); }
|
||||
}
|
||||
|
||||
public Orientation Orientation
|
||||
{
|
||||
get { return this.GetValue(OrientationProperty); }
|
||||
|
@ -66,5 +87,24 @@ namespace Perspex.Controls.Primitives
|
|||
{
|
||||
return base.MeasureOverride(availableSize);
|
||||
}
|
||||
|
||||
private bool CalculateIsVisible()
|
||||
{
|
||||
switch (this.Visibility)
|
||||
{
|
||||
case ScrollBarVisibility.Visible:
|
||||
return true;
|
||||
|
||||
case ScrollBarVisibility.Hidden:
|
||||
return false;
|
||||
|
||||
case ScrollBarVisibility.Auto:
|
||||
var viewportSize = this.ViewportSize;
|
||||
return double.IsNaN(viewportSize) || viewportSize < this.Maximum - this.Minimum;
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException("Invalid value for ScrollBar.Visibility.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ScrollBarVisibility.cs" company="Steven Kirk">
|
||||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Perspex.Controls.Primitives
|
||||
{
|
||||
public enum ScrollBarVisibility
|
||||
{
|
||||
Visible,
|
||||
Hidden,
|
||||
Auto,
|
||||
}
|
||||
}
|
|
@ -23,10 +23,7 @@ namespace Perspex.Controls
|
|||
PerspexProperty.Register<ScrollViewer, Size>("Viewport");
|
||||
|
||||
public static readonly PerspexProperty<bool> CanScrollHorizontallyProperty =
|
||||
PerspexProperty.Register<ScrollViewer, bool>("CanScrollHorizontally", false);
|
||||
|
||||
public static readonly PerspexProperty<bool> IsHorizontalScrollBarVisibleProperty =
|
||||
PerspexProperty.Register<ScrollViewer, bool>("IsHorizontalScrollBarVisible");
|
||||
PerspexProperty.RegisterAttached<ScrollViewer, Control, bool>("CanScrollHorizontally", false);
|
||||
|
||||
public static readonly PerspexProperty<double> HorizontalScrollBarMaximumProperty =
|
||||
PerspexProperty.Register<ScrollViewer, double>("HorizontalScrollBarMaximum");
|
||||
|
@ -37,8 +34,8 @@ namespace Perspex.Controls
|
|||
public static readonly PerspexProperty<double> HorizontalScrollBarViewportSizeProperty =
|
||||
PerspexProperty.Register<ScrollViewer, double>("HorizontalScrollBarViewportSize");
|
||||
|
||||
public static readonly PerspexProperty<bool> IsVerticalScrollBarVisibleProperty =
|
||||
PerspexProperty.Register<ScrollViewer, bool>("IsVerticalScrollBarVisible");
|
||||
public static readonly PerspexProperty<ScrollBarVisibility> HorizontalScrollBarVisibilityProperty =
|
||||
PerspexProperty.RegisterAttached<ScrollBar, Control, ScrollBarVisibility>("HorizontalScrollBarVisibility", ScrollBarVisibility.Auto);
|
||||
|
||||
public static readonly PerspexProperty<double> VerticalScrollBarMaximumProperty =
|
||||
PerspexProperty.Register<ScrollViewer, double>("VerticalScrollBarMaximum");
|
||||
|
@ -49,6 +46,9 @@ namespace Perspex.Controls
|
|||
public static readonly PerspexProperty<double> VerticalScrollBarViewportSizeProperty =
|
||||
PerspexProperty.Register<ScrollViewer, double>("VerticalScrollBarViewportSize");
|
||||
|
||||
public static readonly PerspexProperty<ScrollBarVisibility> VerticalScrollBarVisibilityProperty =
|
||||
PerspexProperty.RegisterAttached<ScrollViewer, Control, ScrollBarVisibility>("VerticalScrollBarVisibility", ScrollBarVisibility.Auto);
|
||||
|
||||
private IDisposable contentBindings;
|
||||
|
||||
static ScrollViewer()
|
||||
|
@ -64,31 +64,21 @@ namespace Perspex.Controls
|
|||
this.GetObservable(ViewportProperty))
|
||||
.Select(x => new { Extent = x[0], Viewport = x[1] });
|
||||
|
||||
this.Bind(
|
||||
IsHorizontalScrollBarVisibleProperty,
|
||||
extentAndViewport.Select(x => x.Extent.Width > x.Viewport.Width),
|
||||
BindingPriority.Style);
|
||||
|
||||
this.Bind(
|
||||
HorizontalScrollBarMaximumProperty,
|
||||
extentAndViewport.Select(x => x.Extent.Width - x.Viewport.Width));
|
||||
extentAndViewport.Select(x => Math.Max(x.Extent.Width - x.Viewport.Width, 0)));
|
||||
|
||||
this.Bind(
|
||||
HorizontalScrollBarViewportSizeProperty,
|
||||
extentAndViewport.Select(x => (x.Viewport.Width / x.Extent.Width) * (x.Extent.Width - x.Viewport.Width)));
|
||||
|
||||
this.Bind(
|
||||
IsVerticalScrollBarVisibleProperty,
|
||||
extentAndViewport.Select(x => x.Extent.Height > x.Viewport.Height),
|
||||
BindingPriority.Style);
|
||||
extentAndViewport.Select(x => Math.Max((x.Viewport.Width / x.Extent.Width) * (x.Extent.Width - x.Viewport.Width), 0)));
|
||||
|
||||
this.Bind(
|
||||
VerticalScrollBarMaximumProperty,
|
||||
extentAndViewport.Select(x => x.Extent.Height - x.Viewport.Height));
|
||||
extentAndViewport.Select(x => Math.Max(x.Extent.Height - x.Viewport.Height, 0)));
|
||||
|
||||
this.Bind(
|
||||
VerticalScrollBarViewportSizeProperty,
|
||||
extentAndViewport.Select(x => (x.Viewport.Height / x.Extent.Height) * (x.Extent.Height - x.Viewport.Height)));
|
||||
extentAndViewport.Select(x => Math.Max((x.Viewport.Height / x.Extent.Height) * (x.Extent.Height - x.Viewport.Height), 0)));
|
||||
|
||||
this.GetObservable(OffsetProperty).Subscribe(x =>
|
||||
{
|
||||
|
@ -101,8 +91,6 @@ namespace Perspex.Controls
|
|||
this.GetObservable(VerticalScrollBarValueProperty))
|
||||
.Select(x => new Vector(x[0], x[1]))
|
||||
.Subscribe(x => this.Offset = x);
|
||||
|
||||
this.GetObservable(ContentProperty).Subscribe(this.ContentChanged);
|
||||
}
|
||||
|
||||
public Size Extent
|
||||
|
@ -129,6 +117,18 @@ namespace Perspex.Controls
|
|||
set { this.SetValue(CanScrollHorizontallyProperty, value); }
|
||||
}
|
||||
|
||||
public ScrollBarVisibility HorizontalScrollBarVisibility
|
||||
{
|
||||
get { return this.GetValue(HorizontalScrollBarVisibilityProperty); }
|
||||
set { this.SetValue(HorizontalScrollBarVisibilityProperty, value); }
|
||||
}
|
||||
|
||||
public ScrollBarVisibility VerticalScrollBarVisibility
|
||||
{
|
||||
get { return this.GetValue(VerticalScrollBarVisibilityProperty); }
|
||||
set { this.SetValue(VerticalScrollBarVisibilityProperty, value); }
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return base.MeasureOverride(availableSize);
|
||||
|
@ -156,23 +156,5 @@ namespace Perspex.Controls
|
|||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private void ContentChanged(object content)
|
||||
{
|
||||
var scrollInfo = content as IScrollInfo;
|
||||
|
||||
if (this.contentBindings != null)
|
||||
{
|
||||
this.contentBindings.Dispose();
|
||||
this.contentBindings = null;
|
||||
}
|
||||
|
||||
if (scrollInfo != null)
|
||||
{
|
||||
this.contentBindings = this.Bind(
|
||||
IsHorizontalScrollBarVisibleProperty,
|
||||
scrollInfo.IsHorizontalScrollBarVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
namespace Perspex.Controls
|
||||
{
|
||||
using System;
|
||||
using System.Reactive.Linq;
|
||||
using Perspex.Controls.Primitives;
|
||||
|
||||
public class TextBox : TemplatedControl
|
||||
|
@ -32,6 +33,25 @@ namespace Perspex.Controls
|
|||
public static readonly PerspexProperty<TextWrapping> TextWrappingProperty =
|
||||
TextBlock.TextWrappingProperty.AddOwner<TextBox>();
|
||||
|
||||
public TextBox()
|
||||
{
|
||||
var canScrollHorizontally = this.GetObservable(AcceptsReturnProperty)
|
||||
.Select(x => !x);
|
||||
|
||||
this.Bind(
|
||||
ScrollViewer.CanScrollHorizontallyProperty,
|
||||
canScrollHorizontally,
|
||||
BindingPriority.Style);
|
||||
|
||||
var horizontalScrollBarVisibility = this.GetObservable(AcceptsReturnProperty)
|
||||
.Select(x => x ? ScrollBarVisibility.Auto : ScrollBarVisibility.Hidden);
|
||||
|
||||
this.Bind(
|
||||
ScrollViewer.HorizontalScrollBarVisibilityProperty,
|
||||
horizontalScrollBarVisibility,
|
||||
BindingPriority.Style);
|
||||
}
|
||||
|
||||
public bool AcceptsReturn
|
||||
{
|
||||
get { return this.GetValue(AcceptsReturnProperty); }
|
||||
|
|
|
@ -58,20 +58,20 @@ namespace Perspex.Themes.Default
|
|||
{
|
||||
Id = "horizontalScrollBar",
|
||||
Orientation = Orientation.Horizontal,
|
||||
[~ScrollBar.IsVisibleProperty] = control[~ScrollViewer.IsHorizontalScrollBarVisibleProperty],
|
||||
[~ScrollBar.MaximumProperty] = control[~ScrollViewer.HorizontalScrollBarMaximumProperty],
|
||||
[~~ScrollBar.ValueProperty] = control[~~ScrollViewer.HorizontalScrollBarValueProperty],
|
||||
[~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.HorizontalScrollBarViewportSizeProperty],
|
||||
[~ScrollBar.VisibilityProperty] = control[~ScrollViewer.HorizontalScrollBarVisibilityProperty],
|
||||
[Grid.RowProperty] = 1,
|
||||
},
|
||||
new ScrollBar
|
||||
{
|
||||
Id = "verticalScrollBar",
|
||||
Orientation = Orientation.Vertical,
|
||||
[~ScrollBar.IsVisibleProperty] = control[~ScrollViewer.IsVerticalScrollBarVisibleProperty],
|
||||
[~ScrollBar.MaximumProperty] = control[~ScrollViewer.VerticalScrollBarMaximumProperty],
|
||||
[~~ScrollBar.ValueProperty] = control[~~ScrollViewer.VerticalScrollBarValueProperty],
|
||||
[~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.VerticalScrollBarViewportSizeProperty],
|
||||
[~ScrollBar.VisibilityProperty] = control[~ScrollViewer.VerticalScrollBarVisibilityProperty],
|
||||
[Grid.ColumnProperty] = 1,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -49,6 +49,9 @@ namespace Perspex.Themes.Default
|
|||
[~Border.BorderThicknessProperty] = control[~TextBox.BorderThicknessProperty],
|
||||
Content = new ScrollViewer
|
||||
{
|
||||
[~ScrollViewer.CanScrollHorizontallyProperty] = control[~ScrollViewer.CanScrollHorizontallyProperty],
|
||||
[~ScrollViewer.HorizontalScrollBarVisibilityProperty] = control[~ScrollViewer.HorizontalScrollBarVisibilityProperty],
|
||||
[~ScrollViewer.VerticalScrollBarVisibilityProperty] = control[~ScrollViewer.VerticalScrollBarVisibilityProperty],
|
||||
Content = new TextPresenter
|
||||
{
|
||||
[~TextPresenter.AcceptsReturnProperty] = control[~TextBox.AcceptsReturnProperty],
|
||||
|
|
Загрузка…
Ссылка в новой задаче