Browse Source

Merge pull request #549 from donandren/hittestingfix

Fixes memory leak in hit testing
pull/552/head
Steven Kirk 10 years ago
parent
commit
c8d34daff8
  1. 6
      src/Avalonia.Input/InputExtensions.cs
  2. 4
      src/Avalonia.SceneGraph/Rect.cs
  3. 22
      src/Avalonia.SceneGraph/VisualTree/TransformedBounds.cs

6
src/Avalonia.Input/InputExtensions.cs

@ -25,7 +25,6 @@ namespace Avalonia.Input
{ {
Contract.Requires<ArgumentNullException>(element != null); Contract.Requires<ArgumentNullException>(element != null);
var transformedBounds = BoundsTracker.GetTransformedBounds((Visual)element); var transformedBounds = BoundsTracker.GetTransformedBounds((Visual)element);
var geometry = transformedBounds.GetTransformedBoundsGeometry();
if (element.IsVisible && if (element.IsVisible &&
element.IsHitTestVisible && element.IsHitTestVisible &&
@ -42,7 +41,7 @@ namespace Avalonia.Input
} }
} }
if (geometry.FillContains(p)) if (transformedBounds.Contains(p))
{ {
yield return element; yield return element;
} }
@ -71,7 +70,6 @@ namespace Avalonia.Input
}) })
.OrderBy(x => x, null) .OrderBy(x => x, null)
.Select(x => x.Element); .Select(x => x.Element);
} }
private class ZOrderElement : IComparable<ZOrderElement> private class ZOrderElement : IComparable<ZOrderElement>
@ -95,4 +93,4 @@ namespace Avalonia.Input
} }
} }
} }
} }

4
src/Avalonia.SceneGraph/Rect.cs

@ -230,8 +230,8 @@ namespace Avalonia
/// <returns>true if the point is in the bounds of the rectangle; otherwise false.</returns> /// <returns>true if the point is in the bounds of the rectangle; otherwise false.</returns>
public bool Contains(Point p) public bool Contains(Point p)
{ {
return p.X >= _x && p.X < _x + _width && return p.X >= _x && p.X <= _x + _width &&
p.Y >= _y && p.Y < _y + _height; p.Y >= _y && p.Y <= _y + _height;
} }
/// <summary> /// <summary>

22
src/Avalonia.SceneGraph/VisualTree/TransformedBounds.cs

@ -38,20 +38,18 @@ namespace Avalonia.VisualTree
/// </summary> /// </summary>
public Matrix Transform { get; } public Matrix Transform { get; }
public Geometry GetTransformedBoundsGeometry() public bool Contains(Point point)
{ {
StreamGeometry geometry = new StreamGeometry(); if (Transform.HasInverse)
using (var context = geometry.Open())
{ {
context.SetFillRule(FillRule.EvenOdd); Point trPoint = point * Transform.Invert();
context.BeginFigure(Bounds.TopLeft * Transform, true);
context.LineTo(Bounds.TopRight * Transform); return Bounds.Contains(trPoint);
context.LineTo(Bounds.BottomRight * Transform); }
context.LineTo(Bounds.BottomLeft * Transform); else
context.LineTo(Bounds.TopLeft * Transform); {
context.EndFigure(true); return Bounds.Contains(point);
} }
return geometry;
} }
} }
} }
Loading…
Cancel
Save