Dualscreen updates to new apis and add hinge angle for UWP (#10244)

* Dual Screen sdk updates
- update to newer windows sdk apis
- Add Hinge Angle Events

* - remove reflection call
This commit is contained in:
Shane Neuville 2020-04-13 04:33:32 -06:00 коммит произвёл GitHub
Родитель 8a458aebef
Коммит 723c4bc2f1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 443 добавлений и 188 удалений

Просмотреть файл

@ -1,11 +1,27 @@
<Project>
<PropertyGroup>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">uap10.0.14393;uap10.0.16299;</TargetFrameworks>
<PropertyGroup Condition=" '$(UwpMinTargetFrameworks)' != '' ">
<TargetFrameworks>$(UwpMinTargetFrameworks)</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(UwpMinTargetFrameworks)' == '' ">
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">uap10.0.14393;uap10.0.16299</TargetFrameworks>
<!--<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">uap10.0.14393;uap10.0.16299;uap10.0.18362</TargetFrameworks>-->
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netstandard2.0</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<TargetPlatformVersion Condition="'$(TargetFramework)' == 'uap10.0.14393'">10.0.16299.0</TargetPlatformVersion>
<TargetPlatformVersion Condition="'$(TargetFramework)' == 'uap10.0.16299'">10.0.18362.0</TargetPlatformVersion>
<TargetPlatformVersion Condition="'$(TargetFramework)' == 'uap10.0.18362'">10.0.19559.0</TargetPlatformVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'uap10.0.14393'">
<PropertyGroup Condition=" $(TargetFramework.StartsWith('uap10.0')) ">
<DefineConstants>$(DefineConstants);UWP</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetPlatformVersion) == '10.0.16299.0'">
<DefineConstants>$(DefineConstants);UWP_14393</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetPlatformVersion) == '10.0.18362.0'">
<DefineConstants>$(DefineConstants);UWP_18362</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetPlatformVersion.StartsWith('10.0.19')) ">
<DefineConstants>$(DefineConstants);UWP_18362;UWP_19000</DefineConstants>
</PropertyGroup>
</Project>

Просмотреть файл

@ -2,11 +2,16 @@
<ItemGroup Condition="'$(TargetFramework)' == 'uap10.0.14393' AND '$(OS)' == 'Windows_NT' ">
<PackageReference Include="NETStandard.Library" Version="2.0.1" />
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('uap10.0')) AND '$(OS)' == 'Windows_NT' ">
<ItemGroup Condition="$(TargetFramework.StartsWith('uap10.0')) AND '$(OS)' == 'Windows_NT' AND $(TargetPlatformMinVersion) &lt;= '10.0.16299.0' ">
<SDKReference Include="WindowsMobile, Version=10.0.18362.0">
<Name>Windows Mobile Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('uap10.0')) AND '$(OS)' == 'Windows_NT' AND $(TargetPlatformMinVersion) &gt;= '10.0.18362.0' ">
<SDKReference Include="WindowsMobile, Version=10.0.19559.0">
<Name>Windows Mobile Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('uap10.0')) AND '$(OS)' == 'Windows_NT' ">
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.0.15" />
</ItemGroup>

Просмотреть файл

