Browse Source

Merge branch 'master' into fixes/1344-listbox-horizontal-scrollbar

pull/1348/head
Jeremy Koritzinsky 8 years ago
committed by GitHub
parent
commit
e8d18f52b6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject
  2. 6
      .ncrunch/Avalonia.Skia.RenderTests.v3.ncrunchproject
  3. 12
      Avalonia.sln
  4. 4
      build.cake
  5. 4
      samples/Previewer/MainWindow.xaml.cs
  6. 4
      samples/RemoteTest/Program.cs
  7. 2
      src/Avalonia.Base/AvaloniaObject.cs
  8. 4
      src/Avalonia.Base/PriorityBindingEntry.cs
  9. 2
      src/Avalonia.Base/Threading/AvaloniaScheduler.cs
  10. 4
      src/Avalonia.Base/Threading/AvaloniaSynchronizationContext.cs
  11. 4
      src/Avalonia.Base/Threading/Dispatcher.cs
  12. 4
      src/Avalonia.Base/Threading/IDispatcher.cs
  13. 2
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  14. 4
      src/Avalonia.Controls/Primitives/AdornerLayer.cs
  15. 2
      src/Avalonia.Controls/Remote/RemoteWidget.cs
  16. 10
      src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs
  17. 2
      src/Avalonia.Controls/TreeView.cs
  18. 2
      src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
  19. 2
      src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
  20. 2
      src/Avalonia.Layout/LayoutManager.cs
  21. 2
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  22. 9
      src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs
  23. 12
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  24. 17
      src/Avalonia.Visuals/Visual.cs
  25. 51
      src/Avalonia.Visuals/VisualTree/BoundsTracker.cs
  26. 5
      src/Avalonia.Visuals/VisualTree/IVisual.cs
  27. 2
      src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs
  28. 2
      src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs
  29. 2
      src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs
  30. 2
      src/Markup/Avalonia.Markup/Data/Plugins/AvaloniaPropertyAccessorPlugin.cs
  31. 2
      src/OSX/Avalonia.MonoMac/TopLevelImpl.cs
  32. 16
      tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj
  33. 2
      tests/Avalonia.Direct2D1.UnitTests/Properties/AssemblyInfo.cs
  34. 12
      tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs
  35. 2
      tests/Avalonia.RenderTests/.gitignore
  36. 33
      tests/Avalonia.RenderTests/Avalonia.RenderTests.projitems
  37. 16
      tests/Avalonia.RenderTests/Avalonia.RenderTests.shproj
  38. 5
      tests/Avalonia.RenderTests/Controls/TextBlockTests.cs
  39. 2
      tests/Avalonia.RenderTests/Properties/AssemblyInfo.cs
  40. 15
      tests/Avalonia.RenderTests/TestBase.cs
  41. 20
      tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj
  42. 4
      tests/Avalonia.UnitTests/ImmediateDispatcher.cs
  43. 4
      tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs
  44. 5
      tests/Avalonia.Visuals.UnitTests/VisualTree/TransformedBoundsTests.cs
  45. BIN
      tests/TestFiles/Cairo/SVGPath/SVGPath.expected.png
  46. BIN
      tests/TestFiles/Skia/Controls/TextBlock/Wrapping_NoWrap.expected.png
  47. 2
      tools/packages.config

3
.ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject

@ -1,5 +1,8 @@
<ProjectConfiguration>
<Settings>
<AdditionalFilesToIncludeForProject>
<Value>..\TestFiles\Direct2D1\**.*</Value>
</AdditionalFilesToIncludeForProject>
<DefaultTestTimeout>3000</DefaultTestTimeout>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings>

6
.ncrunch/Avalonia.Skia.RenderTests.v3.ncrunchproject

@ -1,7 +1,9 @@
<ProjectConfiguration>
<Settings>
<DefaultTestTimeout>1000</DefaultTestTimeout>
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
<AdditionalFilesToIncludeForProject>
<Value>..\TestFiles\Skia\**.*</Value>
</AdditionalFilesToIncludeForProject>
<DefaultTestTimeout>3000</DefaultTestTimeout>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings>
</ProjectConfiguration>

