11 changed files with 562 additions and 1 deletions
@ -0,0 +1,103 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public sealed class ArcSegment : PathSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="IsLargeArc"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<bool> IsLargeArcProperty |
|||
= PerspexProperty.Register<ArcSegment, bool>(nameof(IsLargeArc), false); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="Point"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> PointProperty |
|||
= PerspexProperty.Register<ArcSegment, Point>(nameof(Point)); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="RotationAngle"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<double> RotationAngleProperty |
|||
= PerspexProperty.Register<ArcSegment, double>(nameof(RotationAngle), 0); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="Size"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Size> SizeProperty |
|||
= PerspexProperty.Register<ArcSegment, Size>(nameof(Size)); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="SweepDirection"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<SweepDirection> SweepDirectionProperty |
|||
= PerspexProperty.Register<ArcSegment, SweepDirection>(nameof(SweepDirection), SweepDirection.Clockwise); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a value indicating whether this instance is large arc.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is large arc; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
public bool IsLargeArc |
|||
{ |
|||
get { return GetValue(IsLargeArcProperty); } |
|||
set { SetValue(IsLargeArcProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the point.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The point.
|
|||
/// </value>
|
|||
public Point Point |
|||
{ |
|||
get { return GetValue(PointProperty); } |
|||
set { SetValue(PointProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the rotation angle.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The rotation angle.
|
|||
/// </value>
|
|||
public double RotationAngle |
|||
{ |
|||
get { return GetValue(RotationAngleProperty); } |
|||
set { SetValue(RotationAngleProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the size.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The size.
|
|||
/// </value>
|
|||
public Size Size |
|||
{ |
|||
get { return GetValue(SizeProperty); } |
|||
set { SetValue(SizeProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the sweep direction.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The sweep direction.
|
|||
/// </value>
|
|||
public SweepDirection SweepDirection |
|||
{ |
|||
get { return GetValue(SweepDirectionProperty); } |
|||
set { SetValue(SweepDirectionProperty, value); } |
|||
} |
|||
|
|||
protected internal override void ApplyTo(StreamGeometryContext ctx) |
|||
{ |
|||
ctx.ArcTo(Point, Size, RotationAngle, IsLargeArc, SweepDirection); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public sealed class BezierSegment : PathSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="Point1"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> Point1Property |
|||
= PerspexProperty.Register<BezierSegment, Point>(nameof(Point1)); |
|||
/// <summary>
|
|||
/// Defines the <see cref="Point2"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> Point2Property |
|||
= PerspexProperty.Register<BezierSegment, Point>(nameof(Point2)); |
|||
/// <summary>
|
|||
/// Defines the <see cref="Point3"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> Point3Property |
|||
= PerspexProperty.Register<BezierSegment, Point>(nameof(Point3)); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the point1.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The point1.
|
|||
/// </value>
|
|||
public Point Point1 |
|||
{ |
|||
get { return GetValue(Point1Property); } |
|||
set { SetValue(Point1Property, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the point2.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The point2.
|
|||
/// </value>
|
|||
public Point Point2 |
|||
{ |
|||
get { return GetValue(Point2Property); } |
|||
set { SetValue(Point2Property, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the point3.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The point3.
|
|||
/// </value>
|
|||
public Point Point3 |
|||
{ |
|||
get { return GetValue(Point3Property); } |
|||
set { SetValue(Point3Property, value); } |
|||
} |
|||
|
|||
protected internal override void ApplyTo(StreamGeometryContext ctx) |
|||
{ |
|||
ctx.CubicBezierTo(Point1, Point2, Point3); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public sealed class LineSegment : PathSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="Point"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> PointProperty |
|||
= PerspexProperty.Register<LineSegment, Point>(nameof(Point)); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the point.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The point.
|
|||
/// </value>
|
|||
public Point Point |
|||
{ |
|||
get { return GetValue(PointProperty); } |
|||
set { SetValue(PointProperty, value); } |
|||
} |
|||
|
|||
protected internal override void ApplyTo(StreamGeometryContext ctx) |
|||
{ |
|||
ctx.LineTo(Point); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,102 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Perspex.Metadata; |
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public sealed class PathFigure : PerspexObject |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="IsClosed"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<bool> IsClosedProperty |
|||
= PerspexProperty.Register<PathFigure, bool>(nameof(IsClosed), true); |
|||
/// <summary>
|
|||
/// Defines the <see cref="IsFilled"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<bool> IsFilledProperty |
|||
= PerspexProperty.Register<PathFigure, bool>(nameof(IsFilled), true); |
|||
/// <summary>
|
|||
/// Defines the <see cref="Segments"/> property.
|
|||
/// </summary>
|
|||
public static readonly DirectProperty<PathFigure, PathSegments> SegmentsProperty |
|||
= PerspexProperty.RegisterDirect<PathFigure, PathSegments>(nameof(Segments), f => f.Segments, (f, s) => f.Segments = s); |
|||
/// <summary>
|
|||
/// Defines the <see cref="StartPoint"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> StartPointProperty |
|||
= PerspexProperty.Register<PathFigure, Point>(nameof(StartPoint)); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PathFigure"/> class.
|
|||
/// </summary>
|
|||
public PathFigure() |
|||
{ |
|||
Segments = new PathSegments(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a value indicating whether this instance is closed.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
public bool IsClosed |
|||
{ |
|||
get { return GetValue(IsClosedProperty); } |
|||
set { SetValue(IsClosedProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a value indicating whether this instance is filled.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>true</c> if this instance is filled; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
public bool IsFilled |
|||
{ |
|||
get { return GetValue(IsFilledProperty); } |
|||
set { SetValue(IsFilledProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the segments.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The segments.
|
|||
/// </value>
|
|||
[Content] |
|||
public PathSegments Segments |
|||
{ |
|||
get { return _segments; } |
|||
set { SetAndRaise(SegmentsProperty, ref _segments, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the start point.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The start point.
|
|||
/// </value>
|
|||
public Point StartPoint |
|||
{ |
|||
get { return GetValue(StartPointProperty); } |
|||
set { SetValue(StartPointProperty, value); } |
|||
} |
|||
|
|||
internal void ApplyTo(StreamGeometryContext ctx) |
|||
{ |
|||
ctx.BeginFigure(StartPoint, IsFilled); |
|||
|
|||
foreach (var segment in Segments) |
|||
{ |
|||
segment.ApplyTo(ctx); |
|||
} |
|||
|
|||
ctx.EndFigure(IsClosed); |
|||
} |
|||
|
|||
private PathSegments _segments; |
|||
} |
|||
} |
|||
@ -0,0 +1,123 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Perspex.Collections; |
|||
using Perspex.Metadata; |
|||
using Perspex.Platform; |
|||
using System; |
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public class PathGeometry : StreamGeometry |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="Figures"/> property.
|
|||
/// </summary>
|
|||
public static readonly DirectProperty<PathGeometry, PathFigures> FiguresProperty = |
|||
PerspexProperty.RegisterDirect<PathGeometry, PathFigures>(nameof(Figures), g => g.Figures, (g, f) => g.Figures = f); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="FillRule"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<FillRule> FillRuleProperty = |
|||
PerspexProperty.Register<PathGeometry, FillRule>(nameof(FillRule)); |
|||
|
|||
static PathGeometry() |
|||
{ |
|||
FiguresProperty.Changed.Subscribe(onNext: v => |
|||
{ |
|||
(v.Sender as PathGeometry)?.OnFiguresChanged(v.OldValue as PathFigures, v.NewValue as PathFigures); |
|||
}); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="PathGeometry"/> class.
|
|||
/// </summary>
|
|||
public PathGeometry() |
|||
{ |
|||
Figures = new PathFigures(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the figures.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The figures.
|
|||
/// </value>
|
|||
[Content] |
|||
public PathFigures Figures |
|||
{ |
|||
get { return _figures; } |
|||
set { SetAndRaise(FiguresProperty, ref _figures, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the fill rule.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The fill rule.
|
|||
/// </value>
|
|||
public FillRule FillRule |
|||
{ |
|||
get { return GetValue(FillRuleProperty); } |
|||
set { SetValue(FillRuleProperty, value); } |
|||
} |
|||
|
|||
public override IGeometryImpl PlatformImpl |
|||
{ |
|||
get |
|||
{ |
|||
PrepareIfNeeded(); |
|||
return base.PlatformImpl; |
|||
} |
|||
|
|||
protected set |
|||
{ |
|||
base.PlatformImpl = value; |
|||
} |
|||
} |
|||
|
|||
public override Geometry Clone() |
|||
{ |
|||
PrepareIfNeeded(); |
|||
|
|||
return base.Clone(); |
|||
} |
|||
|
|||
public void PrepareIfNeeded() |
|||
{ |
|||
if (_isDirty) |
|||
{ |
|||
_isDirty = false; |
|||
|
|||
using (var ctx = Open()) |
|||
{ |
|||
ctx.SetFillRule(FillRule); |
|||
foreach (var f in Figures) |
|||
{ |
|||
f.ApplyTo(ctx); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal void NotifyChanged() |
|||
{ |
|||
_isDirty = true; |
|||
} |
|||
|
|||
private PathFigures _figures; |
|||
private IDisposable _figuresObserver = null; |
|||
private IDisposable _figuresPropertiesObserver = null; |
|||
private bool _isDirty = true; |
|||
|
|||
private void OnFiguresChanged(PathFigures oldValue, PathFigures newValue) |
|||
{ |
|||
_figuresObserver?.Dispose(); |
|||
_figuresPropertiesObserver?.Dispose(); |
|||
|
|||
_figuresObserver = newValue?.ForEachItem(f => NotifyChanged(), f => NotifyChanged(), () => NotifyChanged()); |
|||
_figuresPropertiesObserver = newValue?.TrackItemPropertyChanged(t => NotifyChanged()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Perspex.Collections; |
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public sealed class PathFigures : PerspexList<PathFigure> |
|||
{ |
|||
} |
|||
|
|||
public sealed class PathSegments : PerspexList<PathSegment> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public abstract class PathSegment : PerspexObject |
|||
{ |
|||
protected internal abstract void ApplyTo(StreamGeometryContext ctx); |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
namespace Perspex.Media |
|||
{ |
|||
public sealed class QuadraticBezierSegment : PathSegment |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="Point1"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> Point1Property |
|||
= PerspexProperty.Register<QuadraticBezierSegment, Point>(nameof(Point1)); |
|||
|
|||
/// <summary>
|
|||
/// Defines the <see cref="Point2"/> property.
|
|||
/// </summary>
|
|||
public static readonly StyledProperty<Point> Point2Property |
|||
= PerspexProperty.Register<QuadraticBezierSegment, Point>(nameof(Point2)); |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the point1.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The point1.
|
|||
/// </value>
|
|||
public Point Point1 |
|||
{ |
|||
get { return GetValue(Point1Property); } |
|||
set { SetValue(Point1Property, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the point2.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The point2.
|
|||
/// </value>
|
|||
public Point Point2 |
|||
{ |
|||
get { return GetValue(Point2Property); } |
|||
set { SetValue(Point2Property, value); } |
|||
} |
|||
|
|||
protected internal override void ApplyTo(StreamGeometryContext ctx) |
|||
{ |
|||
ctx.QuadraticBezierTo(Point1, Point2); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
// Copyright (c) The Perspex Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Perspex.Collections; |
|||
using Perspex.Metadata; |
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public class TransformGroup : Transform |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the <see cref="Children"/> property.
|
|||
/// </summary>
|
|||
public static readonly PerspexProperty<Transforms> ChildrenProperty = |
|||
PerspexProperty.Register<TransformGroup, Transforms>(nameof(Children)); |
|||
|
|||
public TransformGroup() |
|||
{ |
|||
Children = new Transforms(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the children.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// The children.
|
|||
/// </value>
|
|||
[Content] |
|||
public Transforms Children |
|||
{ |
|||
get { return GetValue(ChildrenProperty); } |
|||
set { SetValue(ChildrenProperty, value); } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the tranform's <see cref="Matrix" />.
|
|||
/// </summary>
|
|||
public override Matrix Value |
|||
{ |
|||
get |
|||
{ |
|||
Matrix result = Matrix.Identity; |
|||
|
|||
foreach (var t in Children) |
|||
{ |
|||
result *= t.Value; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public sealed class Transforms : PerspexList<Transform> |
|||
{ |
|||
} |
|||
} |
|||
Loading…
Reference in new issue