@ -56,7 +56,6 @@ using Android.Support.V4.Content;
[assembly: ExportRenderer(typeof(ShellGestures.TouchTestView), typeof(ShellGesturesTouchTestViewRenderer))]
[assembly: ExportRenderer(typeof(Issue7249Switch), typeof(Issue7249SwitchRenderer))]
[assembly: ExportRenderer(typeof(Issue9360.Issue9360NavigationPage), typeof(Issue9360NavigationPageRenderer))]
[assembly: ExportRenderer(typeof(Xamarin.Forms.Controls.GalleryPages.TwoPaneViewGalleries.HingeAngleLabel), typeof(HingeAngleLabelRenderer))]
[assembly: ExportRenderer(typeof(Xamarin.Forms.Controls.Tests.TestClasses.CustomButton), typeof(CustomButtonRenderer))]
[assembly: ExportRenderer(typeof(Issue8801.PopupStackLayout), typeof(CustomStackLayoutRenderer))]
@ -67,56 +66,6 @@ using Android.Support.V4.Content;
#endif
namespace Xamarin.Forms.ControlGallery.Android
{
public class HingeAngleLabelRenderer : Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer
{
System.Timers.Timer _hingeTimer;
public HingeAngleLabelRenderer(Context context) : base(context)
{
}
async void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (_hingeTimer == null)
return;
_hingeTimer.Stop();
var hingeAngle = await DualScreen.DualScreenInfo.Current.GetHingeAngleAsync();
Device.BeginInvokeOnMainThread(() =>
{
if (_hingeTimer != null)
Element.Text = hingeAngle.ToString();
});
if(_hingeTimer != null)
_hingeTimer.Start();
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if(_hingeTimer == null)
{
_hingeTimer = new System.Timers.Timer(100);
_hingeTimer.Elapsed += OnTimerElapsed;
_hingeTimer.Start();
}
}
protected override void Dispose(bool disposing)
{
if (_hingeTimer != null)
{
_hingeTimer.Elapsed -= OnTimerElapsed;
_hingeTimer.Stop();
_hingeTimer = null;
}
base.Dispose(disposing);
}
}
public class CustomStackLayoutRenderer : VisualElementRenderer<StackLayout>
{
public CustomStackLayoutRenderer(Context context) : base(context)

Просмотреть файл

@ -33,8 +33,8 @@
</Picker>
<Picker Title="WideModeConfiguration" x:Name="WideModeConfiguration" SelectedIndex="1">
</Picker>
<Label Text="Hinge Angle (only works on Android):"></Label>
<twoPaneGallery:HingeAngleLabel />
<Label Text="Hinge Angle"></Label>
<Label x:Name="lblHingeAngle" />
</StackLayout>
</local:TwoPaneView.Pane1>
<local:TwoPaneView.Pane2>

Просмотреть файл

@ -33,11 +33,21 @@ namespace Xamarin.Forms.Controls.GalleryPages.TwoPaneViewGalleries
protected override void OnAppearing()
{
base.OnAppearing();
PanePriority.SelectedIndex = 0;
TallModeConfiguration.SelectedIndex = 1;
WideModeConfiguration.SelectedIndex = 1;
DualScreen.DualScreenInfo.Current.HingeAngleChanged += OnHingeAngleChanged;
}
protected override void OnDisappearing()
{
DualScreen.DualScreenInfo.Current.HingeAngleChanged -= OnHingeAngleChanged;
}
void OnHingeAngleChanged(object sender, DualScreen.HingeAngleChangedEventArgs e)
{
lblHingeAngle.Text = e.HingeAngleInDegrees.ToString();
}
void Setup(double width, double height)
@ -61,6 +71,4 @@ namespace Xamarin.Forms.Controls.GalleryPages.TwoPaneViewGalleries
Pane2Length.Value = 0.5;
}
}
public class HingeAngleLabel : Label { }
}

Просмотреть файл

