21 changed files with 364 additions and 4 deletions
@ -0,0 +1,46 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RadioButton.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using Perspex.Controls.Primitives; |
|||
|
|||
public class RadioButton : ToggleButton |
|||
{ |
|||
public RadioButton() |
|||
{ |
|||
this.GetObservable(IsCheckedProperty).Subscribe(this.IsCheckedChanged); |
|||
} |
|||
|
|||
protected override void Toggle() |
|||
{ |
|||
if (!this.IsChecked) |
|||
{ |
|||
this.IsChecked = true; |
|||
} |
|||
} |
|||
|
|||
private void IsCheckedChanged(bool value) |
|||
{ |
|||
var parent = this.GetVisualParent(); |
|||
|
|||
if (value && parent != null) |
|||
{ |
|||
var siblings = parent |
|||
.GetVisualChildren() |
|||
.OfType<RadioButton>() |
|||
.Where(x => x != this); |
|||
|
|||
foreach (var sibling in siblings) |
|||
{ |
|||
sibling.IsChecked = false; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Rectangle.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Controls.Shapes |
|||
{ |
|||
using Perspex.Media; |
|||
|
|||
public class Ellipse : Shape |
|||
{ |
|||
private Geometry geometry; |
|||
|
|||
private Size geometrySize; |
|||
|
|||
public override Geometry DefiningGeometry |
|||
{ |
|||
get |
|||
{ |
|||
if (this.geometry == null || this.geometrySize != this.ActualSize) |
|||
{ |
|||
var rect = new Rect(0, 0, this.ActualSize.Width, this.ActualSize.Height); |
|||
rect = rect.Deflate(this.StrokeThickness / 2); |
|||
this.geometry = new EllipseGeometry(rect); |
|||
this.geometrySize = this.ActualSize; |
|||
} |
|||
|
|||
return this.geometry; |
|||
} |
|||
} |
|||
|
|||
protected override Size MeasureOverride(Size availableSize) |
|||
{ |
|||
return new Size(this.StrokeThickness, this.StrokeThickness); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="EllipseGeometry.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using System; |
|||
using Perspex.Platform; |
|||
using Splat; |
|||
|
|||
public class EllipseGeometry : Geometry |
|||
{ |
|||
public EllipseGeometry(Rect rect) |
|||
{ |
|||
IPlatformRenderInterface factory = Locator.Current.GetService<IPlatformRenderInterface>(); |
|||
IStreamGeometryImpl impl = factory.CreateStreamGeometry(); |
|||
|
|||
using (IStreamGeometryContextImpl ctx = impl.Open()) |
|||
{ |
|||
double ControlPointRatio = (Math.Sqrt(2) - 1) * 4 / 3; |
|||
var center = rect.Center; |
|||
var radius = new Vector(rect.Width / 2, rect.Height / 2); |
|||
|
|||
var x0 = center.X - radius.X; |
|||
var x1 = center.X - radius.X * ControlPointRatio; |
|||
var x2 = center.X; |
|||
var x3 = center.X + radius.X * ControlPointRatio; |
|||
var x4 = center.X + radius.X; |
|||
|
|||
var y0 = center.Y - radius.Y; |
|||
var y1 = center.Y - radius.Y * ControlPointRatio; |
|||
var y2 = center.Y; |
|||
var y3 = center.Y + radius.Y * ControlPointRatio; |
|||
var y4 = center.Y + radius.Y; |
|||
|
|||
ctx.BeginFigure(new Point(x2, y0), true); |
|||
ctx.BezierTo(new Point(x3, y0), new Point(x4, y1), new Point(x4, y2)); |
|||
ctx.BezierTo(new Point(x4, y3), new Point(x3, y4), new Point(x2, y4)); |
|||
ctx.BezierTo(new Point(x1, y4), new Point(x0, y3), new Point(x0, y2)); |
|||
ctx.BezierTo(new Point(x0, y1), new Point(x1, y0), new Point(x2, y0)); |
|||
ctx.EndFigure(true); |
|||
} |
|||
|
|||
this.PlatformImpl = impl; |
|||
} |
|||
|
|||
public override Rect Bounds |
|||
{ |
|||
get { return this.PlatformImpl.Bounds; } |
|||
} |
|||
|
|||
public override Geometry Clone() |
|||
{ |
|||
return new EllipseGeometry(this.Bounds); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="StreamGeometryContextImpl.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public enum SweepDirection |
|||
{ |
|||
CounterClockwise, |
|||
Clockwise, |
|||
} |
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="RadioButtonStyle.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Themes.Default |
|||
{ |
|||
using System; |
|||
using System.Linq; |
|||
using Perspex.Controls; |
|||
using Perspex.Layout; |
|||
using Perspex.Media; |
|||
using Perspex.Controls.Shapes; |
|||
using Perspex.Styling; |
|||
using Perspex.Controls.Presenters; |
|||
|
|||
public class RadioButtonStyle : Styles |
|||
{ |
|||
public RadioButtonStyle() |
|||
{ |
|||
this.AddRange(new[] |
|||
{ |
|||
new Style(x => x.OfType<RadioButton>()) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter(Button.TemplateProperty, ControlTemplate.Create<RadioButton>(this.Template)), |
|||
}, |
|||
}, |
|||
new Style(x => x.OfType<RadioButton>().Template().Id("checkMark")) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter(Shape.IsVisibleProperty, false), |
|||
}, |
|||
}, |
|||
new Style(x => x.OfType<RadioButton>().Class(":checked").Template().Id("checkMark")) |
|||
{ |
|||
Setters = new[] |
|||
{ |
|||
new Setter(Shape.IsVisibleProperty, true), |
|||
}, |
|||
}, |
|||
}); |
|||
} |
|||
|
|||
private Control Template(RadioButton control) |
|||
{ |
|||
Border result = new Border |
|||
{ |
|||
[~Border.BackgroundProperty] = control[~RadioButton.BackgroundProperty], |
|||
Content = new Grid |
|||
{ |
|||
ColumnDefinitions = new ColumnDefinitions |
|||
{ |
|||
new ColumnDefinition(GridLength.Auto), |
|||
new ColumnDefinition(new GridLength(1, GridUnitType.Star)), |
|||
}, |
|||
Children = new Controls |
|||
{ |
|||
new Ellipse |
|||
{ |
|||
Id = "checkBorder", |
|||
Stroke = Brushes.Black, |
|||
StrokeThickness = 2, |
|||
Width = 18, |
|||
Height = 18, |
|||
VerticalAlignment = VerticalAlignment.Center, |
|||
[Grid.ColumnProperty] = 0, |
|||
}, |
|||
new Ellipse |
|||
{ |
|||
Id = "checkMark", |
|||
Fill = Brushes.Black, |
|||
Width = 10, |
|||
Height = 10, |
|||
Stretch = Stretch.Uniform, |
|||
HorizontalAlignment = HorizontalAlignment.Center, |
|||
VerticalAlignment = VerticalAlignment.Center, |
|||
[Grid.ColumnProperty] = 0, |
|||
}, |
|||
new ContentPresenter |
|||
{ |
|||
Margin = new Thickness(4, 0, 0, 0), |
|||
VerticalAlignment = VerticalAlignment.Center, |
|||
[~ContentPresenter.ContentProperty] = control[~RadioButton.ContentProperty], |
|||
[Grid.ColumnProperty] = 1, |
|||
}, |
|||
}, |
|||
}, |
|||
}; |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,41 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="EllipseTests.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Direct2D1.RenderTests.Shapes |
|||
{ |
|||
using Microsoft.VisualStudio.TestTools.UnitTesting; |
|||
using Perspex.Controls; |
|||
using Perspex.Media; |
|||
using Perspex.Controls.Shapes; |
|||
|
|||
[TestClass] |
|||
public class EllipseTests : TestBase |
|||
{ |
|||
public EllipseTests() |
|||
: base(@"Shapes\Ellipse") |
|||
{ |
|||
} |
|||
|
|||
[TestMethod] |
|||
public void Circle_1px_Stroke() |
|||
{ |
|||
Decorator target = new Decorator |
|||
{ |
|||
Padding = new Thickness(8), |
|||
Width = 200, |
|||
Height = 200, |
|||
Content = new Ellipse |
|||
{ |
|||
Stroke = Brushes.Black, |
|||
StrokeThickness = 1, |
|||
} |
|||
}; |
|||
|
|||
this.RenderToFile(target); |
|||
this.CompareImages(); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue