diff --git a/UICompositionAnimations/CompositionExtensions.cs b/UICompositionAnimations/CompositionExtensions.cs
index c1136f1..32e9ee6 100644
--- a/UICompositionAnimations/CompositionExtensions.cs
+++ b/UICompositionAnimations/CompositionExtensions.cs
@@ -926,7 +926,7 @@ public static SpriteVisual AttachVisualShadow(
shadow.Opacity = opacity;
sprite.Shadow = shadow;
sprite.Size = new Vector2(width ?? (float)element.Width, height ?? (float)element.Height);
- sprite.Offset = new Vector3(-0.5f, -0.5f, 0);
+ sprite.Offset = new Vector3(offsetX, offsetY, 0);
// Clip it and add it to the visual tree
InsetClip clip = compositor.CreateInsetClip(
diff --git a/UICompositionAnimations/Helpers/ApiInformaitonHelper.cs b/UICompositionAnimations/Helpers/ApiInformaitonHelper.cs
index a6fa1f4..f94d5e1 100644
--- a/UICompositionAnimations/Helpers/ApiInformaitonHelper.cs
+++ b/UICompositionAnimations/Helpers/ApiInformaitonHelper.cs
@@ -1,4 +1,6 @@
using System;
+using Windows.ApplicationModel.Resources.Core;
+using Windows.Foundation.Collections;
using Windows.Foundation.Metadata;
using Windows.System.Profile;
using Windows.UI.Composition;
@@ -184,5 +186,61 @@ public static bool AreBackdropEffectsAvailable
public static bool IsRequiresPointerAvailable => ApiInformation.IsPropertyPresent("Windows.UI.Xaml.Controls.Control", nameof(Control.RequiresPointer));
#endregion
+
+ #region Device family
+
+ private static bool? _IsMobileDevice;
+
+ ///
+ /// Gets whether or not the device is a mobile phone
+ ///
+ public static bool IsMobileDevice
+ {
+ get
+ {
+ if (_IsMobileDevice == null)
+ {
+ try
+ {
+ IObservableMap qualifiers = ResourceContext.GetForCurrentView().QualifierValues;
+ _IsMobileDevice = qualifiers.ContainsKey("DeviceFamily") && qualifiers["DeviceFamily"] == "Mobile";
+ }
+ catch (UnauthorizedAccessException)
+ {
+ // No idea why this should happen
+ return ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");
+ }
+ }
+ return _IsMobileDevice.Value;
+ }
+ }
+
+ private static bool? _IsDesktop;
+
+ ///
+ /// Gets whether or not the device is running Windows 10 Desktop
+ ///
+ public static bool IsDesktop
+ {
+ get
+ {
+ if (_IsDesktop == null)
+ {
+ try
+ {
+ IObservableMap qualifiers = ResourceContext.GetForCurrentView().QualifierValues;
+ _IsDesktop = qualifiers.ContainsKey("DeviceFamily") && qualifiers["DeviceFamily"] == "Desktop";
+ }
+ catch (UnauthorizedAccessException)
+ {
+ // Weird crash, but still...
+ return false;
+ }
+ }
+ return _IsDesktop.Value;
+ }
+ }
+
+ #endregion
}
}
diff --git a/UICompositionAnimations/Helpers/PointerHelper.cs b/UICompositionAnimations/Helpers/PointerHelper.cs
new file mode 100644
index 0000000..b885973
--- /dev/null
+++ b/UICompositionAnimations/Helpers/PointerHelper.cs
@@ -0,0 +1,84 @@
+using System;
+using Windows.Devices.Input;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Input;
+
+namespace UICompositionAnimations.Helpers
+{
+ ///
+ /// A static class with some extension methods to manage different pointer states
+ ///
+ public static class PointerHelper
+ {
+ ///
+ /// Adds an event handler to all the pointer events of the target control
+ ///
+ /// The control to monitor
+ /// An action to call every time a pointer event is raised. The bool parameter
+ /// indicates whether the pointer is moving to or from the control
+ public static void ManageControlPointerStates(this UIElement control, Action action)
+ {
+ // Nested functions that adds the actual handlers
+ void AddHandler(RoutedEvent @event, bool state, Func predicate)
+ {
+ control.AddHandler(@event, new PointerEventHandler((_, e) =>
+ {
+ if (predicate == null || predicate(e.Pointer.PointerDeviceType))
+ {
+ action(e.Pointer.PointerDeviceType, state);
+ }
+ }), true);
+ }
+
+ // Add handlers
+ AddHandler(UIElement.PointerExitedEvent, false, null);
+ AddHandler(UIElement.PointerCaptureLostEvent, false, null);
+ AddHandler(UIElement.PointerCanceledEvent, false, null);
+ AddHandler(UIElement.PointerEnteredEvent, true, p => p != PointerDeviceType.Touch);
+ AddHandler(UIElement.PointerReleasedEvent, false, p => p == PointerDeviceType.Touch);
+ }
+
+ ///
+ /// Adds an event handler to all the pointer events of the target element
+ ///
+ /// The element to monitor
+ /// An action to call every time a pointer event is raised. The bool parameter
+ /// indicates whether the pointer is moving to or from the control
+ public static void ManageHostPointerStates(this UIElement element, Action action)
+ {
+ // Nested functions that adds the actual handlers
+ void AddHandler(RoutedEvent @event, bool state, Func predicate)
+ {
+ element.AddHandler(@event, new PointerEventHandler((_, e) =>
+ {
+ if (predicate == null || predicate(e.Pointer.PointerDeviceType))
+ {
+ action(e.Pointer.PointerDeviceType, state);
+ }
+ }), true);
+ }
+
+ // Add handlers
+ AddHandler(UIElement.PointerExitedEvent, false, null);
+ AddHandler(UIElement.PointerMovedEvent, true, p => p != PointerDeviceType.Touch);
+ }
+
+ ///
+ /// Adds the appropriate handlers to a control to help setup the light effects (skipped when on a mobile phone)
+ ///
+ /// The element to monitor
+ /// An action to call every time the light effects state should be changed
+ public static void ManageLightsPointerStates(this UIElement element, Action action)
+ {
+ // Platform check
+ if (ApiInformationHelper.IsMobileDevice) return;
+
+ // Nested functions that adds the actual handlers
+ element.ManageHostPointerStates((pointer, value) =>
+ {
+ if (pointer != PointerDeviceType.Mouse) return;
+ action(value);
+ });
+ }
+ }
+}
diff --git a/UICompositionAnimations/Properties/AssemblyInfo.cs b/UICompositionAnimations/Properties/AssemblyInfo.cs
index 02256ed..c2f335e 100644
--- a/UICompositionAnimations/Properties/AssemblyInfo.cs
+++ b/UICompositionAnimations/Properties/AssemblyInfo.cs
@@ -23,6 +23,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.7.0.0")]
+[assembly: AssemblyVersion("2.8.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/UICompositionAnimations/UICompositionAnimations.csproj b/UICompositionAnimations/UICompositionAnimations.csproj
index c5921b4..0f62907 100644
--- a/UICompositionAnimations/UICompositionAnimations.csproj
+++ b/UICompositionAnimations/UICompositionAnimations.csproj
@@ -133,6 +133,7 @@
+
diff --git a/UICompositionAnimations/UICompositionAnimations.nuspec b/UICompositionAnimations/UICompositionAnimations.nuspec
index cc9e01b..a37b6cd 100644
--- a/UICompositionAnimations/UICompositionAnimations.nuspec
+++ b/UICompositionAnimations/UICompositionAnimations.nuspec
@@ -2,14 +2,14 @@
Sergio0694.UWP.UICompositionAnimations
- 2.7.0.0
+ 2.8.0.0
UICompositionAnimations
A wrapper UWP PCL to work with Windows.UI.Composition and XAML animations, and Win2D effects
Sergio Pedri
Sergio Pedri
https://github.com/Sergio0694/UICompositionAnimations
false
- Added XAML custom acrylic brush
+ PointerHelper class added, minor bug fixes and improvements
Copyright 2017
uwp composition animations xaml csharp windows winrt universal app ui win2d graphics