@ -6,7 +6,7 @@ using System.Threading.Tasks;
using Windows.Foundation.Metadata;
using Windows.UI.ViewManagement;
#if !UWP_14393
#if UWP_18362
using Windows.UI.WindowManagement;
#endif
@ -18,7 +18,7 @@ namespace Xamarin.Forms.DualScreen
public static class DualScreenHelper
{
#if !UWP_14393
#if UWP_18362
public static bool HasCompactModeSupport()
{

Просмотреть файл

@ -3,12 +3,38 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Device.Display;
namespace Xamarin.Forms.DualScreen
{
public partial class DualScreenInfo : INotifyPropertyChanged
{
static object hingeAngleLock = new object();
public Task<int> GetHingeAngleAsync() => DualScreenService.GetHingeAngleAsync();
void ProcessHingeAngleSubscriberCount(int newCount)
{
lock (hingeAngleLock)
{
if (newCount == 1)
{
DualScreen.DualScreenService.DualScreenServiceImpl.HingeAngleChanged += OnHingeAngleChanged;
}
else if (newCount == 0)
{
DualScreen.DualScreenService.DualScreenServiceImpl.HingeAngleChanged -= OnHingeAngleChanged;
}
}
}
void OnHingeAngleChanged(object sender, HingeSensor.HingeSensorChangedEventArgs e)
{
Device.BeginInvokeOnMainThread(() =>
{
_hingeAngleChanged?.Invoke(this, new HingeAngleChangedEventArgs(e.HingeAngle));
});
}
}
}

Просмотреть файл

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Xamarin.Forms.DualScreen
{
public partial class DualScreenInfo : INotifyPropertyChanged
{
public Task<int> GetHingeAngleAsync() => DualScreenService.GetHingeAngleAsync();
void ProcessHingeAngleSubscriberCount(int newCount) { }
}
}

Просмотреть файл

@ -3,24 +3,37 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Xamarin.Forms.DualScreen
{
public class HingeAngleChangedEventArgs : EventArgs
{
public HingeAngleChangedEventArgs(double hingeAngleInDegrees)
{
HingeAngleInDegrees = hingeAngleInDegrees;
}
public double HingeAngleInDegrees { get; }
}
public partial class DualScreenInfo : INotifyPropertyChanged
{
static Lazy<DualScreenInfo> _dualScreenInfo { get; } = new Lazy<DualScreenInfo>(OnCreate);
public event PropertyChangedEventHandler PropertyChanged;
Rectangle[] _spanningBounds;
Rectangle _hingeBounds;
bool _isLandscape;
TwoPaneViewMode _spanMode;
TwoPaneViewLayoutGuide _twoPaneViewLayoutGuide;
IDualScreenService _dualScreenService;
public static DualScreenInfo Current => _dualScreenInfo.Value;
IDualScreenService _dualScreenService;
IDualScreenService DualScreenService =>
_dualScreenService ?? DependencyService.Get<IDualScreenService>() ?? NoDualScreenServiceImpl.Instance;
static Lazy<DualScreenInfo> _dualScreenInfo { get; } = new Lazy<DualScreenInfo>(OnCreate);
public static DualScreenInfo Current => _dualScreenInfo.Value;
public event PropertyChangedEventHandler PropertyChanged;
public DualScreenInfo(VisualElement layout) : this(layout, null)
{
}
@ -35,10 +48,28 @@ namespace Xamarin.Forms.DualScreen
else
{
_twoPaneViewLayoutGuide = new TwoPaneViewLayoutGuide(layout, dualScreenService);
_twoPaneViewLayoutGuide.PropertyChanged += OnTwoPaneViewLayoutGuideChanged;
_twoPaneViewLayoutGuide.PropertyChanged += OnTwoPaneViewLayoutGuideChanged;
}
}
EventHandler<HingeAngleChangedEventArgs> _hingeAngleChanged;
int subscriberCount = 0;
public event EventHandler<HingeAngleChangedEventArgs> HingeAngleChanged
{
add
{
ProcessHingeAngleSubscriberCount(Interlocked.Increment(ref subscriberCount));
_hingeAngleChanged += value;
}
remove
{
ProcessHingeAngleSubscriberCount(Interlocked.Decrement(ref subscriberCount));
_hingeAngleChanged -= value;
}
}
public Rectangle[] SpanningBounds
{
get => GetSpanningBounds();

Просмотреть файл

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Sensors;
namespace Xamarin.Forms.DualScreen
{
public partial class DualScreenInfo : INotifyPropertyChanged
{
static object hingeAngleLock = new object();
public Task<int> GetHingeAngleAsync() => DualScreenService.GetHingeAngleAsync();
#if UWP_18362
Windows.Devices.Sensors.HingeAngleSensor _angleSensor;
#endif
#if UWP_18362
async void ProcessHingeAngleSubscriberCount(int newCount)
{
try
{
if (_angleSensor == null)
_angleSensor = await Windows.Devices.Sensors.HingeAngleSensor.GetDefaultAsync();
if (_angleSensor == null)
return;
lock (hingeAngleLock)
{
if (newCount == 1)
{
_angleSensor.ReadingChanged += OnReadingChanged;
}
else if(newCount == 0)
{
_angleSensor.ReadingChanged -= OnReadingChanged;
}
}
}
catch(Exception e)
{
Internals.Log.Warning(nameof(DualScreenInfo), $"Failed to retrieve Hinge Angle Sensor {e}");
}
void OnReadingChanged(HingeAngleSensor sender, HingeAngleSensorReadingChangedEventArgs args)
{
Device.BeginInvokeOnMainThread(() =>
{
_hingeAngleChanged?.Invoke(this, new HingeAngleChangedEventArgs(args.Reading.AngleInDegrees));
});
}
}
#else
void ProcessHingeAngleSubscriberCount(int newCount)
{
}
#endif
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Android.App;
using Android.Util;
@ -28,11 +29,10 @@ namespace Xamarin.Forms.DualScreen
internal class DualScreenServiceImpl : IDualScreenService, Platform.Android.DualScreen.IDualScreenService
{
public event EventHandler OnScreenChanged;
ScreenHelper _helper;
bool _isDuo = false;
bool IsDuo => (_helper == null || _HingeService == null || _mainActivity == null || _hingeSensor == null) ? false : _isDuo;
HingeSensor _hingeSensor;
bool IsDuo => (_helper == null || _HingeService == null || _mainActivity == null || _singleUseHingeSensor == null) ? false : _isDuo;
HingeSensor _singleUseHingeSensor;
static Activity _mainActivity;
static DualScreenServiceImpl _HingeService;
bool _isLandscape;
@ -40,6 +40,11 @@ namespace Xamarin.Forms.DualScreen
object _hingeAngleLock = new object();
TaskCompletionSource<int> _gettingHingeAngle;
internal static Activity MainActivity => _mainActivity;
static HingeSensor DefaultHingeSensor;
public event EventHandler OnScreenChanged;
[Internals.Preserve(Conditional = true)]
public DualScreenServiceImpl()
{
@ -77,51 +82,19 @@ namespace Xamarin.Forms.DualScreen
if (!isDuo)
{
_HingeService._helper = null;
_HingeService._hingeSensor = null;
_HingeService._helper = null;
_HingeService.SetupHingeSensors(null);
return;
}
_HingeService._helper = screenHelper;
_HingeService._hingeSensor = new HingeSensor(_mainActivity);
_HingeService.SetupHingeSensors(_mainActivity);
if (_mainActivity is IDeviceInfoProvider newDeviceInfoProvider)
{
newDeviceInfoProvider.ConfigurationChanged += _HingeService.ConfigurationChanged;
}
}
void ConfigurationChanged(object sender, EventArgs e)
{
if(IsDuo)
_helper?.Update();
bool screenChanged = false;
if (_isLandscape != IsLandscape)
{
_isLandscape = IsLandscape;
screenChanged = true;
}
if (_mainActivity != null)
{
using (DisplayMetrics display = _mainActivity.Resources.DisplayMetrics)
{
var scalingFactor = display.Density;
_pixelScreenSize = new Size(display.WidthPixels, display.HeightPixels);
var newSize = new Size(_pixelScreenSize.Width / scalingFactor, _pixelScreenSize.Height / scalingFactor);
if (newSize != ScaledScreenSize)
{
ScaledScreenSize = newSize;
screenChanged = true;
}
}
}
if(screenChanged)
OnScreenChanged?.Invoke(this, e);
}
public Size ScaledScreenSize
{
get;
@ -131,43 +104,6 @@ namespace Xamarin.Forms.DualScreen
public bool IsSpanned
=> IsDuo && (_helper?.IsDualMode ?? false);
void StartListeningForHingeChanges()
{
if (!IsDuo)
return;
_hingeSensor.OnSensorChanged += OnSensorChanged;
_hingeSensor.StartListening();
}
void StopListeningForHingeChanges()
{
if (!IsDuo)
return;
_hingeSensor.OnSensorChanged -= OnSensorChanged;
_hingeSensor.StopListening();
}
void OnSensorChanged(object sender, HingeSensor.HingeSensorChangedEventArgs e)
{
SetHingeAngle(e.HingeAngle);
}
void SetHingeAngle(int hingeAngle)
{
TaskCompletionSource<int> toSet = null;
lock (_hingeAngleLock)
{
StopListeningForHingeChanges();
toSet = _gettingHingeAngle;
_gettingHingeAngle = null;
}
if (toSet != null)
toSet.SetResult(hingeAngle);
}
public Task<int> GetHingeAngleAsync()
{
if (!IsDuo)
@ -293,6 +229,145 @@ namespace Xamarin.Forms.DualScreen
}
}
}
static EventHandler<HingeSensor.HingeSensorChangedEventArgs> _hingeAngleChanged;
static int subscriberCount;
static object hingeAngleLock = new object();
public static event EventHandler<HingeSensor.HingeSensorChangedEventArgs> HingeAngleChanged
{
add
{
if (DefaultHingeSensor == null)
return;
ProcessHingeAngleSubscriberCount(Interlocked.Increment(ref subscriberCount));
_hingeAngleChanged += value;
}
remove
{
if (DefaultHingeSensor == null)
return;
ProcessHingeAngleSubscriberCount(Interlocked.Decrement(ref subscriberCount));
_hingeAngleChanged -= value;
}
}
static void ProcessHingeAngleSubscriberCount(int subscriberCount)
{
var sensor = DefaultHingeSensor;
if (sensor == null)
return;
lock(hingeAngleLock)
{
if (subscriberCount == 1)
{
sensor.StartListening();
}
else if (subscriberCount == 0)
{
sensor.StopListening();
}
}
}
void DefaultHingeSensorOnSensorChanged(object sender, HingeSensor.HingeSensorChangedEventArgs e)
{
_hingeAngleChanged?.Invoke(this, e);
}
void SetupHingeSensors(global::Android.Content.Context context)
{
if (context == null)
{
if (DefaultHingeSensor != null)
DefaultHingeSensor.OnSensorChanged -= DefaultHingeSensorOnSensorChanged;
_singleUseHingeSensor = null;
DefaultHingeSensor = null;
}
else
{
_singleUseHingeSensor = new HingeSensor(context);
DefaultHingeSensor = new HingeSensor(context);
DefaultHingeSensor.OnSensorChanged += DefaultHingeSensorOnSensorChanged;
}
}
void ConfigurationChanged(object sender, EventArgs e)
{
if (IsDuo)
_helper?.Update();
bool screenChanged = false;
if (_isLandscape != IsLandscape)
{
_isLandscape = IsLandscape;
screenChanged = true;
}
if (_mainActivity != null)
{
using (DisplayMetrics display = _mainActivity.Resources.DisplayMetrics)
{
var scalingFactor = display.Density;
_pixelScreenSize = new Size(display.WidthPixels, display.HeightPixels);
var newSize = new Size(_pixelScreenSize.Width / scalingFactor, _pixelScreenSize.Height / scalingFactor);
if (newSize != ScaledScreenSize)
{
ScaledScreenSize = newSize;
screenChanged = true;
}
}
}
if (screenChanged)
OnScreenChanged?.Invoke(this, e);
}
void StartListeningForHingeChanges()
{
if (!IsDuo)
return;
_singleUseHingeSensor.OnSensorChanged += OnSensorChanged;
_singleUseHingeSensor.StartListening();
}
void StopListeningForHingeChanges()
{
if (!IsDuo)
return;
_singleUseHingeSensor.OnSensorChanged -= OnSensorChanged;
_singleUseHingeSensor.StopListening();
}
void OnSensorChanged(object sender, HingeSensor.HingeSensorChangedEventArgs e)
{
SetHingeAngle(e.HingeAngle);
}
void SetHingeAngle(int hingeAngle)
{
TaskCompletionSource<int> toSet = null;
lock (_hingeAngleLock)
{
StopListeningForHingeChanges();
toSet = _gettingHingeAngle;
_gettingHingeAngle = null;
}
if (toSet != null)
toSet.SetResult(hingeAngle);
}
}
}
}

Просмотреть файл

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation.Metadata;
using Windows.Graphics.Display;
@ -25,32 +27,50 @@ namespace Xamarin.Forms.DualScreen
public DualScreenService()
{
if(Window.Current != null)
if (Window.Current != null)
{
Window.Current.SizeChanged += OnCurrentSizeChanged;
}
}
public Task<int> GetHingeAngleAsync() => Task.FromResult(0);
public async Task<int> GetHingeAngleAsync()
{
if (!ApiInformation.IsMethodPresent("Windows.Devices.Sensors.HingeAngleSensor", "GetDefaultAsync"))
{
return await NoDualScreenServiceImpl.Instance.GetHingeAngleAsync();
}
#if UWP_18362
var sensor = await Windows.Devices.Sensors.HingeAngleSensor.GetDefaultAsync();
if (sensor == null)
return await NoDualScreenServiceImpl.Instance.GetHingeAngleAsync();
var currentReading = await sensor.GetCurrentReadingAsync();
return (int)currentReading.AngleInDegrees;
#else
return await NoDualScreenServiceImpl.Instance.GetHingeAngleAsync();
#endif
}
void OnCurrentSizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
OnScreenChanged?.Invoke(this, EventArgs.Empty);
}
bool IsDualScreenDevice => ApiInformation.IsMethodPresent("Windows.UI.ViewManagement.ApplicationView", "GetSpanningRects");
public bool IsSpanned
{
get
{
if (!IsDualScreenDevice)
return false;
var viewMode = (int)ApplicationView.GetForCurrentView().ViewMode;
var visibleBounds = Window.Current.Bounds;
if (visibleBounds.Height > 1200 || visibleBounds.Width > 1200)
return true;
return false;
switch (viewMode)
{
case 2:
return true;
default:
return false;
}
}
}
@ -59,13 +79,33 @@ namespace Xamarin.Forms.DualScreen
public bool IsLandscape
{
get
{
if (IsSpanned)
return ApplicationView.GetForCurrentView().Orientation == ApplicationViewOrientation.Portrait;
else
return ApplicationView.GetForCurrentView().Orientation == ApplicationViewOrientation.Landscape;
}
}
{
if (!IsSpanned)
return ApplicationView.GetForCurrentView().Orientation == ApplicationViewOrientation.Landscape;
#if UWP_18362
var displayRegions = ApplicationView.GetForCurrentView().GetDisplayRegions();
if (displayRegions.Count == 2)
{
// We are split in two panes. Layout accordingly
if (displayRegions[0].WorkAreaOffset.X != displayRegions[1].WorkAreaOffset.X)
{
return false;
}
else if (displayRegions[0].WorkAreaOffset.Y != displayRegions[1].WorkAreaOffset.Y)
{
return true;
}
else
{
return ApplicationView.GetForCurrentView().Orientation == ApplicationViewOrientation.Landscape;
}
}
#endif
return ApplicationView.GetForCurrentView().Orientation == ApplicationViewOrientation.Landscape;
}
}
public Size ScaledScreenSize
{
@ -78,21 +118,56 @@ namespace Xamarin.Forms.DualScreen
public Rectangle GetHinge()
{
if (!IsDualScreenDevice)
if (!ApiInformation.IsMethodPresent("Windows.UI.ViewManagement.ApplicationView", "GetSpanningRects"))
return Rectangle.Zero;
var screen = DisplayInformation.GetForCurrentView();
if (!IsSpanned)
return Rectangle.Zero;
if (IsLandscape)
{
if (IsSpanned)
return new Rectangle(0, 664 + 24, ScaledPixels(screen.ScreenWidthInRawPixels), 0);
else
return new Rectangle(0, 664, ScaledPixels(screen.ScreenWidthInRawPixels), 0);
}
else
return new Rectangle(720, 0, 0, ScaledPixels(screen.ScreenHeightInRawPixels));
}
var screen = DisplayInformation.GetForCurrentView();
#if UWP_18362
var applicationView = ApplicationView.GetForCurrentView();
List<Windows.Foundation.Rect> spanningRects = null;
#if UWP_19000
spanningRects = applicationView.GetSpanningRects().ToList();
#endif
if (spanningRects?.Count == 2)
{
if(!IsLandscape)
{
var x = spanningRects[0].Width;
var hingeWidth = spanningRects[1].X - x;
return new Rectangle(x, 0, hingeWidth, ScaledPixels(screen.ScreenHeightInRawPixels));
}
else
{
var y = spanningRects[0].Height;
var hingeHeight = spanningRects[1].Y - y;
return new Rectangle(0, y, ScaledPixels(screen.ScreenWidthInRawPixels), hingeHeight);
}
}
#endif
// fall back to hard coded
Rectangle returnValue = Rectangle.Zero;
if (IsLandscape)
{
if (IsSpanned)
returnValue = new Rectangle(0, 664 + 24, ScaledPixels(screen.ScreenWidthInRawPixels), 0);
else
returnValue = new Rectangle(0, 664, ScaledPixels(screen.ScreenWidthInRawPixels), 0);
}
else
returnValue = new Rectangle(720, 0, 0, ScaledPixels(screen.ScreenHeightInRawPixels));
return returnValue;
}
double ScaledPixels(double n)
=> n / DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;

Просмотреть файл

@ -13,15 +13,6 @@
<XamarinAndroidSupportSkipVerifyVersions>true</XamarinAndroidSupportSkipVerifyVersions>
<GenerateLibraryLayout Condition=" $(TargetFramework.StartsWith('uap10.0')) ">false</GenerateLibraryLayout>
</PropertyGroup>
<PropertyGroup Condition="$(TargetPlatformVersion) == 'uap10.0.14393'">
<DefineConstants>$(DefineConstants);UWP_14393</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetPlatformVersion) == 'uap10.0.16299'">
<DefineConstants>$(DefineConstants);UWP_18362</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('uap10.0')) ">
<DefineConstants>$(DefineConstants);UWP</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('MonoAndroid'))">
<DefineConstants>$(DefineConstants);ANDROID</DefineConstants>
</PropertyGroup>

