diff --git a/Perspex.UnitTests/Perspex.UnitTests.csproj b/Perspex.UnitTests/Perspex.UnitTests.csproj index e2fea584b7..a990c1c6cb 100644 --- a/Perspex.UnitTests/Perspex.UnitTests.csproj +++ b/Perspex.UnitTests/Perspex.UnitTests.csproj @@ -75,7 +75,6 @@ - diff --git a/Perspex.UnitTests/Styling/SelectorTests_Id.cs b/Perspex.UnitTests/Styling/SelectorTests_Id.cs index 4c186b5762..b54ca0978f 100644 --- a/Perspex.UnitTests/Styling/SelectorTests_Id.cs +++ b/Perspex.UnitTests/Styling/SelectorTests_Id.cs @@ -44,15 +44,6 @@ namespace Perspex.UnitTests.Styling CollectionAssert.AreEqual(new[] { false }, target.GetActivator().Take(1).ToEnumerable().ToArray()); } - [TestMethod] - public void Id_Matches_Control_With_TemplatedParent_After_InTemplateOf() - { - var control = new Control1 { Id = "foo", TemplatedParent = new TemplatedControl1() }; - var target = control.Select().InTemplateOf().Id("foo"); - - CollectionAssert.AreEqual(new[] { true }, target.GetActivator().Take(1).ToEnumerable().ToArray()); - } - [TestMethod] public void When_Id_Matches_Control_Other_Selectors_Are_Subscribed() { diff --git a/Perspex.Windows/Renderer.cs b/Perspex.Windows/Renderer.cs index 00a669f73a..dd97d0b05a 100644 --- a/Perspex.Windows/Renderer.cs +++ b/Perspex.Windows/Renderer.cs @@ -71,7 +71,7 @@ namespace Perspex.Windows /// Renders the specified visual. /// /// The visual to render. - public void Render(Visual visual) + public void Render(IVisual visual) { using (DrawingContext context = new DrawingContext(this.renderTarget, this.DirectWriteFactory)) { @@ -94,7 +94,7 @@ namespace Perspex.Windows /// /// The visual to render. /// The drawing context. - private void Render(Visual visual, DrawingContext context) + private void Render(IVisual visual, DrawingContext context) { visual.Render(context); diff --git a/Perspex.Windows/Window.cs b/Perspex.Windows/Window.cs index 4727dffce3..6d2cffdaaf 100644 --- a/Perspex.Windows/Window.cs +++ b/Perspex.Windows/Window.cs @@ -164,7 +164,7 @@ namespace Perspex.Windows control.IsMouseOver = visual.Bounds.Contains(p); } - foreach (Visual child in visual.VisualChildren) + foreach (Visual child in ((IVisual)visual).VisualChildren) { this.MouseMove(child, p - visual.Bounds.Position); } diff --git a/Perspex/ControlTemplate.cs b/Perspex/ControlTemplate.cs index 1d22e2d775..35151b90d5 100644 --- a/Perspex/ControlTemplate.cs +++ b/Perspex/ControlTemplate.cs @@ -46,7 +46,7 @@ namespace Perspex control.TemplatedParent = templatedParent; - foreach (Control child in control.VisualChildren.OfType()) + foreach (Control child in ((IVisual)control).VisualChildren.OfType()) { this.SetTemplatedParent(child, templatedParent); } diff --git a/Perspex/Controls/ContentControl.cs b/Perspex/Controls/ContentControl.cs index a84daaabcd..adefd89cfc 100644 --- a/Perspex/Controls/ContentControl.cs +++ b/Perspex/Controls/ContentControl.cs @@ -24,7 +24,7 @@ namespace Perspex.Controls if (control != null) { - control.VisualParent = this; + ((IVisual)control).VisualParent = this; control.SetValue(ParentPropertyRW, this); } }); @@ -38,7 +38,7 @@ namespace Perspex.Controls protected override Size ArrangeContent(Size finalSize) { - Control child = this.VisualChildren.SingleOrDefault() as Control; + Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; if (child != null) { @@ -53,7 +53,7 @@ namespace Perspex.Controls protected override Size MeasureContent(Size availableSize) { - Control child = this.VisualChildren.SingleOrDefault() as Control; + Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; if (child != null) { diff --git a/Perspex/Controls/ContentPresenter.cs b/Perspex/Controls/ContentPresenter.cs index 641363ff92..4227db97a4 100644 --- a/Perspex/Controls/ContentPresenter.cs +++ b/Perspex/Controls/ContentPresenter.cs @@ -11,7 +11,7 @@ namespace Perspex.Controls using System.Linq; using Perspex.Media; - public class ContentPresenter : Control + public class ContentPresenter : Control, IVisual { public static readonly PerspexProperty ContentProperty = ContentControl.ContentProperty.AddOwner(); @@ -33,7 +33,7 @@ namespace Perspex.Controls set { this.SetValue(DataTemplateProperty, value); } } - public override IEnumerable VisualChildren + IEnumerable IVisual.VisualChildren { get { @@ -60,7 +60,7 @@ namespace Perspex.Controls if (this.visualChild != null) { - this.visualChild.VisualParent = this; + ((IVisual)this.visualChild).VisualParent = this; } } @@ -70,7 +70,7 @@ namespace Perspex.Controls protected override Size ArrangeContent(Size finalSize) { - Control child = this.VisualChildren.SingleOrDefault() as Control; + Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; if (child != null) { @@ -127,7 +127,7 @@ namespace Perspex.Controls protected override Size MeasureContent(Size availableSize) { - Control child = this.VisualChildren.SingleOrDefault() as Control; + Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control; if (child != null) { diff --git a/Perspex/Controls/Control.cs b/Perspex/Controls/Control.cs index ffddaf1a38..d149c8f4c4 100644 --- a/Perspex/Controls/Control.cs +++ b/Perspex/Controls/Control.cs @@ -192,7 +192,7 @@ namespace Perspex.Controls throw new InvalidOperationException("ID already set."); } - if (this.VisualParent != null) + if (((IVisual)this).VisualParent != null) { throw new InvalidOperationException("Cannot set ID : control already added to tree."); } diff --git a/Perspex/Controls/Decorator.cs b/Perspex/Controls/Decorator.cs index 7e5a28d3e3..3d06bcfeba 100644 --- a/Perspex/Controls/Decorator.cs +++ b/Perspex/Controls/Decorator.cs @@ -9,8 +9,9 @@ namespace Perspex.Controls using System; using System.Collections.Generic; using System.Linq; + using System.Reactive.Linq; - public abstract class Decorator : Control + public abstract class Decorator : Control, IVisual { public static readonly PerspexProperty ContentProperty = PerspexProperty.Register("Content"); @@ -21,7 +22,7 @@ namespace Perspex.Controls public Decorator() { // TODO: Unset old content's visual parent. - this.GetObservable(ContentProperty).Subscribe(x => + this.GetObservable(ContentProperty).OfType().Subscribe(x => { if (x != null) { @@ -42,7 +43,7 @@ namespace Perspex.Controls set { this.SetValue(PaddingProperty, value); } } - public override IEnumerable VisualChildren + IEnumerable IVisual.VisualChildren { get { diff --git a/Perspex/Controls/TemplatedControl.cs b/Perspex/Controls/TemplatedControl.cs index bd3b8a102a..e5df95b01d 100644 --- a/Perspex/Controls/TemplatedControl.cs +++ b/Perspex/Controls/TemplatedControl.cs @@ -11,12 +11,12 @@ namespace Perspex.Controls using System.Linq; using Perspex.Media; - public abstract class TemplatedControl : Control, ITemplatedControl + public abstract class TemplatedControl : Control, IVisual, ITemplatedControl { public static readonly PerspexProperty TemplateProperty = PerspexProperty.Register("Template"); - private Visual visualChild; + private IVisual visualChild; public ControlTemplate Template { @@ -24,7 +24,7 @@ namespace Perspex.Controls set { this.SetValue(TemplateProperty, value); } } - public override IEnumerable VisualChildren + IEnumerable ITemplatedControl.VisualChildren { get { @@ -40,6 +40,11 @@ namespace Perspex.Controls } } + IEnumerable IVisual.VisualChildren + { + get { return ((ITemplatedControl)this).VisualChildren; } + } + public sealed override void Render(IDrawingContext context) { } diff --git a/Perspex/ILogical.cs b/Perspex/ILogical.cs new file mode 100644 index 0000000000..20bbf8b7fe --- /dev/null +++ b/Perspex/ILogical.cs @@ -0,0 +1,21 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2014 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + public interface ILogical + { + ILogical LogicalParent { get; set; } + + IEnumerable LogicalChildren { get; } + } +} diff --git a/Perspex/IVisual.cs b/Perspex/IVisual.cs index 1bd69bff5f..182ab1eb1c 100644 --- a/Perspex/IVisual.cs +++ b/Perspex/IVisual.cs @@ -15,8 +15,8 @@ namespace Perspex Rect Bounds { get; } IEnumerable VisualChildren { get; } - - IVisual VisualParent { get; } + + IVisual VisualParent { get; set; } void Render(IDrawingContext context); } diff --git a/Perspex/Perspex.csproj b/Perspex/Perspex.csproj index a924462424..ed6110320c 100644 --- a/Perspex/Perspex.csproj +++ b/Perspex/Perspex.csproj @@ -79,6 +79,7 @@ + diff --git a/Perspex/Properties/AssemblyInfo.cs b/Perspex/Properties/AssemblyInfo.cs index 524a057d81..0dd8327fa8 100644 --- a/Perspex/Properties/AssemblyInfo.cs +++ b/Perspex/Properties/AssemblyInfo.cs @@ -1,5 +1,6 @@ using System.Reflection; using System.Resources; +using System.Runtime.CompilerServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -26,3 +27,5 @@ using System.Resources; // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: InternalsVisibleTo("Perspex.UnitTests")] \ No newline at end of file diff --git a/Perspex/Visual.cs b/Perspex/Visual.cs index 5940521f9d..805bc51467 100644 --- a/Perspex/Visual.cs +++ b/Perspex/Visual.cs @@ -12,8 +12,10 @@ namespace Perspex using System.Linq; using Perspex.Media; - public abstract class Visual : PerspexObject, IVisual + public abstract class Visual : PerspexObject, IVisual, ILogical { + private ILogical logicalParent; + private IVisual visualParent; public Rect Bounds @@ -22,19 +24,30 @@ namespace Perspex protected set; } - public virtual IEnumerable VisualChildren + ILogical ILogical.LogicalParent + { + get { return this.logicalParent; } + set { this.logicalParent = value; } + } + + IEnumerable ILogical.LogicalChildren + { + get { return new ILogical[0]; } + } + + IEnumerable IVisual.VisualChildren { get { return Enumerable.Empty(); } } - public IVisual VisualParent + IVisual IVisual.VisualParent { get { - return this.visualParent; + return this.visualParent; } - internal set + set { if (this.visualParent != value) {