From 5303eb7cd809655e248cb88bb1c2fad72995330f Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 29 Jul 2015 13:03:50 +0200 Subject: [PATCH] Make all tests pass again. Menus displaying weirdly though. --- Perspex.Base/Collections/IPerspexList.cs | 6 +-- Perspex.Base/Collections/PerspexList.cs | 2 +- Perspex.Controls/DropDown.cs | 1 + Perspex.Controls/Panel.cs | 47 +++---------------- Perspex.Controls/Popup.cs | 32 ++++--------- .../Presenters/ContentPresenter.cs | 13 ++--- Perspex.Controls/Presenters/DeckPresenter.cs | 14 ++---- Perspex.Controls/Primitives/AdornerLayer.cs | 23 +++++---- Perspex.Controls/TabControl.cs | 22 ++------- .../ContentControlTests.cs | 3 +- .../Perspex.Controls.UnitTests/PanelTests.cs | 21 +++++---- .../Perspex.Controls.UnitTests/PopupTests.cs | 6 +-- 12 files changed, 63 insertions(+), 127 deletions(-) diff --git a/Perspex.Base/Collections/IPerspexList.cs b/Perspex.Base/Collections/IPerspexList.cs index 34c6dfe5bc..04e9c2f25e 100644 --- a/Perspex.Base/Collections/IPerspexList.cs +++ b/Perspex.Base/Collections/IPerspexList.cs @@ -9,14 +9,10 @@ namespace Perspex.Collections using System.Collections; using System.Collections.Generic; - public interface IPerspexList : IList, IList, IPerspexReadOnlyList + public interface IPerspexList : IList, IPerspexReadOnlyList { - new int Count { get; } - void AddRange(IEnumerable items); - new void Clear(); - void InsertRange(int index, IEnumerable items); void RemoveAll(IEnumerable items); diff --git a/Perspex.Base/Collections/PerspexList.cs b/Perspex.Base/Collections/PerspexList.cs index 5d4b6ef4e8..1c24a52db7 100644 --- a/Perspex.Base/Collections/PerspexList.cs +++ b/Perspex.Base/Collections/PerspexList.cs @@ -23,7 +23,7 @@ namespace Perspex.Collections /// action, passing the items that were /// removed. /// - public class PerspexList : IPerspexList, INotifyCollectionChanged, INotifyPropertyChanged + public class PerspexList : IPerspexList, IList, INotifyCollectionChanged, INotifyPropertyChanged { private List inner; diff --git a/Perspex.Controls/DropDown.cs b/Perspex.Controls/DropDown.cs index bdc7d9b588..a4d736b9b4 100644 --- a/Perspex.Controls/DropDown.cs +++ b/Perspex.Controls/DropDown.cs @@ -69,6 +69,7 @@ namespace Perspex.Controls protected override void OnTemplateApplied() { var container = this.GetTemplateChild("container"); + ((IReparentingControl)container).ReparentLogicalChildren(this, this.LogicalChildren); } private void SetContentParent(Tuple change) diff --git a/Perspex.Controls/Panel.cs b/Perspex.Controls/Panel.cs index db2b41e1ff..2a35bb7267 100644 --- a/Perspex.Controls/Panel.cs +++ b/Perspex.Controls/Panel.cs @@ -21,7 +21,7 @@ namespace Perspex.Controls /// public class Panel : Control, IReparentingControl { - private Controls children; + private Controls children = new Controls(); private ILogical childLogicalParent; @@ -30,6 +30,7 @@ namespace Perspex.Controls /// public Panel() { + this.children.CollectionChanged += this.ChildrenChanged; this.childLogicalParent = this; } @@ -39,19 +40,13 @@ namespace Perspex.Controls /// /// Even though this property can be set, the setter is only intended for use in object /// initializers. Assigning to this property does not change the underlying collection, - /// it simply clears the existing collection and addds the contents of the assigned + /// it simply clears the existing collection and adds the contents of the assigned /// collection. /// public Controls Children { get { - if (this.children == null) - { - this.children = new Controls(); - this.children.CollectionChanged += this.ChildrenChanged; - } - return this.children; } @@ -59,25 +54,10 @@ namespace Perspex.Controls { Contract.Requires(value != null); - if (this.children != value) - { - if (this.children != null) - { - this.ClearLogicalParent(this.children); - this.children.CollectionChanged -= this.ChildrenChanged; - } - - this.children = value; - this.ClearVisualChildren(); - - if (this.children != null) - { - this.children.CollectionChanged += this.ChildrenChanged; - this.AddVisualChildren(value); - this.SetLogicalParent(value); - this.InvalidateMeasure(); - } - } + this.ClearVisualChildren(); + this.children.Clear(); + this.children.AddRange(value); + this.LogicalChildren.AddRange(value); } } @@ -107,16 +87,6 @@ namespace Perspex.Controls } } - /// - protected virtual void OnChildrenAdded(IEnumerable child) - { - } - - /// - protected virtual void OnChildrenRemoved(IEnumerable child) - { - } - /// /// Clears for the specified controls. /// @@ -160,7 +130,6 @@ namespace Perspex.Controls this.SetLogicalParent(controls); this.AddVisualChildren(e.NewItems.OfType()); this.LogicalChildren.InsertRange(e.NewStartingIndex, controls); - this.OnChildrenAdded(controls); break; case NotifyCollectionChangedAction.Remove: @@ -168,7 +137,6 @@ namespace Perspex.Controls this.ClearLogicalParent(e.OldItems.OfType()); this.LogicalChildren.RemoveAll(controls); this.RemoveVisualChildren(e.OldItems.OfType()); - this.OnChildrenRemoved(controls); break; case NotifyCollectionChangedAction.Reset: @@ -177,7 +145,6 @@ namespace Perspex.Controls this.LogicalChildren.Clear(); this.ClearVisualChildren(); this.AddVisualChildren(this.children); - this.OnChildrenAdded(controls); break; } diff --git a/Perspex.Controls/Popup.cs b/Perspex.Controls/Popup.cs index e73d9b5b55..fb71de2b40 100644 --- a/Perspex.Controls/Popup.cs +++ b/Perspex.Controls/Popup.cs @@ -7,7 +7,6 @@ namespace Perspex.Controls { using System; - using Perspex.Collections; using Perspex.Interactivity; using Perspex.Rendering; using Perspex.VisualTree; @@ -58,27 +57,15 @@ namespace Perspex.Controls /// private TopLevel topLevel; - /// - /// The popup's logical child. - /// - private PerspexSingleItemList logicalChild = new PerspexSingleItemList(); - /// /// Initializes static members of the class. /// static Popup() { + ChildProperty.Changed.AddClassHandler(x => x.ChildChanged); IsOpenProperty.Changed.AddClassHandler(x => x.IsOpenChanged); } - /// - /// Initializes a new instance of the class. - /// - public Popup() - { - this.GetObservableWithHistory(ChildProperty).Subscribe(this.ChildChanged); - } - /// /// Raised when the popup closes. /// @@ -267,20 +254,21 @@ namespace Perspex.Controls /// /// Called when the property changes. /// - /// The old and new values. - private void ChildChanged(Tuple values) + /// The event args. + private void ChildChanged(PerspexPropertyChangedEventArgs e) { - if (values.Item1 != null) + this.LogicalChildren.Clear(); + + if (e.OldValue != null) { - ((ISetLogicalParent)values.Item1).SetParent(null); + ((ISetLogicalParent)e.OldValue).SetParent(null); } - if (values.Item2 != null) + if (e.NewValue != null) { - ((ISetLogicalParent)values.Item2).SetParent(this); + ((ISetLogicalParent)e.NewValue).SetParent(this); + this.LogicalChildren.Add((ILogical)e.NewValue); } - - this.logicalChild.SingleItem = values.Item2; } /// diff --git a/Perspex.Controls/Presenters/ContentPresenter.cs b/Perspex.Controls/Presenters/ContentPresenter.cs index 9b18f6321f..a989ddcc9e 100644 --- a/Perspex.Controls/Presenters/ContentPresenter.cs +++ b/Perspex.Controls/Presenters/ContentPresenter.cs @@ -6,14 +6,11 @@ namespace Perspex.Controls.Presenters { - using System; using System.Linq; using System.Reactive.Linq; - using System.Reactive.Subjects; using Perspex.Collections; using Perspex.Controls.Primitives; using Perspex.Controls.Templates; - using Perspex.Media; /// /// Presents a single item of data inside a template. @@ -116,12 +113,17 @@ namespace Perspex.Controls.Presenters IControl result = null; object content = this.Content; + this.LogicalChildren.Clear(); this.ClearVisualChildren(); if (content != null) { result = this.MaterializeDataTemplate(content); - ((ISetLogicalParent)result).SetParent(this.logicalParent ?? this); + + if (result.Parent == null) + { + ((ISetLogicalParent)result).SetParent(this.logicalParent ?? this); + } var templatedParent = this.TemplatedParent as TemplatedControl; @@ -132,10 +134,9 @@ namespace Perspex.Controls.Presenters ((Control)result).TemplatedParent = templatedParent; this.AddVisualChild(result); + this.LogicalChildren.Add(result); } - this.LogicalChildren.Clear(); - this.LogicalChildren.Add(result); this.createdChild = true; } } diff --git a/Perspex.Controls/Presenters/DeckPresenter.cs b/Perspex.Controls/Presenters/DeckPresenter.cs index e24ea4f024..5f25ffd332 100644 --- a/Perspex.Controls/Presenters/DeckPresenter.cs +++ b/Perspex.Controls/Presenters/DeckPresenter.cs @@ -12,11 +12,10 @@ namespace Perspex.Controls.Presenters using System.Reactive.Linq; using System.Threading.Tasks; using Perspex.Animation; - using Collections; + using Perspex.Collections; using Perspex.Controls.Generators; using Perspex.Controls.Primitives; using Perspex.Controls.Utils; - using Perspex.Styling; /// /// Displays pages inside an . @@ -132,14 +131,6 @@ namespace Perspex.Controls.Presenters set { this.SetValue(TransitionProperty, value); } } - Panel IItemsPresenter.Panel - { - get - { - throw new NotImplementedException(); - } - } - /// public override sealed void ApplyTemplate() { @@ -152,7 +143,8 @@ namespace Perspex.Controls.Presenters /// void IReparentingControl.ReparentLogicalChildren(ILogical logicalParent, IPerspexList children) { - throw new NotImplementedException(); + this.ApplyTemplate(); + ((IReparentingControl)this.Panel).ReparentLogicalChildren(logicalParent, children); } /// diff --git a/Perspex.Controls/Primitives/AdornerLayer.cs b/Perspex.Controls/Primitives/AdornerLayer.cs index db61dae0c5..59ddcc1309 100644 --- a/Perspex.Controls/Primitives/AdornerLayer.cs +++ b/Perspex.Controls/Primitives/AdornerLayer.cs @@ -8,6 +8,7 @@ namespace Perspex.Controls.Primitives { using System; using System.Collections.Generic; + using System.Collections.Specialized; using System.Linq; using Perspex.VisualTree; @@ -28,6 +29,11 @@ namespace Perspex.Controls.Primitives IsHitTestVisibleProperty.OverrideDefaultValue(typeof(AdornerLayer), false); } + public AdornerLayer() + { + this.Children.CollectionChanged += ChildrenCollectionChanged; + } + public static Visual GetAdornedElement(Visual adorner) { return adorner.GetValue(AdornedElementProperty); @@ -67,18 +73,19 @@ namespace Perspex.Controls.Primitives return finalSize; } - protected override void OnChildrenAdded(IEnumerable children) + private void ChildrenCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { - foreach (var i in children) + switch (e.Action) { - this.UpdateAdornedElement(i, i.GetValue(AdornedElementProperty)); - } + case NotifyCollectionChangedAction.Add: + foreach (Visual i in e.NewItems) + { + this.UpdateAdornedElement(i, i.GetValue(AdornedElementProperty)); + } - this.InvalidateArrange(); - } + break; + } - protected override void OnChildrenRemoved(IEnumerable child) - { this.InvalidateArrange(); } diff --git a/Perspex.Controls/TabControl.cs b/Perspex.Controls/TabControl.cs index 0ade29b5c8..e1baf59f09 100644 --- a/Perspex.Controls/TabControl.cs +++ b/Perspex.Controls/TabControl.cs @@ -7,10 +7,8 @@ namespace Perspex.Controls { using Perspex.Animation; - using Perspex.Collections; using Perspex.Controls.Primitives; using Perspex.Controls.Templates; - using Perspex.Input; /// /// A tab control that displays a tab strip along with the content of the selected tab. @@ -35,9 +33,6 @@ namespace Perspex.Controls public static readonly PerspexProperty TransitionProperty = Deck.TransitionProperty.AddOwner(); - private PerspexReadOnlyListView logicalChildren = - new PerspexReadOnlyListView(); - /// /// Initializes static members of the class. /// @@ -48,13 +43,6 @@ namespace Perspex.Controls SelectedIndexProperty.Changed.AddClassHandler(x => x.SelectedIndexChanged); } - /// - /// Initializes a new instance of the class. - /// - public TabControl() - { - } - /// /// Gets the content of the selected tab. /// @@ -82,19 +70,15 @@ namespace Perspex.Controls set { this.SetValue(TransitionProperty, value); } } - /// - protected override void OnKeyDown(KeyEventArgs e) - { - // Don't handle keypresses. - } - /// protected override void OnTemplateApplied() { base.OnTemplateApplied(); var deck = this.GetTemplateChild("deck"); - this.logicalChildren.Source = ((ILogical)deck).LogicalChildren; + ((IReparentingControl)deck.Presenter.Panel).ReparentLogicalChildren( + this, + this.LogicalChildren); } /// diff --git a/Tests/Perspex.Controls.UnitTests/ContentControlTests.cs b/Tests/Perspex.Controls.UnitTests/ContentControlTests.cs index 9bd7003bde..f8c9179a5f 100644 --- a/Tests/Perspex.Controls.UnitTests/ContentControlTests.cs +++ b/Tests/Perspex.Controls.UnitTests/ContentControlTests.cs @@ -242,8 +242,7 @@ namespace Perspex.Controls.UnitTests contentControl.Content = child1; contentControl.ApplyTemplate(); - ((ILogical)contentControl).LogicalChildren.CollectionChanged += (s, e) => - called = e.Action == NotifyCollectionChangedAction.Replace; + ((ILogical)contentControl).LogicalChildren.CollectionChanged += (s, e) => called = true; contentControl.Content = child2; diff --git a/Tests/Perspex.Controls.UnitTests/PanelTests.cs b/Tests/Perspex.Controls.UnitTests/PanelTests.cs index 0b177743e5..d2c7c4d880 100644 --- a/Tests/Perspex.Controls.UnitTests/PanelTests.cs +++ b/Tests/Perspex.Controls.UnitTests/PanelTests.cs @@ -7,7 +7,8 @@ namespace Perspex.Controls.UnitTests { using System.Linq; - using Collections; + using Perspex.Collections; + using Perspex.LogicalTree; using Xunit; public class PanelTests @@ -21,7 +22,7 @@ namespace Perspex.Controls.UnitTests panel.Children.Add(child); Assert.Equal(child.Parent, panel); - Assert.Equal(((ILogical)child).LogicalParent, panel); + Assert.Equal(child.GetLogicalParent(), panel); } [Fact] @@ -33,7 +34,7 @@ namespace Perspex.Controls.UnitTests panel.Children = new Controls { child }; Assert.Equal(child.Parent, panel); - Assert.Equal(((ILogical)child).LogicalParent, panel); + Assert.Equal(child.GetLogicalParent(), panel); } [Fact] @@ -46,7 +47,7 @@ namespace Perspex.Controls.UnitTests panel.Children.Remove(child); Assert.Null(child.Parent); - Assert.Null(((ILogical)child).LogicalParent); + Assert.Null(child.GetLogicalParent()); } [Fact] @@ -61,9 +62,9 @@ namespace Perspex.Controls.UnitTests panel.Children.Clear(); Assert.Null(child1.Parent); - Assert.Null(((ILogical)child1).LogicalParent); + Assert.Null(child1.GetLogicalParent()); Assert.Null(child2.Parent); - Assert.Null(((ILogical)child2).LogicalParent); + Assert.Null(child2.GetLogicalParent()); } [Fact] @@ -78,9 +79,9 @@ namespace Perspex.Controls.UnitTests panel.Children = new Controls(); Assert.Null(child1.Parent); - Assert.Null(((ILogical)child1).LogicalParent); + Assert.Null(child1.GetLogicalParent()); Assert.Null(child2.Parent); - Assert.Null(((ILogical)child2).LogicalParent); + Assert.Null(child2.GetLogicalParent()); } [Fact] @@ -92,7 +93,7 @@ namespace Perspex.Controls.UnitTests panel.Children.Add(child); Assert.Equal(new[] { child }, panel.Children); - Assert.Equal(new[] { child }, ((ILogical)panel).LogicalChildren.ToList()); + Assert.Equal(new[] { child }, panel.GetLogicalChildren()); } [Fact] @@ -105,7 +106,7 @@ namespace Perspex.Controls.UnitTests panel.Children.Remove(child); Assert.Equal(new Control[0], panel.Children); - Assert.Equal(new ILogical[0], ((ILogical)panel).LogicalChildren.ToList()); + Assert.Equal(new ILogical[0], panel.GetLogicalChildren()); } [Fact] diff --git a/Tests/Perspex.Controls.UnitTests/PopupTests.cs b/Tests/Perspex.Controls.UnitTests/PopupTests.cs index 9bf58168c9..0c09e46d7d 100644 --- a/Tests/Perspex.Controls.UnitTests/PopupTests.cs +++ b/Tests/Perspex.Controls.UnitTests/PopupTests.cs @@ -8,6 +8,7 @@ namespace Perspex.Controls.UnitTests { using System.Collections.Specialized; using System.Linq; + using Perspex.LogicalTree; using Xunit; public class PopupTests @@ -45,7 +46,7 @@ namespace Perspex.Controls.UnitTests target.Child = child; - Assert.Equal(new[] { child }, ((ILogical)target).LogicalChildren.ToList()); + Assert.Equal(new[] { child }, target.GetLogicalChildren()); } [Fact] @@ -102,8 +103,7 @@ namespace Perspex.Controls.UnitTests target.Child = child1; - ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => - called = e.Action == NotifyCollectionChangedAction.Replace; + ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true; target.Child = child2;