Browse Source

Use measure layout algorithm for arrange.

pull/10/head
Steven Kirk 11 years ago
parent
commit
4f9dc138da
  1. 1
      Perspex.Controls/Window.cs
  2. 57
      Perspex.Layout/LayoutManager.cs
  3. 3
      Perspex.Layout/Layoutable.cs

1
Perspex.Controls/Window.cs

@ -37,6 +37,7 @@ namespace Perspex.Controls
static Window()
{
BackgroundProperty.OverrideDefaultValue(typeof(Window), Brushes.White);
AffectsMeasure(Window.ClientSizeProperty);
}
public Window()

57
Perspex.Layout/LayoutManager.cs

@ -42,6 +42,11 @@ namespace Perspex.Layout
/// </summary>
private Heap<Item> toMeasure = new Heap<Item>(HeapType.Minimum);
/// <summary>
/// The controls that need to be arranged, sorted by distance to layout root.
/// </summary>
private Heap<Item> toArrange = new Heap<Item>(HeapType.Minimum);
/// <summary>
/// Initializes a new instance of the <see cref="LayoutManager"/> class.
/// </summary>
@ -98,7 +103,7 @@ namespace Perspex.Layout
this.measureNeeded = false;
}
this.Root.Arrange(new Rect(this.Root.ClientSize));
this.ExecuteArrange();
System.Diagnostics.Debug.WriteLine(Environment.TickCount + " " + Layoutable.DebugMeasureCount + " " + Layoutable.DebugArrangeCount);
}
@ -110,8 +115,11 @@ namespace Perspex.Layout
/// <param name="distance">The control's distance from the layout root.</param>
public void InvalidateMeasure(ILayoutable control, int distance)
{
var item = new Item(control, distance);
this.toMeasure.Add(item);
this.toArrange.Add(item);
this.measureNeeded = true;
this.toMeasure.Add(new Item(control, distance));
if (!this.LayoutQueued)
{
@ -128,7 +136,7 @@ namespace Perspex.Layout
/// <param name="distance">The control's distance from the layout root.</param>
public void InvalidateArrange(ILayoutable control, int distance)
{
//this.toArrange.Add(item);
this.toArrange.Add(new Item(control, distance));
if (!this.LayoutQueued)
{
@ -138,6 +146,9 @@ namespace Perspex.Layout
}
}
/// <summary>
/// Executes the measure part of the layout pass.
/// </summary>
private void ExecuteMeasure()
{
for (int i = 0; i < MaxTries; ++i)
@ -175,6 +186,46 @@ namespace Perspex.Layout
}
}
/// <summary>
/// Executes the arrange part of the layout pass.
/// </summary>
private void ExecuteArrange()
{
for (int i = 0; i < MaxTries; ++i)
{
var arrange = this.toArrange;
this.toArrange = new Heap<Item>(HeapType.Minimum);
if (!this.Root.IsArrangeValid)
{
this.Root.Arrange(new Rect(this.Root.ClientSize));
}
else
{
foreach (var item in arrange)
{
if (!item.Control.IsArrangeValid)
{
var parent = item.Control.GetVisualParent<ILayoutable>();
while (parent.PreviousArrange == null)
{
parent = parent.GetVisualParent<ILayoutable>();
}
parent.Arrange(parent.PreviousArrange.Value);
}
}
}
if (this.toArrange.Count == 0)
{
break;
}
}
}
private class Item : IComparable<Item>
{
public Item(ILayoutable control, int distance)

3
Perspex.Layout/Layoutable.cs

@ -209,6 +209,7 @@ namespace Perspex.Layout
rect);
this.ArrangeCore(rect);
this.IsArrangeValid = true;
this.previousArrange = rect;
}
@ -217,6 +218,7 @@ namespace Perspex.Layout
var root = this.GetLayoutRoot();
this.IsMeasureValid = false;
this.IsArrangeValid = false;
if (root != null && root.Item1.LayoutManager != null)
{
@ -228,7 +230,6 @@ namespace Perspex.Layout
{
var root = this.GetLayoutRoot();
this.IsMeasureValid = false;
this.IsArrangeValid = false;
if (root != null && root.Item1.LayoutManager != null)

Loading…
Cancel
Save