Browse Source

Don't remeasure/arrange when size hasn't changed.

pull/10/head
Steven Kirk 11 years ago
parent
commit
64c445f826
  1. 4
      Perspex.Layout/ILayoutable.cs
  2. 4
      Perspex.Layout/LayoutManager.cs
  3. 48
      Perspex.Layout/Layoutable.cs
  4. 44
      Perspex.SceneGraph/Point.cs
  5. 49
      Perspex.SceneGraph/Rect.cs
  6. 22
      Perspex.SceneGraph/Size.cs

4
Perspex.Layout/ILayoutable.cs

@ -35,9 +35,9 @@ namespace Perspex.Layout
Rect? PreviousArrange { get; }
void Measure(Size availableSize);
void Measure(Size availableSize, bool force = false);
void Arrange(Rect rect);
void Arrange(Rect rect, bool force = false);
void InvalidateMeasure();

4
Perspex.Layout/LayoutManager.cs

@ -174,7 +174,7 @@ namespace Perspex.Layout
parent = parent.GetVisualParent<ILayoutable>();
}
parent.Measure(parent.PreviousMeasure.Value);
parent.Measure(parent.PreviousMeasure.Value, true);
}
}
}
@ -214,7 +214,7 @@ namespace Perspex.Layout
parent = parent.GetVisualParent<ILayoutable>();
}
parent.Arrange(parent.PreviousArrange.Value);
parent.Arrange(parent.PreviousArrange.Value, true);
}
}
}

48
Perspex.Layout/Layoutable.cs

@ -166,27 +166,30 @@ namespace Perspex.Layout
public static int DebugMeasureCount { get; set; }
public static int DebugArrangeCount { get; set; }
public void Measure(Size availableSize)
public void Measure(Size availableSize, bool force = false)
{
if (double.IsNaN(availableSize.Width) || double.IsNaN(availableSize.Height))
{
throw new InvalidOperationException("Cannot call Measure using a size with NaN values.");
}
++DebugMeasureCount;
if (force || this.previousMeasure != availableSize)
{
++DebugMeasureCount;
this.DesiredSize = this.MeasureCore(availableSize).Constrain(availableSize);
this.IsMeasureValid = true;
this.previousMeasure = availableSize;
this.DesiredSize = this.MeasureCore(availableSize).Constrain(availableSize);
this.IsMeasureValid = true;
this.previousMeasure = availableSize;
this.Log().Debug(
"Measure of {0} (#{1:x8}) requested {2} ",
this.GetType().Name,
this.GetHashCode(),
this.DesiredSize);
this.Log().Debug(
"Measure of {0} (#{1:x8}) requested {2} ",
this.GetType().Name,
this.GetHashCode(),
this.DesiredSize);
}
}
public void Arrange(Rect rect)
public void Arrange(Rect rect, bool force = false)
{
if (rect.Width < 0 || rect.Height < 0 ||
double.IsInfinity(rect.Width) || double.IsInfinity(rect.Height) ||
@ -200,17 +203,21 @@ namespace Perspex.Layout
throw new InvalidOperationException("Arrange called before Measure.");
}
++DebugArrangeCount;
if (force || this.previousArrange != rect)
{
++DebugArrangeCount;
this.Log().Debug(
"Arrange of {0} (#{1:x8}) gave {2} ",
this.GetType().Name,
this.GetHashCode(),
rect);
this.Log().Debug(
"Arrange of {0} (#{1:x8}) gave {2} ",
this.GetType().Name,
this.GetHashCode(),
rect);
this.ArrangeCore(rect);
this.previousArrange = rect;
}
this.ArrangeCore(rect);
this.IsArrangeValid = true;
this.previousArrange = rect;
}
public void InvalidateMeasure()
@ -219,6 +226,8 @@ namespace Perspex.Layout
this.IsMeasureValid = false;
this.IsArrangeValid = false;
this.previousMeasure = null;
this.previousArrange = null;
if (root != null && root.Item1.LayoutManager != null)
{
@ -231,6 +240,7 @@ namespace Perspex.Layout
var root = this.GetLayoutRoot();
this.IsArrangeValid = false;
this.previousArrange = null;
if (root != null && root.Item1.LayoutManager != null)
{

44
Perspex.SceneGraph/Point.cs

@ -50,6 +50,28 @@ namespace Perspex
get { return this.y; }
}
/// <summary>
/// Checks for equality between two <see cref="Point"/>s.
/// </summary>
/// <param name="left">The first point.</param>
/// <param name="right">The second point.</param>
/// <returns>True if the points are equal; otherwise false.</returns>
public static bool operator ==(Point left, Point right)
{
return left.X == right.X && left.Y == right.Y;
}
/// <summary>
/// Checks for unequality between two <see cref="Point"/>s.
/// </summary>
/// <param name="left">The first point.</param>
/// <param name="right">The second point.</param>
/// <returns>True if the points are unequal; otherwise false.</returns>
public static bool operator !=(Point left, Point right)
{
return !(left == right);
}
public static Point operator +(Point a, Point b)
{
return new Point(a.x + b.x, a.y + b.y);
@ -65,6 +87,28 @@ namespace Perspex
return new Vector(p.x, p.y);
}
public override bool Equals(object obj)
{
if (obj is Point)
{
var other = (Point)obj;
return this.X == other.X && this.Y == other.Y;
}
return false;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = (hash * 23) + this.x.GetHashCode();
hash = (hash * 23) + this.y.GetHashCode();
return hash;
}
}
/// <summary>
/// Returns the string representation of the point.
/// </summary>

