This commit is contained in:
Steven Kirk 2014-12-13 23:14:15 +01:00
Родитель 542e81d129
Коммит 39691aecc3
10 изменённых файлов: 104 добавлений и 97 удалений

Просмотреть файл

@ -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],