From 8924977a4939e1815850f29be635766ccfada27a Mon Sep 17 00:00:00 2001 From: grokys Date: Fri, 13 Dec 2013 19:53:59 +0100 Subject: [PATCH] Started implementing Button. --- Perspex.Windows/DrawingContext.cs | 36 ++++++++ Perspex.Windows/Renderer.cs | 8 +- Perspex/Controls/Border.cs | 25 ++++++ Perspex/Controls/Button.cs | 23 ++++++ Perspex/Controls/TextBlock.cs | 2 +- Perspex/Media/IDrawingContext.cs | 8 ++ Perspex/Media/Matrix.cs | 131 ++++++++++++++++++++++++++++++ Perspex/Perspex.csproj | 2 + TestApplication/Program.cs | 8 +- 9 files changed, 237 insertions(+), 6 deletions(-) create mode 100644 Perspex/Controls/Button.cs create mode 100644 Perspex/Media/Matrix.cs diff --git a/Perspex.Windows/DrawingContext.cs b/Perspex.Windows/DrawingContext.cs index 8871a965e9..dec5dac5fe 100644 --- a/Perspex.Windows/DrawingContext.cs +++ b/Perspex.Windows/DrawingContext.cs @@ -7,10 +7,12 @@ namespace Perspex.Windows { using System; + using System.Reactive.Disposables; using Perspex.Media; using Perspex.Windows.Media; using SharpDX; using SharpDX.Direct2D1; + using Matrix = Perspex.Media.Matrix; /// /// Draws using Direct2D1. @@ -102,6 +104,24 @@ namespace Perspex.Windows } } + /// + /// Pushes a matrix transformation. + /// + /// The matrix + /// A disposable used to undo the transformation. + public IDisposable PushTransform(Matrix matrix) + { + Matrix3x2 m3x2 = this.Convert(matrix); + Matrix3x2 transform = this.renderTarget.Transform * m3x2; + this.renderTarget.Transform = transform; + + return Disposable.Create(() => + { + m3x2.Invert(); + this.renderTarget.Transform = transform * m3x2; + }); + } + /// /// Converts a brush to Direct2D. /// @@ -139,6 +159,22 @@ namespace Perspex.Windows (float)(color.A / 255.0)); } + /// + /// Converts a to a Direct2D + /// + /// The . + /// The . + private Matrix3x2 Convert(Matrix matrix) + { + return new Matrix3x2( + (float)matrix.M11, + (float)matrix.M12, + (float)matrix.M21, + (float)matrix.M22, + (float)matrix.OffsetX, + (float)matrix.OffsetY); + } + /// /// Converts a to a /// diff --git a/Perspex.Windows/Renderer.cs b/Perspex.Windows/Renderer.cs index 94575517c8..00a669f73a 100644 --- a/Perspex.Windows/Renderer.cs +++ b/Perspex.Windows/Renderer.cs @@ -10,6 +10,7 @@ namespace Perspex.Windows using SharpDX; using SharpDX.Direct2D1; using DwFactory = SharpDX.DirectWrite.Factory; + using Matrix = Perspex.Media.Matrix; /// /// Renders a . @@ -99,7 +100,12 @@ namespace Perspex.Windows foreach (Visual child in visual.VisualChildren) { - this.Render(child, context); + Matrix translate = Matrix.Translation(child.Bounds.X, child.Bounds.Y); + + using (context.PushTransform(translate)) + { + this.Render(child, context); + } } } } diff --git a/Perspex/Controls/Border.cs b/Perspex/Controls/Border.cs index b16b7781a7..78a3ba8fe7 100644 --- a/Perspex/Controls/Border.cs +++ b/Perspex/Controls/Border.cs @@ -8,20 +8,45 @@ public static readonly PerspexProperty BackgroundProperty = PerspexProperty.Register("Background"); + public static readonly PerspexProperty BorderBrushProperty = + PerspexProperty.Register("BorderBrush"); + + public static readonly PerspexProperty BorderThicknessProperty = + PerspexProperty.Register("BorderThickness"); + public Brush Background { get { return this.GetValue(BackgroundProperty); } set { this.SetValue(BackgroundProperty, value); } } + public Brush BorderBrush + { + get { return this.GetValue(BorderBrushProperty); } + set { this.SetValue(BorderBrushProperty, value); } + } + + public double BorderThickness + { + get { return this.GetValue(BorderThicknessProperty); } + set { this.SetValue(BorderThicknessProperty, value); } + } + public override void Render(IDrawingContext context) { Brush background = this.Background; + Brush borderBrush = this.BorderBrush; + double borderThickness = this.BorderThickness; if (background != null) { context.FillRectange(background, new Rect(this.Bounds.Size)); } + + if (borderBrush != null && borderThickness > 0) + { + context.DrawRectange(new Pen(borderBrush, borderThickness), new Rect(this.Bounds.Size)); + } } } } diff --git a/Perspex/Controls/Button.cs b/Perspex/Controls/Button.cs new file mode 100644 index 0000000000..95cd6cb3d7 --- /dev/null +++ b/Perspex/Controls/Button.cs @@ -0,0 +1,23 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2013 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Controls +{ + public class Button : ContentControl + { + protected override Visual DefaultTemplate() + { + Border border = new Border(); + border.Background = new Perspex.Media.SolidColorBrush(0xff808080); + border.BorderBrush = new Perspex.Media.SolidColorBrush(0xff000000); + border.BorderThickness = 2; + ContentPresenter contentPresenter = new ContentPresenter(); + contentPresenter.Bind(ContentPresenter.ContentProperty, this.GetObservable(ContentProperty)); + border.Content = contentPresenter; + return border; + } + } +} diff --git a/Perspex/Controls/TextBlock.cs b/Perspex/Controls/TextBlock.cs index 9850710b0d..a010b6c7d7 100644 --- a/Perspex/Controls/TextBlock.cs +++ b/Perspex/Controls/TextBlock.cs @@ -67,7 +67,7 @@ context.FillRectange(background, this.Bounds); } - context.DrawText(this.Foreground, this.Bounds, this.FormattedText); + context.DrawText(this.Foreground, new Rect(this.Bounds.Size), this.FormattedText); } protected override Size MeasureContent(Size availableSize) diff --git a/Perspex/Media/IDrawingContext.cs b/Perspex/Media/IDrawingContext.cs index b8ba686250..d73bf83607 100644 --- a/Perspex/Media/IDrawingContext.cs +++ b/Perspex/Media/IDrawingContext.cs @@ -4,6 +4,7 @@ // // ----------------------------------------------------------------------- +using System; namespace Perspex.Media { /// @@ -32,5 +33,12 @@ namespace Perspex.Media /// The brush. /// The rectangle bounds. void FillRectange(Brush brush, Rect rect); + + /// + /// Pushes a matrix transformation. + /// + /// The matrix + /// A disposable used to undo the transformation. + IDisposable PushTransform(Matrix matrix); } } diff --git a/Perspex/Media/Matrix.cs b/Perspex/Media/Matrix.cs new file mode 100644 index 0000000000..47fbcf72c8 --- /dev/null +++ b/Perspex/Media/Matrix.cs @@ -0,0 +1,131 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2013 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Media +{ + using System; + + public struct Matrix + { + private double m11; + private double m12; + private double m21; + private double m22; + private double offsetX; + private double offsetY; + + public Matrix( + double m11, + double m12, + double m21, + double m22, + double offsetX, + double offsetY) + { + this.m11 = m11; + this.m12 = m12; + this.m21 = m21; + this.m22 = m22; + this.offsetX = offsetX; + this.offsetY = offsetY; + } + + public static Matrix Identity + { + get { return new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); } + } + + public double Determinant + { + get { return (this.m11 * this.m22) - (this.m12 * this.m21); } + } + + public bool HasInverse + { + get { return this.Determinant != 0; } + } + + public bool IsIdentity + { + get { return this.Equals(Matrix.Identity); } + } + + public double M11 + { + get { return this.m11; } + } + + public double M12 + { + get { return this.m12; } + } + + public double M21 + { + get { return this.m21; } + } + + public double M22 + { + get { return this.m22; } + } + + public double OffsetX + { + get { return this.offsetX; } + } + + public double OffsetY + { + get { return this.offsetY; } + } + + public static bool Equals(Matrix matrix1, Matrix matrix2) + { + return matrix1.Equals(matrix2); + } + + public static Matrix Translation(double x, double y) + { + return new Matrix(1.0, 0.0, 0.0, 1.0, x, y); + } + + public static bool operator ==(Matrix matrix1, Matrix matrix2) + { + return matrix1.Equals(matrix2); + } + + public static bool operator !=(Matrix matrix1, Matrix matrix2) + { + return !matrix1.Equals(matrix2); + } + + public bool Equals(Matrix value) + { + return this.m11 == value.M11 && + this.m12 == value.M12 && + this.m21 == value.M21 && + this.m22 == value.M22 && + this.offsetX == value.OffsetX && + this.offsetY == value.OffsetY; + } + + public override bool Equals(object o) + { + if (!(o is Matrix)) + { + return false; + } + + return this.Equals((Matrix)o); + } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Perspex/Perspex.csproj b/Perspex/Perspex.csproj index 613d2206c8..957a8d9eb7 100644 --- a/Perspex/Perspex.csproj +++ b/Perspex/Perspex.csproj @@ -69,6 +69,7 @@ + @@ -83,6 +84,7 @@ + diff --git a/TestApplication/Program.cs b/TestApplication/Program.cs index e079f21198..eec8d192f8 100644 --- a/TestApplication/Program.cs +++ b/TestApplication/Program.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; using Perspex; @@ -20,14 +21,13 @@ namespace TestApplication Window window = new Window(); - window.Content = new TextBlock + window.Content = new Button { - Text = "Hello World", - Background = new SolidColorBrush(0xffffffff), + Content = "Hello World", HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, }; - + window.Show(); Dispatcher.Run(); }