From 6205545bc51f92d2173ab03062f4f993cb6532b6 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 19 Sep 2014 16:20:46 +0200 Subject: [PATCH] Make stuff get measured properly. And added some logging to Layoutable to help diagnose this. --- Perspex.Controls/Panel.cs | 40 +++++++++++++++++++++++++++++++++--- Perspex.Layout/Layoutable.cs | 15 +++++++++++++- Perspex.SceneGraph/Visual.cs | 12 +++++++++++ Perspex.Windows/Window.cs | 15 ++++---------- 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/Perspex.Controls/Panel.cs b/Perspex.Controls/Panel.cs index 56bb01e896..417a0d2b45 100644 --- a/Perspex.Controls/Panel.cs +++ b/Perspex.Controls/Panel.cs @@ -7,7 +7,7 @@ namespace Perspex.Controls { using System; - using System.Collections.Generic; + using System.Collections.Specialized; using System.Linq; /// @@ -24,22 +24,56 @@ namespace Perspex.Controls if (this.children == null) { this.children = new Controls(); + this.children.CollectionChanged += ChildrenChanged; } return this.children; } - + set { Contract.Requires(value != null); if (this.children != value) { + if (this.children != null) + { + this.children.CollectionChanged -= ChildrenChanged; + } + this.children = value; this.ClearVisualChildren(); - this.AddVisualChildren(value); + + if (this.children != null) + { + this.children.CollectionChanged += ChildrenChanged; + this.AddVisualChildren(value); + this.InvalidateMeasure(); + } } } } + + private void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e) + { + // TODO: Handle Move and Replace. + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + this.AddVisualChildren(e.NewItems.OfType()); + break; + + case NotifyCollectionChangedAction.Remove: + this.RemoveVisualChildren(e.OldItems.OfType()); + break; + + case NotifyCollectionChangedAction.Reset: + this.ClearVisualChildren(); + this.AddVisualChildren(this.children); + break; + } + + this.InvalidateMeasure(); + } } } diff --git a/Perspex.Layout/Layoutable.cs b/Perspex.Layout/Layoutable.cs index 8dd8a3f4a0..60a9b17a55 100644 --- a/Perspex.Layout/Layoutable.cs +++ b/Perspex.Layout/Layoutable.cs @@ -8,6 +8,7 @@ namespace Perspex.Layout { using System; using System.Linq; + using Splat; public enum HorizontalAlignment { @@ -25,7 +26,7 @@ namespace Perspex.Layout Bottom, } - public class Layoutable : Visual, ILayoutable + public class Layoutable : Visual, ILayoutable, IEnableLogger { public static readonly PerspexProperty WidthProperty = PerspexProperty.Register("Width", double.NaN); @@ -123,10 +124,22 @@ namespace Perspex.Layout { availableSize = availableSize.Deflate(this.Margin); this.DesiredSize = this.MeasureCore(availableSize).Constrain(availableSize); + + this.Log().Debug(string.Format( + "Measure of {0} (#{1:x8}) requested {2} ", + this.GetType().Name, + this.GetHashCode(), + this.DesiredSize)); } public void Arrange(Rect rect) { + this.Log().Debug(string.Format( + "Arrange of {0} (#{1:x8}) gave {2} ", + this.GetType().Name, + this.GetHashCode(), + rect)); + if (this.DesiredSize.HasValue) { this.ArrangeCore(rect); diff --git a/Perspex.SceneGraph/Visual.cs b/Perspex.SceneGraph/Visual.cs index 533ef69ecc..16101bf646 100644 --- a/Perspex.SceneGraph/Visual.cs +++ b/Perspex.SceneGraph/Visual.cs @@ -143,6 +143,18 @@ namespace Perspex this.visualChildren.Remove(visual); } + protected void RemoveVisualChildren(IEnumerable visuals) + { + Contract.Requires(visuals != null); + + this.EnsureVisualChildrenCreated(); + + foreach (var v in visuals) + { + this.visualChildren.Remove(v); + } + } + protected void SetVisualBounds(Rect bounds) { this.bounds = bounds; diff --git a/Perspex.Windows/Window.cs b/Perspex.Windows/Window.cs index f2b8fcfcd5..cab28f85ae 100644 --- a/Perspex.Windows/Window.cs +++ b/Perspex.Windows/Window.cs @@ -33,8 +33,6 @@ namespace Perspex.Windows private IInputManager inputManager; - private bool layoutPending; - public Window() { IPlatformRenderInterface factory = Locator.Current.GetService(); @@ -47,9 +45,8 @@ namespace Perspex.Windows this.inputManager = Locator.Current.GetService(); this.Template = ControlTemplate.Create(this.DefaultTemplate); - this.LayoutManager.LayoutNeeded.Where(_ => !this.layoutPending).Subscribe(x => + this.LayoutManager.LayoutNeeded.Subscribe(x => { - this.layoutPending = true; WindowsDispatcher.CurrentDispatcher.BeginInvoke( DispatcherPriority.Render, () => @@ -57,22 +54,18 @@ namespace Perspex.Windows this.LayoutManager.ExecuteLayoutPass(); this.renderer.Render(this); this.RenderManager.RenderFinished(); - this.layoutPending = false; }); }); - this.RenderManager.RenderNeeded.Where(_ => !layoutPending) + this.RenderManager.RenderNeeded .Subscribe(x => { WindowsDispatcher.CurrentDispatcher.BeginInvoke( DispatcherPriority.Render, () => { - if (!this.layoutPending) - { - this.renderer.Render(this); - this.RenderManager.RenderFinished(); - } + this.renderer.Render(this); + this.RenderManager.RenderFinished(); }); }); }