Browse Source

Make SolidColorBrush properly immutable.

Previous its color was immutable but because it inherited from Brush, its Opacity was mutable. This wasn't good, as it meant that e.g. Brushes.Red could be changed. Make it properly immutable by using the IBrush interface everywhere and not inheriting from Brush.
pull/496/head
Steven Kirk 11 years ago
parent
commit
a40f0be1d9
  1. 4
      samples/TestApplicationShared/GalleryStyle.cs
  2. 70
      samples/TestApplicationShared/MainWindow.cs
  3. 8
      src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
  4. 2
      src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs
  5. 4
      src/Markup/Perspex.Markup.Xaml/Context/PerspexTypeFeatureProvider.cs
  6. 33
      src/Markup/Perspex.Markup.Xaml/Converters/SolidColorBrushTypeConverter.cs
  7. 4
      src/Markup/Perspex.Markup.Xaml/Data/StyleResourceBinding.cs
  8. 1
      src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj
  9. 12
      src/Perspex.Controls/Border.cs
  10. 6
      src/Perspex.Controls/Panel.cs
  11. 8
      src/Perspex.Controls/Presenters/ContentPresenter.cs
  12. 4
      src/Perspex.Controls/Presenters/TextPresenter.cs
  13. 12
      src/Perspex.Controls/Primitives/TemplatedControl.cs
  14. 12
      src/Perspex.Controls/Shapes/Shape.cs
  15. 16
      src/Perspex.Controls/TextBlock.cs
  16. 6
      src/Perspex.HtmlRenderer/Adapters/BrushAdapter.cs
  17. 4
      src/Perspex.HtmlRenderer/Adapters/PenAdapter.cs
  18. 4
      src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs
  19. 12
      src/Perspex.HtmlRenderer/HtmlControl.cs
  20. 6
      src/Perspex.SceneGraph/Media/Brush.cs
  21. 6
      src/Perspex.SceneGraph/Media/DrawingContext.cs
  22. 2
      src/Perspex.SceneGraph/Media/FormattedText.cs
  23. 16
      src/Perspex.SceneGraph/Media/IBrush.cs
  24. 6
      src/Perspex.SceneGraph/Media/IDrawingContext.cs
  25. 16
      src/Perspex.SceneGraph/Media/ISolidColorBrush.cs
  26. 2
      src/Perspex.SceneGraph/Media/Mutable/SolidColorBrush.cs
  27. 4
      src/Perspex.SceneGraph/Media/Pen.cs
  28. 16
      src/Perspex.SceneGraph/Media/SolidColorBrush.cs
  29. 2
      src/Perspex.SceneGraph/Perspex.SceneGraph.csproj
  30. 2
      src/Perspex.SceneGraph/Platform/IFormattedTextImpl.cs
  31. 8
      src/Skia/Perspex.Skia/DrawingContextImpl.cs
  32. 2
      src/Skia/Perspex.Skia/FormattedTextImpl.cs
  33. 4
      src/Windows/Perspex.Direct2D1/Media/BrushWrapper.cs
  34. 15
      src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs
  35. 2
      src/Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs
  36. 17
      src/Windows/Perspex.Direct2D1/Media/SolidColorBrushImpl.cs

4
samples/TestApplicationShared/GalleryStyle.cs