Просмотреть файл

@ -94,13 +94,13 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup Condition="$(TargetFramework) == 'uap10.0.16299'">
<ItemGroup Condition=" '$(OS)' == 'Windows_NT' AND $(TargetFramework.StartsWith('uap10.0')) AND $(TargetPlatformMinVersion) &gt;= '10.0.16299.0'">
<Page Include="Shell\ShellStyles.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup Condition="$(TargetFramework) == 'uap10.0.14393'">
<ItemGroup Condition="'$(OS)' == 'Windows_NT' AND $(TargetFramework.StartsWith('uap10.0')) AND $(TargetPlatformMinVersion) &lt; '10.0.16299.0'">
<Page Remove="Shell\ShellStyles.xaml">
</Page>
</ItemGroup>
@ -114,11 +114,11 @@
<ProjectReference Include="..\Xamarin.Forms.Xaml\Xamarin.Forms.Xaml.csproj">
</ProjectReference>
</ItemGroup>
<ItemGroup Condition=" '$(OS)' == 'Windows_NT' ">
<PackageReference Include="Microsoft.UI.Xaml" Condition="$(TargetFramework) == 'uap10.0.14393'">
<ItemGroup Condition=" '$(OS)' == 'Windows_NT' AND $(TargetFramework.StartsWith('uap10.0')) ">
<PackageReference Include="Microsoft.UI.Xaml" Condition="$(TargetPlatformMinVersion) &lt; '10.0.16299.0'">
<Version>2.1.190606001</Version>
</PackageReference>
<PackageReference Include="Microsoft.UI.Xaml" Condition="$(TargetFramework) == 'uap10.0.16299'">
<PackageReference Include="Microsoft.UI.Xaml" Condition="$(TargetPlatformMinVersion) &gt;= '10.0.16299.0'">
<Version>2.3.191211002</Version>
</PackageReference>
<PackageReference Include="Win2D.uwp">