UI: Fix some MainWindow bugs and implement menubar items to change window size. (#6750)
* Do not save window dimensions when maximized. * Implement option to disable window size/position memory. * Remove logging statements * Implement menubar items for common window sizes. * formatting fixes * Set 720p window as a composite value. * Remove unused using * Fix exception paramter. * Force restore window when a size change is requested * Fix some resizing bugs.
This commit is contained in:
parent
65c035cdf8
commit
d0cc13ce0b
8 changed files with 103 additions and 10 deletions
|
@ -15,7 +15,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current version of the file format
|
/// The current version of the file format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int CurrentVersion = 50;
|
public const int CurrentVersion = 51;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
||||||
|
@ -162,6 +162,11 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowConfirmExit { get; set; }
|
public bool ShowConfirmExit { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables save window size, position and state on close.
|
||||||
|
/// </summary>
|
||||||
|
public bool RememberWindowState { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables hardware-accelerated rendering for Avalonia
|
/// Enables hardware-accelerated rendering for Avalonia
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -626,6 +626,11 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> ShowConfirmExit { get; private set; }
|
public ReactiveObject<bool> ShowConfirmExit { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables save window size, position and state on close.
|
||||||
|
/// </summary>
|
||||||
|
public ReactiveObject<bool> RememberWindowState { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables hardware-accelerated rendering for Avalonia
|
/// Enables hardware-accelerated rendering for Avalonia
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -647,6 +652,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
EnableDiscordIntegration = new ReactiveObject<bool>();
|
EnableDiscordIntegration = new ReactiveObject<bool>();
|
||||||
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
CheckUpdatesOnStart = new ReactiveObject<bool>();
|
||||||
ShowConfirmExit = new ReactiveObject<bool>();
|
ShowConfirmExit = new ReactiveObject<bool>();
|
||||||
|
RememberWindowState = new ReactiveObject<bool>();
|
||||||
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
EnableHardwareAcceleration = new ReactiveObject<bool>();
|
||||||
HideCursor = new ReactiveObject<HideCursorMode>();
|
HideCursor = new ReactiveObject<HideCursorMode>();
|
||||||
}
|
}
|
||||||
|
@ -684,6 +690,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
EnableDiscordIntegration = EnableDiscordIntegration,
|
EnableDiscordIntegration = EnableDiscordIntegration,
|
||||||
CheckUpdatesOnStart = CheckUpdatesOnStart,
|
CheckUpdatesOnStart = CheckUpdatesOnStart,
|
||||||
ShowConfirmExit = ShowConfirmExit,
|
ShowConfirmExit = ShowConfirmExit,
|
||||||
|
RememberWindowState = RememberWindowState,
|
||||||
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
||||||
HideCursor = HideCursor,
|
HideCursor = HideCursor,
|
||||||
EnableVsync = Graphics.EnableVsync,
|
EnableVsync = Graphics.EnableVsync,
|
||||||
|
@ -792,6 +799,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
EnableDiscordIntegration.Value = true;
|
EnableDiscordIntegration.Value = true;
|
||||||
CheckUpdatesOnStart.Value = true;
|
CheckUpdatesOnStart.Value = true;
|
||||||
ShowConfirmExit.Value = true;
|
ShowConfirmExit.Value = true;
|
||||||
|
RememberWindowState.Value = true;
|
||||||
EnableHardwareAcceleration.Value = true;
|
EnableHardwareAcceleration.Value = true;
|
||||||
HideCursor.Value = HideCursorMode.OnIdle;
|
HideCursor.Value = HideCursorMode.OnIdle;
|
||||||
Graphics.EnableVsync.Value = true;
|
Graphics.EnableVsync.Value = true;
|
||||||
|
@ -1459,6 +1467,15 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 51)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 51.");
|
||||||
|
|
||||||
|
configurationFileFormat.RememberWindowState = true;
|
||||||
|
|
||||||
|
configurationFileUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||||
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
||||||
|
@ -1489,6 +1506,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
|
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
|
||||||
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
|
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
|
||||||
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
|
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;
|
||||||
|
RememberWindowState.Value = configurationFileFormat.RememberWindowState;
|
||||||
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
|
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
|
||||||
HideCursor.Value = configurationFileFormat.HideCursor;
|
HideCursor.Value = configurationFileFormat.HideCursor;
|
||||||
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
|
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
"MenuBarToolsManageFileTypes": "Manage file types",
|
"MenuBarToolsManageFileTypes": "Manage file types",
|
||||||
"MenuBarToolsInstallFileTypes": "Install file types",
|
"MenuBarToolsInstallFileTypes": "Install file types",
|
||||||
"MenuBarToolsUninstallFileTypes": "Uninstall file types",
|
"MenuBarToolsUninstallFileTypes": "Uninstall file types",
|
||||||
|
"MenuBarView": "_View",
|
||||||
|
"MenuBarViewWindow": "Window Size",
|
||||||
|
"MenuBarViewWindow720": "720p",
|
||||||
|
"MenuBarViewWindow1080": "1080p",
|
||||||
"MenuBarHelp": "_Help",
|
"MenuBarHelp": "_Help",
|
||||||
"MenuBarHelpCheckForUpdates": "Check for Updates",
|
"MenuBarHelpCheckForUpdates": "Check for Updates",
|
||||||
"MenuBarHelpAbout": "About",
|
"MenuBarHelpAbout": "About",
|
||||||
|
@ -92,6 +96,7 @@
|
||||||
"SettingsTabGeneralEnableDiscordRichPresence": "Enable Discord Rich Presence",
|
"SettingsTabGeneralEnableDiscordRichPresence": "Enable Discord Rich Presence",
|
||||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Check for Updates on Launch",
|
"SettingsTabGeneralCheckUpdatesOnLaunch": "Check for Updates on Launch",
|
||||||
"SettingsTabGeneralShowConfirmExitDialog": "Show \"Confirm Exit\" Dialog",
|
"SettingsTabGeneralShowConfirmExitDialog": "Show \"Confirm Exit\" Dialog",
|
||||||
|
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||||
"SettingsTabGeneralHideCursor": "Hide Cursor:",
|
"SettingsTabGeneralHideCursor": "Hide Cursor:",
|
||||||
"SettingsTabGeneralHideCursorNever": "Never",
|
"SettingsTabGeneralHideCursorNever": "Never",
|
||||||
"SettingsTabGeneralHideCursorOnIdle": "On Idle",
|
"SettingsTabGeneralHideCursorOnIdle": "On Idle",
|
||||||
|
|
|
@ -131,6 +131,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
public bool EnableDiscordIntegration { get; set; }
|
public bool EnableDiscordIntegration { get; set; }
|
||||||
public bool CheckUpdatesOnStart { get; set; }
|
public bool CheckUpdatesOnStart { get; set; }
|
||||||
public bool ShowConfirmExit { get; set; }
|
public bool ShowConfirmExit { get; set; }
|
||||||
|
public bool RememberWindowState { get; set; }
|
||||||
public int HideCursor { get; set; }
|
public int HideCursor { get; set; }
|
||||||
public bool EnableDockedMode { get; set; }
|
public bool EnableDockedMode { get; set; }
|
||||||
public bool EnableKeyboard { get; set; }
|
public bool EnableKeyboard { get; set; }
|
||||||
|
@ -390,6 +391,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
EnableDiscordIntegration = config.EnableDiscordIntegration;
|
EnableDiscordIntegration = config.EnableDiscordIntegration;
|
||||||
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
|
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
|
||||||
ShowConfirmExit = config.ShowConfirmExit;
|
ShowConfirmExit = config.ShowConfirmExit;
|
||||||
|
RememberWindowState = config.RememberWindowState;
|
||||||
HideCursor = (int)config.HideCursor.Value;
|
HideCursor = (int)config.HideCursor.Value;
|
||||||
|
|
||||||
GameDirectories.Clear();
|
GameDirectories.Clear();
|
||||||
|
@ -474,6 +476,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
|
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
|
||||||
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
|
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
|
||||||
config.ShowConfirmExit.Value = ShowConfirmExit;
|
config.ShowConfirmExit.Value = ShowConfirmExit;
|
||||||
|
config.RememberWindowState.Value = RememberWindowState;
|
||||||
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
||||||
|
|
||||||
if (_directoryChanged)
|
if (_directoryChanged)
|
||||||
|
|
|
@ -186,6 +186,12 @@
|
||||||
<MenuItem Header="{locale:Locale MenuBarToolsUninstallFileTypes}" Click="UninstallFileTypes_Click"/>
|
<MenuItem Header="{locale:Locale MenuBarToolsUninstallFileTypes}" Click="UninstallFileTypes_Click"/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarView}">
|
||||||
|
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarViewWindow}">
|
||||||
|
<MenuItem Header="{locale:Locale MenuBarViewWindow720}" Tag="720" Click="ChangeWindowSize_Click" />
|
||||||
|
<MenuItem Header="{locale:Locale MenuBarViewWindow1080}" Tag="1080" Click="ChangeWindowSize_Click" />
|
||||||
|
</MenuItem>
|
||||||
|
</MenuItem>
|
||||||
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarHelp}">
|
<MenuItem VerticalAlignment="Center" Header="{locale:Locale MenuBarHelp}">
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Name="UpdateMenuItem"
|
Name="UpdateMenuItem"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Threading;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using LibHac.Tools.FsSystem.NcaUtils;
|
using LibHac.Tools.FsSystem.NcaUtils;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
@ -211,6 +212,40 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void ChangeWindowSize_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is MenuItem item)
|
||||||
|
{
|
||||||
|
int height;
|
||||||
|
int width;
|
||||||
|
|
||||||
|
switch (item.Tag)
|
||||||
|
{
|
||||||
|
case "720":
|
||||||
|
height = 720;
|
||||||
|
width = 1280;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "1080":
|
||||||
|
height = 1080;
|
||||||
|
width = 1920;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentNullException($"Invalid Tag for {item}");
|
||||||
|
}
|
||||||
|
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
ViewModel.WindowState = WindowState.Normal;
|
||||||
|
|
||||||
|
height += (int)Window.StatusBarHeight + (int)Window.MenuBarHeight;
|
||||||
|
|
||||||
|
Window.Arrange(new Rect(Window.Position.X, Window.Position.Y, width, height));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async void CheckForUpdates(object sender, RoutedEventArgs e)
|
public async void CheckForUpdates(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (Updater.CanUpdate(true))
|
if (Updater.CanUpdate(true))
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
<CheckBox IsChecked="{Binding ShowConfirmExit}">
|
<CheckBox IsChecked="{Binding ShowConfirmExit}">
|
||||||
<TextBlock Text="{locale:Locale SettingsTabGeneralShowConfirmExitDialog}" />
|
<TextBlock Text="{locale:Locale SettingsTabGeneralShowConfirmExitDialog}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
|
<CheckBox IsChecked="{Binding RememberWindowState}">
|
||||||
|
<TextBlock Text="{locale:Locale SettingsTabGeneralRememberWindowState}" />
|
||||||
|
</CheckBox>
|
||||||
<StackPanel Margin="0, 15, 0, 0" Orientation="Horizontal">
|
<StackPanel Margin="0, 15, 0, 0" Orientation="Horizontal">
|
||||||
<TextBlock VerticalAlignment="Center"
|
<TextBlock VerticalAlignment="Center"
|
||||||
Text="{locale:Locale SettingsTabGeneralHideCursor}"
|
Text="{locale:Locale SettingsTabGeneralHideCursor}"
|
||||||
|
|
|
@ -67,8 +67,6 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
|
|
||||||
DataContext = ViewModel;
|
DataContext = ViewModel;
|
||||||
|
|
||||||
SetWindowSizePosition();
|
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Load();
|
Load();
|
||||||
|
|
||||||
|
@ -83,6 +81,8 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
Height = ((Height - barHeight) / Program.WindowScaleFactor) + barHeight;
|
Height = ((Height - barHeight) / Program.WindowScaleFactor) + barHeight;
|
||||||
Width /= Program.WindowScaleFactor;
|
Width /= Program.WindowScaleFactor;
|
||||||
|
|
||||||
|
SetWindowSizePosition();
|
||||||
|
|
||||||
if (Program.PreviewerDetached)
|
if (Program.PreviewerDetached)
|
||||||
{
|
{
|
||||||
InputManager = new InputManager(new AvaloniaKeyboardDriver(this), new SDL2GamepadDriver());
|
InputManager = new InputManager(new AvaloniaKeyboardDriver(this), new SDL2GamepadDriver());
|
||||||
|
@ -324,6 +324,17 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
|
|
||||||
private void SetWindowSizePosition()
|
private void SetWindowSizePosition()
|
||||||
{
|
{
|
||||||
|
if (!ConfigurationState.Instance.RememberWindowState)
|
||||||
|
{
|
||||||
|
ViewModel.WindowHeight = (720 + StatusBarHeight + MenuBarHeight) * Program.WindowScaleFactor;
|
||||||
|
ViewModel.WindowWidth = 1280 * Program.WindowScaleFactor;
|
||||||
|
|
||||||
|
WindowState = WindowState.Normal;
|
||||||
|
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PixelPoint savedPoint = new(ConfigurationState.Instance.UI.WindowStartup.WindowPositionX,
|
PixelPoint savedPoint = new(ConfigurationState.Instance.UI.WindowStartup.WindowPositionX,
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY);
|
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY);
|
||||||
|
|
||||||
|
@ -358,14 +369,18 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
|
|
||||||
private void SaveWindowSizePosition()
|
private void SaveWindowSizePosition()
|
||||||
{
|
{
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight.Value = (int)Height;
|
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)Width;
|
|
||||||
|
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowPositionX.Value = Position.X;
|
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
|
|
||||||
|
|
||||||
ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized;
|
ConfigurationState.Instance.UI.WindowStartup.WindowMaximized.Value = WindowState == WindowState.Maximized;
|
||||||
|
|
||||||
|
// Only save rectangle properties if the window is not in a maximized state.
|
||||||
|
if (WindowState != WindowState.Maximized)
|
||||||
|
{
|
||||||
|
ConfigurationState.Instance.UI.WindowStartup.WindowSizeHeight.Value = (int)Height;
|
||||||
|
ConfigurationState.Instance.UI.WindowStartup.WindowSizeWidth.Value = (int)Width;
|
||||||
|
|
||||||
|
ConfigurationState.Instance.UI.WindowStartup.WindowPositionX.Value = Position.X;
|
||||||
|
ConfigurationState.Instance.UI.WindowStartup.WindowPositionY.Value = Position.Y;
|
||||||
|
}
|
||||||
|
|
||||||
MainWindowViewModel.SaveConfig();
|
MainWindowViewModel.SaveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +492,10 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveWindowSizePosition();
|
if (ConfigurationState.Instance.RememberWindowState)
|
||||||
|
{
|
||||||
|
SaveWindowSizePosition();
|
||||||
|
}
|
||||||
|
|
||||||
ApplicationLibrary.CancelLoading();
|
ApplicationLibrary.CancelLoading();
|
||||||
InputManager.Dispose();
|
InputManager.Dispose();
|
||||||
|
|
Reference in a new issue