From 6b06d0ee4c305090849ba8b89f20ecc0f9110e76 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 16 Feb 2016 23:05:45 +0100 Subject: [PATCH 01/38] Started adding Style resources. Added Style.Resources and confirmed that Color can be added to the resources. However, SolidColorBrush doesn't work - needs a fix from OmniXAML. --- src/Perspex.Styling/Styling/Style.cs | 8 ++- .../StyleTests.cs | 49 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/Perspex.Styling/Styling/Style.cs b/src/Perspex.Styling/Styling/Style.cs index b1337b0233..0a10471f72 100644 --- a/src/Perspex.Styling/Styling/Style.cs +++ b/src/Perspex.Styling/Styling/Style.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reactive.Linq; using Perspex.Metadata; @@ -15,12 +14,14 @@ namespace Perspex.Styling public class Style : IStyle { private static readonly IObservable True = Observable.Never().StartWith(true); + private Lazy> _resources; /// /// Initializes a new instance of the class. /// public Style() { + _resources = new Lazy>(() => new Dictionary()); } /// @@ -32,6 +33,11 @@ namespace Perspex.Styling Selector = selector(new Selector()); } + /// + /// Gets a dictionary of style resources. + /// + public IDictionary Resources => _resources.Value; + /// /// Gets or sets style's selector. /// diff --git a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs index 4c6783c0e0..5a9d9bbcef 100644 --- a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs +++ b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs @@ -6,6 +6,7 @@ using System.Reactive.Linq; using Perspex.Controls; using Perspex.Data; using Perspex.Markup.Xaml.Data; +using Perspex.Media; using Perspex.Styling; using Perspex.UnitTests; using Xunit; @@ -14,6 +15,54 @@ namespace Perspex.Markup.Xaml.UnitTests { public class StyleTests { + [Fact] + public void Color_Can_Be_Added_To_Style_Resources() + { + using (UnitTestApplication.Start(TestServices.MockPlatformWrapper)) + { + var xaml = @" + + + + +"; + var loader = new PerspexXamlLoader(); + var userControl = (UserControl)loader.Load(xaml); + var color = (Color)((Style)userControl.Styles[0]).Resources["color"]; + + Assert.Equal(0xff506070, color.ToUint32()); + } + } + + [Fact] + public void SolidColorBrush_Can_Be_Added_To_Style_Resources() + { + using (UnitTestApplication.Start(TestServices.MockPlatformWrapper)) + { + var xaml = @" + + + + +"; + var loader = new PerspexXamlLoader(); + var userControl = (UserControl)loader.Load(xaml); + var brush = (SolidColorBrush)((Style)userControl.Styles[0]).Resources["brush"]; + + Assert.Equal(0xff506070, brush.Color.ToUint32()); + } + } + [Fact] public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound() { From f7150c65c77ad31ea77bbdbd9a55770ac7830abf Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 20:38:28 +0100 Subject: [PATCH 02/38] Allow SolidColorBrushes in style resources. --- .../Context/PerspexTypeFeatureProvider.cs | 1 + .../SolidColorBrushTypeConverter.cs | 33 +++++++++++++++++++ src/Markup/Perspex.Markup.Xaml/OmniXAML | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/Markup/Perspex.Markup.Xaml/Converters/SolidColorBrushTypeConverter.cs diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexTypeFeatureProvider.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexTypeFeatureProvider.cs index 25b3189da5..a875a751c4 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexTypeFeatureProvider.cs +++ b/src/Markup/Perspex.Markup.Xaml/Context/PerspexTypeFeatureProvider.cs @@ -166,6 +166,7 @@ namespace Perspex.Markup.Xaml.Context RegisterTypeConverter(typeof(RelativeRect), new RelativeRectTypeConverter()); RegisterTypeConverter(typeof(RowDefinitions), new RowDefinitionsTypeConverter()); RegisterTypeConverter(typeof(Selector), new SelectorTypeConverter()); + RegisterTypeConverter(typeof(SolidColorBrush), new SolidColorBrushTypeConverter()); RegisterTypeConverter(typeof(Thickness), new ThicknessTypeConverter()); RegisterTypeConverter(typeof(TimeSpan), new TimeSpanTypeConverter()); RegisterTypeConverter(typeof(Uri), new UriTypeConverter()); diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/SolidColorBrushTypeConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/SolidColorBrushTypeConverter.cs new file mode 100644 index 0000000000..005b8a91c4 --- /dev/null +++ b/src/Markup/Perspex.Markup.Xaml/Converters/SolidColorBrushTypeConverter.cs @@ -0,0 +1,33 @@ +// 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(ITypeConverterContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public bool CanConvertTo(ITypeConverterContext context, Type destinationType) + { + return false; + } + + public object ConvertFrom(ITypeConverterContext context, CultureInfo culture, object value) + { + return Brush.Parse((string)value); + } + + public object ConvertTo(ITypeConverterContext context, CultureInfo culture, object value, Type destinationType) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/OmniXAML b/src/Markup/Perspex.Markup.Xaml/OmniXAML index 27005c8b4d..e1a5fb60b0 160000 --- a/src/Markup/Perspex.Markup.Xaml/OmniXAML +++ b/src/Markup/Perspex.Markup.Xaml/OmniXAML @@ -1 +1 @@ -Subproject commit 27005c8b4d41f2a6d3b85da7eb6ed994b57e0138 +Subproject commit e1a5fb60b09862183ba5c48c36a52bea7a66bd42 From 19af37a6af5c8116837405015761c85b1126a222 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 22:09:58 +0100 Subject: [PATCH 03/38] Started adding StyleResource markup extension. OmniXAML issue #84 is now blocking us. --- .../StyleResourceExtension.cs | 33 ++++++++ .../Perspex.Markup.Xaml.csproj | 2 + .../Styling/StyleInclude.cs | 12 +++ src/Perspex.Styling/Perspex.Styling.csproj | 1 + src/Perspex.Styling/Styling/IStyle.cs | 9 +++ src/Perspex.Styling/Styling/Style.cs | 49 +++++++++++- .../Styling/StyleExtensions.cs | 39 ++++++++++ src/Perspex.Styling/Styling/Styles.cs | 23 ++++++ .../StyleTests.cs | 27 ++++++- .../Perspex.Styling.UnitTests.csproj | 1 + .../ResourceTests.cs | 78 +++++++++++++++++++ 11 files changed, 269 insertions(+), 5 deletions(-) create mode 100644 src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs create mode 100644 src/Perspex.Styling/Styling/StyleExtensions.cs create mode 100644 tests/Perspex.Styling.UnitTests/ResourceTests.cs diff --git a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs new file mode 100644 index 0000000000..c1acd8cbff --- /dev/null +++ b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs @@ -0,0 +1,33 @@ +// 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 OmniXaml; +using Perspex.LogicalTree; +using Perspex.Styling; + +namespace Perspex.Markup.Xaml.MarkupExtensions +{ + public class StyleResourceExtension : MarkupExtension + { + public StyleResourceExtension(string name) + { + Name = name; + } + + public override object ProvideValue(MarkupExtensionContext extensionContext) + { + var styleHost = extensionContext.TargetObject as IStyleHost; + + if (styleHost == null) + { + throw new ParseException( + $"StyleResource cannot be assigned to an object of type '{styleHost.GetType()}'."); + } + + return styleHost.FindStyleResource(Name); + } + + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj index 984762d50f..35aff8a3a2 100644 --- a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj +++ b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj @@ -55,6 +55,7 @@ + @@ -78,6 +79,7 @@ + diff --git a/src/Markup/Perspex.Markup.Xaml/Styling/StyleInclude.cs b/src/Markup/Perspex.Markup.Xaml/Styling/StyleInclude.cs index fee252de17..6991e48f16 100644 --- a/src/Markup/Perspex.Markup.Xaml/Styling/StyleInclude.cs +++ b/src/Markup/Perspex.Markup.Xaml/Styling/StyleInclude.cs @@ -35,5 +35,17 @@ namespace Perspex.Markup.Xaml.Styling Loaded.Attach(control, container); } } + + /// + /// Tries to find a named resource within the style. + /// + /// The resource name. + /// + /// The resource if found, otherwise . + /// + public object FindResource(string name) + { + return Loaded.FindResource(name); + } } } diff --git a/src/Perspex.Styling/Perspex.Styling.csproj b/src/Perspex.Styling/Perspex.Styling.csproj index 4ed57c90e3..92edaa3db6 100644 --- a/src/Perspex.Styling/Perspex.Styling.csproj +++ b/src/Perspex.Styling/Perspex.Styling.csproj @@ -63,6 +63,7 @@ + diff --git a/src/Perspex.Styling/Styling/IStyle.cs b/src/Perspex.Styling/Styling/IStyle.cs index 4404853bf0..5847aa5ee1 100644 --- a/src/Perspex.Styling/Styling/IStyle.cs +++ b/src/Perspex.Styling/Styling/IStyle.cs @@ -16,5 +16,14 @@ namespace Perspex.Styling /// The control that contains this style. May be null. /// void Attach(IStyleable control, IStyleHost container); + + /// + /// Tries to find a named resource within the style. + /// + /// The resource name. + /// + /// The resource if found, otherwise . + /// + object FindResource(string name); } } diff --git a/src/Perspex.Styling/Styling/Style.cs b/src/Perspex.Styling/Styling/Style.cs index 0a10471f72..58fd2fa721 100644 --- a/src/Perspex.Styling/Styling/Style.cs +++ b/src/Perspex.Styling/Styling/Style.cs @@ -14,14 +14,13 @@ namespace Perspex.Styling public class Style : IStyle { private static readonly IObservable True = Observable.Never().StartWith(true); - private Lazy> _resources; + private Dictionary _resources; /// /// Initializes a new instance of the class. /// public Style() { - _resources = new Lazy>(() => new Dictionary()); } /// @@ -34,9 +33,30 @@ namespace Perspex.Styling } /// - /// Gets a dictionary of style resources. + /// Gets or sets a dictionary of style resources. /// - public IDictionary Resources => _resources.Value; + public IDictionary Resources + { + get + { + if (_resources == null) + { + _resources = new Dictionary(); + } + + return _resources; + } + + set + { + var resources = Resources; + + foreach (var i in value) + { + resources.Add(i); + } + } + } /// /// Gets or sets style's selector. @@ -83,6 +103,27 @@ namespace Perspex.Styling } } + /// + /// Tries to find a named resource within the style. + /// + /// The resource name. + /// + /// The resource if found, otherwise . + /// + public object FindResource(string name) + { + object result = null; + + if (_resources?.TryGetValue(name, out result) == true) + { + return result; + } + else + { + return PerspexProperty.UnsetValue; + } + } + /// /// Returns a string representation of the style. /// diff --git a/src/Perspex.Styling/Styling/StyleExtensions.cs b/src/Perspex.Styling/Styling/StyleExtensions.cs new file mode 100644 index 0000000000..dc30041b49 --- /dev/null +++ b/src/Perspex.Styling/Styling/StyleExtensions.cs @@ -0,0 +1,39 @@ +// 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; + +namespace Perspex.Styling +{ + public static class StyleExtensions + { + /// + /// Tries to find a named style resource. + /// + /// The control from which to find the resource. + /// The resource name. + /// + /// The resource if found, otherwise . + /// + public static object FindStyleResource(this IStyleHost control, string name) + { + Contract.Requires(control != null); + Contract.Requires(name != null); + Contract.Requires(!string.IsNullOrWhiteSpace(name)); + + while (control != null) + { + var result = control.Styles.FindResource(name); + + if (result != PerspexProperty.UnsetValue) + { + return result; + } + + control = control.StylingParent; + } + + return PerspexProperty.UnsetValue; + } + } +} diff --git a/src/Perspex.Styling/Styling/Styles.cs b/src/Perspex.Styling/Styling/Styles.cs index 877235a337..4806670369 100644 --- a/src/Perspex.Styling/Styling/Styles.cs +++ b/src/Perspex.Styling/Styling/Styles.cs @@ -1,6 +1,7 @@ // 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.Linq; using Perspex.Collections; namespace Perspex.Styling @@ -24,5 +25,27 @@ namespace Perspex.Styling style.Attach(control, container); } } + + /// + /// Tries to find a named resource within the style. + /// + /// The resource name. + /// + /// The resource if found, otherwise . + /// + public object FindResource(string name) + { + foreach (var style in this.Reverse()) + { + var result = style.FindResource(name); + + if (result != PerspexProperty.UnsetValue) + { + return result; + } + } + + return PerspexProperty.UnsetValue; + } } } diff --git a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs index 5a9d9bbcef..9eb0309b42 100644 --- a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs +++ b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs @@ -19,7 +19,7 @@ namespace Perspex.Markup.Xaml.UnitTests public void Color_Can_Be_Added_To_Style_Resources() { using (UnitTestApplication.Start(TestServices.MockPlatformWrapper)) - { + { var xaml = @" @@ -63,6 +63,31 @@ namespace Perspex.Markup.Xaml.UnitTests } } + [Fact] + public void StyleResource_Can_Be_Assigned_To_Property() + { + var xaml = @" + + + + + + +"; + + var loader = new PerspexXamlLoader(); + var userControl = (UserControl)loader.Load(xaml); + var border = userControl.FindControl("border"); + var brush = (SolidColorBrush)border.Background; + + Assert.Equal(0xff506070, brush.Color.ToUint32()); + } + [Fact] public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound() { diff --git a/tests/Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj b/tests/Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj index 574660616c..d775308d8d 100644 --- a/tests/Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj +++ b/tests/Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj @@ -97,6 +97,7 @@ + diff --git a/tests/Perspex.Styling.UnitTests/ResourceTests.cs b/tests/Perspex.Styling.UnitTests/ResourceTests.cs new file mode 100644 index 0000000000..bbfa119150 --- /dev/null +++ b/tests/Perspex.Styling.UnitTests/ResourceTests.cs @@ -0,0 +1,78 @@ +// 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.Collections.Generic; +using Perspex.Controls; +using Xunit; + +namespace Perspex.Styling.UnitTests +{ + public class ResourceTests + { + [Fact] + public void FindStyleResource_Should_Find_Correct_Resource() + { + Border target; + + var tree = new Decorator + { + Styles = new Styles + { + new Style + { + Resources = new Dictionary + { + { "Foo", "foo resource" }, + { "Bar", "overridden" }, + } + } + }, + Child = target = new Border + { + Styles = new Styles + { + new Style + { + Resources = new Dictionary + { + { "Bar", "again overridden" }, + } + }, + new Style + { + Resources = new Dictionary + { + { "Bar", "bar resource" }, + } + } + } + } + }; + + Assert.Equal("foo resource", target.FindStyleResource("Foo")); + Assert.Equal("bar resource", target.FindStyleResource("Bar")); + } + + [Fact] + public void FindStyleResource_Should_Return_UnsetValue_For_Not_Found() + { + Border target; + + var tree = target = new Border + { + Styles = new Styles + { + new Style + { + Resources = new Dictionary + { + { "Foo", "foo" }, + } + }, + } + }; + + Assert.Equal(PerspexProperty.UnsetValue, target.FindStyleResource("Baz")); + } + } +} From a72c3e46bf33be1123ebc0115076669512381f1c Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 23:07:10 +0100 Subject: [PATCH 04/38] Moved ILogical to Perspex.LogicalTree. --- src/Perspex.Controls/Control.cs | 1 + src/Perspex.Controls/IControl.cs | 1 + src/Perspex.Controls/ISetLogicalParent.cs | 2 ++ src/Perspex.Controls/ItemsControl.cs | 1 + src/Perspex.Controls/Mixins/ContentControlMixin.cs | 1 + src/Perspex.Controls/Panel.cs | 1 + src/Perspex.Controls/Presenters/ContentPresenter.cs | 1 + src/Perspex.Diagnostics/ViewModels/LogicalTreeNode.cs | 1 + src/Perspex.Styling/{ => LogicalTree}/ILogical.cs | 2 +- src/Perspex.Styling/Perspex.Styling.csproj | 2 +- src/Perspex.Styling/Styling/Selectors.cs | 1 + tests/Perspex.Controls.UnitTests/DecoratorTests.cs | 1 + tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs | 1 + tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs | 1 + 14 files changed, 15 insertions(+), 2 deletions(-) rename src/Perspex.Styling/{ => LogicalTree}/ILogical.cs (96%) diff --git a/src/Perspex.Controls/Control.cs b/src/Perspex.Controls/Control.cs index 8a70ba201f..badec4b788 100644 --- a/src/Perspex.Controls/Control.cs +++ b/src/Perspex.Controls/Control.cs @@ -14,6 +14,7 @@ using Perspex.Controls.Templates; using Perspex.Data; using Perspex.Input; using Perspex.Interactivity; +using Perspex.LogicalTree; using Perspex.Styling; namespace Perspex.Controls diff --git a/src/Perspex.Controls/IControl.cs b/src/Perspex.Controls/IControl.cs index a76fda9c01..7baa03fb9b 100644 --- a/src/Perspex.Controls/IControl.cs +++ b/src/Perspex.Controls/IControl.cs @@ -5,6 +5,7 @@ using System; using Perspex.Controls.Templates; using Perspex.Input; using Perspex.Layout; +using Perspex.LogicalTree; using Perspex.Styling; namespace Perspex.Controls diff --git a/src/Perspex.Controls/ISetLogicalParent.cs b/src/Perspex.Controls/ISetLogicalParent.cs index 8ead31b4c6..9b8e0a00f2 100644 --- a/src/Perspex.Controls/ISetLogicalParent.cs +++ b/src/Perspex.Controls/ISetLogicalParent.cs @@ -1,6 +1,8 @@ // 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.LogicalTree; + namespace Perspex.Controls { /// diff --git a/src/Perspex.Controls/ItemsControl.cs b/src/Perspex.Controls/ItemsControl.cs index 76d2133dc2..27028cba4b 100644 --- a/src/Perspex.Controls/ItemsControl.cs +++ b/src/Perspex.Controls/ItemsControl.cs @@ -12,6 +12,7 @@ using Perspex.Controls.Presenters; using Perspex.Controls.Primitives; using Perspex.Controls.Templates; using Perspex.Controls.Utils; +using Perspex.LogicalTree; using Perspex.Metadata; namespace Perspex.Controls diff --git a/src/Perspex.Controls/Mixins/ContentControlMixin.cs b/src/Perspex.Controls/Mixins/ContentControlMixin.cs index a935fafc00..b1fc17624b 100644 --- a/src/Perspex.Controls/Mixins/ContentControlMixin.cs +++ b/src/Perspex.Controls/Mixins/ContentControlMixin.cs @@ -8,6 +8,7 @@ using Perspex.Collections; using Perspex.Controls.Presenters; using Perspex.Controls.Primitives; using Perspex.Interactivity; +using Perspex.LogicalTree; using Perspex.Styling; namespace Perspex.Controls.Mixins diff --git a/src/Perspex.Controls/Panel.cs b/src/Perspex.Controls/Panel.cs index fc80cc1656..ec87c5ba18 100644 --- a/src/Perspex.Controls/Panel.cs +++ b/src/Perspex.Controls/Panel.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; +using Perspex.LogicalTree; using Perspex.Media; using Perspex.Metadata; diff --git a/src/Perspex.Controls/Presenters/ContentPresenter.cs b/src/Perspex.Controls/Presenters/ContentPresenter.cs index 23cd87d5dd..246db77c46 100644 --- a/src/Perspex.Controls/Presenters/ContentPresenter.cs +++ b/src/Perspex.Controls/Presenters/ContentPresenter.cs @@ -3,6 +3,7 @@ using Perspex.Controls.Primitives; using Perspex.Controls.Templates; +using Perspex.LogicalTree; namespace Perspex.Controls.Presenters { diff --git a/src/Perspex.Diagnostics/ViewModels/LogicalTreeNode.cs b/src/Perspex.Diagnostics/ViewModels/LogicalTreeNode.cs index bef186b246..e71163292e 100644 --- a/src/Perspex.Diagnostics/ViewModels/LogicalTreeNode.cs +++ b/src/Perspex.Diagnostics/ViewModels/LogicalTreeNode.cs @@ -3,6 +3,7 @@ using System; using Perspex.Controls; +using Perspex.LogicalTree; using ReactiveUI; namespace Perspex.Diagnostics.ViewModels diff --git a/src/Perspex.Styling/ILogical.cs b/src/Perspex.Styling/LogicalTree/ILogical.cs similarity index 96% rename from src/Perspex.Styling/ILogical.cs rename to src/Perspex.Styling/LogicalTree/ILogical.cs index b1f5ded5b6..2d3faa2020 100644 --- a/src/Perspex.Styling/ILogical.cs +++ b/src/Perspex.Styling/LogicalTree/ILogical.cs @@ -3,7 +3,7 @@ using Perspex.Collections; -namespace Perspex +namespace Perspex.LogicalTree { /// /// Represents a node in the logical tree. diff --git a/src/Perspex.Styling/Perspex.Styling.csproj b/src/Perspex.Styling/Perspex.Styling.csproj index 92edaa3db6..39ed053d7b 100644 --- a/src/Perspex.Styling/Perspex.Styling.csproj +++ b/src/Perspex.Styling/Perspex.Styling.csproj @@ -43,7 +43,7 @@ Properties\SharedAssemblyInfo.cs - + diff --git a/src/Perspex.Styling/Styling/Selectors.cs b/src/Perspex.Styling/Styling/Selectors.cs index 3c88cac0a6..14d9d0d4be 100644 --- a/src/Perspex.Styling/Styling/Selectors.cs +++ b/src/Perspex.Styling/Styling/Selectors.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Reactive; using System.Reactive.Linq; using System.Reflection; +using Perspex.LogicalTree; namespace Perspex.Styling { diff --git a/tests/Perspex.Controls.UnitTests/DecoratorTests.cs b/tests/Perspex.Controls.UnitTests/DecoratorTests.cs index 84be13c397..da102c5cf1 100644 --- a/tests/Perspex.Controls.UnitTests/DecoratorTests.cs +++ b/tests/Perspex.Controls.UnitTests/DecoratorTests.cs @@ -3,6 +3,7 @@ using System.Collections.Specialized; using System.Linq; +using Perspex.LogicalTree; using Xunit; namespace Perspex.Controls.UnitTests diff --git a/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs b/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs index 427a806376..3d58006145 100644 --- a/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs +++ b/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs @@ -9,6 +9,7 @@ using System.Reactive.Linq; using Perspex.Collections; using Perspex.Controls; using Perspex.Data; +using Perspex.LogicalTree; using Xunit; namespace Perspex.Styling.UnitTests diff --git a/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs b/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs index fab2f15a97..7e1bd429d1 100644 --- a/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs +++ b/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Perspex.Collections; using Perspex.Controls; using Perspex.Data; +using Perspex.LogicalTree; using Xunit; namespace Perspex.Styling.UnitTests From 338b71b20428fb919a53d6cd3f30e55faf5bbde3 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 23:18:43 +0100 Subject: [PATCH 05/38] Moved IVisual to Perspex.VisualTree. --- src/Perspex.Controls/Expander.cs | 1 + src/Perspex.Controls/IControl.cs | 1 + src/Perspex.Controls/Mixins/SelectableMixin.cs | 1 + src/Perspex.Controls/RequestBringIntoViewEventArgs.cs | 1 + src/Perspex.Diagnostics/Debug.cs | 1 + src/Perspex.Input/IInputElement.cs | 1 + src/Perspex.Input/IMainMenu.cs | 2 ++ src/Perspex.Input/IPointerDevice.cs | 1 + src/Perspex.Input/KeyboardDevice.cs | 1 + src/Perspex.Input/PointerEventArgs.cs | 1 + src/Perspex.Interactivity/Interactive.cs | 1 + src/Perspex.Layout/ILayoutable.cs | 2 ++ src/Perspex.SceneGraph/Animation/CrossFade.cs | 1 + src/Perspex.SceneGraph/Animation/IPageTransition.cs | 1 + src/Perspex.SceneGraph/Animation/PageSlide.cs | 1 + src/Perspex.SceneGraph/Media/VisualBrush.cs | 2 ++ src/Perspex.SceneGraph/Perspex.SceneGraph.csproj | 2 +- src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs | 1 + src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs | 1 + src/Perspex.SceneGraph/Rendering/RendererMixin.cs | 1 + src/Perspex.SceneGraph/{ => VisualTree}/IVisual.cs | 3 +-- tests/Perspex.Controls.UnitTests/TestTemplatedControl.cs | 1 + tests/Perspex.Controls.UnitTests/Utils/AncestorFinderTests.cs | 1 + tests/Perspex.Layout.UnitTests/FullLayoutTests.cs | 1 + tests/Perspex.SceneGraph.UnitTests/TestVisual.cs | 1 + tests/Perspex.Styling.UnitTests/SelectorTests_Multiple.cs | 1 + 26 files changed, 29 insertions(+), 3 deletions(-) rename src/Perspex.SceneGraph/{ => VisualTree}/IVisual.cs (98%) diff --git a/src/Perspex.Controls/Expander.cs b/src/Perspex.Controls/Expander.cs index 523976d596..be46949c22 100644 --- a/src/Perspex.Controls/Expander.cs +++ b/src/Perspex.Controls/Expander.cs @@ -1,5 +1,6 @@ using Perspex.Animation; using Perspex.Controls.Primitives; +using Perspex.VisualTree; namespace Perspex.Controls { diff --git a/src/Perspex.Controls/IControl.cs b/src/Perspex.Controls/IControl.cs index 7baa03fb9b..32f23b3e8f 100644 --- a/src/Perspex.Controls/IControl.cs +++ b/src/Perspex.Controls/IControl.cs @@ -7,6 +7,7 @@ using Perspex.Input; using Perspex.Layout; using Perspex.LogicalTree; using Perspex.Styling; +using Perspex.VisualTree; namespace Perspex.Controls { diff --git a/src/Perspex.Controls/Mixins/SelectableMixin.cs b/src/Perspex.Controls/Mixins/SelectableMixin.cs index 4d1e5bb25f..fc975e805e 100644 --- a/src/Perspex.Controls/Mixins/SelectableMixin.cs +++ b/src/Perspex.Controls/Mixins/SelectableMixin.cs @@ -4,6 +4,7 @@ using System; using Perspex.Interactivity; using Perspex.Controls.Primitives; +using Perspex.VisualTree; namespace Perspex.Controls.Mixins { diff --git a/src/Perspex.Controls/RequestBringIntoViewEventArgs.cs b/src/Perspex.Controls/RequestBringIntoViewEventArgs.cs index da8d49a840..c892b80da6 100644 --- a/src/Perspex.Controls/RequestBringIntoViewEventArgs.cs +++ b/src/Perspex.Controls/RequestBringIntoViewEventArgs.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using Perspex.Interactivity; +using Perspex.VisualTree; namespace Perspex.Controls { diff --git a/src/Perspex.Diagnostics/Debug.cs b/src/Perspex.Diagnostics/Debug.cs index 2977992f30..128ae0a8cf 100644 --- a/src/Perspex.Diagnostics/Debug.cs +++ b/src/Perspex.Diagnostics/Debug.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using Perspex.Controls; using Perspex.Data; +using Perspex.VisualTree; namespace Perspex.Diagnostics { diff --git a/src/Perspex.Input/IInputElement.cs b/src/Perspex.Input/IInputElement.cs index c40087ca86..1a04d06859 100644 --- a/src/Perspex.Input/IInputElement.cs +++ b/src/Perspex.Input/IInputElement.cs @@ -5,6 +5,7 @@ using System.Diagnostics.Contracts; using System; using System.Collections.Generic; using Perspex.Interactivity; +using Perspex.VisualTree; namespace Perspex.Input { diff --git a/src/Perspex.Input/IMainMenu.cs b/src/Perspex.Input/IMainMenu.cs index afe954c78a..aedff1b1f7 100644 --- a/src/Perspex.Input/IMainMenu.cs +++ b/src/Perspex.Input/IMainMenu.cs @@ -1,6 +1,8 @@ // 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.VisualTree; + namespace Perspex.Input { /// diff --git a/src/Perspex.Input/IPointerDevice.cs b/src/Perspex.Input/IPointerDevice.cs index 8af791b745..ecbc6b39a6 100644 --- a/src/Perspex.Input/IPointerDevice.cs +++ b/src/Perspex.Input/IPointerDevice.cs @@ -3,6 +3,7 @@ using System; using Perspex.Interactivity; +using Perspex.VisualTree; namespace Perspex.Input { diff --git a/src/Perspex.Input/KeyboardDevice.cs b/src/Perspex.Input/KeyboardDevice.cs index 87d7b9c02c..be9e8833dc 100644 --- a/src/Perspex.Input/KeyboardDevice.cs +++ b/src/Perspex.Input/KeyboardDevice.cs @@ -8,6 +8,7 @@ using System.Reactive.Linq; using System.Runtime.CompilerServices; using Perspex.Input.Raw; using Perspex.Interactivity; +using Perspex.VisualTree; namespace Perspex.Input { diff --git a/src/Perspex.Input/PointerEventArgs.cs b/src/Perspex.Input/PointerEventArgs.cs index 25fbf7f26d..e0d2dfde23 100644 --- a/src/Perspex.Input/PointerEventArgs.cs +++ b/src/Perspex.Input/PointerEventArgs.cs @@ -3,6 +3,7 @@ using System; using Perspex.Interactivity; +using Perspex.VisualTree; namespace Perspex.Input { diff --git a/src/Perspex.Interactivity/Interactive.cs b/src/Perspex.Interactivity/Interactive.cs index c348a3ed83..9915219f7a 100644 --- a/src/Perspex.Interactivity/Interactive.cs +++ b/src/Perspex.Interactivity/Interactive.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Reactive.Disposables; using System.Reactive.Linq; using Perspex.Layout; +using Perspex.VisualTree; namespace Perspex.Interactivity { diff --git a/src/Perspex.Layout/ILayoutable.cs b/src/Perspex.Layout/ILayoutable.cs index 0d704272f2..478c3d4209 100644 --- a/src/Perspex.Layout/ILayoutable.cs +++ b/src/Perspex.Layout/ILayoutable.cs @@ -1,6 +1,8 @@ // 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.VisualTree; + namespace Perspex.Layout { /// diff --git a/src/Perspex.SceneGraph/Animation/CrossFade.cs b/src/Perspex.SceneGraph/Animation/CrossFade.cs index d035a9c83d..722082801d 100644 --- a/src/Perspex.SceneGraph/Animation/CrossFade.cs +++ b/src/Perspex.SceneGraph/Animation/CrossFade.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Reactive.Threading.Tasks; using System.Threading.Tasks; +using Perspex.VisualTree; namespace Perspex.Animation { diff --git a/src/Perspex.SceneGraph/Animation/IPageTransition.cs b/src/Perspex.SceneGraph/Animation/IPageTransition.cs index 50274734b9..92d4e451b2 100644 --- a/src/Perspex.SceneGraph/Animation/IPageTransition.cs +++ b/src/Perspex.SceneGraph/Animation/IPageTransition.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.Threading.Tasks; +using Perspex.VisualTree; namespace Perspex.Animation { diff --git a/src/Perspex.SceneGraph/Animation/PageSlide.cs b/src/Perspex.SceneGraph/Animation/PageSlide.cs index cf145286fc..20fe2fdf76 100644 --- a/src/Perspex.SceneGraph/Animation/PageSlide.cs +++ b/src/Perspex.SceneGraph/Animation/PageSlide.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Reactive.Threading.Tasks; using System.Threading.Tasks; using Perspex.Media; +using Perspex.VisualTree; namespace Perspex.Animation { diff --git a/src/Perspex.SceneGraph/Media/VisualBrush.cs b/src/Perspex.SceneGraph/Media/VisualBrush.cs index 6ba6200074..fe35e32c86 100644 --- a/src/Perspex.SceneGraph/Media/VisualBrush.cs +++ b/src/Perspex.SceneGraph/Media/VisualBrush.cs @@ -1,6 +1,8 @@ // 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.VisualTree; + namespace Perspex.Media { /// diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index 9f6aa6216e..ab38fb8c0a 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -86,7 +86,7 @@ - + diff --git a/src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs b/src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs index a583bcbc85..c3d83dec19 100644 --- a/src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs +++ b/src/Perspex.SceneGraph/Rendering/IRenderQueueManager.cs @@ -3,6 +3,7 @@ using System; using System.Reactive; +using Perspex.VisualTree; namespace Perspex.Rendering { diff --git a/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs b/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs index bec552302c..c77ba4737f 100644 --- a/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs +++ b/src/Perspex.SceneGraph/Rendering/RenderQueueManager.cs @@ -4,6 +4,7 @@ using System; using System.Reactive; using System.Reactive.Subjects; +using Perspex.VisualTree; namespace Perspex.Rendering { diff --git a/src/Perspex.SceneGraph/Rendering/RendererMixin.cs b/src/Perspex.SceneGraph/Rendering/RendererMixin.cs index 6acb10e6e9..628280bd76 100644 --- a/src/Perspex.SceneGraph/Rendering/RendererMixin.cs +++ b/src/Perspex.SceneGraph/Rendering/RendererMixin.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Perspex.Media; using Perspex.Platform; +using Perspex.VisualTree; namespace Perspex.Rendering { diff --git a/src/Perspex.SceneGraph/IVisual.cs b/src/Perspex.SceneGraph/VisualTree/IVisual.cs similarity index 98% rename from src/Perspex.SceneGraph/IVisual.cs rename to src/Perspex.SceneGraph/VisualTree/IVisual.cs index de14703144..2cad9cf757 100644 --- a/src/Perspex.SceneGraph/IVisual.cs +++ b/src/Perspex.SceneGraph/VisualTree/IVisual.cs @@ -4,9 +4,8 @@ using System; using Perspex.Collections; using Perspex.Media; -using Perspex.VisualTree; -namespace Perspex +namespace Perspex.VisualTree { /// /// Represents a node in the visual scene graph. diff --git a/tests/Perspex.Controls.UnitTests/TestTemplatedControl.cs b/tests/Perspex.Controls.UnitTests/TestTemplatedControl.cs index 56f2ca8b3b..84146ed432 100644 --- a/tests/Perspex.Controls.UnitTests/TestTemplatedControl.cs +++ b/tests/Perspex.Controls.UnitTests/TestTemplatedControl.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using Perspex.Controls.Primitives; +using Perspex.VisualTree; namespace Perspex.Controls.UnitTests { diff --git a/tests/Perspex.Controls.UnitTests/Utils/AncestorFinderTests.cs b/tests/Perspex.Controls.UnitTests/Utils/AncestorFinderTests.cs index d44d42edb4..0adf9ebd53 100644 --- a/tests/Perspex.Controls.UnitTests/Utils/AncestorFinderTests.cs +++ b/tests/Perspex.Controls.UnitTests/Utils/AncestorFinderTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Perspex.Controls.Utils; +using Perspex.VisualTree; using Xunit; namespace Perspex.Controls.UnitTests.Utils diff --git a/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs b/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs index b3ec813f75..7945d944ac 100644 --- a/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs +++ b/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs @@ -18,6 +18,7 @@ using Perspex.Rendering; using Perspex.Shared.PlatformSupport; using Perspex.Styling; using Perspex.Themes.Default; +using Perspex.VisualTree; using Ploeh.AutoFixture; using Ploeh.AutoFixture.AutoMoq; using Xunit; diff --git a/tests/Perspex.SceneGraph.UnitTests/TestVisual.cs b/tests/Perspex.SceneGraph.UnitTests/TestVisual.cs index 21a4427fbc..7ef0296b03 100644 --- a/tests/Perspex.SceneGraph.UnitTests/TestVisual.cs +++ b/tests/Perspex.SceneGraph.UnitTests/TestVisual.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Perspex.Rendering; +using Perspex.VisualTree; namespace Perspex.SceneGraph.UnitTests { diff --git a/tests/Perspex.Styling.UnitTests/SelectorTests_Multiple.cs b/tests/Perspex.Styling.UnitTests/SelectorTests_Multiple.cs index 89cd535338..9b407a6de3 100644 --- a/tests/Perspex.Styling.UnitTests/SelectorTests_Multiple.cs +++ b/tests/Perspex.Styling.UnitTests/SelectorTests_Multiple.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using Perspex.Controls; using Perspex.Controls.Templates; +using Perspex.VisualTree; using Xunit; namespace Perspex.Styling.UnitTests From 81065f1d24870d81b228af8459a47a7093d282c2 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 23:21:05 +0100 Subject: [PATCH 06/38] Added logical tree attachment events to ILogical. --- src/Markup/Perspex.Markup/ControlLocator.cs | 1 + src/Perspex.Controls/DropDown.cs | 1 + src/Perspex.Controls/Perspex.Controls.csproj | 1 - src/Perspex.Controls/TextBlock.cs | 1 + src/Perspex.Styling/LogicalTree/ILogical.cs | 11 +++++++++++ .../LogicalTree}/LogicalTreeAttachmentEventArgs.cs | 6 +++--- src/Perspex.Styling/Perspex.Styling.csproj | 1 + 7 files changed, 18 insertions(+), 4 deletions(-) rename src/{Perspex.Controls => Perspex.Styling/LogicalTree}/LogicalTreeAttachmentEventArgs.cs (82%) diff --git a/src/Markup/Perspex.Markup/ControlLocator.cs b/src/Markup/Perspex.Markup/ControlLocator.cs index 730c4d24f9..b6080ae059 100644 --- a/src/Markup/Perspex.Markup/ControlLocator.cs +++ b/src/Markup/Perspex.Markup/ControlLocator.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.Reactive.Linq; using Perspex.Controls; +using Perspex.LogicalTree; namespace Perspex.Markup { diff --git a/src/Perspex.Controls/DropDown.cs b/src/Perspex.Controls/DropDown.cs index 7f8c1789ee..b9211caddd 100644 --- a/src/Perspex.Controls/DropDown.cs +++ b/src/Perspex.Controls/DropDown.cs @@ -7,6 +7,7 @@ using Perspex.Controls.Primitives; using Perspex.Controls.Shapes; using Perspex.Input; using Perspex.Layout; +using Perspex.LogicalTree; using Perspex.Media; using Perspex.VisualTree; diff --git a/src/Perspex.Controls/Perspex.Controls.csproj b/src/Perspex.Controls/Perspex.Controls.csproj index 58aee7f2a5..07cd25039b 100644 --- a/src/Perspex.Controls/Perspex.Controls.csproj +++ b/src/Perspex.Controls/Perspex.Controls.csproj @@ -164,7 +164,6 @@ - diff --git a/src/Perspex.Controls/TextBlock.cs b/src/Perspex.Controls/TextBlock.cs index 29a760b11f..cf9ce6b919 100644 --- a/src/Perspex.Controls/TextBlock.cs +++ b/src/Perspex.Controls/TextBlock.cs @@ -5,6 +5,7 @@ using System; using System.Reactive; using System.Reactive.Linq; using Perspex.Data; +using Perspex.LogicalTree; using Perspex.Media; using Perspex.Metadata; diff --git a/src/Perspex.Styling/LogicalTree/ILogical.cs b/src/Perspex.Styling/LogicalTree/ILogical.cs index 2d3faa2020..5eb4b42abf 100644 --- a/src/Perspex.Styling/LogicalTree/ILogical.cs +++ b/src/Perspex.Styling/LogicalTree/ILogical.cs @@ -1,6 +1,7 @@ // 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 Perspex.Collections; namespace Perspex.LogicalTree @@ -10,6 +11,16 @@ namespace Perspex.LogicalTree /// public interface ILogical { + /// + /// Raised when the control is attached to a rooted logical tree. + /// + event EventHandler AttachedToLogicalTree; + + /// + /// Raised when the control is detached from a rooted logical tree. + /// + event EventHandler DetachedFromLogicalTree; + /// /// Gets a value indicating whether the element is attached to a rooted logical tree. /// diff --git a/src/Perspex.Controls/LogicalTreeAttachmentEventArgs.cs b/src/Perspex.Styling/LogicalTree/LogicalTreeAttachmentEventArgs.cs similarity index 82% rename from src/Perspex.Controls/LogicalTreeAttachmentEventArgs.cs rename to src/Perspex.Styling/LogicalTree/LogicalTreeAttachmentEventArgs.cs index 024942cf71..0ccfad830e 100644 --- a/src/Perspex.Controls/LogicalTreeAttachmentEventArgs.cs +++ b/src/Perspex.Styling/LogicalTree/LogicalTreeAttachmentEventArgs.cs @@ -4,11 +4,11 @@ using System; using Perspex.Styling; -namespace Perspex.Controls +namespace Perspex.LogicalTree { /// - /// Holds the event arguments for the and - /// events. + /// Holds the event arguments for the and + /// events. /// public class LogicalTreeAttachmentEventArgs : EventArgs { diff --git a/src/Perspex.Styling/Perspex.Styling.csproj b/src/Perspex.Styling/Perspex.Styling.csproj index 39ed053d7b..2219312704 100644 --- a/src/Perspex.Styling/Perspex.Styling.csproj +++ b/src/Perspex.Styling/Perspex.Styling.csproj @@ -45,6 +45,7 @@ + From be8e650184414b1a9693b917303565e5e5117f8e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 23:26:27 +0100 Subject: [PATCH 07/38] Fix non-compiling tests. --- tests/Perspex.Interactivity.UnitTests/InteractiveTests.cs | 1 + tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs | 2 ++ tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs | 2 ++ 3 files changed, 5 insertions(+) diff --git a/tests/Perspex.Interactivity.UnitTests/InteractiveTests.cs b/tests/Perspex.Interactivity.UnitTests/InteractiveTests.cs index 7946f96523..7dfeda83cf 100644 --- a/tests/Perspex.Interactivity.UnitTests/InteractiveTests.cs +++ b/tests/Perspex.Interactivity.UnitTests/InteractiveTests.cs @@ -385,6 +385,7 @@ namespace Perspex.Interactivity.UnitTests private class TestInteractive : Interactive { public bool ClassHandlerInvoked { get; private set; } + public string Name { get; set; } public IEnumerable Children { diff --git a/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs b/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs index 3d58006145..1e11fcfeb9 100644 --- a/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs +++ b/tests/Perspex.Styling.UnitTests/SelectorTests_Child.cs @@ -80,6 +80,8 @@ namespace Perspex.Styling.UnitTests } public event EventHandler PropertyChanged; + public event EventHandler AttachedToLogicalTree; + public event EventHandler DetachedFromLogicalTree; public Classes Classes { get; } diff --git a/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs b/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs index 7e1bd429d1..c6749fd58e 100644 --- a/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs +++ b/tests/Perspex.Styling.UnitTests/SelectorTests_Descendent.cs @@ -111,6 +111,8 @@ namespace Perspex.Styling.UnitTests } public event EventHandler PropertyChanged; + public event EventHandler AttachedToLogicalTree; + public event EventHandler DetachedFromLogicalTree; public Classes Classes { get; } From 663b1fe4908d7ae657426abfb86ca33f16d761e7 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 23:26:50 +0100 Subject: [PATCH 08/38] Moved Name to Control. --- src/Perspex.Controls/Control.cs | 39 ++++++++++++++++++++++++++++- src/Perspex.SceneGraph/Visual.cs | 43 +------------------------------- 2 files changed, 39 insertions(+), 43 deletions(-) diff --git a/src/Perspex.Controls/Control.cs b/src/Perspex.Controls/Control.cs index badec4b788..d6f3cd9d2e 100644 --- a/src/Perspex.Controls/Control.cs +++ b/src/Perspex.Controls/Control.cs @@ -31,7 +31,7 @@ namespace Perspex.Controls /// - Implements to allow styling to work on the control. /// - Implements to form part of a logical tree. /// - public class Control : InputElement, IControl, ISetLogicalParent + public class Control : InputElement, IControl, INamed, ISetLogicalParent { /// /// Defines the property. @@ -48,6 +48,12 @@ namespace Perspex.Controls public static readonly StyledProperty> FocusAdornerProperty = PerspexProperty.Register>(nameof(FocusAdorner)); + /// + /// Defines the property. + /// + public static readonly DirectProperty NameProperty = + PerspexProperty.RegisterDirect(nameof(Name), o => o.Name, (o, v) => o.Name = v); + /// /// Defines the property. /// @@ -78,6 +84,7 @@ namespace Perspex.Controls public static readonly RoutedEvent RequestBringIntoViewEvent = RoutedEvent.Register("RequestBringIntoView", RoutingStrategies.Bubble); + private string _name; private IControl _parent; private readonly Classes _classes = new Classes(); private DataTemplates _dataTemplates; @@ -126,6 +133,36 @@ namespace Perspex.Controls /// public event EventHandler DataContextChanged; + /// + /// Gets or sets the name of the control. + /// + /// + /// An element's name is used to uniquely identify a control within the control's name + /// scope. Once the element is added to a logical tree, its name cannot be changed. + /// + public string Name + { + get + { + return _name; + } + + set + { + if (value.Trim() == string.Empty) + { + throw new InvalidOperationException("Cannot set Name to empty string."); + } + + if (VisualRoot != null) + { + throw new InvalidOperationException("Cannot set Name : control already added to tree."); + } + + _name = value; + } + } + /// /// Gets or sets the control's classes. /// diff --git a/src/Perspex.SceneGraph/Visual.cs b/src/Perspex.SceneGraph/Visual.cs index fb4a3f28a9..575f555617 100644 --- a/src/Perspex.SceneGraph/Visual.cs +++ b/src/Perspex.SceneGraph/Visual.cs @@ -27,7 +27,7 @@ namespace Perspex /// To traverse the scene graph (aka Visual Tree), use the extension methods defined /// in . /// - public class Visual : Animatable, IVisual, INamed + public class Visual : Animatable, IVisual { /// /// Defines the property. @@ -47,12 +47,6 @@ namespace Perspex public static readonly StyledProperty IsVisibleProperty = PerspexProperty.Register(nameof(IsVisible), true); - /// - /// Defines the property. - /// - public static readonly DirectProperty NameProperty = - PerspexProperty.RegisterDirect(nameof(Name), o => o.Name, (o, v) => o.Name = v); - /// /// Defines the property. /// @@ -83,11 +77,6 @@ namespace Perspex public static readonly StyledProperty ZIndexProperty = PerspexProperty.Register(nameof(ZIndex)); - /// - /// The name of the visual, if any. - /// - private string _name; - /// /// The visual's bounds relative to its parent. /// @@ -176,36 +165,6 @@ namespace Perspex set { SetValue(IsVisibleProperty, value); } } - /// - /// Gets or sets the name of the visual. - /// - /// - /// An element's name is used to uniquely identify a control within the control's name - /// scope. Once the element is added to a visual tree, its name cannot be changed. - /// - public string Name - { - get - { - return _name; - } - - set - { - if (value.Trim() == string.Empty) - { - throw new InvalidOperationException("Cannot set Name to empty string."); - } - - if (VisualRoot != null) - { - throw new InvalidOperationException("Cannot set Name : control already added to tree."); - } - - _name = value; - } - } - /// /// Gets the opacity of the scene graph node. /// From d7baf6fef676e6db3ab2a1c719f11d367a963c23 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 23:27:28 +0100 Subject: [PATCH 09/38] Fix name on addition to logical tree. --- src/Perspex.Controls/Control.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perspex.Controls/Control.cs b/src/Perspex.Controls/Control.cs index d6f3cd9d2e..fe97dc072e 100644 --- a/src/Perspex.Controls/Control.cs +++ b/src/Perspex.Controls/Control.cs @@ -154,7 +154,7 @@ namespace Perspex.Controls throw new InvalidOperationException("Cannot set Name to empty string."); } - if (VisualRoot != null) + if (_isAttachedToLogicalTree) { throw new InvalidOperationException("Cannot set Name : control already added to tree."); } From cae6868b0284bf42051914e7799aca8bc0789d92 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 18 Feb 2016 23:41:52 +0100 Subject: [PATCH 10/38] Hacked around OmniXAML issue #84. --- .../StyleResourceExtension.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs index c1acd8cbff..1f406e8d37 100644 --- a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs +++ b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using System.Reactive.Linq; using OmniXaml; using Perspex.LogicalTree; using Perspex.Styling; @@ -25,7 +26,26 @@ namespace Perspex.Markup.Xaml.MarkupExtensions $"StyleResource cannot be assigned to an object of type '{styleHost.GetType()}'."); } - return styleHost.FindStyleResource(Name); + // HACK: This should be as simple as: + // return styleHost.FindStyleResource(Name); + // Waiting on OmniXAML issue #84 to be fixed before it can be that simple though. + var po = (PerspexObject)styleHost; + var parent = PerspexPropertyRegistry.Instance.FindRegistered(po, "Parent"); + + po.GetObservable(parent) + .Where(x => x != PerspexProperty.UnsetValue && x != null) + .Take(1) + .Subscribe(_ => + { + var resource = styleHost.FindStyleResource(Name); + + if (resource != PerspexProperty.UnsetValue) + { + extensionContext.TargetProperty.SetValue(extensionContext.TargetObject, resource); + } + }); + + return PerspexProperty.UnsetValue; } public string Name { get; set; } From 5348c23e4b1f838899c2cc63cabb3d7688a9b193 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 19 Feb 2016 00:28:15 +0100 Subject: [PATCH 11/38] Fixed NullReferenceExceptions. --- .../Converters/PerspexPropertyTypeConverter.cs | 2 +- .../MarkupExtensions/StyleResourceExtension.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/PerspexPropertyTypeConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/PerspexPropertyTypeConverter.cs index 520f8aa347..9d08195789 100644 --- a/src/Markup/Perspex.Markup.Xaml/Converters/PerspexPropertyTypeConverter.cs +++ b/src/Markup/Perspex.Markup.Xaml/Converters/PerspexPropertyTypeConverter.cs @@ -36,7 +36,7 @@ namespace Perspex.Markup.Xaml.Converters { var styleType = context.TypeRepository.GetByType(typeof(Style)); var style = (Style)context.TopDownValueContext.GetLastInstance(styleType); - type = style.Selector.TargetType; + type = style.Selector?.TargetType; if (type == null) { diff --git a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs index 1f406e8d37..1a1e5f12eb 100644 --- a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs +++ b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs @@ -23,7 +23,7 @@ namespace Perspex.Markup.Xaml.MarkupExtensions if (styleHost == null) { throw new ParseException( - $"StyleResource cannot be assigned to an object of type '{styleHost.GetType()}'."); + $"StyleResource cannot be assigned to an object of type '{extensionContext.TargetObject.GetType()}'."); } // HACK: This should be as simple as: From d1cbc3fa22d694f842d3a4600b879bbca364ea31 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 19 Feb 2016 00:28:49 +0100 Subject: [PATCH 12/38] Added failing test. --- .../StyleTests.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs index 9eb0309b42..321ac355fc 100644 --- a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs +++ b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs @@ -88,6 +88,32 @@ namespace Perspex.Markup.Xaml.UnitTests Assert.Equal(0xff506070, brush.Color.ToUint32()); } + [Fact] + public void StyleResource_Can_Be_Assigned_To_Setter() + { + var xaml = @" + + + + + +"; + + var loader = new PerspexXamlLoader(); + var userControl = (UserControl)loader.Load(xaml); + var style = (Style)userControl.Styles[1]; + var setter = (Setter)style.Setters.Single(); + + Assert.NotNull(setter.Value); + } + [Fact] public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound() { From f62f32c83c8b620cb9940b2438352ca198faba2e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 19 Feb 2016 17:53:05 +0100 Subject: [PATCH 13/38] Allow {StyleResource} in setter. --- .../Data/StyleResourceBinding.cs | 87 +++++++++++++++++++ .../StyleResourceExtension.cs | 30 +------ src/Markup/Perspex.Markup.Xaml/OmniXAML | 2 +- .../Perspex.Markup.Xaml.csproj | 1 + .../StyleTests.cs | 32 ++++--- 5 files changed, 111 insertions(+), 41 deletions(-) create mode 100644 src/Markup/Perspex.Markup.Xaml/Data/StyleResourceBinding.cs diff --git a/src/Markup/Perspex.Markup.Xaml/Data/StyleResourceBinding.cs b/src/Markup/Perspex.Markup.Xaml/Data/StyleResourceBinding.cs new file mode 100644 index 0000000000..f1c897dfd9 --- /dev/null +++ b/src/Markup/Perspex.Markup.Xaml/Data/StyleResourceBinding.cs @@ -0,0 +1,87 @@ +// 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.Reactive.Disposables; +using System.Reactive.Linq; +using System.Reactive.Subjects; +using Perspex.Data; +using Perspex.Styling; + +namespace Perspex.Markup.Xaml.Data +{ + public class StyleResourceBinding : IBinding + { + /// + /// Initializes a new instance of the class. + /// + /// The resource name. + public StyleResourceBinding(string name) + { + Name = name; + } + + /// + public BindingMode Mode => BindingMode.OneTime; + + /// + /// Gets the resource name. + /// + public string Name { get; } + + /// + public BindingPriority Priority => BindingPriority.LocalValue; + + /// + public ISubject CreateSubject(IPerspexObject target, PerspexProperty targetProperty) + { + return new Subject(target, Name); + } + + private class Subject : ISubject + { + private IPerspexObject _target; + private string _name; + + public Subject(IPerspexObject target, string name) + { + _target = target; + _name = name; + } + + public void OnCompleted() + { + } + + public void OnError(Exception error) + { + } + + public void OnNext(object value) + { + } + + public IDisposable Subscribe(IObserver observer) + { + // HACK around OmniXAML issue #84. + var po = (PerspexObject)_target; + var parent = PerspexPropertyRegistry.Instance.FindRegistered(po, "Parent"); + + return po.GetObservable(parent) + .Where(x => x != PerspexProperty.UnsetValue && x != null) + .Take(1) + .Subscribe(_ => + { + var resource = ((IStyleHost)_target).FindStyleResource(_name); + + if (resource != PerspexProperty.UnsetValue) + { + observer.OnNext(resource); + } + + observer.OnCompleted(); + }); + } + } + } +} diff --git a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs index 1a1e5f12eb..48bec12be2 100644 --- a/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs +++ b/src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs @@ -5,6 +5,7 @@ using System; using System.Reactive.Linq; using OmniXaml; using Perspex.LogicalTree; +using Perspex.Markup.Xaml.Data; using Perspex.Styling; namespace Perspex.Markup.Xaml.MarkupExtensions @@ -18,34 +19,7 @@ namespace Perspex.Markup.Xaml.MarkupExtensions public override object ProvideValue(MarkupExtensionContext extensionContext) { - var styleHost = extensionContext.TargetObject as IStyleHost; - - if (styleHost == null) - { - throw new ParseException( - $"StyleResource cannot be assigned to an object of type '{extensionContext.TargetObject.GetType()}'."); - } - - // HACK: This should be as simple as: - // return styleHost.FindStyleResource(Name); - // Waiting on OmniXAML issue #84 to be fixed before it can be that simple though. - var po = (PerspexObject)styleHost; - var parent = PerspexPropertyRegistry.Instance.FindRegistered(po, "Parent"); - - po.GetObservable(parent) - .Where(x => x != PerspexProperty.UnsetValue && x != null) - .Take(1) - .Subscribe(_ => - { - var resource = styleHost.FindStyleResource(Name); - - if (resource != PerspexProperty.UnsetValue) - { - extensionContext.TargetProperty.SetValue(extensionContext.TargetObject, resource); - } - }); - - return PerspexProperty.UnsetValue; + return new StyleResourceBinding(this.Name); } public string Name { get; set; } diff --git a/src/Markup/Perspex.Markup.Xaml/OmniXAML b/src/Markup/Perspex.Markup.Xaml/OmniXAML index e1a5fb60b0..2b41f290bd 160000 --- a/src/Markup/Perspex.Markup.Xaml/OmniXAML +++ b/src/Markup/Perspex.Markup.Xaml/OmniXAML @@ -1 +1 @@ -Subproject commit e1a5fb60b09862183ba5c48c36a52bea7a66bd42 +Subproject commit 2b41f290bdf4dce07730a8f55622a637f966945b diff --git a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj index 35aff8a3a2..830eb87498 100644 --- a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj +++ b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj @@ -78,6 +78,7 @@ + diff --git a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs index 321ac355fc..8fa212c17a 100644 --- a/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs +++ b/tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Reactive.Linq; using Perspex.Controls; using Perspex.Data; +using Perspex.Input; using Perspex.Markup.Xaml.Data; using Perspex.Media; using Perspex.Styling; @@ -91,27 +92,34 @@ namespace Perspex.Markup.Xaml.UnitTests [Fact] public void StyleResource_Can_Be_Assigned_To_Setter() { - var xaml = @" - - + // For some reason this type can't always be found if we don't do this. + var hack = typeof(KeyboardNavigation); + + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" + + - -"; + +