@ -49,7 +49,7 @@ namespace TestApplication
Setters = new[] Setters = new[]
{ {
new Setter(TemplatedControl.ForegroundProperty, Brushes.White), new Setter(TemplatedControl.ForegroundProperty, Brushes.White),
new Setter(TemplatedControl.BackgroundProperty, new SolidColorBrush(Colors.White) { Opacity = 0.1 }), new Setter(TemplatedControl.BackgroundProperty, new SolidColorBrush(Colors.White, 0.1)),
}, },
}, },
}); });
@ -91,7 +91,7 @@ namespace TestApplication
new Border new Border
{ {
Width = 190, Width = 190,
Background = SolidColorBrush.Parse("#1976D2"), Background = Brush.Parse("#1976D2"),
Child = new ScrollViewer Child = new ScrollViewer
{ {
Content = new TabStrip Content = new TabStrip

70
samples/TestApplicationShared/MainWindow.cs

@ -131,13 +131,13 @@ namespace TestApplication
Text = "Button", Text = "Button",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A button control", Text = "A button control",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new Button new Button
@ -157,13 +157,13 @@ namespace TestApplication
Text = "ToggleButton", Text = "ToggleButton",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A toggle button control", Text = "A toggle button control",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new ToggleButton new ToggleButton
@ -207,13 +207,13 @@ namespace TestApplication
Text = "TextBlock", Text = "TextBlock",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A control for displaying text.", Text = "A control for displaying text.",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new TextBlock new TextBlock
@ -245,18 +245,18 @@ namespace TestApplication
Text = "HtmlLabel", Text = "HtmlLabel",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A label capable of displaying HTML content", Text = "A label capable of displaying HTML content",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new HtmlLabel new HtmlLabel
{ {
Background = SolidColorBrush.Parse("#CCCCCC"), Background = Brush.Parse("#CCCCCC"),
Padding = new Thickness(5), Padding = new Thickness(5),
Text = @"<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href=""#"">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p> Text = @"<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href=""#"">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
<h2>Header Level 2</h2> <h2>Header Level 2</h2>
@ -300,13 +300,13 @@ namespace TestApplication
Text = "TextBox", Text = "TextBox",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A text box control", Text = "A text box control",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
@ -320,13 +320,13 @@ namespace TestApplication
Text = "CheckBox", Text = "CheckBox",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A check box control", Text = "A check box control",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new CheckBox { IsChecked = true, Margin = new Thickness(0, 0, 0, 5), Content = "Checked" }, new CheckBox { IsChecked = true, Margin = new Thickness(0, 0, 0, 5), Content = "Checked" },
@ -337,13 +337,13 @@ namespace TestApplication
Text = "RadioButton", Text = "RadioButton",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A radio button control", Text = "A radio button control",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new RadioButton { IsChecked = true, Content = "Option 1" }, new RadioButton { IsChecked = true, Content = "Option 1" },
@ -398,13 +398,13 @@ namespace TestApplication
Text = "ListBox", Text = "ListBox",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A list box control.", Text = "A list box control.",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new ListBox new ListBox
@ -420,13 +420,13 @@ namespace TestApplication
Text = "TreeView", Text = "TreeView",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A tree view control.", Text = "A tree view control.",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new TreeView new TreeView
@ -514,13 +514,13 @@ namespace TestApplication
Text = "Carousel", Text = "Carousel",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "An items control that displays its items as pages that fill the controls.", Text = "An items control that displays its items as pages that fill the controls.",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new StackPanel new StackPanel
@ -573,13 +573,13 @@ namespace TestApplication
Text = "Grid", Text = "Grid",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "Lays out child controls according to a grid.", Text = "Lays out child controls according to a grid.",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new Grid new Grid
@ -601,21 +601,21 @@ namespace TestApplication
new Rectangle new Rectangle
{ {
Fill = SolidColorBrush.Parse("#FF5722"), Fill = Brush.Parse("#FF5722"),
[Grid.ColumnSpanProperty] = 2, [Grid.ColumnSpanProperty] = 2,
Height = 200, Height = 200,
Margin = new Thickness(2.5) Margin = new Thickness(2.5)
}, },
new Rectangle new Rectangle
{ {
Fill = SolidColorBrush.Parse("#FF5722"), Fill = Brush.Parse("#FF5722"),
[Grid.RowProperty] = 1, [Grid.RowProperty] = 1,
Height = 100, Height = 100,
Margin = new Thickness(2.5) Margin = new Thickness(2.5)
}, },
new Rectangle new Rectangle
{ {
Fill = SolidColorBrush.Parse("#FF5722"), Fill = Brush.Parse("#FF5722"),
[Grid.RowProperty] = 1, [Grid.RowProperty] = 1,
[Grid.ColumnProperty] = 1, [Grid.ColumnProperty] = 1,
Height = 100, Height = 100,
@ -629,13 +629,13 @@ namespace TestApplication
Text = "StackPanel", Text = "StackPanel",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A panel which lays out its children horizontally or vertically.", Text = "A panel which lays out its children horizontally or vertically.",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new StackPanel new StackPanel
@ -647,17 +647,17 @@ namespace TestApplication
{ {
new Rectangle new Rectangle
{ {
Fill = SolidColorBrush.Parse("#FFC107"), Fill = Brush.Parse("#FFC107"),
Height = 50, Height = 50,
}, },
new Rectangle new Rectangle
{ {
Fill = SolidColorBrush.Parse("#FFC107"), Fill = Brush.Parse("#FFC107"),
Height = 50, Height = 50,
}, },
new Rectangle new Rectangle
{ {
Fill = SolidColorBrush.Parse("#FFC107"), Fill = Brush.Parse("#FFC107"),
Height = 50, Height = 50,
}, },
} }
@ -668,13 +668,13 @@ namespace TestApplication
Text = "Canvas", Text = "Canvas",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A panel which lays out its children by explicit coordinates.", Text = "A panel which lays out its children by explicit coordinates.",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
new Canvas new Canvas
@ -762,13 +762,13 @@ namespace TestApplication
Text = "Animations", Text = "Animations",
FontWeight = FontWeight.Medium, FontWeight = FontWeight.Medium,
FontSize = 20, FontSize = 20,
Foreground = SolidColorBrush.Parse("#212121"), Foreground = Brush.Parse("#212121"),
}, },
new TextBlock new TextBlock
{ {
Text = "A few animations showcased below", Text = "A few animations showcased below",
FontSize = 13, FontSize = 13,
Foreground = SolidColorBrush.Parse("#727272"), Foreground = Brush.Parse("#727272"),
Margin = new Thickness(0, 0, 0, 10) Margin = new Thickness(0, 0, 0, 10)
}, },
(button1 = new Button (button1 = new Button

8
src/Gtk/Perspex.Cairo/Media/DrawingContext.cs

@ -135,7 +135,7 @@ namespace Perspex.Cairo.Media
/// <param name="brush">The fill brush.</param> /// <param name="brush">The fill brush.</param>
/// <param name="pen">The stroke pen.</param> /// <param name="pen">The stroke pen.</param>
/// <param name="geometry">The geometry.</param> /// <param name="geometry">The geometry.</param>
public void DrawGeometry(Brush brush, Pen pen, Geometry geometry) public void DrawGeometry(IBrush brush, Pen pen, Geometry geometry)
{ {
var impl = geometry.PlatformImpl as StreamGeometryImpl; var impl = geometry.PlatformImpl as StreamGeometryImpl;
@ -190,7 +190,7 @@ namespace Perspex.Cairo.Media
/// <param name="foreground">The foreground brush.</param> /// <param name="foreground">The foreground brush.</param>
/// <param name="origin">The upper-left corner of the text.</param> /// <param name="origin">The upper-left corner of the text.</param>
/// <param name="text">The text.</param> /// <param name="text">The text.</param>
public void DrawText(Brush foreground, Point origin, FormattedText text) public void DrawText(IBrush foreground, Point origin, FormattedText text)
{ {
var layout = ((FormattedTextImpl)text.PlatformImpl).Layout; var layout = ((FormattedTextImpl)text.PlatformImpl).Layout;
_context.MoveTo(origin.X, origin.Y); _context.MoveTo(origin.X, origin.Y);
@ -206,7 +206,7 @@ namespace Perspex.Cairo.Media
/// </summary> /// </summary>
/// <param name="brush">The brush.</param> /// <param name="brush">The brush.</param>
/// <param name="rect">The rectangle bounds.</param> /// <param name="rect">The rectangle bounds.</param>
public void FillRectangle(Brush brush, Rect rect, float cornerRadius) public void FillRectangle(IBrush brush, Rect rect, float cornerRadius)
{ {
using (var b = SetBrush(brush, rect.Size)) using (var b = SetBrush(brush, rect.Size))
{ {
@ -271,7 +271,7 @@ namespace Perspex.Cairo.Media
private double opacityOverride = 1.0f; private double opacityOverride = 1.0f;
private IDisposable SetBrush(Brush brush, Size destinationSize) private IDisposable SetBrush(IBrush brush, Size destinationSize)
{ {
_context.Save (); _context.Save ();

2
src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs

@ -133,7 +133,7 @@ namespace Perspex.Cairo.Media
return new Size(width, height); return new Size(width, height);
} }
public void SetForegroundBrush(Brush brush, int startIndex, int count) public void SetForegroundBrush(IBrush brush, int startIndex, int count)
{ {
var scb = brush as SolidColorBrush; var scb = brush as SolidColorBrush;
if (scb != null) if (scb != null)

4
src/Markup/Perspex.Markup.Xaml/Context/PerspexTypeFeatureProvider.cs

@ -150,7 +150,7 @@ namespace Perspex.Markup.Xaml.Context
RegisterTypeConverter(typeof(Type), new TypeTypeConverter()); RegisterTypeConverter(typeof(Type), new TypeTypeConverter());
RegisterTypeConverter(typeof(IBitmap), new BitmapTypeConverter()); RegisterTypeConverter(typeof(IBitmap), new BitmapTypeConverter());
RegisterTypeConverter(typeof(Brush), new BrushTypeConverter()); RegisterTypeConverter(typeof(IBrush), new BrushTypeConverter());
RegisterTypeConverter(typeof(Color), new ColorTypeConverter()); RegisterTypeConverter(typeof(Color), new ColorTypeConverter());
RegisterTypeConverter(typeof(Classes), new ClassesTypeConverter()); RegisterTypeConverter(typeof(Classes), new ClassesTypeConverter());
RegisterTypeConverter(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter()); RegisterTypeConverter(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter());
@ -166,7 +166,7 @@ namespace Perspex.Markup.Xaml.Context
RegisterTypeConverter(typeof(RelativeRect), new RelativeRectTypeConverter()); RegisterTypeConverter(typeof(RelativeRect), new RelativeRectTypeConverter());
RegisterTypeConverter(typeof(RowDefinitions), new RowDefinitionsTypeConverter()); RegisterTypeConverter(typeof(RowDefinitions), new RowDefinitionsTypeConverter());
RegisterTypeConverter(typeof(Selector), new SelectorTypeConverter()); RegisterTypeConverter(typeof(Selector), new SelectorTypeConverter());
RegisterTypeConverter(typeof(SolidColorBrush), new SolidColorBrushTypeConverter()); RegisterTypeConverter(typeof(SolidColorBrush), new BrushTypeConverter());
RegisterTypeConverter(typeof(Thickness), new ThicknessTypeConverter()); RegisterTypeConverter(typeof(Thickness), new ThicknessTypeConverter());
RegisterTypeConverter(typeof(TimeSpan), new TimeSpanTypeConverter()); RegisterTypeConverter(typeof(TimeSpan), new TimeSpanTypeConverter());
RegisterTypeConverter(typeof(Uri), new UriTypeConverter()); RegisterTypeConverter(typeof(Uri), new UriTypeConverter());

33
src/Markup/Perspex.Markup.Xaml/Converters/SolidColorBrushTypeConverter.cs

@ -1,33 +0,0 @@
// 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 System;
using System.Globalization;
using OmniXaml.TypeConversion;
using Perspex.Media;
namespace Perspex.Markup.Xaml.Converters
{
public class SolidColorBrushTypeConverter : ITypeConverter
{
public bool CanConvertFrom(IValueContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public bool CanConvertTo(IValueContext context, Type destinationType)
{
return false;
}
public object ConvertFrom(IValueContext context, CultureInfo culture, object value)
{
return Brush.Parse((string)value);
}
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType)
{
throw new NotImplementedException();
}
}
}

4
src/Markup/Perspex.Markup.Xaml/Data/StyleResourceBinding.cs

@ -39,6 +39,10 @@ namespace Perspex.Markup.Xaml.Data
PerspexProperty targetProperty, PerspexProperty targetProperty,
object anchor = null) object anchor = null)
{ {
if (Name == "Red")
{
}
var host = (target as IControl) ?? (anchor as IControl); var host = (target as IControl) ?? (anchor as IControl);
var style = anchor as IStyle; var style = anchor as IStyle;
var resource = PerspexProperty.UnsetValue; var resource = PerspexProperty.UnsetValue;

1
src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj

@ -56,7 +56,6 @@
<Compile Include="Converters\BitmapTypeConverter.cs" /> <Compile Include="Converters\BitmapTypeConverter.cs" />
<Compile Include="Converters\BrushTypeConverter.cs" /> <Compile Include="Converters\BrushTypeConverter.cs" />
<Compile Include="Converters\ClassesTypeConverter.cs" /> <Compile Include="Converters\ClassesTypeConverter.cs" />
<Compile Include="Converters\SolidColorBrushTypeConverter.cs" />
<Compile Include="Converters\ColorTypeConverter.cs" /> <Compile Include="Converters\ColorTypeConverter.cs" />
<Compile Include="Converters\ColumnDefinitionsTypeConverter.cs" /> <Compile Include="Converters\ColumnDefinitionsTypeConverter.cs" />
<Compile Include="Converters\CursorTypeConverter.cs" /> <Compile Include="Converters\CursorTypeConverter.cs" />

12
src/Perspex.Controls/Border.cs

@ -13,14 +13,14 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Background"/> property. /// Defines the <see cref="Background"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> BackgroundProperty = public static readonly StyledProperty<IBrush> BackgroundProperty =
PerspexProperty.Register<Border, Brush>(nameof(Background)); PerspexProperty.Register<Border, IBrush>(nameof(Background));
/// <summary> /// <summary>
/// Defines the <see cref="BorderBrush"/> property. /// Defines the <see cref="BorderBrush"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> BorderBrushProperty = public static readonly StyledProperty<IBrush> BorderBrushProperty =
PerspexProperty.Register<Border, Brush>(nameof(BorderBrush)); PerspexProperty.Register<Border, IBrush>(nameof(BorderBrush));
/// <summary> /// <summary>
/// Defines the <see cref="BorderThickness"/> property. /// Defines the <see cref="BorderThickness"/> property.
@ -45,7 +45,7 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Gets or sets a brush with which to paint the background. /// Gets or sets a brush with which to paint the background.
/// </summary> /// </summary>
public Brush Background public IBrush Background
{ {
get { return GetValue(BackgroundProperty); } get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); } set { SetValue(BackgroundProperty, value); }
@ -54,7 +54,7 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Gets or sets a brush with which to paint the border. /// Gets or sets a brush with which to paint the border.
/// </summary> /// </summary>
public Brush BorderBrush public IBrush BorderBrush
{ {
get { return GetValue(BorderBrushProperty); } get { return GetValue(BorderBrushProperty); }
set { SetValue(BorderBrushProperty, value); } set { SetValue(BorderBrushProperty, value); }

6
src/Perspex.Controls/Panel.cs

@ -22,7 +22,7 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Background"/> property. /// Defines the <see cref="Background"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> BackgroundProperty = public static readonly StyledProperty<IBrush> BackgroundProperty =
Border.BackgroundProperty.AddOwner<Panel>(); Border.BackgroundProperty.AddOwner<Panel>();
private readonly Controls _children = new Controls(); private readonly Controls _children = new Controls();
@ -73,7 +73,7 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Gets or Sets Panel background brush. /// Gets or Sets Panel background brush.
/// </summary> /// </summary>
public Brush Background public IBrush Background
{ {
get { return GetValue(BackgroundProperty); } get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); } set { SetValue(BackgroundProperty, value); }
@ -129,7 +129,7 @@ namespace Perspex.Controls
/// <param name="context">The drawing context.</param> /// <param name="context">The drawing context.</param>
public override void Render(DrawingContext context) public override void Render(DrawingContext context)
{ {
Brush background = Background; var background = Background;
if (background != null) if (background != null)
{ {
var renderSize = Bounds.Size; var renderSize = Bounds.Size;

8
src/Perspex.Controls/Presenters/ContentPresenter.cs

@ -18,13 +18,13 @@ namespace Perspex.Controls.Presenters
/// <summary> /// <summary>
/// Defines the <see cref="Background"/> property. /// Defines the <see cref="Background"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> BackgroundProperty = public static readonly StyledProperty<IBrush> BackgroundProperty =
Border.BackgroundProperty.AddOwner<ContentPresenter>(); Border.BackgroundProperty.AddOwner<ContentPresenter>();
/// <summary> /// <summary>
/// Defines the <see cref="BorderBrush"/> property. /// Defines the <see cref="BorderBrush"/> property.
/// </summary> /// </summary>
public static readonly PerspexProperty<Brush> BorderBrushProperty = public static readonly PerspexProperty<IBrush> BorderBrushProperty =
Border.BorderBrushProperty.AddOwner<ContentPresenter>(); Border.BorderBrushProperty.AddOwner<ContentPresenter>();
/// <summary> /// <summary>
@ -86,7 +86,7 @@ namespace Perspex.Controls.Presenters
/// <summary> /// <summary>
/// Gets or sets a brush with which to paint the background. /// Gets or sets a brush with which to paint the background.
/// </summary> /// </summary>
public Brush Background public IBrush Background
{ {
get { return GetValue(BackgroundProperty); } get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); } set { SetValue(BackgroundProperty, value); }
@ -95,7 +95,7 @@ namespace Perspex.Controls.Presenters
/// <summary> /// <summary>
/// Gets or sets a brush with which to paint the border. /// Gets or sets a brush with which to paint the border.
/// </summary> /// </summary>
public Brush BorderBrush public IBrush BorderBrush
{ {
get { return GetValue(BorderBrushProperty); } get { return GetValue(BorderBrushProperty); }
set { SetValue(BorderBrushProperty, value); } set { SetValue(BorderBrushProperty, value); }

4
src/Perspex.Controls/Presenters/TextPresenter.cs

@ -23,7 +23,7 @@ namespace Perspex.Controls.Presenters
private readonly DispatcherTimer _caretTimer; private readonly DispatcherTimer _caretTimer;
private bool _caretBlink; private bool _caretBlink;
private Brush _highlightBrush; private IBrush _highlightBrush;
static TextPresenter() static TextPresenter()
{ {
@ -82,7 +82,7 @@ namespace Perspex.Controls.Presenters
if (_highlightBrush == null) if (_highlightBrush == null)
{ {
_highlightBrush = (Brush)this.FindStyleResource("HighlightBrush"); _highlightBrush = (IBrush)this.FindStyleResource("HighlightBrush");
} }
foreach (var rect in rects) foreach (var rect in rects)

12
src/Perspex.Controls/Primitives/TemplatedControl.cs

@ -23,13 +23,13 @@ namespace Perspex.Controls.Primitives
/// <summary> /// <summary>
/// Defines the <see cref="Background"/> property. /// Defines the <see cref="Background"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> BackgroundProperty = public static readonly StyledProperty<IBrush> BackgroundProperty =
Border.BackgroundProperty.AddOwner<TemplatedControl>(); Border.BackgroundProperty.AddOwner<TemplatedControl>();
/// <summary> /// <summary>
/// Defines the <see cref="BorderBrush"/> property. /// Defines the <see cref="BorderBrush"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> BorderBrushProperty = public static readonly StyledProperty<IBrush> BorderBrushProperty =
Border.BorderBrushProperty.AddOwner<TemplatedControl>(); Border.BorderBrushProperty.AddOwner<TemplatedControl>();
/// <summary> /// <summary>
@ -65,7 +65,7 @@ namespace Perspex.Controls.Primitives
/// <summary> /// <summary>
/// Defines the <see cref="Foreground"/> property. /// Defines the <see cref="Foreground"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> ForegroundProperty = public static readonly StyledProperty<IBrush> ForegroundProperty =
TextBlock.ForegroundProperty.AddOwner<TemplatedControl>(); TextBlock.ForegroundProperty.AddOwner<TemplatedControl>();
/// <summary> /// <summary>
@ -117,7 +117,7 @@ namespace Perspex.Controls.Primitives
/// <summary> /// <summary>
/// Gets or sets the brush used to draw the control's background. /// Gets or sets the brush used to draw the control's background.
/// </summary> /// </summary>
public Brush Background public IBrush Background
{ {
get { return GetValue(BackgroundProperty); } get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); } set { SetValue(BackgroundProperty, value); }
@ -126,7 +126,7 @@ namespace Perspex.Controls.Primitives
/// <summary> /// <summary>
/// Gets or sets the brush used to draw the control's border. /// Gets or sets the brush used to draw the control's border.
/// </summary> /// </summary>
public Brush BorderBrush public IBrush BorderBrush
{ {
get { return GetValue(BorderBrushProperty); } get { return GetValue(BorderBrushProperty); }
set { SetValue(BorderBrushProperty, value); } set { SetValue(BorderBrushProperty, value); }
@ -180,7 +180,7 @@ namespace Perspex.Controls.Primitives
/// <summary> /// <summary>
/// Gets or sets the brush used to draw the control's text and other foreground elements. /// Gets or sets the brush used to draw the control's text and other foreground elements.
/// </summary> /// </summary>
public Brush Foreground public IBrush Foreground
{ {
get { return GetValue(ForegroundProperty); } get { return GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); } set { SetValue(ForegroundProperty, value); }

12
src/Perspex.Controls/Shapes/Shape.cs

@ -10,14 +10,14 @@ namespace Perspex.Controls.Shapes
{ {
public abstract class Shape : Control public abstract class Shape : Control
{ {
public static readonly StyledProperty<Brush> FillProperty = public static readonly StyledProperty<IBrush> FillProperty =
PerspexProperty.Register<Shape, Brush>("Fill"); PerspexProperty.Register<Shape, IBrush>("Fill");
public static readonly StyledProperty<Stretch> StretchProperty = public static readonly StyledProperty<Stretch> StretchProperty =
PerspexProperty.Register<Shape, Stretch>("Stretch"); PerspexProperty.Register<Shape, Stretch>("Stretch");
public static readonly StyledProperty<Brush> StrokeProperty = public static readonly StyledProperty<IBrush> StrokeProperty =
PerspexProperty.Register<Shape, Brush>("Stroke"); PerspexProperty.Register<Shape, IBrush>("Stroke");
public static readonly StyledProperty<PerspexList<double>> StrokeDashArrayProperty = public static readonly StyledProperty<PerspexList<double>> StrokeDashArrayProperty =
PerspexProperty.Register<Shape, PerspexList<double>>("StrokeDashArray"); PerspexProperty.Register<Shape, PerspexList<double>>("StrokeDashArray");
@ -48,7 +48,7 @@ namespace Perspex.Controls.Shapes
} }
} }
public Brush Fill public IBrush Fill
{ {
get { return GetValue(FillProperty); } get { return GetValue(FillProperty); }
set { SetValue(FillProperty, value); } set { SetValue(FillProperty, value); }
@ -77,7 +77,7 @@ namespace Perspex.Controls.Shapes
set { SetValue(StretchProperty, value); } set { SetValue(StretchProperty, value); }
} }
public Brush Stroke public IBrush Stroke
{ {
get { return GetValue(StrokeProperty); } get { return GetValue(StrokeProperty); }
set { SetValue(StrokeProperty, value); } set { SetValue(StrokeProperty, value); }

16
src/Perspex.Controls/TextBlock.cs

@ -19,7 +19,7 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Background"/> property. /// Defines the <see cref="Background"/> property.
/// </summary> /// </summary>
public static readonly StyledProperty<Brush> BackgroundProperty = public static readonly StyledProperty<IBrush> BackgroundProperty =
Border.BackgroundProperty.AddOwner<TextBlock>(); Border.BackgroundProperty.AddOwner<TextBlock>();
// TODO: Define these attached properties elswhere (e.g. on a Text class) and AddOwner // TODO: Define these attached properties elswhere (e.g. on a Text class) and AddOwner
@ -63,8 +63,8 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Defines the <see cref="Foreground"/> property. /// Defines the <see cref="Foreground"/> property.
/// </summary> /// </summary>
public static readonly AttachedProperty<Brush> ForegroundProperty = public static readonly AttachedProperty<IBrush> ForegroundProperty =
PerspexProperty.RegisterAttached<TextBlock, Control, Brush>( PerspexProperty.RegisterAttached<TextBlock, Control, IBrush>(
nameof(Foreground), nameof(Foreground),
new SolidColorBrush(0xff000000), new SolidColorBrush(0xff000000),
inherits: true); inherits: true);
@ -128,7 +128,7 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Gets or sets a brush used to paint the control's background. /// Gets or sets a brush used to paint the control's background.
/// </summary> /// </summary>
public Brush Background public IBrush Background
{ {
get { return GetValue(BackgroundProperty); } get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); } set { SetValue(BackgroundProperty, value); }
@ -183,7 +183,7 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Gets or sets a brush used to paint the text. /// Gets or sets a brush used to paint the text.
/// </summary> /// </summary>
public Brush Foreground public IBrush Foreground
{ {
get { return GetValue(ForegroundProperty); } get { return GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); } set { SetValue(ForegroundProperty, value); }
@ -268,7 +268,7 @@ namespace Perspex.Controls
/// </summary> /// </summary>
/// <param name="control">The control.</param> /// <param name="control">The control.</param>
/// <returns>The foreground.</returns> /// <returns>The foreground.</returns>
public static Brush GetForeground(Control control) public static IBrush GetForeground(Control control)
{ {
return control.GetValue(ForegroundProperty); return control.GetValue(ForegroundProperty);
} }
@ -323,7 +323,7 @@ namespace Perspex.Controls
/// <param name="control">The control.</param> /// <param name="control">The control.</param>
/// <param name="value">The property value to set.</param> /// <param name="value">The property value to set.</param>
/// <returns>The font family.</returns> /// <returns>The font family.</returns>
public static void SetForeground(Control control, Brush value) public static void SetForeground(Control control, IBrush value)
{ {
control.SetValue(ForegroundProperty, value); control.SetValue(ForegroundProperty, value);
} }
@ -334,7 +334,7 @@ namespace Perspex.Controls
/// <param name="context">The drawing context.</param> /// <param name="context">The drawing context.</param>
public override void Render(DrawingContext context) public override void Render(DrawingContext context)
{ {
Brush background = Background; var background = Background;
if (background != null) if (background != null)
{ {

6
src/Perspex.HtmlRenderer/Adapters/BrushAdapter.cs

@ -23,12 +23,12 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters
/// <summary> /// <summary>
/// The actual Perspex brush instance. /// The actual Perspex brush instance.
/// </summary> /// </summary>
private readonly Brush _brush; private readonly IBrush _brush;
/// <summary> /// <summary>
/// Init. /// Init.
/// </summary> /// </summary>
public BrushAdapter(Brush brush) public BrushAdapter(IBrush brush)
{ {
_brush = brush; _brush = brush;
} }
@ -36,7 +36,7 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters
/// <summary> /// <summary>
/// The actual Perspex brush instance. /// The actual Perspex brush instance.
/// </summary> /// </summary>
public Brush Brush public IBrush Brush
{ {
get { return _brush; } get { return _brush; }
} }

4
src/Perspex.HtmlRenderer/Adapters/PenAdapter.cs

@ -25,7 +25,7 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters
/// <summary> /// <summary>
/// The actual Perspex brush instance. /// The actual Perspex brush instance.
/// </summary> /// </summary>
private readonly Brush _brush; private readonly IBrush _brush;
/// <summary> /// <summary>
/// the width of the pen /// the width of the pen
@ -42,7 +42,7 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters
/// <summary> /// <summary>
/// Init. /// Init.
/// </summary> /// </summary>
public PenAdapter(Brush brush) public PenAdapter(IBrush brush)
{ {
_brush = brush; _brush = brush;
} }

4
src/Perspex.HtmlRenderer/Adapters/PerspexAdapter.cs

@ -50,9 +50,9 @@ namespace TheArtOfDev.HtmlRenderer.Perspex.Adapters
/// <summary> /// <summary>
/// Get solid color brush for the given color. /// Get solid color brush for the given color.
/// </summary> /// </summary>
private static Brush GetSolidColorBrush(RColor color) private static IBrush GetSolidColorBrush(RColor color)
{ {
Brush solidBrush; IBrush solidBrush;
if (color == RColor.White) if (color == RColor.White)
solidBrush = Brushes.White; solidBrush = Brushes.White;
else if (color == RColor.Black) else if (color == RColor.Black)

12
src/Perspex.HtmlRenderer/HtmlControl.cs

@ -85,14 +85,14 @@ namespace Perspex.Controls.Html
public static readonly PerspexProperty TextProperty = public static readonly PerspexProperty TextProperty =
PropertyHelper.Register<HtmlControl, string>("Text", null, OnPerspexProperty_valueChanged); PropertyHelper.Register<HtmlControl, string>("Text", null, OnPerspexProperty_valueChanged);
public static readonly StyledProperty<Brush> BackgroundProperty = public static readonly StyledProperty<IBrush> BackgroundProperty =
Border.BackgroundProperty.AddOwner<HtmlControl>(); Border.BackgroundProperty.AddOwner<HtmlControl>();
public static readonly PerspexProperty BorderThicknessProperty = public static readonly PerspexProperty BorderThicknessProperty =
PerspexProperty.Register<HtmlControl, Thickness>("BorderThickness", new Thickness(0)); PerspexProperty.Register<HtmlControl, Thickness>("BorderThickness", new Thickness(0));
public static readonly PerspexProperty BorderBrushProperty = public static readonly PerspexProperty BorderBrushProperty =
PerspexProperty.Register<HtmlControl, Brush>("BorderBrush"); PerspexProperty.Register<HtmlControl, IBrush>("BorderBrush");
public static readonly PerspexProperty PaddingProperty = public static readonly PerspexProperty PaddingProperty =
PerspexProperty.Register<HtmlControl, Thickness>("Padding", new Thickness(0)); PerspexProperty.Register<HtmlControl, Thickness>("Padding", new Thickness(0));
@ -255,9 +255,9 @@ namespace Perspex.Controls.Html
set { SetValue(BorderThicknessProperty, value); } set { SetValue(BorderThicknessProperty, value); }
} }
public Brush BorderBrush public IBrush BorderBrush
{ {
get { return (Brush)GetValue(BorderBrushProperty); } get { return (IBrush)GetValue(BorderBrushProperty); }
set { SetValue(BorderThicknessProperty, value); } set { SetValue(BorderThicknessProperty, value); }
} }
@ -267,9 +267,9 @@ namespace Perspex.Controls.Html
set { SetValue(PaddingProperty, value); } set { SetValue(PaddingProperty, value); }
} }
public Brush Background public IBrush Background
{ {
get { return (Brush) GetValue(BackgroundProperty); } get { return (IBrush) GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value);} set { SetValue(BackgroundProperty, value);}
} }

6
src/Perspex.SceneGraph/Media/Brush.cs

@ -10,7 +10,7 @@ namespace Perspex.Media
/// <summary> /// <summary>
/// Describes how an area is painted. /// Describes how an area is painted.
/// </summary> /// </summary>
public abstract class Brush : PerspexObject public abstract class Brush : PerspexObject, IBrush
{ {
/// <summary> /// <summary>
/// Defines the <see cref="Opacity"/> property. /// Defines the <see cref="Opacity"/> property.
@ -32,7 +32,7 @@ namespace Perspex.Media
/// </summary> /// </summary>
/// <param name="s">The brush string.</param> /// <param name="s">The brush string.</param>
/// <returns>The <see cref="Color"/>.</returns> /// <returns>The <see cref="Color"/>.</returns>
public static Brush Parse(string s) public static IBrush Parse(string s)
{ {
if (s[0] == '#') if (s[0] == '#')
{ {
@ -46,7 +46,7 @@ namespace Perspex.Media
if (member != null) if (member != null)
{ {
return (Brush)member.GetValue(null); return (IBrush)member.GetValue(null);
} }
else else
{ {

6
src/Perspex.SceneGraph/Media/DrawingContext.cs

@ -83,7 +83,7 @@ namespace Perspex.Media
/// <param name="brush">The fill brush.</param> /// <param name="brush">The fill brush.</param>
/// <param name="pen">The stroke pen.</param> /// <param name="pen">The stroke pen.</param>
/// <param name="geometry">The geometry.</param> /// <param name="geometry">The geometry.</param>
public void DrawGeometry(Brush brush, Pen pen, Geometry geometry) => _impl.DrawGeometry(brush, pen, geometry); public void DrawGeometry(IBrush brush, Pen pen, Geometry geometry) => _impl.DrawGeometry(brush, pen, geometry);
/// <summary> /// <summary>
/// Draws the outline of a rectangle. /// Draws the outline of a rectangle.
@ -100,7 +100,7 @@ namespace Perspex.Media
/// <param name="foreground">The foreground brush.</param> /// <param name="foreground">The foreground brush.</param>
/// <param name="origin">The upper-left corner of the text.</param> /// <param name="origin">The upper-left corner of the text.</param>
/// <param name="text">The text.</param> /// <param name="text">The text.</param>
public void DrawText(Brush foreground, Point origin, FormattedText text) public void DrawText(IBrush foreground, Point origin, FormattedText text)
=> _impl.DrawText(foreground, origin, text); => _impl.DrawText(foreground, origin, text);
/// <summary> /// <summary>
@ -109,7 +109,7 @@ namespace Perspex.Media
/// <param name="brush">The brush.</param> /// <param name="brush">The brush.</param>
/// <param name="rect">The rectangle bounds.</param> /// <param name="rect">The rectangle bounds.</param>
/// <param name="cornerRadius">The corner radius.</param> /// <param name="cornerRadius">The corner radius.</param>
public void FillRectangle(Brush brush, Rect rect, float cornerRadius = 0.0f) public void FillRectangle(IBrush brush, Rect rect, float cornerRadius = 0.0f)
=> _impl.FillRectangle(brush, rect, cornerRadius); => _impl.FillRectangle(brush, rect, cornerRadius);
public struct PushedState : IDisposable public struct PushedState : IDisposable

2
src/Perspex.SceneGraph/Media/FormattedText.cs

@ -206,7 +206,7 @@ namespace Perspex.Media
/// <param name="brush">The brush.</param> /// <param name="brush">The brush.</param>
/// <param name="startIndex">The start of the text range.</param> /// <param name="startIndex">The start of the text range.</param>
/// <param name="length">The length of the text range.</param> /// <param name="length">The length of the text range.</param>
public void SetForegroundBrush(Brush brush, int startIndex, int length) public void SetForegroundBrush(IBrush brush, int startIndex, int length)
{ {
CheckDisposed(); CheckDisposed();
PlatformImpl.SetForegroundBrush(brush, startIndex, length); PlatformImpl.SetForegroundBrush(brush, startIndex, length);

16
src/Perspex.SceneGraph/Media/IBrush.cs

@ -0,0 +1,16 @@
// 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
{
/// <summary>
/// Describes how an area is painted.
/// </summary>
public interface IBrush
{
/// <summary>
/// Gets the opacity of the brush.
/// </summary>
double Opacity { get; }
}
}

6
src/Perspex.SceneGraph/Media/IDrawingContext.cs

@ -39,7 +39,7 @@ namespace Perspex.Media
/// <param name="brush">The fill brush.</param> /// <param name="brush">The fill brush.</param>
/// <param name="pen">The stroke pen.</param> /// <param name="pen">The stroke pen.</param>
/// <param name="geometry">The geometry.</param> /// <param name="geometry">The geometry.</param>
void DrawGeometry(Brush brush, Pen pen, Geometry geometry); void DrawGeometry(IBrush brush, Pen pen, Geometry geometry);
/// <summary> /// <summary>
/// Draws the outline of a rectangle. /// Draws the outline of a rectangle.
@ -55,7 +55,7 @@ namespace Perspex.Media
/// <param name="foreground">The foreground brush.</param> /// <param name="foreground">The foreground brush.</param>
/// <param name="origin">The upper-left corner of the text.</param> /// <param name="origin">The upper-left corner of the text.</param>
/// <param name="text">The text.</param> /// <param name="text">The text.</param>
void DrawText(Brush foreground, Point origin, FormattedText text); void DrawText(IBrush foreground, Point origin, FormattedText text);
/// <summary> /// <summary>
/// Draws a filled rectangle. /// Draws a filled rectangle.
@ -63,7 +63,7 @@ namespace Perspex.Media
/// <param name="brush">The brush.</param> /// <param name="brush">The brush.</param>
/// <param name="rect">The rectangle bounds.</param> /// <param name="rect">The rectangle bounds.</param>
/// <param name="cornerRadius">The corner radius.</param> /// <param name="cornerRadius">The corner radius.</param>
void FillRectangle(Brush brush, Rect rect, float cornerRadius = 0.0f); void FillRectangle(IBrush brush, Rect rect, float cornerRadius = 0.0f);
/// <summary> /// <summary>
/// Pushes a clip rectange. /// Pushes a clip rectange.

16
src/Perspex.SceneGraph/Media/ISolidColorBrush.cs

@ -0,0 +1,16 @@
// 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
{
/// <summary>
/// Fills an area with a solid color.
/// </summary>
public interface ISolidColorBrush : IBrush
{
/// <summary>
/// Gets the color of the brush.
/// </summary>
Color Color { get; }
}
}

2
src/Perspex.SceneGraph/Media/Mutable/SolidColorBrush.cs

@ -10,7 +10,7 @@ namespace Perspex.Media.Mutable
/// This is a mutable version of the normal immutable <see cref="Perspex.Media.SolidColorBrush"/> /// This is a mutable version of the normal immutable <see cref="Perspex.Media.SolidColorBrush"/>
/// for use in XAML. XAML really needs support for immutable data... /// for use in XAML. XAML really needs support for immutable data...
/// </remarks> /// </remarks>
public class SolidColorBrush : Brush public class SolidColorBrush : Brush, ISolidColorBrush
{ {
public static readonly DirectProperty<SolidColorBrush, Color> ColorProperty = public static readonly DirectProperty<SolidColorBrush, Color> ColorProperty =
PerspexProperty.RegisterDirect<SolidColorBrush, Color>( PerspexProperty.RegisterDirect<SolidColorBrush, Color>(

4
src/Perspex.SceneGraph/Media/Pen.cs

@ -20,7 +20,7 @@ namespace Perspex.Media
/// <param name="lineJoin">The line join.</param> /// <param name="lineJoin">The line join.</param>
/// <param name="miterLimit">The miter limit.</param> /// <param name="miterLimit">The miter limit.</param>
public Pen( public Pen(
Brush brush, IBrush brush,
double thickness = 1.0, double thickness = 1.0,
DashStyle dashStyle = null, DashStyle dashStyle = null,
PenLineCap dashCap = PenLineCap.Flat, PenLineCap dashCap = PenLineCap.Flat,
@ -73,7 +73,7 @@ namespace Perspex.Media
/// <summary> /// <summary>
/// Gets the brush used to draw the stroke. /// Gets the brush used to draw the stroke.
/// </summary> /// </summary>
public Brush Brush { get; } public IBrush Brush { get; }
/// <summary> /// <summary>
/// Gets the stroke thickness. /// Gets the stroke thickness.

16
src/Perspex.SceneGraph/Media/SolidColorBrush.cs

@ -6,15 +6,17 @@ namespace Perspex.Media
/// <summary> /// <summary>
/// Fills an area with a solid color. /// Fills an area with a solid color.
/// </summary> /// </summary>
public class SolidColorBrush : Brush public class SolidColorBrush : ISolidColorBrush
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SolidColorBrush"/> class. /// Initializes a new instance of the <see cref="SolidColorBrush"/> class.
/// </summary> /// </summary>
/// <param name="color">The color to use.</param> /// <param name="color">The color to use.</param>
public SolidColorBrush(Color color) /// <param name="opacity">The opacity of the brush.</param>
public SolidColorBrush(Color color, double opacity = 1)
{ {
Color = color; Color = color;
Opacity = opacity;
} }
/// <summary> /// <summary>
@ -29,10 +31,12 @@ namespace Perspex.Media
/// <summary> /// <summary>
/// Gets the color of the brush. /// Gets the color of the brush.
/// </summary> /// </summary>
public Color Color public Color Color { get; }
{
get; /// <summary>
} /// Gets the opacity of the brush.
/// </summary>
public double Opacity { get; }
/// <summary> /// <summary>
/// Returns a string representation of the brush. /// Returns a string representation of the brush.

2
src/Perspex.SceneGraph/Perspex.SceneGraph.csproj

@ -72,6 +72,8 @@
<Compile Include="Media\GradientBrush.cs" /> <Compile Include="Media\GradientBrush.cs" />
<Compile Include="Media\GradientSpreadMethod.cs" /> <Compile Include="Media\GradientSpreadMethod.cs" />
<Compile Include="Media\GradientStop.cs" /> <Compile Include="Media\GradientStop.cs" />
<Compile Include="Media\IBrush.cs" />
<Compile Include="Media\ISolidColorBrush.cs" />
<Compile Include="Media\LineGeometry.cs" /> <Compile Include="Media\LineGeometry.cs" />
<Compile Include="Media\Mutable\SolidColorBrush.cs" /> <Compile Include="Media\Mutable\SolidColorBrush.cs" />
<Compile Include="Media\PenLineJoin.cs" /> <Compile Include="Media\PenLineJoin.cs" />

2
src/Perspex.SceneGraph/Platform/IFormattedTextImpl.cs

@ -61,6 +61,6 @@ namespace Perspex.Platform
/// <param name="brush">The brush.</param> /// <param name="brush">The brush.</param>
/// <param name="startIndex">The start of the text range.</param> /// <param name="startIndex">The start of the text range.</param>
/// <param name="length">The length of the text range.</param> /// <param name="length">The length of the text range.</param>
void SetForegroundBrush(Brush brush, int startIndex, int length); void SetForegroundBrush(IBrush brush, int startIndex, int length);
} }
} }

8
src/Skia/Perspex.Skia/DrawingContextImpl.cs

@ -34,7 +34,7 @@ namespace Perspex.Skia
} }
static readonly NativeBrushContainer _dummy = new NativeBrushContainer(null); static readonly NativeBrushContainer _dummy = new NativeBrushContainer(null);
public void DrawGeometry(Brush brush, Pen pen, Geometry geometry) public void DrawGeometry(IBrush brush, Pen pen, Geometry geometry)
{ {
var impl = ((StreamGeometryImpl) geometry.PlatformImpl); var impl = ((StreamGeometryImpl) geometry.PlatformImpl);
var size = geometry.Bounds.Size; var size = geometry.Bounds.Size;
@ -46,7 +46,7 @@ namespace Perspex.Skia
} }
} }
unsafe NativeBrushContainer CreateBrush(Brush brush, Size targetSize) unsafe NativeBrushContainer CreateBrush(IBrush brush, Size targetSize)
{ {
var rv = NativeBrushPool.Instance.Get(); var rv = NativeBrushPool.Instance.Get();
rv.Brush->Opacity = brush.Opacity; rv.Brush->Opacity = brush.Opacity;
@ -141,7 +141,7 @@ namespace Perspex.Skia
} }
} }
public void FillRectangle(Brush pbrush, Rect rect, float cornerRadius = 0) public void FillRectangle(IBrush pbrush, Rect rect, float cornerRadius = 0)
{ {
using (var brush = CreateBrush(pbrush, rect.Size)) using (var brush = CreateBrush(pbrush, rect.Size))
{ {
@ -150,7 +150,7 @@ namespace Perspex.Skia
} }
} }
public void DrawText(Brush foreground, Point origin, FormattedText text) public void DrawText(IBrush foreground, Point origin, FormattedText text)
{ {
using (var br = CreateBrush(foreground, text.Measure())) using (var br = CreateBrush(foreground, text.Measure()))
MethodTable.Instance.DrawFormattedText(Handle, br.Brush, ((FormattedTextImpl) text.PlatformImpl).Handle, MethodTable.Instance.DrawFormattedText(Handle, br.Brush, ((FormattedTextImpl) text.PlatformImpl).Handle,

2
src/Skia/Perspex.Skia/FormattedTextImpl.cs

@ -73,7 +73,7 @@ namespace Perspex.Skia
return _size; return _size;
} }
public void SetForegroundBrush(Brush brush, int startIndex, int length) public void SetForegroundBrush(IBrush brush, int startIndex, int length)
{ {
} }

4
src/Windows/Perspex.Direct2D1/Media/BrushWrapper.cs

@ -8,11 +8,11 @@ namespace Perspex.Direct2D1.Media
{ {
internal class BrushWrapper : ComObject internal class BrushWrapper : ComObject
{ {
public BrushWrapper(Brush brush) public BrushWrapper(IBrush brush)
{ {
Brush = brush; Brush = brush;
} }
public Brush Brush { get; private set; } public IBrush Brush { get; private set; }
} }
} }

15
src/Windows/Perspex.Direct2D1/Media/DrawingContext.cs

@ -114,7 +114,7 @@ namespace Perspex.Direct2D1.Media
/// <param name="brush">The fill brush.</param> /// <param name="brush">The fill brush.</param>
/// <param name="pen">The stroke pen.</param> /// <param name="pen">The stroke pen.</param>
/// <param name="geometry">The geometry.</param> /// <param name="geometry">The geometry.</param>
public void DrawGeometry(Perspex.Media.Brush brush, Pen pen, Perspex.Media.Geometry geometry) public void DrawGeometry(IBrush brush, Pen pen, Perspex.Media.Geometry geometry)
{ {
if (brush != null) if (brush != null)
{ {
@ -181,7 +181,7 @@ namespace Perspex.Direct2D1.Media
/// <param name="foreground">The foreground brush.</param> /// <param name="foreground">The foreground brush.</param>
/// <param name="origin">The upper-left corner of the text.</param> /// <param name="origin">The upper-left corner of the text.</param>
/// <param name="text">The text.</param> /// <param name="text">The text.</param>
public void DrawText(Perspex.Media.Brush foreground, Point origin, FormattedText text) public void DrawText(IBrush foreground, Point origin, FormattedText text)
{ {
if (!string.IsNullOrEmpty(text.Text)) if (!string.IsNullOrEmpty(text.Text))
{ {
@ -204,7 +204,7 @@ namespace Perspex.Direct2D1.Media
/// <param name="brush">The brush.</param> /// <param name="brush">The brush.</param>
/// <param name="rect">The rectangle bounds.</param> /// <param name="rect">The rectangle bounds.</param>
/// <param name="cornerRadius">The corner radius.</param> /// <param name="cornerRadius">The corner radius.</param>
public void FillRectangle(Perspex.Media.Brush brush, Rect rect, float cornerRadius) public void FillRectangle(IBrush brush, Rect rect, float cornerRadius)
{ {
using (var b = CreateBrush(brush, rect.Size)) using (var b = CreateBrush(brush, rect.Size))
{ {
@ -291,10 +291,9 @@ namespace Perspex.Direct2D1.Media
/// <param name="brush">The perspex brush.</param> /// <param name="brush">The perspex brush.</param>
/// <param name="destinationSize">The size of the brush's target area.</param> /// <param name="destinationSize">The size of the brush's target area.</param>
/// <returns>The Direct2D brush wrapper.</returns> /// <returns>The Direct2D brush wrapper.</returns>
public BrushImpl CreateBrush(Perspex.Media.Brush brush, Size destinationSize) public BrushImpl CreateBrush(IBrush brush, Size destinationSize)
{ {
var solidColorBrush = brush as Perspex.Media.SolidColorBrush; var solidColorBrush = brush as Perspex.Media.ISolidColorBrush;
var mutableSolidColorBrush = brush as Perspex.Media.Mutable.SolidColorBrush;
var linearGradientBrush = brush as Perspex.Media.LinearGradientBrush; var linearGradientBrush = brush as Perspex.Media.LinearGradientBrush;
var radialGradientBrush = brush as Perspex.Media.RadialGradientBrush; var radialGradientBrush = brush as Perspex.Media.RadialGradientBrush;
var imageBrush = brush as Perspex.Media.ImageBrush; var imageBrush = brush as Perspex.Media.ImageBrush;
@ -304,10 +303,6 @@ namespace Perspex.Direct2D1.Media
{ {
return new SolidColorBrushImpl(solidColorBrush, _renderTarget); return new SolidColorBrushImpl(solidColorBrush, _renderTarget);
} }
if (mutableSolidColorBrush != null)
{
return new SolidColorBrushImpl(mutableSolidColorBrush, _renderTarget);
}
else if (linearGradientBrush != null) else if (linearGradientBrush != null)
{ {
return new LinearGradientBrushImpl(linearGradientBrush, _renderTarget, destinationSize); return new LinearGradientBrushImpl(linearGradientBrush, _renderTarget, destinationSize);

2
src/Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs

@ -118,7 +118,7 @@ namespace Perspex.Direct2D1.Media
return new Size(width, TextLayout.Metrics.Height); return new Size(width, TextLayout.Metrics.Height);
} }
public void SetForegroundBrush(Brush brush, int startIndex, int count) public void SetForegroundBrush(IBrush brush, int startIndex, int count)
{ {
TextLayout.SetDrawingEffect( TextLayout.SetDrawingEffect(
new BrushWrapper(brush), new BrushWrapper(brush),

17
src/Windows/Perspex.Direct2D1/Media/SolidColorBrushImpl.cs

@ -1,24 +1,13 @@
// Copyright (c) The Perspex Project. All rights reserved. // 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. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using Perspex.Media;
namespace Perspex.Direct2D1.Media namespace Perspex.Direct2D1.Media
{ {
public class SolidColorBrushImpl : BrushImpl public class SolidColorBrushImpl : BrushImpl
{ {
public SolidColorBrushImpl(Perspex.Media.SolidColorBrush brush, SharpDX.Direct2D1.RenderTarget target) public SolidColorBrushImpl(ISolidColorBrush brush, SharpDX.Direct2D1.RenderTarget target)
{
PlatformBrush = new SharpDX.Direct2D1.SolidColorBrush(
target,
brush?.Color.ToDirect2D() ?? new SharpDX.Mathematics.Interop.RawColor4(),
new SharpDX.Direct2D1.BrushProperties
{
Opacity = brush != null ? (float)brush.Opacity : 1.0f,
Transform = target.Transform
}
);
}
public SolidColorBrushImpl(Perspex.Media.Mutable.SolidColorBrush brush, SharpDX.Direct2D1.RenderTarget target)
{ {
PlatformBrush = new SharpDX.Direct2D1.SolidColorBrush( PlatformBrush = new SharpDX.Direct2D1.SolidColorBrush(
target, target,

Loading…
Cancel
Save