12
Avalonia.sln

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2008
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base", "src\Avalonia.Base\Avalonia.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}"
EndProject
@ -45,11 +45,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Layout.UnitTests",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Interactivity.UnitTests", "tests\Avalonia.Interactivity.UnitTests\Avalonia.Interactivity.UnitTests.csproj", "{08478EF5-44E8-42E9-92D6-15E00EC038D8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1.RenderTests", "tests\Avalonia.RenderTests\Avalonia.Direct2D1.RenderTests.csproj", "{DABFD304-D6A4-4752-8123-C2CCF7AC7831}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1.RenderTests", "tests\Avalonia.Direct2D1.RenderTests\Avalonia.Direct2D1.RenderTests.csproj", "{DABFD304-D6A4-4752-8123-C2CCF7AC7831}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Input.UnitTests", "tests\Avalonia.Input.UnitTests\Avalonia.Input.UnitTests.csproj", "{AC18926A-E784-40FE-B09D-BB0FE2B599F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1.UnitTests", "tests\Avalonia.Direct2D1.UnitTests\Avalonia.Direct2D1.UnitTests.csproj", "{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Direct2D1.UnitTests", "tests\Avalonia.Direct2D1.UnitTests\Avalonia.Direct2D1.UnitTests.csproj", "{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.Xaml.UnitTests", "tests\Avalonia.Markup.Xaml.UnitTests\Avalonia.Markup.Xaml.UnitTests.csproj", "{99135EAB-653D-47E4-A378-C96E1278CA44}"
EndProject
@ -114,8 +114,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.Te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.TestApp", "tests\Avalonia.DesignerSupport.TestApp\Avalonia.DesignerSupport.TestApp.csproj", "{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Avalonia.RenderTests", "tests\Avalonia.RenderTests\Avalonia.RenderTests.shproj", "{48840EDD-24BF-495D-911E-2EB12AE75D3B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualizationTest", "samples\VirtualizationTest\VirtualizationTest.csproj", "{FBCAF3D0-2808-4934-8E96-3F607594517B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{A0CC0258-D18C-4AB3-854F-7101680FC3F9}"
@ -176,7 +174,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Direct3DInteropSample", "sa
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.Skia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Remote.Protocol", "src\Avalonia.Remote.Protocol\Avalonia.Remote.Protocol.csproj", "{D78A720C-C0C6-478B-8564-F167F9BDD01B}"
EndProject
@ -200,7 +198,6 @@ Global
src\Shared\RenderHelpers\RenderHelpers.projitems*{3e908f67-5543-4879-a1dc-08eace79b3cd}*SharedItemsImports = 4
src\Windows\Avalonia.Win32\Avalonia.Win32.Shared.projitems*{40759a76-d0f2-464e-8000-6ff0f5c4bd7c}*SharedItemsImports = 4
src\Shared\PlatformSupport\PlatformSupport.projitems*{4488ad85-1495-4809-9aa4-ddfe0a48527e}*SharedItemsImports = 4
tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{48840edd-24bf-495d-911e-2eb12ae75d3b}*SharedItemsImports = 13
src\Shared\PlatformSupport\PlatformSupport.projitems*{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}*SharedItemsImports = 4
src\Shared\PlatformSupport\PlatformSupport.projitems*{7863ea94-f0fb-4386-bf8c-e5bfa761560a}*SharedItemsImports = 4
src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 4
@ -2643,7 +2640,6 @@ Global
{57E0455D-D565-44BB-B069-EE1AA20F8337} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{52F55355-D120-42AC-8116-8410A7D602FA} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{F1381F98-4D24-409A-A6C5-1C5B1E08BB08} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{48840EDD-24BF-495D-911E-2EB12AE75D3B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{FBCAF3D0-2808-4934-8E96-3F607594517B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{A0CC0258-D18C-4AB3-854F-7101680FC3F9} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{C7A69145-60B6-4882-97D6-A3921DD43978} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}

4
build.cake

@ -197,8 +197,8 @@ Task("Run-Render-Tests")
.IsDependentOn("Build")
.WithCriteria(() => !parameters.SkipTests && parameters.IsRunningOnWindows)
.Does(() => {
RunCoreTest("./tests/Avalonia.RenderTests/Avalonia.Skia.RenderTests.csproj", parameters, true);
RunCoreTest("./tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", parameters, true);
RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", parameters, true);
RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", parameters, true);
});
Task("Run-Designer-Unit-Tests")

4
samples/Previewer/MainWindow.xaml.cs

@ -39,7 +39,7 @@ namespace Previewer
}));
new BsonTcpTransport().Listen(IPAddress.Loopback, 25000, t =>
{
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
if (_connection != null)
{
@ -61,7 +61,7 @@ namespace Previewer
private void OnMessage(IAvaloniaRemoteTransportConnection transport, object obj)
{
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
if (transport != _connection)
return;

4
samples/RemoteTest/Program.cs

@ -25,7 +25,7 @@ namespace RemoteTest
var transport = new BsonTcpTransport();
transport.Listen(IPAddress.Loopback, port, sc =>
{
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
new RemoteServer(sc).Content = new MainView();
});
@ -34,7 +34,7 @@ namespace RemoteTest
var cts = new CancellationTokenSource();
transport.Connect(IPAddress.Loopback, port).ContinueWith(t =>
{
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
var window = new Window()
{

2
src/Avalonia.Base/AvaloniaObject.cs

@ -774,7 +774,7 @@ namespace Avalonia
}
else
{
Dispatcher.UIThread.InvokeAsync(Set);
Dispatcher.UIThread.Post(Set);
}
}

4
src/Avalonia.Base/PriorityBindingEntry.cs

@ -123,7 +123,7 @@ namespace Avalonia
}
else
{
Dispatcher.UIThread.InvokeAsync(Signal);
Dispatcher.UIThread.Post(Signal);
}
}
@ -135,7 +135,7 @@ namespace Avalonia
}
else
{
Dispatcher.UIThread.InvokeAsync(() => _owner.Completed(this));
Dispatcher.UIThread.Post(() => _owner.Completed(this));
}
}
}

2
src/Avalonia.Base/Threading/AvaloniaScheduler.cs

@ -33,7 +33,7 @@ namespace Avalonia.Threading
if (!Dispatcher.UIThread.CheckAccess())
{
var cancellation = new CancellationDisposable();
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
if (!cancellation.Token.IsCancellationRequested)
{

4
src/Avalonia.Base/Threading/AvaloniaSynchronizationContext.cs

@ -36,7 +36,7 @@ namespace Avalonia.Threading
/// <inheritdoc/>
public override void Post(SendOrPostCallback d, object state)
{
Dispatcher.UIThread.InvokeAsync(() => d(state), DispatcherPriority.Send);
Dispatcher.UIThread.Post(() => d(state), DispatcherPriority.Send);
}
/// <inheritdoc/>
@ -45,7 +45,7 @@ namespace Avalonia.Threading
if (Dispatcher.UIThread.CheckAccess())
d(state);
else
Dispatcher.UIThread.InvokeTaskAsync(() => d(state), DispatcherPriority.Send).Wait();
Dispatcher.UIThread.InvokeAsync(() => d(state), DispatcherPriority.Send).Wait();
}
}
}

