Browse Source
Currently works so far as to scroll an image in the Images tab of the test app. Hiding the scrollbars is currently disabled as it requires a layout pass to be triggered during a layout pass. Need to work out a way around that...pull/4/head
10 changed files with 282 additions and 5 deletions
@ -0,0 +1,78 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="ScrollContentPresenter.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Presenters |
||||
|
{ |
||||
|
using System.Linq; |
||||
|
using Perspex.Layout; |
||||
|
|
||||
|
public class ScrollContentPresenter : ContentPresenter |
||||
|
{ |
||||
|
public static PerspexProperty<Size> ExtentProperty = |
||||
|
ScrollViewer.ExtentProperty.AddOwner<ScrollContentPresenter>(); |
||||
|
|
||||
|
public static PerspexProperty<Vector> OffsetProperty = |
||||
|
ScrollViewer.OffsetProperty.AddOwner<ScrollContentPresenter>(); |
||||
|
|
||||
|
public static PerspexProperty<Size> ViewportProperty = |
||||
|
ScrollViewer.ViewportProperty.AddOwner<ScrollContentPresenter>(); |
||||
|
|
||||
|
public ScrollContentPresenter() |
||||
|
{ |
||||
|
AffectsRender(OffsetProperty); |
||||
|
} |
||||
|
|
||||
|
public Size Extent |
||||
|
{ |
||||
|
get { return this.GetValue(ExtentProperty); } |
||||
|
private set { this.SetValue(ExtentProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public Vector Offset |
||||
|
{ |
||||
|
get { return this.GetValue(OffsetProperty); } |
||||
|
set { this.SetValue(OffsetProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public Size Viewport |
||||
|
{ |
||||
|
get { return this.GetValue(ViewportProperty); } |
||||
|
private set { this.SetValue(ViewportProperty, value); } |
||||
|
} |
||||
|
|
||||
|
protected override Size MeasureOverride(Size availableSize) |
||||
|
{ |
||||
|
var content = this.Content as ILayoutable; |
||||
|
|
||||
|
if (content != null) |
||||
|
{ |
||||
|
content.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); |
||||
|
var size = content.DesiredSize.Value; |
||||
|
this.Extent = size; |
||||
|
return size.Constrain(availableSize); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return this.Extent = new Size(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override Size ArrangeOverride(Size finalSize) |
||||
|
{ |
||||
|
var child = this.GetVisualChildren().SingleOrDefault() as ILayoutable; |
||||
|
|
||||
|
this.Viewport = finalSize; |
||||
|
|
||||
|
if (child != null) |
||||
|
{ |
||||
|
child.Arrange(new Rect((Point)(-this.Offset), child.DesiredSize.Value)); |
||||
|
return finalSize; |
||||
|
} |
||||
|
|
||||
|
return new Size(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,95 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="DefinitionBase.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
using System.Reactive.Linq; |
||||
|
using Perspex.Controls.Presenters; |
||||
|
using Perspex.Controls.Primitives; |
||||
|
|
||||
|
namespace Perspex.Controls |
||||
|
{ |
||||
|
public class ScrollViewer : ContentControl |
||||
|
{ |
||||
|
public static PerspexProperty<Size> ExtentProperty = |
||||
|
PerspexProperty.Register<ScrollViewer, Size>("Extent"); |
||||
|
|
||||
|
public static PerspexProperty<Vector> OffsetProperty = |
||||
|
PerspexProperty.Register<ScrollViewer, Vector>("Offset"); |
||||
|
|
||||
|
public static PerspexProperty<Size> ViewportProperty = |
||||
|
PerspexProperty.Register<ScrollViewer, Size>("Viewport"); |
||||
|
|
||||
|
private ScrollContentPresenter presenter; |
||||
|
|
||||
|
private ScrollBar horizontalScrollBar; |
||||
|
|
||||
|
private ScrollBar verticalScrollBar; |
||||
|
|
||||
|
public Size Extent |
||||
|
{ |
||||
|
get { return this.GetValue(ExtentProperty); } |
||||
|
private set { this.SetValue(ExtentProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public Vector Offset |
||||
|
{ |
||||
|
get { return this.GetValue(OffsetProperty); } |
||||
|
set { this.SetValue(OffsetProperty, value); } |
||||
|
} |
||||
|
|
||||
|
public Size Viewport |
||||
|
{ |
||||
|
get { return this.GetValue(ViewportProperty); } |
||||
|
private set { this.SetValue(ViewportProperty, value); } |
||||
|
} |
||||
|
|
||||
|
protected override void OnTemplateApplied() |
||||
|
{ |
||||
|
this.presenter = this.GetTemplateChild<ScrollContentPresenter>("presenter"); |
||||
|
this.horizontalScrollBar = this.GetTemplateChild<ScrollBar>("horizontalScrollBar"); |
||||
|
this.verticalScrollBar = this.GetTemplateChild<ScrollBar>("verticalScrollBar"); |
||||
|
|
||||
|
this[!ExtentProperty] = this.presenter[!ExtentProperty]; |
||||
|
this[!ViewportProperty] = this.presenter[!ViewportProperty]; |
||||
|
this.presenter[!OffsetProperty] = this[!OffsetProperty]; |
||||
|
|
||||
|
var extentAndViewport = Observable.CombineLatest( |
||||
|
this.GetObservable(ExtentProperty).StartWith(this.Extent), |
||||
|
this.GetObservable(ViewportProperty).StartWith(this.Viewport)) |
||||
|
.Select(x => new { Extent = x[0], Viewport = x[1] }); |
||||
|
|
||||
|
//this.horizontalScrollBar.Bind(
|
||||
|
// IsVisibleProperty,
|
||||
|
// extentAndViewport.Select(x => x.Extent.Width > x.Viewport.Width));
|
||||
|
|
||||
|
this.horizontalScrollBar.Bind( |
||||
|
ScrollBar.MaximumProperty, |
||||
|
extentAndViewport.Select(x => x.Extent.Width)); |
||||
|
|
||||
|
this.horizontalScrollBar.Bind( |
||||
|
ScrollBar.ViewportSizeProperty, |
||||
|
extentAndViewport.Select(x => x.Viewport.Width)); |
||||
|
|
||||
|
//this.verticalScrollBar.Bind(
|
||||
|
// IsVisibleProperty,
|
||||
|
// extentAndViewport.Select(x => x.Extent.Height > x.Viewport.Height));
|
||||
|
|
||||
|
this.verticalScrollBar.Bind( |
||||
|
ScrollBar.MaximumProperty, |
||||
|
extentAndViewport.Select(x => x.Extent.Height)); |
||||
|
|
||||
|
this.verticalScrollBar.Bind( |
||||
|
ScrollBar.ViewportSizeProperty, |
||||
|
extentAndViewport.Select(x => x.Viewport.Height)); |
||||
|
|
||||
|
var offset = Observable.CombineLatest( |
||||
|
this.horizontalScrollBar.GetObservable(ScrollBar.ValueProperty), |
||||
|
this.verticalScrollBar.GetObservable(ScrollBar.ValueProperty)) |
||||
|
.Select(x => new Vector(x[0], x[1])); |
||||
|
|
||||
|
this.Bind(OffsetProperty, offset); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="ScrollViewerStyle.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Themes.Default |
||||
|
{ |
||||
|
using System.Linq; |
||||
|
using Perspex.Controls; |
||||
|
using Perspex.Controls.Presenters; |
||||
|
using Perspex.Controls.Primitives; |
||||
|
using Perspex.Media; |
||||
|
using Perspex.Styling; |
||||
|
|
||||
|
public class ScrollViewerStyle : Styles |
||||
|
{ |
||||
|
public ScrollViewerStyle() |
||||
|
{ |
||||
|
this.AddRange(new[] |
||||
|
{ |
||||
|
new Style(x => x.OfType<ScrollViewer>()) |
||||
|
{ |
||||
|
Setters = new[] |
||||
|
{ |
||||
|
new Setter(ScrollViewer.TemplateProperty, ControlTemplate.Create<ScrollViewer>(this.Template)), |
||||
|
}, |
||||
|
}, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private Control Template(ScrollViewer control) |
||||
|
{ |
||||
|
return new Grid |
||||
|
{ |
||||
|
ColumnDefinitions = new ColumnDefinitions |
||||
|
{ |
||||
|
new ColumnDefinition(1, GridUnitType.Star), |
||||
|
new ColumnDefinition(GridLength.Auto), |
||||
|
}, |
||||
|
RowDefinitions = new RowDefinitions |
||||
|
{ |
||||
|
new RowDefinition(1, GridUnitType.Star), |
||||
|
new RowDefinition(GridLength.Auto), |
||||
|
}, |
||||
|
Children = new Controls |
||||
|
{ |
||||
|
new ScrollContentPresenter |
||||
|
{ |
||||
|
Id = "presenter", |
||||
|
[~ContentPresenter.ContentProperty] = control[~ScrollViewer.ContentProperty], |
||||
|
}, |
||||
|
new ScrollBar |
||||
|
{ |
||||
|
Id = "horizontalScrollBar", |
||||
|
Orientation = Orientation.Horizontal, |
||||
|
[Grid.RowProperty] = 1, |
||||
|
}, |
||||
|
new ScrollBar |
||||
|
{ |
||||
|
Id = "verticalScrollBar", |
||||
|
Orientation = Orientation.Vertical, |
||||
|
[Grid.ColumnProperty] = 1, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue