Browse Source

Make all tests pass again.

Menus displaying weirdly though.
pull/72/merge
Steven Kirk 11 years ago
parent
commit
5303eb7cd8
  1. 6
      Perspex.Base/Collections/IPerspexList.cs
  2. 2
      Perspex.Base/Collections/PerspexList.cs
  3. 1
      Perspex.Controls/DropDown.cs
  4. 47
      Perspex.Controls/Panel.cs
  5. 32
      Perspex.Controls/Popup.cs
  6. 13
      Perspex.Controls/Presenters/ContentPresenter.cs
  7. 14
      Perspex.Controls/Presenters/DeckPresenter.cs
  8. 23
      Perspex.Controls/Primitives/AdornerLayer.cs
  9. 22
      Perspex.Controls/TabControl.cs
  10. 3
      Tests/Perspex.Controls.UnitTests/ContentControlTests.cs
  11. 21
      Tests/Perspex.Controls.UnitTests/PanelTests.cs
  12. 6
      Tests/Perspex.Controls.UnitTests/PopupTests.cs

6
Perspex.Base/Collections/IPerspexList.cs

@ -9,14 +9,10 @@ namespace Perspex.Collections
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
public interface IPerspexList<T> : IList<T>, IList, IPerspexReadOnlyList<T> public interface IPerspexList<T> : IList<T>, IPerspexReadOnlyList<T>
{ {
new int Count { get; }
void AddRange(IEnumerable<T> items); void AddRange(IEnumerable<T> items);
new void Clear();
void InsertRange(int index, IEnumerable<T> items); void InsertRange(int index, IEnumerable<T> items);
void RemoveAll(IEnumerable<T> items); void RemoveAll(IEnumerable<T> items);

2
Perspex.Base/Collections/PerspexList.cs

@ -23,7 +23,7 @@ namespace Perspex.Collections
/// <see cref="NotifyCollectionChangedAction.Remove"/> action, passing the items that were /// <see cref="NotifyCollectionChangedAction.Remove"/> action, passing the items that were
/// removed. /// removed.
/// </remarks> /// </remarks>
public class PerspexList<T> : IPerspexList<T>, INotifyCollectionChanged, INotifyPropertyChanged public class PerspexList<T> : IPerspexList<T>, IList, INotifyCollectionChanged, INotifyPropertyChanged
{ {
private List<T> inner; private List<T> inner;

1
Perspex.Controls/DropDown.cs

@ -69,6 +69,7 @@ namespace Perspex.Controls
protected override void OnTemplateApplied() protected override void OnTemplateApplied()
{ {
var container = this.GetTemplateChild<Panel>("container"); var container = this.GetTemplateChild<Panel>("container");
((IReparentingControl)container).ReparentLogicalChildren(this, this.LogicalChildren);
} }
private void SetContentParent(Tuple<object, object> change) private void SetContentParent(Tuple<object, object> change)

47
Perspex.Controls/Panel.cs

@ -21,7 +21,7 @@ namespace Perspex.Controls
/// </remarks> /// </remarks>
public class Panel : Control, IReparentingControl public class Panel : Control, IReparentingControl
{ {
private Controls children; private Controls children = new Controls();
private ILogical childLogicalParent; private ILogical childLogicalParent;
@ -30,6 +30,7 @@ namespace Perspex.Controls
/// </summary> /// </summary>
public Panel() public Panel()
{ {
this.children.CollectionChanged += this.ChildrenChanged;
this.childLogicalParent = this; this.childLogicalParent = this;
} }
@ -39,19 +40,13 @@ namespace Perspex.Controls
/// <remarks> /// <remarks>
/// Even though this property can be set, the setter is only intended for use in object /// 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, /// 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. /// collection.
/// </remarks> /// </remarks>
public Controls Children public Controls Children
{ {
get get
{ {
if (this.children == null)
{
this.children = new Controls();
this.children.CollectionChanged += this.ChildrenChanged;
}
return this.children; return this.children;
} }
@ -59,25 +54,10 @@ namespace Perspex.Controls
{ {
Contract.Requires<ArgumentNullException>(value != null); Contract.Requires<ArgumentNullException>(value != null);
if (this.children != value) this.ClearVisualChildren();
{ this.children.Clear();
if (this.children != null) this.children.AddRange(value);
{ this.LogicalChildren.AddRange(value);
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();
}
}
} }
} }
@ -107,16 +87,6 @@ namespace Perspex.Controls
} }
} }
/// <inheritdoc/>
protected virtual void OnChildrenAdded(IEnumerable<Control> child)
{
}
/// <inheritdoc/>
protected virtual void OnChildrenRemoved(IEnumerable<Control> child)
{
}
/// <summary> /// <summary>
/// Clears <see cref="IControl.Parent"/> for the specified controls. /// Clears <see cref="IControl.Parent"/> for the specified controls.
/// </summary> /// </summary>
@ -160,7 +130,6 @@ namespace Perspex.Controls
this.SetLogicalParent(controls); this.SetLogicalParent(controls);
this.AddVisualChildren(e.NewItems.OfType<Visual>()); this.AddVisualChildren(e.NewItems.OfType<Visual>());
this.LogicalChildren.InsertRange(e.NewStartingIndex, controls); this.LogicalChildren.InsertRange(e.NewStartingIndex, controls);
this.OnChildrenAdded(controls);
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
@ -168,7 +137,6 @@ namespace Perspex.Controls
this.ClearLogicalParent(e.OldItems.OfType<Control>()); this.ClearLogicalParent(e.OldItems.OfType<Control>());
this.LogicalChildren.RemoveAll(controls); this.LogicalChildren.RemoveAll(controls);
this.RemoveVisualChildren(e.OldItems.OfType<Visual>()); this.RemoveVisualChildren(e.OldItems.OfType<Visual>());
this.OnChildrenRemoved(controls);
break; break;
case NotifyCollectionChangedAction.Reset: case NotifyCollectionChangedAction.Reset:
@ -177,7 +145,6 @@ namespace Perspex.Controls
this.LogicalChildren.Clear(); this.LogicalChildren.Clear();
this.ClearVisualChildren(); this.ClearVisualChildren();
this.AddVisualChildren(this.children); this.AddVisualChildren(this.children);
this.OnChildrenAdded(controls);
break; break;
} }

32
Perspex.Controls/Popup.cs

@ -7,7 +7,6 @@
namespace Perspex.Controls namespace Perspex.Controls
{ {
using System; using System;
using Perspex.Collections;
using Perspex.Interactivity; using Perspex.Interactivity;
using Perspex.Rendering; using Perspex.Rendering;
using Perspex.VisualTree; using Perspex.VisualTree;
@ -58,27 +57,15 @@ namespace Perspex.Controls
/// </summary> /// </summary>
private TopLevel topLevel; private TopLevel topLevel;
/// <summary>
/// The popup's logical child.
/// </summary>
private PerspexSingleItemList<ILogical> logicalChild = new PerspexSingleItemList<ILogical>();
/// <summary> /// <summary>
/// Initializes static members of the <see cref="Popup"/> class. /// Initializes static members of the <see cref="Popup"/> class.
/// </summary> /// </summary>
static Popup() static Popup()
{ {
ChildProperty.Changed.AddClassHandler<Popup>(x => x.ChildChanged);
IsOpenProperty.Changed.AddClassHandler<Popup>(x => x.IsOpenChanged); IsOpenProperty.Changed.AddClassHandler<Popup>(x => x.IsOpenChanged);
} }
/// <summary>
/// Initializes a new instance of the <see cref="Popup"/> class.
/// </summary>
public Popup()
{
this.GetObservableWithHistory(ChildProperty).Subscribe(this.ChildChanged);
}
/// <summary> /// <summary>
/// Raised when the popup closes. /// Raised when the popup closes.
/// </summary> /// </summary>
@ -267,20 +254,21 @@ namespace Perspex.Controls
/// <summary> /// <summary>
/// Called when the <see cref="Child"/> property changes. /// Called when the <see cref="Child"/> property changes.
/// </summary> /// </summary>
/// <param name="values">The old and new values.</param> /// <param name="e">The event args.</param>
private void ChildChanged(Tuple<Control, Control> values) 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;
} }
/// <summary> /// <summary>

13
Perspex.Controls/Presenters/ContentPresenter.cs

@ -6,14 +6,11 @@
namespace Perspex.Controls.Presenters namespace Perspex.Controls.Presenters
{ {
using System;
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Reactive.Subjects;
using Perspex.Collections; using Perspex.Collections;
using Perspex.Controls.Primitives; using Perspex.Controls.Primitives;
using Perspex.Controls.Templates; using Perspex.Controls.Templates;
using Perspex.Media;
/// <summary> /// <summary>
/// Presents a single item of data inside a <see cref="TemplatedControl"/> template. /// Presents a single item of data inside a <see cref="TemplatedControl"/> template.
@ -116,12 +113,17 @@ namespace Perspex.Controls.Presenters
IControl result = null; IControl result = null;
object content = this.Content; object content = this.Content;
this.LogicalChildren.Clear();
this.ClearVisualChildren(); this.ClearVisualChildren();
if (content != null) if (content != null)
{ {
result = this.MaterializeDataTemplate(content); 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; var templatedParent = this.TemplatedParent as TemplatedControl;
@ -132,10 +134,9 @@ namespace Perspex.Controls.Presenters
((Control)result).TemplatedParent = templatedParent; ((Control)result).TemplatedParent = templatedParent;
this.AddVisualChild(result); this.AddVisualChild(result);
this.LogicalChildren.Add(result);
} }
this.LogicalChildren.Clear();
this.LogicalChildren.Add(result);
this.createdChild = true; this.createdChild = true;
} }
} }

14
Perspex.Controls/Presenters/DeckPresenter.cs

@ -12,11 +12,10 @@ namespace Perspex.Controls.Presenters
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Perspex.Animation; using Perspex.Animation;
using Collections; using Perspex.Collections;
using Perspex.Controls.Generators; using Perspex.Controls.Generators;
using Perspex.Controls.Primitives; using Perspex.Controls.Primitives;
using Perspex.Controls.Utils; using Perspex.Controls.Utils;
using Perspex.Styling;
/// <summary> /// <summary>
/// Displays pages inside an <see cref="ItemsControl"/>. /// Displays pages inside an <see cref="ItemsControl"/>.
@ -132,14 +131,6 @@ namespace Perspex.Controls.Presenters
set { this.SetValue(TransitionProperty, value); } set { this.SetValue(TransitionProperty, value); }
} }
Panel IItemsPresenter.Panel
{
get
{
throw new NotImplementedException();
}
}
/// <inheritdoc/> /// <inheritdoc/>
public override sealed void ApplyTemplate() public override sealed void ApplyTemplate()
{ {
@ -152,7 +143,8 @@ namespace Perspex.Controls.Presenters
/// <inheritdoc/> /// <inheritdoc/>
void IReparentingControl.ReparentLogicalChildren(ILogical logicalParent, IPerspexList<ILogical> children) void IReparentingControl.ReparentLogicalChildren(ILogical logicalParent, IPerspexList<ILogical> children)
{ {
throw new NotImplementedException(); this.ApplyTemplate();
((IReparentingControl)this.Panel).ReparentLogicalChildren(logicalParent, children);
} }
/// <summary> /// <summary>

23
Perspex.Controls/Primitives/AdornerLayer.cs

@ -8,6 +8,7 @@ namespace Perspex.Controls.Primitives
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq; using System.Linq;
using Perspex.VisualTree; using Perspex.VisualTree;
@ -28,6 +29,11 @@ namespace Perspex.Controls.Primitives
IsHitTestVisibleProperty.OverrideDefaultValue(typeof(AdornerLayer), false); IsHitTestVisibleProperty.OverrideDefaultValue(typeof(AdornerLayer), false);
} }
public AdornerLayer()
{
this.Children.CollectionChanged += ChildrenCollectionChanged;
}
public static Visual GetAdornedElement(Visual adorner) public static Visual GetAdornedElement(Visual adorner)
{ {
return adorner.GetValue(AdornedElementProperty); return adorner.GetValue(AdornedElementProperty);
@ -67,18 +73,19 @@ namespace Perspex.Controls.Primitives
return finalSize; return finalSize;
} }
protected override void OnChildrenAdded(IEnumerable<Control> 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<Control> child)
{
this.InvalidateArrange(); this.InvalidateArrange();
} }

22
Perspex.Controls/TabControl.cs

@ -7,10 +7,8 @@
namespace Perspex.Controls namespace Perspex.Controls
{ {
using Perspex.Animation; using Perspex.Animation;
using Perspex.Collections;
using Perspex.Controls.Primitives; using Perspex.Controls.Primitives;
using Perspex.Controls.Templates; using Perspex.Controls.Templates;
using Perspex.Input;
/// <summary> /// <summary>
/// A tab control that displays a tab strip along with the content of the selected tab. /// 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<IPageTransition> TransitionProperty = public static readonly PerspexProperty<IPageTransition> TransitionProperty =
Deck.TransitionProperty.AddOwner<TabControl>(); Deck.TransitionProperty.AddOwner<TabControl>();
private PerspexReadOnlyListView<ILogical> logicalChildren =
new PerspexReadOnlyListView<ILogical>();
/// <summary> /// <summary>
/// Initializes static members of the <see cref="TabControl"/> class. /// Initializes static members of the <see cref="TabControl"/> class.
/// </summary> /// </summary>
@ -48,13 +43,6 @@ namespace Perspex.Controls
SelectedIndexProperty.Changed.AddClassHandler<TabControl>(x => x.SelectedIndexChanged); SelectedIndexProperty.Changed.AddClassHandler<TabControl>(x => x.SelectedIndexChanged);
} }
/// <summary>
/// Initializes a new instance of the <see cref="TabControl"/> class.
/// </summary>
public TabControl()
{
}
/// <summary> /// <summary>
/// Gets the content of the selected tab. /// Gets the content of the selected tab.
/// </summary> /// </summary>
@ -82,19 +70,15 @@ namespace Perspex.Controls
set { this.SetValue(TransitionProperty, value); } set { this.SetValue(TransitionProperty, value); }
} }
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
// Don't handle keypresses.
}
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnTemplateApplied() protected override void OnTemplateApplied()
{ {
base.OnTemplateApplied(); base.OnTemplateApplied();
var deck = this.GetTemplateChild<Deck>("deck"); var deck = this.GetTemplateChild<Deck>("deck");
this.logicalChildren.Source = ((ILogical)deck).LogicalChildren; ((IReparentingControl)deck.Presenter.Panel).ReparentLogicalChildren(
this,
this.LogicalChildren);
} }
/// <summary> /// <summary>

3
Tests/Perspex.Controls.UnitTests/ContentControlTests.cs

@ -242,8 +242,7 @@ namespace Perspex.Controls.UnitTests
contentControl.Content = child1; contentControl.Content = child1;
contentControl.ApplyTemplate(); contentControl.ApplyTemplate();
((ILogical)contentControl).LogicalChildren.CollectionChanged += (s, e) => ((ILogical)contentControl).LogicalChildren.CollectionChanged += (s, e) => called = true;
called = e.Action == NotifyCollectionChangedAction.Replace;
contentControl.Content = child2; contentControl.Content = child2;

21
Tests/Perspex.Controls.UnitTests/PanelTests.cs

@ -7,7 +7,8 @@
namespace Perspex.Controls.UnitTests namespace Perspex.Controls.UnitTests
{ {
using System.Linq; using System.Linq;
using Collections; using Perspex.Collections;
using Perspex.LogicalTree;
using Xunit; using Xunit;
public class PanelTests public class PanelTests
@ -21,7 +22,7 @@ namespace Perspex.Controls.UnitTests
panel.Children.Add(child); panel.Children.Add(child);
Assert.Equal(child.Parent, panel); Assert.Equal(child.Parent, panel);
Assert.Equal(((ILogical)child).LogicalParent, panel); Assert.Equal(child.GetLogicalParent(), panel);
} }
[Fact] [Fact]
@ -33,7 +34,7 @@ namespace Perspex.Controls.UnitTests
panel.Children = new Controls { child }; panel.Children = new Controls { child };
Assert.Equal(child.Parent, panel); Assert.Equal(child.Parent, panel);
Assert.Equal(((ILogical)child).LogicalParent, panel); Assert.Equal(child.GetLogicalParent(), panel);
} }
[Fact] [Fact]
@ -46,7 +47,7 @@ namespace Perspex.Controls.UnitTests
panel.Children.Remove(child); panel.Children.Remove(child);
Assert.Null(child.Parent); Assert.Null(child.Parent);
Assert.Null(((ILogical)child).LogicalParent); Assert.Null(child.GetLogicalParent());
} }
[Fact] [Fact]
@ -61,9 +62,9 @@ namespace Perspex.Controls.UnitTests
panel.Children.Clear(); panel.Children.Clear();
Assert.Null(child1.Parent); Assert.Null(child1.Parent);
Assert.Null(((ILogical)child1).LogicalParent); Assert.Null(child1.GetLogicalParent());
Assert.Null(child2.Parent); Assert.Null(child2.Parent);
Assert.Null(((ILogical)child2).LogicalParent); Assert.Null(child2.GetLogicalParent());
} }
[Fact] [Fact]
@ -78,9 +79,9 @@ namespace Perspex.Controls.UnitTests
panel.Children = new Controls(); panel.Children = new Controls();
Assert.Null(child1.Parent); Assert.Null(child1.Parent);
Assert.Null(((ILogical)child1).LogicalParent); Assert.Null(child1.GetLogicalParent());
Assert.Null(child2.Parent); Assert.Null(child2.Parent);
Assert.Null(((ILogical)child2).LogicalParent); Assert.Null(child2.GetLogicalParent());
} }
[Fact] [Fact]
@ -92,7 +93,7 @@ namespace Perspex.Controls.UnitTests
panel.Children.Add(child); panel.Children.Add(child);
Assert.Equal(new[] { child }, panel.Children); Assert.Equal(new[] { child }, panel.Children);
Assert.Equal(new[] { child }, ((ILogical)panel).LogicalChildren.ToList()); Assert.Equal(new[] { child }, panel.GetLogicalChildren());
} }
[Fact] [Fact]
@ -105,7 +106,7 @@ namespace Perspex.Controls.UnitTests
panel.Children.Remove(child); panel.Children.Remove(child);
Assert.Equal(new Control[0], panel.Children); Assert.Equal(new Control[0], panel.Children);
Assert.Equal(new ILogical[0], ((ILogical)panel).LogicalChildren.ToList()); Assert.Equal(new ILogical[0], panel.GetLogicalChildren());
} }
[Fact] [Fact]

6
Tests/Perspex.Controls.UnitTests/PopupTests.cs

@ -8,6 +8,7 @@ namespace Perspex.Controls.UnitTests
{ {
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Linq; using System.Linq;
using Perspex.LogicalTree;
using Xunit; using Xunit;
public class PopupTests public class PopupTests
@ -45,7 +46,7 @@ namespace Perspex.Controls.UnitTests
target.Child = child; target.Child = child;
Assert.Equal(new[] { child }, ((ILogical)target).LogicalChildren.ToList()); Assert.Equal(new[] { child }, target.GetLogicalChildren());
} }
[Fact] [Fact]
@ -102,8 +103,7 @@ namespace Perspex.Controls.UnitTests
target.Child = child1; target.Child = child1;
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true;
called = e.Action == NotifyCollectionChangedAction.Replace;
target.Child = child2; target.Child = child2;

Loading…
Cancel
Save