Allow window to remember its size, position and state (GTK + Avalonia) (#4657)
* Update ConfigurationState.cs * Update ConfigurationFileFormat.cs * Update MainWindow.cs * Update ConfigurationFileFormat.cs * Update ConfigurationState.cs * Update MainWindow.cs * Update MainWindow.cs * Update Ryujinx.Ui.Common/Configuration/ConfigurationState.cs Co-authored-by: gdkchan <gab.dark.100@gmail.com> * Update MainWindow.cs * Update Ryujinx/Ui/MainWindow.cs Co-authored-by: gdkchan <gab.dark.100@gmail.com> * Initial properties * Viewmodel adjustments and additions * abstract and monitor dimension changes * Remove position from ViewModel and simplify methods * Remove unused dep * Update configuration and fix typo from AA * review changes * Review changes * Screensize checks - Ava * Review changes 2 * basic review changes * Standardise GTK/Ava functions * Actually call function --------- Co-authored-by: HaizenTrist <123991082+HaizenTrist@users.noreply.github.com> Co-authored-by: gdkchan <gab.dark.100@gmail.com>
This commit is contained in:
parent
3b4ff2d6d9
commit
21c4176157
7 changed files with 189 additions and 15 deletions
|
@ -95,6 +95,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
private string _currentEmulatedGamePath;
|
||||
private AutoResetEvent _rendererWaitEvent;
|
||||
private WindowState _windowState;
|
||||
private double _windowWidth;
|
||||
private double _windowHeight;
|
||||
|
||||
private bool _isActive;
|
||||
|
||||
public ApplicationData ListSelectedApplication;
|
||||
|
@ -623,6 +626,28 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public double WindowWidth
|
||||
{
|
||||
get => _windowWidth;
|
||||
set
|
||||
{
|
||||
_windowWidth = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowHeight
|
||||
{
|
||||
get => _windowHeight;
|
||||
set
|
||||
{
|
||||
_windowHeight = value;
|
||||
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsGrid => Glyph == Glyph.Grid;
|
||||
public bool IsList => Glyph == Glyph.List;
|
||||
|
||||
|
|
|
@ -12,15 +12,14 @@
|
|||
Cursor="{Binding Cursor}"
|
||||
Title="{Binding Title}"
|
||||
WindowState="{Binding WindowState}"
|
||||
Width="1280"
|
||||
Height="777"
|
||||
Width="{Binding WindowWidth}"
|
||||
Height="{Binding WindowHeight}"
|
||||
MinWidth="1092"
|
||||
MinHeight="672"
|
||||
d:DesignHeight="720"
|
||||
d:DesignWidth="1280"
|
||||
x:CompileBindings="True"
|
||||
x:DataType="viewModels:MainWindowViewModel"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d"
|
||||
Focusable="True">
|
||||
<Window.Styles>
|
||||
|
|
|
@ -62,6 +62,8 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
|
||||
DataContext = ViewModel;
|
||||
|
||||
SetWindowSizePosition();
|
||||
|
||||
InitializeComponent();
|
||||
Load();
|
||||
|
||||
|
@ -297,6 +299,51 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
LoadHotKeys();
|
||||
}
|
||||
|
||||
private void SetWindowSizePosition()
|
||||
{
|
||||
PixelPoint SavedPoint = new PixelPoint(ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX,
|
||||
ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY);
|
||||
|
||||
ViewModel.WindowHeight = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight * Program.WindowScaleFactor;
|
||||
ViewModel.WindowWidth = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth * Program.WindowScaleFactor;
|
||||
|
||||
ViewModel.WindowState = ConfigurationState.Instance.Ui.WindowStartup.WindowMaximized.Value is true ? WindowState.Maximized : WindowState.Normal;
|
||||
|
||||
if (CheckScreenBounds(SavedPoint))
|
||||
{
|
||||
Position = SavedPoint;
|
||||
}
|
||||
|
||||
else WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
||||
}
|
||||
|
||||
private bool CheckScreenBounds(PixelPoint configPoint)
|
||||
{
|
||||
for (int i = 0; i < Screens.ScreenCount; i++)
|
||||
{
|
||||
if (Screens.All[i].Bounds.Contains(configPoint))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Warning?.Print(LogClass.Application, $"Failed to find valid start-up coordinates. Defaulting to primary monitor center.");
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
MainWindowViewModel.SaveConfig();
|
||||
}
|
||||
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
|
@ -388,6 +435,8 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
return;
|
||||
}
|
||||
|
||||
SaveWindowSizePosition();
|
||||
|
||||
ApplicationLibrary.CancelLoading();
|
||||
InputManager.Dispose();
|
||||
Program.Exit();
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
/// <summary>
|
||||
/// The current version of the file format
|
||||
/// </summary>
|
||||
public const int CurrentVersion = 46;
|
||||
public const int CurrentVersion = 47;
|
||||
|
||||
/// <summary>
|
||||
/// Version of the configuration file format
|
||||
|
@ -251,6 +251,11 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
/// </summary>
|
||||
public ShownFileTypes ShownFileTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Main window start-up position, size and state
|
||||
/// </summary>
|
||||
public WindowStartup WindowStartup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Language Code for the UI
|
||||
/// </summary>
|
||||
|
|
|
@ -83,6 +83,27 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// Determines main window start-up position, size and state
|
||||
///<summary>
|
||||
public class WindowStartupSettings
|
||||
{
|
||||
public ReactiveObject<int> WindowSizeWidth { get; private set; }
|
||||
public ReactiveObject<int> WindowSizeHeight { get; private set; }
|
||||
public ReactiveObject<int> WindowPositionX { get; private set; }
|
||||
public ReactiveObject<int> WindowPositionY { get; private set; }
|
||||
public ReactiveObject<bool> WindowMaximized { get; private set; }
|
||||
|
||||
public WindowStartupSettings()
|
||||
{
|
||||
WindowSizeWidth = new ReactiveObject<int>();
|
||||
WindowSizeHeight = new ReactiveObject<int>();
|
||||
WindowPositionX = new ReactiveObject<int>();
|
||||
WindowPositionY = new ReactiveObject<int>();
|
||||
WindowMaximized = new ReactiveObject<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to toggle columns in the GUI
|
||||
/// </summary>
|
||||
|
@ -103,6 +124,11 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
/// </summary>
|
||||
public ShownFileTypeSettings ShownFileTypes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines main window start-up position, size and state
|
||||
/// </summary>
|
||||
public WindowStartupSettings WindowStartup { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Language Code for the UI
|
||||
/// </summary>
|
||||
|
@ -164,6 +190,7 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
ColumnSort = new ColumnSortSettings();
|
||||
GameDirs = new ReactiveObject<List<string>>();
|
||||
ShownFileTypes = new ShownFileTypeSettings();
|
||||
WindowStartup = new WindowStartupSettings();
|
||||
EnableCustomTheme = new ReactiveObject<bool>();
|
||||
CustomThemePath = new ReactiveObject<string>();
|
||||
BaseStyle = new ReactiveObject<string>();
|
||||
|
@ -678,6 +705,14 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
NRO = Ui.ShownFileTypes.NRO,
|
||||
NSO = Ui.ShownFileTypes.NSO,
|
||||
},
|
||||
WindowStartup = new WindowStartup
|
||||
{
|
||||
WindowSizeWidth = Ui.WindowStartup.WindowSizeWidth,
|
||||
WindowSizeHeight = Ui.WindowStartup.WindowSizeHeight,
|
||||
WindowPositionX = Ui.WindowStartup.WindowPositionX,
|
||||
WindowPositionY = Ui.WindowStartup.WindowPositionY,
|
||||
WindowMaximized = Ui.WindowStartup.WindowMaximized,
|
||||
},
|
||||
LanguageCode = Ui.LanguageCode,
|
||||
EnableCustomTheme = Ui.EnableCustomTheme,
|
||||
CustomThemePath = Ui.CustomThemePath,
|
||||
|
@ -781,6 +816,11 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
Ui.IsAscendingOrder.Value = true;
|
||||
Ui.StartFullscreen.Value = false;
|
||||
Ui.ShowConsole.Value = true;
|
||||
Ui.WindowStartup.WindowSizeWidth.Value = 1280;
|
||||
Ui.WindowStartup.WindowSizeHeight.Value = 760;
|
||||
Ui.WindowStartup.WindowPositionX.Value = 0;
|
||||
Ui.WindowStartup.WindowPositionY.Value = 0;
|
||||
Ui.WindowStartup.WindowMaximized.Value = false;
|
||||
Hid.EnableKeyboard.Value = false;
|
||||
Hid.EnableMouse.Value = false;
|
||||
Hid.Hotkeys.Value = new KeyboardHotkeys
|
||||
|
@ -1334,13 +1374,29 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
|
||||
if (configurationFileFormat.Version < 46)
|
||||
{
|
||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 45.");
|
||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 46.");
|
||||
|
||||
configurationFileFormat.MultiplayerLanInterfaceId = "0";
|
||||
|
||||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
if (configurationFileFormat.Version < 47)
|
||||
{
|
||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 47.");
|
||||
|
||||
configurationFileFormat.WindowStartup = new WindowStartup
|
||||
{
|
||||
WindowPositionX = 0,
|
||||
WindowPositionY = 0,
|
||||
WindowSizeHeight = 760,
|
||||
WindowSizeWidth = 1280,
|
||||
WindowMaximized = false,
|
||||
};
|
||||
|
||||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
||||
|
@ -1416,6 +1472,11 @@ namespace Ryujinx.Ui.Common.Configuration
|
|||
Ui.ApplicationSort.Value = configurationFileFormat.ApplicationSort;
|
||||
Ui.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
|
||||
Ui.ShowConsole.Value = configurationFileFormat.ShowConsole;
|
||||
Ui.WindowStartup.WindowSizeWidth.Value = configurationFileFormat.WindowStartup.WindowSizeWidth;
|
||||
Ui.WindowStartup.WindowSizeHeight.Value = configurationFileFormat.WindowStartup.WindowSizeHeight;
|
||||
Ui.WindowStartup.WindowPositionX.Value = configurationFileFormat.WindowStartup.WindowPositionX;
|
||||
Ui.WindowStartup.WindowPositionY.Value = configurationFileFormat.WindowStartup.WindowPositionY;
|
||||
Ui.WindowStartup.WindowMaximized.Value = configurationFileFormat.WindowStartup.WindowMaximized;
|
||||
Hid.EnableKeyboard.Value = configurationFileFormat.EnableKeyboard;
|
||||
Hid.EnableMouse.Value = configurationFileFormat.EnableMouse;
|
||||
Hid.Hotkeys.Value = configurationFileFormat.Hotkeys;
|
||||
|
|
11
src/Ryujinx.Ui.Common/Configuration/Ui/WindowStartup.cs
Normal file
11
src/Ryujinx.Ui.Common/Configuration/Ui/WindowStartup.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Ryujinx.Ui.Common.Configuration.Ui
|
||||
{
|
||||
public struct WindowStartup
|
||||
{
|
||||
public int WindowSizeWidth { get; set; }
|
||||
public int WindowSizeHeight { get; set; }
|
||||
public int WindowPositionX { get; set; }
|
||||
public int WindowPositionY { get; set; }
|
||||
public bool WindowMaximized { get; set; }
|
||||
}
|
||||
}
|
|
@ -153,13 +153,8 @@ namespace Ryujinx.Ui
|
|||
|
||||
// Apply custom theme if needed.
|
||||
ThemeHelper.ApplyTheme();
|
||||
Gdk.Monitor monitor = Display.GetMonitor(0);
|
||||
// Sets overridden fields.
|
||||
int monitorWidth = monitor.Geometry.Width * monitor.ScaleFactor;
|
||||
int monitorHeight = monitor.Geometry.Height * monitor.ScaleFactor;
|
||||
|
||||
DefaultWidth = monitorWidth < 1280 ? monitorWidth : 1280;
|
||||
DefaultHeight = monitorHeight < 760 ? monitorHeight : 760;
|
||||
SetWindowSizePosition();
|
||||
|
||||
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
|
||||
Title = $"Ryujinx {Program.Version}";
|
||||
|
@ -1314,6 +1309,7 @@ namespace Ryujinx.Ui
|
|||
{
|
||||
if (!_gameLoaded || !ConfigurationState.Instance.ShowConfirmExit || GtkDialog.CreateExitDialog())
|
||||
{
|
||||
SaveWindowSizePosition();
|
||||
End();
|
||||
}
|
||||
}
|
||||
|
@ -1322,6 +1318,7 @@ namespace Ryujinx.Ui
|
|||
{
|
||||
if (!_gameLoaded || !ConfigurationState.Instance.ShowConfirmExit || GtkDialog.CreateExitDialog())
|
||||
{
|
||||
SaveWindowSizePosition();
|
||||
End();
|
||||
}
|
||||
else
|
||||
|
@ -1330,6 +1327,33 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
}
|
||||
|
||||
private void SetWindowSizePosition()
|
||||
{
|
||||
DefaultWidth = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth;
|
||||
DefaultHeight = ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight;
|
||||
|
||||
Move(ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX, ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY);
|
||||
|
||||
if (ConfigurationState.Instance.Ui.WindowStartup.WindowMaximized)
|
||||
{
|
||||
Maximize();
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveWindowSizePosition()
|
||||
{
|
||||
GetSize(out int windowWidth, out int windowHeight);
|
||||
GetPosition(out int windowXPos, out int windowYPos);
|
||||
|
||||
ConfigurationState.Instance.Ui.WindowStartup.WindowMaximized.Value = IsMaximized;
|
||||
ConfigurationState.Instance.Ui.WindowStartup.WindowSizeWidth.Value = windowWidth;
|
||||
ConfigurationState.Instance.Ui.WindowStartup.WindowSizeHeight.Value = windowHeight;
|
||||
ConfigurationState.Instance.Ui.WindowStartup.WindowPositionX.Value = windowXPos;
|
||||
ConfigurationState.Instance.Ui.WindowStartup.WindowPositionY.Value = windowYPos;
|
||||
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void StopEmulation_Pressed(object sender, EventArgs args)
|
||||
{
|
||||
if (_emulationContext != null)
|
||||
|
|
Loading…
Reference in a new issue