diff --git a/OnlyM.Core/Models/MonitorChangeDescription.cs b/OnlyM.Core/Models/MonitorChangeDescription.cs index 2c348176..b22dac5c 100644 --- a/OnlyM.Core/Models/MonitorChangeDescription.cs +++ b/OnlyM.Core/Models/MonitorChangeDescription.cs @@ -9,5 +9,6 @@ public enum MonitorChangeDescription WindowToMonitor, WindowToNone, MonitorToNone, + WindowToWindow, } } diff --git a/OnlyM.Core/Services/Options/IOptionsService.cs b/OnlyM.Core/Services/Options/IOptionsService.cs index 9900df89..42bed9af 100644 --- a/OnlyM.Core/Services/Options/IOptionsService.cs +++ b/OnlyM.Core/Services/Options/IOptionsService.cs @@ -22,8 +22,6 @@ public interface IOptionsService event EventHandler MediaMonitorChangedEvent; - event EventHandler MediaWindowSizeChangedEvent; - event EventHandler RenderingMethodChangedEvent; event EventHandler PermanentBackdropChangedEvent; diff --git a/OnlyM.Core/Services/Options/OptionsService.cs b/OnlyM.Core/Services/Options/OptionsService.cs index dfd6a7e3..018bbabf 100644 --- a/OnlyM.Core/Services/Options/OptionsService.cs +++ b/OnlyM.Core/Services/Options/OptionsService.cs @@ -53,9 +53,7 @@ public OptionsService( public event EventHandler? WindowedMediaAlwaysOnTopChangedEvent; public event EventHandler? MediaMonitorChangedEvent; - - public event EventHandler? MediaWindowSizeChangedEvent; - + public event EventHandler? RenderingMethodChangedEvent; public event EventHandler? PermanentBackdropChangedEvent; @@ -468,7 +466,7 @@ public Size MediaWindowSize { _options.Value.MediaWindowSize = value; - MediaWindowSizeChangedEvent?.Invoke(this, EventArgs.Empty); + OnMediaMonitorChangedEvent(MonitorChangeDescription.WindowToWindow); } } } diff --git a/OnlyM.CoreSys/WindowsPositioning/WindowsPlacement.cs b/OnlyM.CoreSys/WindowsPositioning/WindowsPlacement.cs index d4976915..75aae1c9 100644 --- a/OnlyM.CoreSys/WindowsPositioning/WindowsPlacement.cs +++ b/OnlyM.CoreSys/WindowsPositioning/WindowsPlacement.cs @@ -35,6 +35,11 @@ public static class WindowsPlacement private static readonly XmlSerializer Serializer = new(typeof(WINDOWPLACEMENT)); public static void SetPlacement(this Window window, string placementJson) + { + SetPlacement(window, placementJson, Size.Empty); + } + + public static void SetPlacement(this Window window, string placementJson, Size sizeOverride) { if (!string.IsNullOrEmpty(placementJson)) { @@ -55,6 +60,12 @@ public static void SetPlacement(this Window window, string placementJson) placement = obj.Value; } + if (!sizeOverride.IsEmpty) + { + placement.normalPosition.Right = placement.normalPosition.Left + (int)sizeOverride.Width; + placement.normalPosition.Bottom = placement.normalPosition.Top + (int)sizeOverride.Height; + } + placement.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)); placement.flags = 0; placement.showCmd = placement.showCmd == SwShowMinimized ? SwShowNormal : placement.showCmd; diff --git a/OnlyM/Services/MediaWindowPositionHelper.cs b/OnlyM/Services/MediaWindowPositionHelper.cs index 467f60e0..47ec857d 100644 --- a/OnlyM/Services/MediaWindowPositionHelper.cs +++ b/OnlyM/Services/MediaWindowPositionHelper.cs @@ -66,11 +66,15 @@ public static void PositionMediaWindow( } } - public static void PositionMediaWindowWindowed(MediaWindow mediaWindow) + public static void PositionMediaWindowWindowed(MediaWindow mediaWindow, Size windowSize, bool restorePosition) { mediaWindow.IsWindowed = true; - PrepareForWindowedDisplay(mediaWindow); - mediaWindow.RestoreWindowPositionAndSize(); + PrepareForWindowedDisplay(mediaWindow, windowSize); + + if (restorePosition) + { + mediaWindow.RestoreWindowPositionAndSize(); + } } private static void PrepareForFullScreenMonitorDisplay(Window mediaWindow) @@ -80,9 +84,19 @@ private static void PrepareForFullScreenMonitorDisplay(Window mediaWindow) mediaWindow.WindowStyle = WindowStyle.None; } - private static void PrepareForWindowedDisplay(Window mediaWindow) + private static void PrepareForWindowedDisplay(Window mediaWindow, Size windowSize) { - mediaWindow.ResizeMode = ResizeMode.CanResize; + if (windowSize.IsEmpty) + { + mediaWindow.ResizeMode = ResizeMode.CanResize; + } + else + { + mediaWindow.ResizeMode = ResizeMode.CanMinimize; + mediaWindow.Width = windowSize.Width; + mediaWindow.Height = windowSize.Height; + } + mediaWindow.ShowInTaskbar = true; mediaWindow.WindowStyle = WindowStyle.None; } diff --git a/OnlyM/Services/Pages/PageService.cs b/OnlyM/Services/Pages/PageService.cs index e2920301..e87ac76c 100644 --- a/OnlyM/Services/Pages/PageService.cs +++ b/OnlyM/Services/Pages/PageService.cs @@ -221,7 +221,7 @@ public async void ForciblyStopAllPlayback(IReadOnlyCollection activeI } } - private void PositionMediaWindowWindowed() + private void PositionMediaWindowWindowed(bool resizeOnly = false) { CheckMediaWindow(); @@ -230,7 +230,7 @@ private void PositionMediaWindowWindowed() return; } - MediaWindowPositionHelper.PositionMediaWindowWindowed(_mediaWindow); + MediaWindowPositionHelper.PositionMediaWindowWindowed(_mediaWindow, _optionsService.MediaWindowSize, !resizeOnly); _mediaWindow.Topmost = _optionsService.WindowedAlwaysOnTop; @@ -283,7 +283,7 @@ private void OnShutDown(object? sender, ShutDownMessage message) CloseMediaWindow(); } - private void RelocateMediaWindow() + private void RelocateMediaWindow(bool resizeOnly = false) { if (_mediaWindow != null) { @@ -294,7 +294,7 @@ private void RelocateMediaWindow() _mediaWindow.Hide(); _mediaWindow.WindowState = WindowState.Normal; - PositionMediaWindowWindowed(); + PositionMediaWindowWindowed(resizeOnly); if (!isOriginallyVisible) { @@ -452,6 +452,10 @@ private void UpdateMediaMonitor(MonitorChangeDescription change) RelocateMediaWindow(); break; + case MonitorChangeDescription.WindowToWindow: + RelocateMediaWindow(true); + break; + case MonitorChangeDescription.WindowToNone: case MonitorChangeDescription.MonitorToNone: CloseMediaWindow(); diff --git a/OnlyM/ViewModel/MediaViewModel.cs b/OnlyM/ViewModel/MediaViewModel.cs index 9dfdf30a..82f9ce6f 100644 --- a/OnlyM/ViewModel/MediaViewModel.cs +++ b/OnlyM/ViewModel/MediaViewModel.cs @@ -20,16 +20,6 @@ internal class MediaViewModel : ObservableObject private bool _isWebPage; private int _videoRotation; - private double _height = 500; - private double _width = 500; - - private double _minHeight; - private double _minWidth; - private double _maxHeight; - private double _maxWidth; - - private ResizeMode _resizeMode = ResizeMode.CanResize; - public MediaViewModel(IOptionsService optionsService) { _optionsService = optionsService; @@ -37,9 +27,6 @@ public MediaViewModel(IOptionsService optionsService) _optionsService.RenderingMethodChangedEvent += HandleRenderingMethodChangedEvent; _optionsService.MagnifierChangedEvent += HandleMagnifierChangedEvent; _optionsService.BrowserChangedEvent += HandleBrowserChangedEvent; - _optionsService.MediaWindowSizeChangedEvent += HandleMediaWindowSizeChangedEvent; - - HandleMediaWindowSizeChangedEvent(_optionsService, EventArgs.Empty); InitCommands(); } @@ -89,48 +76,6 @@ public Size WindowSize } } - public ResizeMode ResizeMode - { - get => _resizeMode; - private set => SetProperty(ref _resizeMode, value); - } - - public double Height - { - get => _height; - set => SetProperty(ref _height, value); - } - - public double Width - { - get => _width; - set => SetProperty(ref _width, value); - } - - public double MinHeight - { - get => _minHeight; - set => SetProperty(ref _minHeight, value); - } - - public double MinWidth - { - get => _minWidth; - set => SetProperty(ref _minWidth, value); - } - - public double MaxHeight - { - get => _maxHeight; - set => SetProperty(ref _maxHeight, value); - } - - public double MaxWidth - { - get => _maxWidth; - set => SetProperty(ref _maxWidth, value); - } - public double BrowserZoomLevelIncrement { get => _optionsService.BrowserZoomLevelIncrement; @@ -394,32 +339,5 @@ private void HandleBrowserChangedEvent(object? sender, EventArgs e) { OnPropertyChanged(nameof(BrowserZoomLevelIncrement)); } - - private void HandleMediaWindowSizeChangedEvent(object? sender, EventArgs e) - { - if (_optionsService.MediaWindowSize.IsEmpty) - { - MinWidth = 200; - MaxWidth = double.PositiveInfinity; - - MinHeight = 160; - MaxHeight = double.PositiveInfinity; - - ResizeMode = ResizeMode.CanResize; - } - else - { - // Unfortunately just setting ResizeMode doesn't work as expected, so enforce it using min/max - MinWidth = _optionsService.MediaWindowSize.Width; - Width = _optionsService.MediaWindowSize.Width; - MaxWidth = _optionsService.MediaWindowSize.Width; - - MinHeight = _optionsService.MediaWindowSize.Height; - Height = _optionsService.MediaWindowSize.Height; - MaxHeight = _optionsService.MediaWindowSize.Height; - - ResizeMode = ResizeMode.CanMinimize; - } - } } } diff --git a/OnlyM/ViewModel/SettingsViewModel.cs b/OnlyM/ViewModel/SettingsViewModel.cs index f54015f3..4dba9cc6 100644 --- a/OnlyM/ViewModel/SettingsViewModel.cs +++ b/OnlyM/ViewModel/SettingsViewModel.cs @@ -34,6 +34,9 @@ internal class SettingsViewModel : ObservableObject private static readonly Size Size720P = new(1280, 720); private static readonly Size Size1080P = new(1920, 1080); + private static readonly Size MinSize = new(192, 108); + private static readonly Size MaxSize = new(8192, 6144); + private readonly IPageService _pageService; private readonly IMonitorsService _monitorsService; private readonly IOptionsService _optionsService; @@ -924,13 +927,29 @@ public bool MediaWindowFixed public int? MediaWindowWidth { get => MediaWindowSize.IsEmpty ? null : (int)MediaWindowSize.Width; - set => MediaWindowSize = value.HasValue ? new Size(value.Value, MediaWindowSize.Height) : Size.Empty; + set + { + if ((value ?? 0) < 0) + { + return; + } + + MediaWindowSize = value.HasValue ? new Size(value.Value, MediaWindowSize.Height) : Size.Empty; + } } - + public int? MediaWindowHeight { get => MediaWindowSize.IsEmpty ? null : (int)MediaWindowSize.Height; - set => MediaWindowSize = value.HasValue ? new Size(MediaWindowSize.Width, value.Value) : Size.Empty; + set + { + if ((value ?? 0) < 0) + { + return; + } + + MediaWindowSize = value.HasValue ? new Size(MediaWindowSize.Width, value.Value) : Size.Empty; + } } public Size MediaWindowSize @@ -938,7 +957,7 @@ public Size MediaWindowSize get => _optionsService.MediaWindowSize; set { - _optionsService.MediaWindowSize = value; + _optionsService.MediaWindowSize = NormalizeSize(value); OnPropertyChanged(); OnPropertyChanged(nameof(MediaWindowResizable)); OnPropertyChanged(nameof(MediaWindowFixed)); @@ -953,6 +972,35 @@ public Size MediaWindowSize } } + private Size NormalizeSize(Size value) + { + if (value.IsEmpty) + { + return value; + } + + return new Size() + { + Width = LimitNumber(MinSize.Width, value.Width, MaxSize.Width), + Height = LimitNumber(MinSize.Height, value.Height, MaxSize.Height) + }; + } + + private double LimitNumber(double lowerLimitIncl, double value, double upperLimitIncl) + { + if (value < lowerLimitIncl) + { + return lowerLimitIncl; + } + + if (value > upperLimitIncl) + { + return upperLimitIncl; + } + + return value; + } + private void OnShutDown(object? sender, ShutDownMessage obj) { _optionsService.RecentlyUsedMediaFolders = _recentlyUsedMediaFolders.GetFolders().ToList(); diff --git a/OnlyM/Windows/MediaWindow.xaml b/OnlyM/Windows/MediaWindow.xaml index 023ba464..131f98a2 100644 --- a/OnlyM/Windows/MediaWindow.xaml +++ b/OnlyM/Windows/MediaWindow.xaml @@ -12,16 +12,13 @@ mc:Ignorable="d" Title="OnlyM Media Window" AllowsTransparency="False" - Height="{Binding Height, Mode=TwoWay}" - Width="{Binding Width, Mode=TwoWay}" - MaxHeight="{Binding MaxHeight, Mode=OneWay}" - MaxWidth="{Binding MaxWidth, Mode=OneWay}" - MinHeight="{Binding MinHeight, Mode=OneWay}" - MinWidth="{Binding MinWidth, Mode=OneWay}" + Height="500" + Width="500" + MinHeight="108" + MinWidth="192" Closing="WindowClosing" - SizeChanged="WindowSizeChanged" - MouseDown="Window_MouseDown" - ResizeMode="{Binding ResizeMode, Mode=OneWay}" > + SizeChanged="WindowSizeChanged" + MouseDown="Window_MouseDown" >