From 4598670693c2acda5ff288bd4e4074e6de6e93ac Mon Sep 17 00:00:00 2001 From: James Crutchley Date: Sat, 5 Oct 2024 00:44:50 -0700 Subject: [PATCH 1/4] Improve layout and fullscreen handling for MediaElement - Wrap content in ScrollView in MediaElementCarouselViewPage.xaml - Replace Border with Grid in MediaElementCollectionViewPage.xaml - Use Grid for complex layout in MediaElementMultipleWindowsPage.cs - Add method for foreground window handle in MauiMediaElement.windows.cs - Refactor AppWindow retrieval and fullscreen handling logic - Add methods for screen size retrieval and popup configuration --- .../MediaElementCarouselViewPage.xaml | 103 ++++++------ .../MediaElementCollectionViewPage.xaml | 52 ++++--- .../MediaElementMultipleWindowsPage.cs | 24 ++- .../Views/MauiMediaElement.windows.cs | 146 ++++++++++-------- 4 files changed, 182 insertions(+), 143 deletions(-) diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml index 2ba3802d16..07bd044e7a 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml @@ -10,39 +10,40 @@ x:Class="CommunityToolkit.Maui.Sample.Pages.Views.MediaElementCarouselViewPage" Padding="0, 20, 0, 0" Title="MediaElement in CarouselView"> - - + \ No newline at end of file diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml index 931bb4fd30..10fb5b1079 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml @@ -28,31 +28,33 @@ - - - - - - - - - + + + + + + + + + + + diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs index ed20588e1a..076bf726d9 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs @@ -20,17 +20,29 @@ public MediaElementMultipleWindowsPage(MediaElementMultipleWindowsViewModel view #if WINDOWS || MACCATALYST secondWindow = new Window(new ContentPage { - Content = new MediaElement + Content = new Grid { - Source = elephantsDreamMp4Url, - ShouldAutoPlay = true + Children = + { + new MediaElement + { + Source = elephantsDreamMp4Url, + ShouldAutoPlay = true + } + } } }); - Content = new MediaElement + Content = new Grid { - Source = buckBunnyMp4Url, - ShouldAutoPlay = true + Children = + { + new MediaElement + { + Source = buckBunnyMp4Url, + ShouldAutoPlay = true + } + } }; #else Content = new Label() diff --git a/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs b/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs index edac52be68..f4d760633c 100644 --- a/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs +++ b/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs @@ -1,3 +1,4 @@ +using System.Runtime.InteropServices; using CommunityToolkit.Maui.Extensions; using CommunityToolkit.Maui.Views; using Microsoft.UI; @@ -7,7 +8,7 @@ using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Media; -using WinRT.Interop; +using Windows.Graphics; using Application = Microsoft.Maui.Controls.Application; using Button = Microsoft.UI.Xaml.Controls.Button; using Colors = Microsoft.UI.Colors; @@ -23,13 +24,16 @@ namespace CommunityToolkit.Maui.Core.Views; /// public class MauiMediaElement : Grid, IDisposable { - static readonly AppWindow appWindow = GetAppWindowForCurrentWindow(); + [DllImport("user32.dll")] + static extern IntPtr GetForegroundWindow(); + + SizeInt32? windowSize; + PointInt32? windowPosition; readonly Popup popup = new(); readonly Grid fullScreenGrid = new(); readonly Grid buttonContainer; readonly Button fullScreenButton; readonly MediaPlayerElement mediaPlayerElement; - // Cannot be static readonly because we need to be able to add icon to multiple instances of the button readonly FontIcon fullScreenIcon = new() { Glyph = "\uE740", FontFamily = new FontFamily("Segoe Fluent Icons") }; readonly FontIcon exitFullScreenIcon = new() { Glyph = "\uE73F", FontFamily = new FontFamily("Segoe Fluent Icons") }; bool doesNavigationBarExistBeforeFullScreen; @@ -111,23 +115,6 @@ protected virtual void Dispose(bool disposing) isDisposed = true; } - static AppWindow GetAppWindowForCurrentWindow() - { - // let's cache the CurrentPage here, since the user can navigate or background the app - // while this method is running - var currentPage = CurrentPage; - - if (currentPage?.GetParentWindow().Handler.PlatformView is not MauiWinUIWindow window) - { - throw new InvalidOperationException($"{nameof(window)} cannot be null."); - } - - var handle = WindowNative.GetWindowHandle(window); - var id = Win32Interop.GetWindowIdFromWindow(handle); - - return AppWindow.GetFromWindowId(id); - } - async void OnMediaPlayerElementPointerMoved(object sender, PointerRoutedEventArgs e) { e.Handled = true; @@ -150,53 +137,90 @@ async void OnMediaPlayerElementPointerMoved(object sender, PointerRoutedEventArg void OnFullScreenButtonClick(object sender, RoutedEventArgs e) { var currentPage = CurrentPage; + var windowHandle = GetForegroundWindow(); + var appWindow = GetAppWindowForWindowHandle(windowHandle); if (appWindow.Presenter.Kind is AppWindowPresenterKind.FullScreen) { - appWindow.SetPresenter(AppWindowPresenterKind.Default); - Shell.SetNavBarIsVisible(CurrentPage, doesNavigationBarExistBeforeFullScreen); - - if (popup.IsOpen) - { - popup.IsOpen = false; - popup.Child = null; - fullScreenGrid.Children.Clear(); - } - fullScreenButton.Content = fullScreenIcon; - Children.Add(mediaPlayerElement); - Children.Add(buttonContainer); - - var parent = mediaPlayerElement.Parent as FrameworkElement; - mediaPlayerElement.Width = parent?.Width ?? mediaPlayerElement.Width; - mediaPlayerElement.Height = parent?.Height ?? mediaPlayerElement.Height; + ExitFullScreen(appWindow, currentPage); } else { - appWindow.SetPresenter(AppWindowPresenterKind.FullScreen); - doesNavigationBarExistBeforeFullScreen = Shell.GetNavBarIsVisible(currentPage); - Shell.SetNavBarIsVisible(CurrentPage, false); - - var displayInfo = DeviceDisplay.Current.MainDisplayInfo; - mediaPlayerElement.Width = displayInfo.Width / displayInfo.Density; - mediaPlayerElement.Height = displayInfo.Height / displayInfo.Density; - - Children.Clear(); - fullScreenButton.Content = exitFullScreenIcon; - fullScreenGrid.Children.Add(mediaPlayerElement); - fullScreenGrid.Children.Add(buttonContainer); - - popup.XamlRoot = mediaPlayerElement.XamlRoot; - popup.HorizontalOffset = 0; - popup.VerticalOffset = 0; - popup.ShouldConstrainToRootBounds = false; - popup.VerticalAlignment = Microsoft.UI.Xaml.VerticalAlignment.Center; - popup.HorizontalAlignment = Microsoft.UI.Xaml.HorizontalAlignment.Center; - popup.Child = fullScreenGrid; - - if (!popup.IsOpen) - { - popup.IsOpen = true; - } + EnterFullScreen(appWindow, currentPage); + } + } + + static AppWindow GetAppWindowForWindowHandle(IntPtr hwnd) + { + var windowId = Win32Interop.GetWindowIdFromWindow(hwnd); + return AppWindow.GetFromWindowId(windowId); + } + + void ExitFullScreen(AppWindow window, Page currentPage) + { + window.SetPresenter(AppWindowPresenterKind.Default); + Shell.SetNavBarIsVisible(currentPage, doesNavigationBarExistBeforeFullScreen); + + if (popup.IsOpen) + { + popup.IsOpen = false; + popup.Child = null; + fullScreenGrid.Children.Clear(); + } + + fullScreenButton.Content = fullScreenIcon; + Children.Add(mediaPlayerElement); + Children.Add(buttonContainer); + var parent = mediaPlayerElement.Parent as FrameworkElement; + mediaPlayerElement.Width = parent?.Width ?? mediaPlayerElement.Width; + mediaPlayerElement.Height = parent?.Height ?? mediaPlayerElement.Height; + window.Move(windowPosition ?? new PointInt32(0, 0)); + window.Resize(windowSize ?? new SizeInt32((int)mediaPlayerElement.Width, (int)mediaPlayerElement.Height)); + } + + void EnterFullScreen(AppWindow window, Page currentPage) + { + + doesNavigationBarExistBeforeFullScreen = Shell.GetNavBarIsVisible(currentPage); + Shell.SetNavBarIsVisible(currentPage, false); + var (screenWidth, screenHeight) = GetScreenSize(); + + windowSize = window.Size; + windowPosition = new PointInt32(window.Position.X, window.Position.Y); + window.Resize(new SizeInt32((int)screenWidth, (int)screenHeight)); + window.Move(new PointInt32(0, 0)); + window.SetPresenter(AppWindowPresenterKind.FullScreen); + + fullScreenButton.Content = exitFullScreenIcon; + mediaPlayerElement.Width = screenWidth; + mediaPlayerElement.Height = screenHeight; + Children.Clear(); + fullScreenGrid.Children.Add(mediaPlayerElement); + fullScreenGrid.Children.Add(buttonContainer); + + ConfigureAndShowPopup(); + } + + static (double Width, double Height) GetScreenSize() + { + var displayInfo = DeviceDisplay.Current.MainDisplayInfo; + double screenWidth = displayInfo.Width / displayInfo.Density; + double screenHeight = displayInfo.Height / displayInfo.Density; + return (screenWidth, screenHeight); + } + void ConfigureAndShowPopup() + { + popup.XamlRoot = mediaPlayerElement.XamlRoot; + popup.HorizontalOffset = 0; + popup.VerticalOffset = 0; + popup.ShouldConstrainToRootBounds = false; + popup.VerticalAlignment = Microsoft.UI.Xaml.VerticalAlignment.Center; + popup.HorizontalAlignment = Microsoft.UI.Xaml.HorizontalAlignment.Center; + popup.Child = fullScreenGrid; + + if (!popup.IsOpen) + { + popup.IsOpen = true; } } } \ No newline at end of file From 9c87af8a3d6ea07a73dd1769bfc15e1652a74f00 Mon Sep 17 00:00:00 2001 From: James Crutchley Date: Sat, 5 Oct 2024 11:13:56 -0700 Subject: [PATCH 2/4] Enable unsafe code, use partial classes, update imports Modified `CommunityToolkit.Maui.MediaElement.csproj` to allow unsafe code blocks by adding `true`. Changed `MauiMediaElement` class in `MauiMediaElement.windows.cs` to a partial class. Replaced `DllImport` with `LibraryImport` for `GetForegroundWindow` and marked the method as `internal static partial`. --- .../CommunityToolkit.Maui.MediaElement.csproj | 1 + .../Views/MauiMediaElement.windows.cs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CommunityToolkit.Maui.MediaElement/CommunityToolkit.Maui.MediaElement.csproj b/src/CommunityToolkit.Maui.MediaElement/CommunityToolkit.Maui.MediaElement.csproj index 8fab04e6d9..00ff56ef9e 100644 --- a/src/CommunityToolkit.Maui.MediaElement/CommunityToolkit.Maui.MediaElement.csproj +++ b/src/CommunityToolkit.Maui.MediaElement/CommunityToolkit.Maui.MediaElement.csproj @@ -7,6 +7,7 @@ true true true + true 11.0 13.1 diff --git a/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs b/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs index f4d760633c..a7058037f8 100644 --- a/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs +++ b/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs @@ -22,10 +22,10 @@ namespace CommunityToolkit.Maui.Core.Views; /// /// The user-interface element that represents the on Windows. /// -public class MauiMediaElement : Grid, IDisposable +public partial class MauiMediaElement : Grid, IDisposable { - [DllImport("user32.dll")] - static extern IntPtr GetForegroundWindow(); + [LibraryImport("user32.dll")] + internal static partial IntPtr GetForegroundWindow(); SizeInt32? windowSize; PointInt32? windowPosition; From 3639064dae448ca26d42e182b563c7e7ca54f0c6 Mon Sep 17 00:00:00 2001 From: James Crutchley Date: Mon, 14 Oct 2024 22:26:16 -0700 Subject: [PATCH 3/4] Removed Grid as layouts should only be used if multiple visual elements are required. --- .../MediaElementMultipleWindowsPage.cs | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs index 076bf726d9..cc77f1b609 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs @@ -9,8 +9,8 @@ namespace CommunityToolkit.Maui.Sample.Pages.Views; public class MediaElementMultipleWindowsPage : BasePage { - const string buckBunnyMp4Url = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; #if WINDOWS || MACCATALYST + const string buckBunnyMp4Url = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; const string elephantsDreamMp4Url = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4"; readonly Window secondWindow; #endif @@ -20,29 +20,17 @@ public MediaElementMultipleWindowsPage(MediaElementMultipleWindowsViewModel view #if WINDOWS || MACCATALYST secondWindow = new Window(new ContentPage { - Content = new Grid - { - Children = - { - new MediaElement - { - Source = elephantsDreamMp4Url, - ShouldAutoPlay = true - } - } - } + Content = new MediaElement + { + Source = elephantsDreamMp4Url, + ShouldAutoPlay = true + } }); - Content = new Grid + Content = new MediaElement { - Children = - { - new MediaElement - { - Source = buckBunnyMp4Url, - ShouldAutoPlay = true - } - } + Source = buckBunnyMp4Url, + ShouldAutoPlay = true }; #else Content = new Label() From 01bc20e1f4d77deaaf3008e4a8d3f61d4dd1048f Mon Sep 17 00:00:00 2001 From: James Crutchley Date: Fri, 20 Dec 2024 05:11:08 -0800 Subject: [PATCH 4/4] Revert changes to sample pages Update PageExtensions to grab last index window Refactor `MauiMediaElement` --- .../MediaElementCarouselViewPage.xaml | 103 ++++++++-------- .../MediaElementCollectionViewPage.xaml | 52 ++++---- .../MediaElementMultipleWindowsPage.cs | 10 +- .../Extensions/PageExtensions.cs | 2 +- .../Views/MauiMediaElement.windows.cs | 111 +++++++----------- 5 files changed, 125 insertions(+), 153 deletions(-) diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml index 07bd044e7a..2ba3802d16 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCarouselViewPage.xaml @@ -10,40 +10,39 @@ x:Class="CommunityToolkit.Maui.Sample.Pages.Views.MediaElementCarouselViewPage" Padding="0, 20, 0, 0" Title="MediaElement in CarouselView"> - - - - + + \ No newline at end of file diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml index 10fb5b1079..931bb4fd30 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementCollectionViewPage.xaml @@ -28,33 +28,31 @@ - - - - - - - - - - - + + + + + + + + + diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs index 5fb07327f1..98301cb8f3 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementMultipleWindowsPage.cs @@ -9,8 +9,8 @@ namespace CommunityToolkit.Maui.Sample.Pages.Views; public partial class MediaElementMultipleWindowsPage : BasePage { -#if WINDOWS || MACCATALYST const string buckBunnyMp4Url = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; +#if WINDOWS || MACCATALYST const string elephantsDreamMp4Url = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4"; readonly Window secondWindow; #endif @@ -21,10 +21,10 @@ public MediaElementMultipleWindowsPage(MediaElementMultipleWindowsViewModel view secondWindow = new Window(new ContentPage { Content = new MediaElement - { - Source = elephantsDreamMp4Url, - ShouldAutoPlay = true - } + { + Source = elephantsDreamMp4Url, + ShouldAutoPlay = true + } }); Content = new MediaElement diff --git a/src/CommunityToolkit.Maui.MediaElement/Extensions/PageExtensions.cs b/src/CommunityToolkit.Maui.MediaElement/Extensions/PageExtensions.cs index 62db610fc3..80ae10965e 100644 --- a/src/CommunityToolkit.Maui.MediaElement/Extensions/PageExtensions.cs +++ b/src/CommunityToolkit.Maui.MediaElement/Extensions/PageExtensions.cs @@ -31,7 +31,7 @@ internal static Page GetCurrentPage(this Page currentPage) internal record struct ParentWindow { - static Page CurrentPage => GetCurrentPage(Application.Current?.Windows[0].Page ?? throw new InvalidOperationException($"{nameof(Page)} cannot be null.")); + static Page CurrentPage => GetCurrentPage(Application.Current?.Windows[^1].Page ?? throw new InvalidOperationException($"{nameof(Page)} cannot be null.")); /// /// Checks if the parent window is null. /// diff --git a/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs b/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs index e760ddeb20..fc557837c3 100644 --- a/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs +++ b/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.windows.cs @@ -8,7 +8,6 @@ using Microsoft.UI.Xaml.Controls.Primitives; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Media; -using Windows.Graphics; using Application = Microsoft.Maui.Controls.Application; using Button = Microsoft.UI.Xaml.Controls.Button; using Colors = Microsoft.UI.Colors; @@ -27,13 +26,12 @@ public partial class MauiMediaElement : Grid, IDisposable [LibraryImport("user32.dll")] internal static partial IntPtr GetForegroundWindow(); - SizeInt32? windowSize; - PointInt32? windowPosition; readonly Popup popup = new(); readonly Grid fullScreenGrid = new(); readonly Grid buttonContainer; readonly Button fullScreenButton; readonly MediaPlayerElement mediaPlayerElement; + // Cannot be static readonly because we need to be able to add icon to multiple instances of the button readonly FontIcon fullScreenIcon = new() { Glyph = "\uE740", FontFamily = new FontFamily("Segoe Fluent Icons") }; readonly FontIcon exitFullScreenIcon = new() { Glyph = "\uE73F", FontFamily = new FontFamily("Segoe Fluent Icons") }; bool doesNavigationBarExistBeforeFullScreen; @@ -68,8 +66,9 @@ public MauiMediaElement(MediaPlayerElement mediaPlayerElement) fullScreenButton.Click += OnFullScreenButtonClick; buttonContainer.Children.Add(fullScreenButton); - Children.Add(this.mediaPlayerElement); - Children.Add(buttonContainer); + fullScreenGrid.Children.Add(this.mediaPlayerElement); + fullScreenGrid.Children.Add(buttonContainer); + Children.Add(fullScreenGrid); mediaPlayerElement.PointerMoved += OnMediaPlayerElementPointerMoved; } @@ -92,7 +91,7 @@ public void Dispose() /// Gets the presented page. /// protected static Page CurrentPage => - PageExtensions.GetCurrentPage(Application.Current?.Windows[0].Page ?? throw new InvalidOperationException($"{nameof(Page)} cannot be null.")); + PageExtensions.GetCurrentPage(Application.Current?.Windows[^1]?.Page ?? throw new InvalidOperationException($"{nameof(Page)} cannot be null.")); /// /// Releases the managed and unmanaged resources used by the . @@ -115,9 +114,18 @@ protected virtual void Dispose(bool disposing) isDisposed = true; } + static AppWindow GetAppWindowForWindowHandle(IntPtr hwnd) + { + var windowId = Win32Interop.GetWindowIdFromWindow(hwnd); + return AppWindow.GetFromWindowId(windowId); + } async void OnMediaPlayerElementPointerMoved(object sender, PointerRoutedEventArgs e) { e.Handled = true; + if(buttonContainer is null) + { + return; + } buttonContainer.Visibility = mediaPlayerElement.TransportControls.Visibility; if (mediaPlayerElement.TransportControls.Visibility == Microsoft.UI.Xaml.Visibility.Collapsed) @@ -139,88 +147,55 @@ void OnFullScreenButtonClick(object sender, RoutedEventArgs e) var currentPage = CurrentPage; var windowHandle = GetForegroundWindow(); var appWindow = GetAppWindowForWindowHandle(windowHandle); - if (appWindow.Presenter.Kind is AppWindowPresenterKind.FullScreen) { - ExitFullScreen(appWindow, currentPage); + SetDefaultScreen(appWindow, currentPage); } else { - EnterFullScreen(appWindow, currentPage); + SetFullScreen(appWindow, currentPage); } } - static AppWindow GetAppWindowForWindowHandle(IntPtr hwnd) - { - var windowId = Win32Interop.GetWindowIdFromWindow(hwnd); - return AppWindow.GetFromWindowId(windowId); - } - - void ExitFullScreen(AppWindow window, Page currentPage) + void SetFullScreen(AppWindow appWindow, Page currentPage) { - window.SetPresenter(AppWindowPresenterKind.Default); - Shell.SetNavBarIsVisible(currentPage, doesNavigationBarExistBeforeFullScreen); - if (popup.IsOpen) { - popup.IsOpen = false; - popup.Child = null; - fullScreenGrid.Children.Clear(); + return; } - - fullScreenButton.Content = fullScreenIcon; - Children.Add(mediaPlayerElement); - Children.Add(buttonContainer); - var parent = mediaPlayerElement.Parent as FrameworkElement; - mediaPlayerElement.Width = parent?.Width ?? mediaPlayerElement.Width; - mediaPlayerElement.Height = parent?.Height ?? mediaPlayerElement.Height; - window.Move(windowPosition ?? new PointInt32(0, 0)); - window.Resize(windowSize ?? new SizeInt32((int)mediaPlayerElement.Width, (int)mediaPlayerElement.Height)); - } - - void EnterFullScreen(AppWindow window, Page currentPage) - { - + doesNavigationBarExistBeforeFullScreen = Shell.GetNavBarIsVisible(currentPage); Shell.SetNavBarIsVisible(currentPage, false); - var (screenWidth, screenHeight) = GetScreenSize(); - - windowSize = window.Size; - windowPosition = new PointInt32(window.Position.X, window.Position.Y); - window.Resize(new SizeInt32((int)screenWidth, (int)screenHeight)); - window.Move(new PointInt32(0, 0)); - window.SetPresenter(AppWindowPresenterKind.FullScreen); + Children.Remove(fullScreenGrid); fullScreenButton.Content = exitFullScreenIcon; - mediaPlayerElement.Width = screenWidth; - mediaPlayerElement.Height = screenHeight; - Children.Clear(); - fullScreenGrid.Children.Add(mediaPlayerElement); - fullScreenGrid.Children.Add(buttonContainer); - - ConfigureAndShowPopup(); - } - - static (double Width, double Height) GetScreenSize() - { + var displayInfo = DeviceDisplay.Current.MainDisplayInfo; - double screenWidth = displayInfo.Width / displayInfo.Density; - double screenHeight = displayInfo.Height / displayInfo.Density; - return (screenWidth, screenHeight); - } - void ConfigureAndShowPopup() - { - popup.XamlRoot = mediaPlayerElement.XamlRoot; - popup.HorizontalOffset = 0; - popup.VerticalOffset = 0; - popup.ShouldConstrainToRootBounds = false; - popup.VerticalAlignment = Microsoft.UI.Xaml.VerticalAlignment.Center; - popup.HorizontalAlignment = Microsoft.UI.Xaml.HorizontalAlignment.Center; + mediaPlayerElement.Height = displayInfo.Height / displayInfo.Density; + + appWindow.SetPresenter(AppWindowPresenterKind.FullScreen); + popup.XamlRoot = XamlRoot; + popup.ShouldConstrainToRootBounds = true; popup.Child = fullScreenGrid; + popup.IsOpen = true; + } - if (!popup.IsOpen) + void SetDefaultScreen(AppWindow appWindow, Page currentPage) + { + if(!popup.IsOpen) { - popup.IsOpen = true; + return; } + + popup.IsOpen = false; + popup.Child = null; + + appWindow.SetPresenter(AppWindowPresenterKind.Default); + Shell.SetNavBarIsVisible(currentPage, doesNavigationBarExistBeforeFullScreen); + + fullScreenButton.Content = fullScreenIcon; + Children.Add(fullScreenGrid); + mediaPlayerElement.Height = double.NaN; + } } \ No newline at end of file