diff --git a/.gitignore b/.gitignore
index c36f64e5de..640725fa26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -162,7 +162,8 @@ $RECYCLE.BIN/
#################
## Cake
#################
-tools/
+tools/*
+!tools/packages.config
.nuget
artifacts/
nuget
diff --git a/build.cake b/build.cake
index 6518431959..b3822271d4 100644
--- a/build.cake
+++ b/build.cake
@@ -11,7 +11,7 @@
// TOOLS
///////////////////////////////////////////////////////////////////////////////
-#tool "nuget:?package=xunit.runner.console&version=2.1.0"
+#tool "nuget:?package=xunit.runner.console&version=2.2.0"
#tool "nuget:?package=OpenCover"
///////////////////////////////////////////////////////////////////////////////
@@ -98,7 +98,6 @@ Task("Clean")
CleanDirectory(parameters.TestsRoot);
});
-
Task("Restore-NuGet-Packages")
.IsDependentOn("Clean")
.WithCriteria(parameters.IsRunningOnWindows)
@@ -171,23 +170,25 @@ void RunCoreTest(string dir, Parameters parameters, bool net461Only)
continue;
Information("Running for " + fw);
DotNetCoreTest(System.IO.Path.Combine(dir, System.IO.Path.GetFileName(dir)+".csproj"),
- new DotNetCoreTestSettings{Framework = fw});
+ new DotNetCoreTestSettings {
+ Configuration = parameters.Configuration,
+ Framework = fw
+ });
}
}
-
Task("Run-Net-Core-Unit-Tests")
.IsDependentOn("Clean")
.Does(() => {
RunCoreTest("./tests/Avalonia.Base.UnitTests", parameters, false);
- RunCoreTest("./tests/Avalonia.Controls.UnitTests", parameters, true);
- RunCoreTest("./tests/Avalonia.Input.UnitTests", parameters, true);
- RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", parameters, true);
- RunCoreTest("./tests/Avalonia.Layout.UnitTests", parameters, true);
- //RunCoreTest("./tests/Avalonia.Markup.UnitTests", parameters, true);
- //RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", parameters, true);
- RunCoreTest("./tests/Avalonia.Styling.UnitTests", parameters, true);
- RunCoreTest("./tests/Avalonia.Visuals.UnitTests", parameters, true);
+ RunCoreTest("./tests/Avalonia.Controls.UnitTests", parameters, false);
+ RunCoreTest("./tests/Avalonia.Input.UnitTests", parameters, false);
+ RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", parameters, false);
+ RunCoreTest("./tests/Avalonia.Layout.UnitTests", parameters, false);
+ RunCoreTest("./tests/Avalonia.Markup.UnitTests", parameters, false);
+ RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", parameters, false);
+ RunCoreTest("./tests/Avalonia.Styling.UnitTests", parameters, false);
+ RunCoreTest("./tests/Avalonia.Visuals.UnitTests", parameters, false);
});
Task("Run-Unit-Tests")
diff --git a/build/Moq.props b/build/Moq.props
index c8544b8309..55242d922e 100644
--- a/build/Moq.props
+++ b/build/Moq.props
@@ -1,5 +1,5 @@
-
+
diff --git a/build/XUnit.props b/build/XUnit.props
index 58df7e8d3c..27e0afc987 100644
--- a/build/XUnit.props
+++ b/build/XUnit.props
@@ -7,7 +7,9 @@
-
-
+
+
+
+
diff --git a/docs/tutorial/from-wpf.md b/docs/tutorial/from-wpf.md
index aa7a9bc13a..2db40cfd86 100644
--- a/docs/tutorial/from-wpf.md
+++ b/docs/tutorial/from-wpf.md
@@ -33,7 +33,7 @@ placed in a `DataTemplates` collection on each control (and on `Application`):
-
+
diff --git a/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj b/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
index 54a816b0a9..d90a251173 100644
--- a/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
+++ b/samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
@@ -22,6 +22,7 @@
+
diff --git a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
index 28e5e274d0..ac7d25a91e 100644
--- a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
+++ b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
@@ -181,5 +181,6 @@
+
\ No newline at end of file
diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs
index c779031e6c..e9b4ad0a6d 100644
--- a/src/Android/Avalonia.Android/AndroidPlatform.cs
+++ b/src/Android/Avalonia.Android/AndroidPlatform.cs
@@ -51,7 +51,6 @@ namespace Avalonia.Android
.Bind().ToTransient()
.Bind().ToTransient()
.Bind().ToSingleton()
- .Bind().ToSingleton()
.Bind().ToConstant(Instance)
.Bind().ToConstant(ImmediateRenderer.Factory)
.Bind().ToConstant(new AndroidThreadingInterface())
diff --git a/src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs b/src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs
index 9ae79efb48..d52eeb15e4 100644
--- a/src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs
+++ b/src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs
@@ -4,6 +4,8 @@ namespace Avalonia.Android.Platform.Input
{
public class AndroidMouseDevice : MouseDevice
{
+ public static AndroidMouseDevice Instance { get; } = new AndroidMouseDevice();
+
public AndroidMouseDevice()
{
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
index 64dbeb89cc..051a058363 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
@@ -44,7 +44,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public int Width { get; }
public int Height { get; }
public int RowBytes { get; }
- public Size Dpi { get; } = new Size(96, 96);
+ public Vector Dpi { get; } = new Vector(96, 96);
public PixelFormat Format { get; }
[DllImport("android")]
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
index 75772be171..0c62eb9060 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
@@ -10,6 +10,7 @@ using Avalonia.Platform;
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
+using Avalonia.Android.Platform.Input;
using Avalonia.Controls;
using Avalonia.Controls.Platform.Surfaces;
@@ -65,6 +66,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform
}
}
+ public IMouseDevice MouseDevice => AndroidMouseDevice.Instance;
+
public Action Closed { get; set; }
public Action Input { get; set; }
diff --git a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
index 702829b91c..0f90472bd0 100644
--- a/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
+++ b/src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
@@ -71,7 +71,7 @@ namespace Avalonia.Android.Platform.Specific.Helpers
if (x <= _point.X && r >= _point.X && y <= _point.Y && b >= _point.Y)
{
var inputRoot = _getInputRoot();
- var mouseDevice = MouseDevice.Instance;
+ var mouseDevice = Avalonia.Android.Platform.Input.AndroidMouseDevice.Instance;
//in order the controls to work in a predictable way
//we need to generate mouse move before first mouse down event
diff --git a/src/Avalonia.Base/Collections/AvaloniaListExtensions.cs b/src/Avalonia.Base/Collections/AvaloniaListExtensions.cs
index ffb7199619..54cd132b95 100644
--- a/src/Avalonia.Base/Collections/AvaloniaListExtensions.cs
+++ b/src/Avalonia.Base/Collections/AvaloniaListExtensions.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
@@ -59,7 +60,8 @@ namespace Avalonia.Collections
/// the index in the collection and the item.
///
///
- /// An action called when the collection is reset.
+ /// An action called when the collection is reset. This will be followed by calls to
+ /// for each item present in the collection after the reset.
///
/// A disposable used to terminate the subscription.
public static IDisposable ForEachItem(
@@ -68,112 +70,38 @@ namespace Avalonia.Collections
Action removed,
Action reset)
{
- int index;
-
- NotifyCollectionChangedEventHandler handler = (_, e) =>
+ void Add(int index, IList items)
{
- switch (e.Action)
+ foreach (T item in items)
{
- case NotifyCollectionChangedAction.Add:
- index = e.NewStartingIndex;
-
- foreach (T item in e.NewItems)
- {
- added(index++, item);
- }
-
- break;
-
- case NotifyCollectionChangedAction.Replace:
- index = e.OldStartingIndex;
-
- foreach (T item in e.OldItems)
- {
- removed(index++, item);
- }
-
- index = e.NewStartingIndex;
-
- foreach (T item in e.NewItems)
- {
- added(index++, item);
- }
-
- break;
-
- case NotifyCollectionChangedAction.Remove:
- index = e.OldStartingIndex;
-
- foreach (T item in e.OldItems)
- {
- removed(index++, item);
- }
-
- break;
-
- case NotifyCollectionChangedAction.Reset:
- if (reset == null)
- {
- throw new InvalidOperationException(
- "Reset called on collection without reset handler.");
- }
-
- reset();
- break;
+ added(index++, item);
}
- };
+ }
- index = 0;
- foreach (T i in collection)
+ void Remove(int index, IList items)
{
- added(index++, i);
+ for (var i = items.Count - 1; i >= 0; --i)
+ {
+ removed(index + i, (T)items[i]);
+ }
}
- collection.CollectionChanged += handler;
-
- return Disposable.Create(() => collection.CollectionChanged -= handler);
- }
-
- ///
- /// Invokes an action for each item in a collection and subsequently each item added or
- /// removed from the collection.
- ///
- /// The type of the collection items.
- /// The collection.
- ///
- /// An action called initially with all items in the collection and subsequently with a
- /// list of items added to the collection. The parameters passed are the index of the
- /// first item added to the collection and the items added.
- ///
- ///
- /// An action called with all items removed from the collection. The parameters passed
- /// are the index of the first item removed from the collection and the items removed.
- ///
- ///
- /// An action called when the collection is reset.
- ///
- /// A disposable used to terminate the subscription.
- public static IDisposable ForEachItem(
- this IAvaloniaReadOnlyList collection,
- Action> added,
- Action> removed,
- Action reset)
- {
NotifyCollectionChangedEventHandler handler = (_, e) =>
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
- added(e.NewStartingIndex, e.NewItems.Cast());
+ Add(e.NewStartingIndex, e.NewItems);
break;
+ case NotifyCollectionChangedAction.Move:
case NotifyCollectionChangedAction.Replace:
- removed(e.OldStartingIndex, e.OldItems.Cast());
- added(e.NewStartingIndex, e.NewItems.Cast());
+ Remove(e.OldStartingIndex, e.OldItems);
+ Add(e.NewStartingIndex, e.NewItems);
break;
case NotifyCollectionChangedAction.Remove:
- removed(e.OldStartingIndex, e.OldItems.Cast());
+ Remove(e.OldStartingIndex, e.OldItems);
break;
case NotifyCollectionChangedAction.Reset:
@@ -184,16 +112,31 @@ namespace Avalonia.Collections
}
reset();
+ Add(0, (IList)collection);
break;
}
};
- added(0, collection);
+ Add(0, (IList)collection);
collection.CollectionChanged += handler;
return Disposable.Create(() => collection.CollectionChanged -= handler);
}
+ public static IAvaloniaReadOnlyList CreateDerivedList(
+ this IAvaloniaReadOnlyList collection,
+ Func select)
+ {
+ var result = new AvaloniaList();
+
+ collection.ForEachItem(
+ (i, item) => result.Insert(i, select(item)),
+ (i, item) => result.RemoveAt(i),
+ () => result.Clear());
+
+ return result;
+ }
+
///
/// Listens for property changed events from all items in a collection.
///
diff --git a/src/Avalonia.Base/Data/BindingNotification.cs b/src/Avalonia.Base/Data/BindingNotification.cs
index 3394bc4f1a..5510a73b91 100644
--- a/src/Avalonia.Base/Data/BindingNotification.cs
+++ b/src/Avalonia.Base/Data/BindingNotification.cs
@@ -45,11 +45,7 @@ namespace Avalonia.Data
public static readonly BindingNotification UnsetValue =
new BindingNotification(AvaloniaProperty.UnsetValue);
- // Null cannot be held in WeakReference as it's indistinguishable from an expired value so
- // use this value in its place.
- private static readonly object NullValue = new object();
-
- private WeakReference