49
Perspex.SceneGraph/Rect.cs

@ -191,6 +191,28 @@ namespace Perspex
get { return this.width == 0 && this.height == 0; }
}
/// <summary>
/// Checks for equality between two <see cref="Rect"/>s.
/// </summary>
/// <param name="left">The first rect.</param>
/// <param name="right">The second rect.</param>
/// <returns>True if the rects are equal; otherwise false.</returns>
public static bool operator ==(Rect left, Rect right)
{
return left.Position == right.Position && left.Size == right.Size;
}
/// <summary>
/// Checks for unequality between two <see cref="Rect"/>s.
/// </summary>
/// <param name="left">The first rect.</param>
/// <param name="right">The second rect.</param>
/// <returns>True if the rects are unequal; otherwise false.</returns>
public static bool operator !=(Rect left, Rect right)
{
return !(left == right);
}
public static Rect operator *(Rect rect, Vector scale)
{
double centerX = rect.x + rect.width / 2;
@ -261,6 +283,33 @@ namespace Perspex
this.Size.Deflate(thickness));
}
public override bool Equals(object obj)
{
if (obj is Rect)
{
var other = (Rect)obj;
return this.X == other.X &&
this.X == other.X &&
this.Width == other.Width &&
this.Height == other.Height;
}
return false;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = (hash * 23) + this.X.GetHashCode();
hash = (hash * 23) + this.Y.GetHashCode();
hash = (hash * 23) + this.Width.GetHashCode();
hash = (hash * 23) + this.Height.GetHashCode();
return hash;
}
}
public Rect Intersect(Rect rect)
{
double x = Math.Max(this.x, rect.x);

22
Perspex.SceneGraph/Size.cs

@ -120,6 +120,28 @@ namespace Perspex
Math.Max(0, this.height - thickness.Top - thickness.Bottom));
}
public override bool Equals(object obj)
{
if (obj is Size)
{
var other = (Size)obj;
return this.Width == other.Width && this.Height == other.Height;
}
return false;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = (hash * 23) + this.Width.GetHashCode();
hash = (hash * 23) + this.Height.GetHashCode();
return hash;
}
}
/// <summary>
/// Inflates the size by a <see cref="Thickness"/>.
/// </summary>

Loading…
Cancel
Save