4
src/Avalonia.Base/Threading/Dispatcher.cs

@ -79,13 +79,13 @@ namespace Avalonia.Threading
public void RunJobs(DispatcherPriority minimumPriority) => _jobRunner.RunJobs(minimumPriority);
/// <inheritdoc/>
public Task InvokeTaskAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
public Task InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
return _jobRunner?.InvokeAsync(action, priority);
}
/// <inheritdoc/>
public void InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
public void Post(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
_jobRunner?.Post(action, priority);
}

4
src/Avalonia.Base/Threading/IDispatcher.cs

@ -25,7 +25,7 @@ namespace Avalonia.Threading
/// <param name="action">The method.</param>
/// <param name="priority">The priority with which to invoke the method.</param>
/// <returns>A task that can be used to track the method's execution.</returns>
void InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal);
void Post(Action action, DispatcherPriority priority = DispatcherPriority.Normal);
/// <summary>
/// Post action that will be invoked on main thread
@ -34,6 +34,6 @@ namespace Avalonia.Threading
/// <param name="priority">The priority with which to invoke the method.</param>
// TODO: The naming of this method is confusing: the Async suffix usually means return a task.
// Remove this and rename InvokeTaskAsync as InvokeAsync. See #816.
Task InvokeTaskAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal);
Task InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal);
}
}

2
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -191,7 +191,7 @@ namespace Avalonia.Controls.Presenters
// The measure is currently invalid so there's no point trying to bring the
// current char into view until a measure has been carried out as the scroll
// viewer extents may not be up-to-date.
Dispatcher.UIThread.InvokeAsync(
Dispatcher.UIThread.Post(
() =>
{
var rect = FormattedText.HitTestTextPosition(caretIndex);

4
src/Avalonia.Controls/Primitives/AdornerLayer.cs

@ -18,8 +18,6 @@ namespace Avalonia.Controls.Primitives
private static readonly AttachedProperty<AdornedElementInfo> s_adornedElementInfoProperty =
AvaloniaProperty.RegisterAttached<AdornerLayer, Visual, AdornedElementInfo>("AdornedElementInfo");
private readonly BoundsTracker _tracker = new BoundsTracker();
static AdornerLayer()
{
AdornedElementProperty.Changed.Subscribe(AdornedElementChanged);
@ -118,7 +116,7 @@ namespace Avalonia.Controls.Primitives
adorner.SetValue(s_adornedElementInfoProperty, info);
}
info.Subscription = _tracker.Track(adorned).Subscribe(x =>
info.Subscription = adorned.GetObservable(TransformedBoundsProperty).Subscribe(x =>
{
info.Bounds = x;
InvalidateArrange();

2
src/Avalonia.Controls/Remote/RemoteWidget.cs

@ -18,7 +18,7 @@ namespace Avalonia.Controls.Remote
public RemoteWidget(IAvaloniaRemoteTransportConnection connection)
{
_connection = connection;
_connection.OnMessage += (t, msg) => Dispatcher.UIThread.InvokeAsync(() => OnMessage(msg));
_connection.OnMessage += (t, msg) => Dispatcher.UIThread.Post(() => OnMessage(msg));
_connection.Send(new ClientSupportedPixelFormatsMessage
{
Formats = new[]

10
src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs

@ -46,16 +46,16 @@ namespace Avalonia.Controls.Remote.Server
{
_lastReceivedFrame = lastFrame.SequenceId;
}
Dispatcher.UIThread.InvokeAsync(RenderIfNeeded);
Dispatcher.UIThread.Post(RenderIfNeeded);
}
if (obj is ClientSupportedPixelFormatsMessage supportedFormats)
{
lock (_lock)
_supportedFormats = supportedFormats.Formats;
Dispatcher.UIThread.InvokeAsync(RenderIfNeeded);
Dispatcher.UIThread.Post(RenderIfNeeded);
}
if (obj is MeasureViewportMessage measure)
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
var m = Measure(new Size(measure.Width, measure.Height));
_transport.Send(new MeasureViewportMessage
@ -69,7 +69,7 @@ namespace Avalonia.Controls.Remote.Server
lock (_lock)
{
if (_pendingAllocation == null)
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
ClientViewportAllocatedMessage allocation;
lock (_lock)
@ -168,7 +168,7 @@ namespace Avalonia.Controls.Remote.Server
public override void Invalidate(Rect rect)
{
_invalidated = true;
Dispatcher.UIThread.InvokeAsync(RenderIfNeeded);
Dispatcher.UIThread.Post(RenderIfNeeded);
}
public override IMouseDevice MouseDevice { get; } = new MouseDevice();

2
src/Avalonia.Controls/TreeView.cs

@ -250,7 +250,7 @@ namespace Avalonia.Controls
if (AutoScrollToSelectedItem)
{
Dispatcher.UIThread.InvokeAsync(container.ContainerControl.BringIntoView);
Dispatcher.UIThread.Post(container.ContainerControl.BringIntoView);
}
break;

2
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@ -49,7 +49,7 @@ namespace Avalonia.DesignerSupport.Remote
// In previewer mode we completely ignore client-side viewport size
if (obj is ClientViewportAllocatedMessage alloc)
{
Dispatcher.UIThread.InvokeAsync(() => SetDpi(new Vector(alloc.DpiX, alloc.DpiY)));
Dispatcher.UIThread.Post(() => SetDpi(new Vector(alloc.DpiX, alloc.DpiY)));
return;
}
base.OnMessage(transport, obj);

2
src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs

@ -140,7 +140,7 @@ namespace Avalonia.DesignerSupport.Remote
};
}
private static void OnTransportMessage(IAvaloniaRemoteTransportConnection transport, object obj) => Dispatcher.UIThread.InvokeAsync(() =>
private static void OnTransportMessage(IAvaloniaRemoteTransportConnection transport, object obj) => Dispatcher.UIThread.Post(() =>
{
if (obj is ClientSupportedPixelFormatsMessage formats)
{

2
src/Avalonia.Layout/LayoutManager.cs

@ -203,7 +203,7 @@ namespace Avalonia.Layout
{
if (!_queued && !_running)
{
Dispatcher.UIThread.InvokeAsync(ExecuteLayoutPass, DispatcherPriority.Layout);
Dispatcher.UIThread.Post(ExecuteLayoutPass, DispatcherPriority.Layout);
_queued = true;
}
}

2
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -415,7 +415,7 @@ namespace Avalonia.Rendering
if (!_updateQueued && (_dirty == null || _dirty.Count > 0))
{
_updateQueued = true;
_dispatcher.InvokeAsync(UpdateScene, DispatcherPriority.Render);
_dispatcher.Post(UpdateScene, DispatcherPriority.Render);
}
Scene scene = null;

9
src/Avalonia.Visuals/Rendering/ImmediateRenderer.cs

@ -169,7 +169,7 @@ namespace Avalonia.Rendering
{
foreach (var e in visual.GetSelfAndVisualDescendants())
{
BoundsTracker.SetTransformedBounds((Visual)visual, null);
visual.TransformedBounds = null;
}
}
@ -197,7 +197,7 @@ namespace Avalonia.Rendering
if (filter?.Invoke(visual) != false)
{
bool containsPoint = BoundsTracker.GetTransformedBounds((Visual)visual)?.Contains(p) == true;
bool containsPoint = visual.TransformedBounds?.Contains(p) == true;
if ((containsPoint || !visual.ClipToBounds) && visual.VisualChildren.Count > 0)
{
@ -257,10 +257,7 @@ namespace Avalonia.Rendering
new TransformedBounds(bounds, new Rect(), context.CurrentContainerTransform);
#pragma warning restore 0618
if (visual is Visual)
{
BoundsTracker.SetTransformedBounds((Visual)visual, transformed);
}
visual.TransformedBounds = transformed;
foreach (var child in visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance))
{

12
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -209,11 +209,8 @@ namespace Avalonia.Rendering.SceneGraph
}
catch { }
if (visual is Visual)
{
var transformed = new TransformedBounds(new Rect(visual.Bounds.Size), clip, node.Transform);
BoundsTracker.SetTransformedBounds((Visual)visual, transformed);
}
var transformed = new TransformedBounds(new Rect(visual.Bounds.Size), clip, node.Transform);
visual.TransformedBounds = transformed;
if (forceRecurse)
{
@ -279,10 +276,7 @@ namespace Avalonia.Rendering.SceneGraph
scene.Layers[node.LayerRoot].Dirty.Add(node.Bounds);
if (node.Visual is Visual v)
{
BoundsTracker.SetTransformedBounds(v, null);
}
node.Visual.TransformedBounds = null;
foreach (VisualNode child in node.Children)
{

17
src/Avalonia.Visuals/Visual.cs

@ -32,6 +32,11 @@ namespace Avalonia
public static readonly DirectProperty<Visual, Rect> BoundsProperty =
AvaloniaProperty.RegisterDirect<Visual, Rect>(nameof(Bounds), o => o.Bounds);
public static readonly DirectProperty<Visual, TransformedBounds?> TransformedBoundsProperty =
AvaloniaProperty.RegisterDirect<Visual, TransformedBounds?>(
nameof(TransformedBounds),
o => o.TransformedBounds);
/// <summary>
/// Defines the <see cref="ClipToBounds"/> property.
/// </summary>
@ -87,6 +92,7 @@ namespace Avalonia
AvaloniaProperty.Register<Visual, int>(nameof(ZIndex));
private Rect _bounds;
private TransformedBounds? _transformedBounds;
private IRenderRoot _visualRoot;
private IVisual _visualParent;
@ -135,6 +141,11 @@ namespace Avalonia
protected set { SetAndRaise(BoundsProperty, ref _bounds, value); }
}
/// <summary>
/// Gets the bounds of the control relative to the window, accounting for rendering transforms.
/// </summary>
public TransformedBounds? TransformedBounds => _transformedBounds;
/// <summary>
/// Gets a value indicating whether the control should be clipped to its bounds.
/// </summary>
@ -253,6 +264,12 @@ namespace Avalonia
/// Gets the root of the visual tree, if the control is attached to a visual tree.
/// </summary>
IRenderRoot IVisual.VisualRoot => VisualRoot;
TransformedBounds? IVisual.TransformedBounds
{
get { return _transformedBounds; }
set { SetAndRaise(TransformedBoundsProperty, ref _transformedBounds, value); }
}
/// <summary>
/// Invalidates the visual and queues a repaint.

51
src/Avalonia.Visuals/VisualTree/BoundsTracker.cs

@ -1,51 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Avalonia.VisualTree
{
/// <summary>
/// Tracks the bounds of a control.
/// </summary>
/// <remarks>
/// This class is used to track a controls's bounds for hit testing.
/// TODO: This shouldn't be implemented as an attached property: it would be more performant
/// to just store bounds in some sort of central repository.
/// </remarks>
public class BoundsTracker
{
/// <summary>
/// Defines the TransformedBounds attached property.
/// </summary>
private static AttachedProperty<TransformedBounds?> TransformedBoundsProperty =
AvaloniaProperty.RegisterAttached<BoundsTracker, Visual, TransformedBounds?>("TransformedBounds");
/// <summary>
/// Starts tracking the specified visual.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>An observable that returns the tracked bounds.</returns>
public IObservable<TransformedBounds?> Track(Visual visual)
{
return visual.GetObservable(TransformedBoundsProperty);
}
/// <summary>
/// Sets the transformed bounds of the visual.
/// </summary>
/// <param name="visual">The visual.</param>
/// <param name="value">The transformed bounds.</param>
internal static void SetTransformedBounds(Visual visual, TransformedBounds? value)
{
visual.SetValue(TransformedBoundsProperty, value);
}
/// <summary>
/// Gets the transformed bounds of the visual.
/// </summary>
/// <param name="visual">The visual.</param>
/// <returns>The transformed bounds or null if the visual is not visible.</returns>
public static TransformedBounds? GetTransformedBounds(Visual visual) => visual.GetValue(TransformedBoundsProperty);
}
}

5
src/Avalonia.Visuals/VisualTree/IVisual.cs

@ -36,6 +36,11 @@ namespace Avalonia.VisualTree
/// </summary>
Rect Bounds { get; }
/// <summary>
/// Gets the bounds of the control relative to the window, accounting for rendering transforms.
/// </summary>
TransformedBounds? TransformedBounds { get; set; }
/// <summary>
/// Gets a value indicating whether the control should be clipped to its bounds.
/// </summary>

2
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@ -351,7 +351,7 @@ namespace Avalonia.Gtk3
void OnInput(RawInputEventArgs args)
{
Dispatcher.UIThread.InvokeAsync(() => Input?.Invoke(args), DispatcherPriority.Input);
Dispatcher.UIThread.Post(() => Input?.Invoke(args), DispatcherPriority.Input);
}
public Point PointToClient(Point point)

2
src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs

@ -41,7 +41,7 @@ namespace Avalonia.LinuxFramebuffer
if(_renderQueued)
return;
_renderQueued = true;
Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Post(() =>
{
Paint?.Invoke(new Rect(default(Point), ClientSize));
_renderQueued = false;

2
src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs

@ -62,7 +62,7 @@ public static class LinuxFramebufferPlatformExtensions
public TokenClosable(CancellationToken token)
{
token.Register(() => Dispatcher.UIThread.InvokeAsync(() => Closed?.Invoke(this, new EventArgs())));
token.Register(() => Dispatcher.UIThread.Post(() => Closed?.Invoke(this, new EventArgs())));
}
}

2
src/Markup/Avalonia.Markup/Data/Plugins/AvaloniaPropertyAccessorPlugin.cs

@ -104,7 +104,7 @@ namespace Avalonia.Markup.Data.Plugins
protected override void SubscribeCore(IObserver<object> observer)
{
_subscription = Instance.GetWeakObservable(_property).Subscribe(observer);
_subscription = Instance?.GetWeakObservable(_property).Subscribe(observer);
}
}
}

2
src/OSX/Avalonia.MonoMac/TopLevelImpl.cs

@ -107,7 +107,7 @@ namespace Avalonia.MonoMac
if (_nonUiRedrawQueued)
return;
_nonUiRedrawQueued = true;
Dispatcher.UIThread.InvokeAsync(
Dispatcher.UIThread.Post(
() =>
{
lock (SyncRoot)

16
tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.csproj → tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj

@ -1,19 +1,9 @@
<Project>
<PropertyGroup>
<BaseIntermediateOutputPath>obj-Direct2D1</BaseIntermediateOutputPath>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
<OutputPath>bin\Direct2D\$(Configuration)</OutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<DefineConstants>$(DefineConstants);AVALONIA_DIRECT2D</DefineConstants>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Remove="obj\**" />
<None Remove="obj\**" />
<Compile Include="..\Avalonia.RenderTests\**\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj" />
@ -33,7 +23,5 @@
<Import Project="..\..\build\Moq.props" />
<Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\XUnit.props" />
<Import Project="Avalonia.RenderTests.projitems" Label="Shared" />
<Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

2
tests/Avalonia.Direct2D1.UnitTests/Properties/AssemblyInfo.cs

@ -4,7 +4,5 @@
using System.Reflection;
using Xunit;
[assembly: AssemblyTitle("Avalonia.Direct2D1.UnitTests")]
// Don't run tests in parallel.
[assembly: CollectionBehavior(DisableTestParallelization = true)]

12
tests/Avalonia.Markup.UnitTests/Data/ExpressionObserverTests_Observable.cs

@ -103,20 +103,22 @@ namespace Avalonia.Markup.UnitTests.Data
{
using (var sync = UnitTestSynchronizationContext.Begin())
{
var data = new Class1();
var target = new ExpressionObserver(data, "Next^.Foo", true);
var data1 = new Class1();
var data2 = new Class2("foo");
var target = new ExpressionObserver(data1, "Next^.Foo", true);
var result = new List<object>();
var sub = target.Subscribe(x => result.Add(x));
data.Next.OnNext(new Class2("foo"));
data1.Next.OnNext(data2);
sync.ExecutePostedCallbacks();
Assert.Equal(new[] { new BindingNotification("foo") }, result);
sub.Dispose();
Assert.Equal(0, data.PropertyChangedSubscriptionCount);
Assert.Equal(0, data1.PropertyChangedSubscriptionCount);
GC.KeepAlive(data);
GC.KeepAlive(data1);
GC.KeepAlive(data2);
}
}

2
tests/Avalonia.RenderTests/.gitignore

@ -1,2 +0,0 @@
obj-Skia/
obj-Skia/*

33
tests/Avalonia.RenderTests/Avalonia.RenderTests.projitems

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>48840edd-24bf-495d-911e-2eb12ae75d3b</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>Avalonia.RenderTests</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Controls\CustomRenderTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)GeometryClippingTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\RadialGradientBrushTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Media\BitmapTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)OpacityMaskTests.cs" />
<Compile Include="$(MSBuildThisFileDirectory)SVGPathTests.cs" />
<Compile Include="Media\FormattedTextImplTests.cs" />
<Compile Include="Controls\ImageTests.cs" />
<Compile Include="Controls\BorderTests.cs" />
<Compile Include="Media\ImageBrushTests.cs" />
<Compile Include="Media\LinearGradientBrushTests.cs" />
<Compile Include="Media\VisualBrushTests.cs" />
<Compile Include="Shapes\LineTests.cs" />
<Compile Include="Shapes\PathTests.cs" />
<Compile Include="Shapes\EllipseTests.cs" />
<Compile Include="Shapes\PolygonTests.cs" />
<Compile Include="Shapes\PolylineTests.cs" />
<Compile Include="Shapes\RectangleTests.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
</Project>

16
tests/Avalonia.RenderTests/Avalonia.RenderTests.shproj

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>48840edd-24bf-495d-911e-2eb12ae75d3b</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="Avalonia.RenderTests.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>

5
tests/Avalonia.RenderTests/Controls/TextBlockTests.cs

@ -1,6 +1,7 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Media;
@ -20,7 +21,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls
}
[Fact]
public void Wrapping_NoWrap()
public async Task Wrapping_NoWrap()
{
Decorator target = new Decorator
{
@ -38,7 +39,7 @@ namespace Avalonia.Direct2D1.RenderTests.Controls
}
};
RenderToFile(target);
await RenderToFile(target);
CompareImages();
}
}

2
tests/Avalonia.RenderTests/Properties/AssemblyInfo.cs

@ -4,7 +4,5 @@
using System.Reflection;
using Xunit;
[assembly: AssemblyTitle("Avalonia.Direct2D1.RenderTests")]
// Don't run tests in parallel.
[assembly: CollectionBehavior(DisableTestParallelization = true)]

15
tests/Avalonia.RenderTests/TestBase.cs

@ -46,7 +46,8 @@ namespace Avalonia.Direct2D1.RenderTests
public TestBase(string outputPath)
{
var testFiles = Path.GetFullPath(@"..\..\..\..\..\TestFiles\");
var testPath = GetTestsDirectory();
var testFiles = Path.Combine(testPath, "TestFiles");
#if AVALONIA_SKIA
var platform = "Skia";
#else
@ -142,6 +143,18 @@ namespace Avalonia.Direct2D1.RenderTests
}
}
private string GetTestsDirectory()
{
var path = Directory.GetCurrentDirectory();
while (path.Length > 0 && Path.GetFileName(path) != "tests")
{
path = Path.GetDirectoryName(path);
}
return path;
}
private class TestThreadingInterface : IPlatformThreadingInterface
{
public bool CurrentThreadIsLoopThread => MainThread.ManagedThreadId == Thread.CurrentThread.ManagedThreadId;

20
tests/Avalonia.RenderTests/Avalonia.Skia.RenderTests.csproj → tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj

@ -1,21 +1,10 @@
<Project>
<PropertyGroup>
<BaseIntermediateOutputPath>obj-Skia</BaseIntermediateOutputPath>
</PropertyGroup>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
<OutputPath>bin\Skia\$(Configuration)</OutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<DefineConstants>$(DefineConstants);AVALONIA_SKIA;AVALONIA_SKIA_SKIP_FAIL</DefineConstants>
<OutputType>Library</OutputType>
<DefineConstants>AVALONIA_SKIA;AVALONIA_SKIA_SKIP_FAIL</DefineConstants>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Remove="obj\**" />
<None Remove="obj\**" />
<Compile Include="..\Avalonia.RenderTests\**\*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj" />
@ -35,9 +24,6 @@
<Import Project="..\..\build\Moq.props" />
<Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\XUnit.props" />
<Import Project="Avalonia.RenderTests.projitems" Label="Shared" />
<Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
<Import Project="..\..\build\SkiaSharp.props" />
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
</Project>

4
tests/Avalonia.UnitTests/ImmediateDispatcher.cs

@ -14,12 +14,12 @@ namespace Avalonia.UnitTests
return true;
}
public void InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
public void Post(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
action();
}
public Task InvokeTaskAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
public Task InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
{
action();
return Task.FromResult<object>(null);

4
tests/Avalonia.Visuals.UnitTests/Rendering/DeferredRendererTests.cs

@ -24,13 +24,13 @@ namespace Avalonia.Visuals.UnitTests.Rendering
var root = new TestRoot();
var dispatcher = new Mock<IDispatcher>();
dispatcher.Setup(x => x.InvokeAsync(It.IsAny<Action>(), DispatcherPriority.Render))
dispatcher.Setup(x => x.Post(It.IsAny<Action>(), DispatcherPriority.Render))
.Callback<Action, DispatcherPriority>((a, p) => a());
CreateTargetAndRunFrame(root, dispatcher: dispatcher.Object);
dispatcher.Verify(x =>
x.InvokeAsync(
x.Post(
It.Is<Action>(a => a.Method.Name == "UpdateScene"),
DispatcherPriority.Render));
}

5
tests/Avalonia.Visuals.UnitTests/VisualTree/BoundsTrackerTests.cs → tests/Avalonia.Visuals.UnitTests/VisualTree/TransformedBoundsTests.cs

@ -17,14 +17,13 @@ using Avalonia.Platform;
namespace Avalonia.Visuals.UnitTests.VisualTree
{
public class BoundsTrackerTests
public class TransformedBoundsTests
{
[Fact]
public void Should_Track_Bounds()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new BoundsTracker();
var control = default(Rectangle);
var tree = new Decorator
{
@ -46,7 +45,7 @@ namespace Avalonia.Visuals.UnitTests.VisualTree
tree.Arrange(new Rect(0, 0, 100, 100));
ImmediateRenderer.Render(tree, context);
var track = target.Track(control);
var track = control.GetObservable(Visual.TransformedBoundsProperty);
var results = new List<TransformedBounds?>();
track.Subscribe(results.Add);

BIN
tests/TestFiles/Cairo/SVGPath/SVGPath.expected.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

BIN
tests/TestFiles/Skia/Controls/TextBlock/Wrapping_NoWrap.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

2
tools/packages.config

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Cake" version="0.22.2" />
<package id="Cake" version="0.25.0" />
</packages>

Loading…
Cancel
Save