|
|
|
@ -5,6 +5,7 @@ using System; |
|
|
|
using Avalonia.Platform; |
|
|
|
using Avalonia.VisualTree; |
|
|
|
using System.Collections.Generic; |
|
|
|
using Avalonia.Threading; |
|
|
|
|
|
|
|
namespace Avalonia.Rendering |
|
|
|
{ |
|
|
|
@ -14,6 +15,7 @@ namespace Avalonia.Rendering |
|
|
|
private readonly IRenderRoot _root; |
|
|
|
private IRenderTarget _renderTarget; |
|
|
|
private bool _dirty; |
|
|
|
private bool _renderQueued; |
|
|
|
|
|
|
|
public Renderer(IRenderRoot root, IRenderLoop renderLoop) |
|
|
|
{ |
|
|
|
@ -39,7 +41,7 @@ namespace Avalonia.Rendering |
|
|
|
|
|
|
|
public IEnumerable<IVisual> HitTest(Point p, Func<IVisual, bool> filter) |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
|
return HitTest(_root, p, filter); |
|
|
|
} |
|
|
|
|
|
|
|
public void Render(Rect rect) |
|
|
|
@ -63,14 +65,45 @@ namespace Avalonia.Rendering |
|
|
|
finally |
|
|
|
{ |
|
|
|
_dirty = false; |
|
|
|
_renderQueued = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static IEnumerable<IVisual> HitTest( |
|
|
|
IVisual visual, |
|
|
|
Point p, |
|
|
|
Func<IVisual, bool> filter) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(visual != null); |
|
|
|
|
|
|
|
if (filter?.Invoke(visual) != false) |
|
|
|
{ |
|
|
|
bool containsPoint = BoundsTracker.GetTransformedBounds((Visual)visual)?.Contains(p) == true; |
|
|
|
|
|
|
|
if ((containsPoint || !visual.ClipToBounds) && visual.VisualChildren.Count > 0) |
|
|
|
{ |
|
|
|
foreach (var child in visual.VisualChildren.SortByZIndex()) |
|
|
|
{ |
|
|
|
foreach (var result in HitTest(child, p, filter)) |
|
|
|
{ |
|
|
|
yield return result; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (containsPoint) |
|
|
|
{ |
|
|
|
yield return visual; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void OnRenderLoopTick(object sender, EventArgs e) |
|
|
|
{ |
|
|
|
if (_dirty) |
|
|
|
if (_dirty && !_renderQueued) |
|
|
|
{ |
|
|
|
_root.Invalidate(new Rect(_root.ClientSize)); |
|
|
|
_renderQueued = true; |
|
|
|
Dispatcher.UIThread.InvokeAsync(() => Render(new Rect(_root.ClientSize))); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|