From 486863f7953374b2661f2df1ea6f37596965fcb6 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 28 Mar 2014 05:30:25 +0100 Subject: [PATCH] Added StyleTrigger binding priority. This allows :mouseover etc to override the value that comes from the templated parent. --- .../Controls/ContentControlTests.cs | 2 +- .../Styling/SelectorTests_Class.cs | 9 +++++++++ Perspex.UnitTests/Styling/SelectorTests_Id.cs | 9 +++++++++ .../Styling/SelectorTests_OfType.cs | 9 +++++++++ Perspex/PerspexObject.cs | 19 +++++++++++++++---- Perspex/Styling/Selector.cs | 16 ++++++++++++++++ Perspex/Styling/Selectors.cs | 2 +- Perspex/Styling/Style.cs | 2 +- Perspex/Themes/Default/ButtonStyle.cs | 4 ++-- 9 files changed, 63 insertions(+), 9 deletions(-) diff --git a/Perspex.UnitTests/Controls/ContentControlTests.cs b/Perspex.UnitTests/Controls/ContentControlTests.cs index 5c42fc3a5a..027139b0ae 100644 --- a/Perspex.UnitTests/Controls/ContentControlTests.cs +++ b/Perspex.UnitTests/Controls/ContentControlTests.cs @@ -74,7 +74,7 @@ namespace Perspex.UnitTests.Controls contentPresenter.Bind( ContentPresenter.ContentProperty, parent.GetObservable(ContentControl.ContentProperty), - BindingPriority.Template); + BindingPriority.TemplatedParent); border.Content = contentPresenter; return border; }); diff --git a/Perspex.UnitTests/Styling/SelectorTests_Class.cs b/Perspex.UnitTests/Styling/SelectorTests_Class.cs index 63b19a82b1..9c2fcd4eb0 100644 --- a/Perspex.UnitTests/Styling/SelectorTests_Class.cs +++ b/Perspex.UnitTests/Styling/SelectorTests_Class.cs @@ -16,6 +16,15 @@ namespace Perspex.UnitTests.Styling [TestClass] public class SelectorTests_Class { + [TestMethod] + public void Class_Priority_Is_StyleTrigger() + { + var control = new Control1(); + var target = new Selector().Class("foo"); + + Assert.AreEqual(BindingPriority.StyleTrigger, target.Priority); + } + [TestMethod] public void Class_Matches_Control_With_Class() { diff --git a/Perspex.UnitTests/Styling/SelectorTests_Id.cs b/Perspex.UnitTests/Styling/SelectorTests_Id.cs index 505208c3eb..65a8d0b574 100644 --- a/Perspex.UnitTests/Styling/SelectorTests_Id.cs +++ b/Perspex.UnitTests/Styling/SelectorTests_Id.cs @@ -18,6 +18,15 @@ namespace Perspex.UnitTests.Styling [TestClass] public class SelectorTests_Id { + [TestMethod] + public void Id_Priority_Is_Style() + { + var control = new Control1(); + var target = new Selector().Id("foo"); + + Assert.AreEqual(BindingPriority.Style, target.Priority); + } + [TestMethod] public void Id_Matches_Control_With_Correct_Id() { diff --git a/Perspex.UnitTests/Styling/SelectorTests_OfType.cs b/Perspex.UnitTests/Styling/SelectorTests_OfType.cs index 3f33de8966..8f8336c81f 100644 --- a/Perspex.UnitTests/Styling/SelectorTests_OfType.cs +++ b/Perspex.UnitTests/Styling/SelectorTests_OfType.cs @@ -16,6 +16,15 @@ namespace Perspex.UnitTests.Styling [TestClass] public class SelectorTests_OfType { + [TestMethod] + public void OfType_Priority_Is_Style() + { + var control = new Control1(); + var target = new Selector().OfType(); + + Assert.AreEqual(BindingPriority.Style, target.Priority); + } + [TestMethod] public void OfType_Matches_Control_Of_Correct_Type() { diff --git a/Perspex/PerspexObject.cs b/Perspex/PerspexObject.cs index b4aaf0d8c7..6c25359e03 100644 --- a/Perspex/PerspexObject.cs +++ b/Perspex/PerspexObject.cs @@ -24,14 +24,25 @@ namespace Perspex LocalValue, /// - /// A style binding. + /// A triggered style binding. /// - Style, + /// + /// A style trigger is a selector such as .class which overrides a + /// binding. In this way, a basic control can have + /// for example a Background from the templated parent which changes when the + /// control has the :mouseover class. + /// + StyleTrigger, /// - /// A template binding. + /// A binding to a property on the templated parent. /// - Template, + TemplatedParent, + + /// + /// A style binding. + /// + Style, } /// diff --git a/Perspex/Styling/Selector.cs b/Perspex/Styling/Selector.cs index fe44e99e7e..75a44a482b 100644 --- a/Perspex/Styling/Selector.cs +++ b/Perspex/Styling/Selector.cs @@ -20,16 +20,26 @@ namespace Perspex.Styling public Selector() { this.GetObservable = _ => Observable.Return(true); + this.Priority = BindingPriority.Style; } public Selector(Selector previous, bool stopTraversal = false) : this() { this.Previous = previous; + this.Priority = previous.Priority; this.InTemplate = previous != null ? previous.InTemplate : false; this.stopTraversal = stopTraversal; } + public Selector(Selector previous, BindingPriority priority) + : this() + { + this.Previous = previous; + this.Priority = priority; + this.InTemplate = previous != null ? previous.InTemplate : false; + } + public bool InTemplate { get; @@ -48,6 +58,12 @@ namespace Perspex.Styling private set; } + public BindingPriority Priority + { + get; + private set; + } + public string SelectorString { get; diff --git a/Perspex/Styling/Selectors.cs b/Perspex/Styling/Selectors.cs index 2878b4e0ed..a41529e48d 100644 --- a/Perspex/Styling/Selectors.cs +++ b/Perspex/Styling/Selectors.cs @@ -18,7 +18,7 @@ namespace Perspex.Styling Contract.Requires(previous != null); Contract.Requires(name != null); - return new Selector(previous) + return new Selector(previous, BindingPriority.StyleTrigger) { GetObservable = control => Observable .Return(control.Classes.Contains(name)) diff --git a/Perspex/Styling/Style.cs b/Perspex/Styling/Style.cs index 772304528c..74fc8fb2e1 100644 --- a/Perspex/Styling/Style.cs +++ b/Perspex/Styling/Style.cs @@ -48,7 +48,7 @@ namespace Perspex.Styling foreach (Setter setter in this.Setters) { StyleBinding binding = new StyleBinding(activator, setter.Value, description); - control.Bind(setter.Property, binding, BindingPriority.Style); + control.Bind(setter.Property, binding, this.Selector.Priority); } } } diff --git a/Perspex/Themes/Default/ButtonStyle.cs b/Perspex/Themes/Default/ButtonStyle.cs index 06685285af..65cbb74b68 100644 --- a/Perspex/Themes/Default/ButtonStyle.cs +++ b/Perspex/Themes/Default/ButtonStyle.cs @@ -59,13 +59,13 @@ namespace Perspex.Themes.Default border.Bind( Border.BackgroundProperty, control.GetObservable(Button.BackgroundProperty), - BindingPriority.Template); + BindingPriority.TemplatedParent); ContentPresenter contentPresenter = new ContentPresenter(); contentPresenter.Bind( ContentPresenter.ContentProperty, control.GetObservable(Button.ContentProperty), - BindingPriority.Template); + BindingPriority.TemplatedParent); border.Content = contentPresenter; return border;