Skip to content

Commit

Permalink
Allow window to remember its size, position and state (GTK + Avalonia…
Browse files Browse the repository at this point in the history
…) (#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 <[email protected]>

* Update MainWindow.cs

* Update Ryujinx/Ui/MainWindow.cs

Co-authored-by: gdkchan <[email protected]>

* 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 <[email protected]>
Co-authored-by: gdkchan <[email protected]>
  • Loading branch information
3 people authored Apr 28, 2023
1 parent 3b4ff2d commit 21c4176
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 15 deletions.
25 changes: 25 additions & 0 deletions src/Ryujinx.Ava/UI/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ public class MainWindowViewModel : BaseModel
private string _currentEmulatedGamePath;
private AutoResetEvent _rendererWaitEvent;
private WindowState _windowState;
private double _windowWidth;
private double _windowHeight;

private bool _isActive;

public ApplicationData ListSelectedApplication;
Expand Down Expand Up @@ -622,6 +625,28 @@ internal set
OnPropertyChanged();
}
}

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;
Expand Down
5 changes: 2 additions & 3 deletions src/Ryujinx.Ava/UI/Windows/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
49 changes: 49 additions & 0 deletions src/Ryujinx.Ava/UI/Windows/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public MainWindow()

DataContext = ViewModel;

SetWindowSizePosition();

InitializeComponent();
Load();

Expand Down Expand Up @@ -297,6 +299,51 @@ private void Load()
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);
Expand Down Expand Up @@ -388,6 +435,8 @@ protected override void OnClosing(CancelEventArgs e)
return;
}

SaveWindowSizePosition();

ApplicationLibrary.CancelLoading();
InputManager.Dispose();
Program.Exit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ConfigurationFileFormat
/// <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
Expand Down Expand Up @@ -251,6 +251,11 @@ public class ConfigurationFileFormat
/// </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>
Expand Down
69 changes: 65 additions & 4 deletions src/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,27 @@ public ShownFileTypeSettings()
}
}

// <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>
Expand All @@ -103,6 +124,11 @@ public ShownFileTypeSettings()
/// </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>
Expand Down Expand Up @@ -163,7 +189,8 @@ public UiSection()
GuiColumns = new Columns();
ColumnSort = new ColumnSortSettings();
GameDirs = new ReactiveObject<List<string>>();
ShownFileTypes = new ShownFileTypeSettings();
ShownFileTypes = new ShownFileTypeSettings();
WindowStartup = new WindowStartupSettings();
EnableCustomTheme = new ReactiveObject<bool>();
CustomThemePath = new ReactiveObject<string>();
BaseStyle = new ReactiveObject<string>();
Expand Down Expand Up @@ -663,12 +690,12 @@ public ConfigurationFileFormat ToFileFormat()
FileSizeColumn = Ui.GuiColumns.FileSizeColumn,
PathColumn = Ui.GuiColumns.PathColumn
},
ColumnSort = new ColumnSort
ColumnSort = new ColumnSort
{
SortColumnId = Ui.ColumnSort.SortColumnId,
SortAscending = Ui.ColumnSort.SortAscending
},
GameDirs = Ui.GameDirs,
GameDirs = Ui.GameDirs,
ShownFileTypes = new ShownFileTypes
{
NSP = Ui.ShownFileTypes.NSP,
Expand All @@ -678,6 +705,14 @@ public ConfigurationFileFormat ToFileFormat()
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,
Expand Down Expand Up @@ -781,6 +816,11 @@ public void LoadDefault()
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
Expand Down Expand Up @@ -1334,13 +1374,29 @@ public ConfigurationLoadResult Load(ConfigurationFileFormat configurationFileFor

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;
Expand Down Expand Up @@ -1416,6 +1472,11 @@ public ConfigurationLoadResult Load(ConfigurationFileFormat configurationFileFor
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;
Expand Down
11 changes: 11 additions & 0 deletions src/Ryujinx.Ui.Common/Configuration/Ui/WindowStartup.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
38 changes: 31 additions & 7 deletions src/Ryujinx/Ui/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,8 @@ private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("_mainWin")

// 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}";
Expand Down Expand Up @@ -1314,6 +1309,7 @@ private void Exit_Pressed(object sender, EventArgs args)
{
if (!_gameLoaded || !ConfigurationState.Instance.ShowConfirmExit || GtkDialog.CreateExitDialog())
{
SaveWindowSizePosition();
End();
}
}
Expand All @@ -1322,6 +1318,7 @@ private void Window_Close(object sender, DeleteEventArgs args)
{
if (!_gameLoaded || !ConfigurationState.Instance.ShowConfirmExit || GtkDialog.CreateExitDialog())
{
SaveWindowSizePosition();
End();
}
else
Expand All @@ -1330,6 +1327,33 @@ private void Window_Close(object sender, DeleteEventArgs args)
}
}

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)
Expand Down Expand Up @@ -1831,4 +1855,4 @@ private void RefreshList_Pressed(object sender, ButtonReleaseEventArgs args)
UpdateGameTable();
}
}
}
}

0 comments on commit 21c4176

Please sign in to comment.