Merge e6bb6f8d65
into eb212aa91b
This commit is contained in:
commit
650ec8b99f
34 changed files with 794 additions and 4 deletions
|
@ -320,6 +320,11 @@ namespace Ryujinx
|
|||
}
|
||||
}
|
||||
|
||||
if (ConfigurationState.Instance.UI.ShowProfilesAtStartup)
|
||||
{
|
||||
mainWindow.ShowProfilesSelector();
|
||||
}
|
||||
|
||||
if (CommandLineState.LaunchPathArg != null)
|
||||
{
|
||||
mainWindow.RunApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg);
|
||||
|
|
|
@ -887,6 +887,12 @@ namespace Ryujinx.UI
|
|||
return false;
|
||||
}
|
||||
|
||||
public void ShowProfilesSelector()
|
||||
{
|
||||
var window = new UserProfilesSelectorWindow(_accountManager, _contentManager, _virtualFileSystem);
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public void RunApplication(string path, bool startFullscreen = false)
|
||||
{
|
||||
if (_gameLoaded)
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace Ryujinx.UI.Windows
|
|||
[GUI] CheckButton _dockedModeToggle;
|
||||
[GUI] CheckButton _discordToggle;
|
||||
[GUI] CheckButton _checkUpdatesToggle;
|
||||
[GUI] CheckButton _showProfileToggle;
|
||||
[GUI] CheckButton _showConfirmExitToggle;
|
||||
[GUI] RadioButton _hideCursorNever;
|
||||
[GUI] RadioButton _hideCursorOnIdle;
|
||||
|
@ -225,6 +226,11 @@ namespace Ryujinx.UI.Windows
|
|||
_checkUpdatesToggle.Click();
|
||||
}
|
||||
|
||||
if (ConfigurationState.Instance.UI.ShowProfilesAtStartup)
|
||||
{
|
||||
_showProfileToggle.Click();
|
||||
}
|
||||
|
||||
if (ConfigurationState.Instance.ShowConfirmExit)
|
||||
{
|
||||
_showConfirmExitToggle.Click();
|
||||
|
@ -626,6 +632,7 @@ namespace Ryujinx.UI.Windows
|
|||
ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
|
||||
ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
|
||||
ConfigurationState.Instance.CheckUpdatesOnStart.Value = _checkUpdatesToggle.Active;
|
||||
ConfigurationState.Instance.UI.ShowProfilesAtStartup.Value = _showProfileToggle.Active;
|
||||
ConfigurationState.Instance.ShowConfirmExit.Value = _showConfirmExitToggle.Active;
|
||||
ConfigurationState.Instance.HideCursor.Value = hideCursor;
|
||||
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
|
||||
|
|
|
@ -143,6 +143,22 @@
|
|||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="_showProfileToggle">
|
||||
<property name="label" translatable="yes">Show Profiles on Launch</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="receives-default">False</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="draw-indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="_showConfirmExitToggle">
|
||||
<property name="label" translatable="yes">Show "Confirm Exit" Dialog</property>
|
||||
|
@ -156,7 +172,7 @@
|
|||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">5</property>
|
||||
<property name="position">2</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
|
|
160
src/Ryujinx.Gtk3/UI/Windows/UserProfilesSelectorWindow.Designer.cs
generated
Normal file
160
src/Ryujinx.Gtk3/UI/Windows/UserProfilesSelectorWindow.Designer.cs
generated
Normal file
|
@ -0,0 +1,160 @@
|
|||
using Gtk;
|
||||
using Pango;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.UI.Windows
|
||||
{
|
||||
public partial class UserProfilesSelectorWindow : Window
|
||||
{
|
||||
private Box _mainBox;
|
||||
private Label _selectedLabel;
|
||||
private Box _selectedUserBox;
|
||||
private Image _selectedUserImage;
|
||||
private Box _selectedUserInfoBox;
|
||||
private Entry _selectedUserNameEntry;
|
||||
private Label _selectedUserIdLabel;
|
||||
private Box _selectedUserButtonsBox;
|
||||
private Button _saveProfileNameButton;
|
||||
private Button _changeProfileImageButton;
|
||||
private Box _usersTreeViewBox;
|
||||
private Label _availableUsersLabel;
|
||||
private ScrolledWindow _usersTreeViewWindow;
|
||||
private ListStore _tableStore;
|
||||
private TreeView _usersTreeView;
|
||||
private Box _bottomBox;
|
||||
private Button _addButton;
|
||||
private Button _deleteButton;
|
||||
private Button _closeButton;
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
//
|
||||
// UserProfilesManagerWindow
|
||||
//
|
||||
CanFocus = false;
|
||||
Resizable = false;
|
||||
Modal = true;
|
||||
WindowPosition = WindowPosition.Center;
|
||||
DefaultWidth = 620;
|
||||
DefaultHeight = 548;
|
||||
TypeHint = Gdk.WindowTypeHint.Dialog;
|
||||
|
||||
//
|
||||
// _mainBox
|
||||
//
|
||||
_mainBox = new Box(Orientation.Vertical, 0);
|
||||
|
||||
|
||||
//
|
||||
// _viewBox
|
||||
//
|
||||
_usersTreeViewBox = new Box(Orientation.Vertical, 0);
|
||||
|
||||
//
|
||||
// _saveProfileNameButton
|
||||
//
|
||||
_saveProfileNameButton = new Button()
|
||||
{
|
||||
Label = "Save Profile Name",
|
||||
CanFocus = true,
|
||||
ReceivesDefault = true,
|
||||
Sensitive = false,
|
||||
};
|
||||
_saveProfileNameButton.Clicked += EditProfileNameButton_Pressed;
|
||||
|
||||
//
|
||||
// _changeProfileImageButton
|
||||
//
|
||||
_changeProfileImageButton = new Button()
|
||||
{
|
||||
Label = "Change Profile Image",
|
||||
CanFocus = true,
|
||||
ReceivesDefault = true,
|
||||
MarginTop = 10,
|
||||
};
|
||||
_changeProfileImageButton.Clicked += ChangeProfileImageButton_Pressed;
|
||||
|
||||
//
|
||||
// _availableUsersLabel
|
||||
//
|
||||
_availableUsersLabel = new Label("Available User Profiles:")
|
||||
{
|
||||
Margin = 15,
|
||||
Attributes = new AttrList(),
|
||||
Halign = Align.Start,
|
||||
};
|
||||
_availableUsersLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
|
||||
|
||||
//
|
||||
// _usersTreeViewWindow
|
||||
//
|
||||
_usersTreeViewWindow = new ScrolledWindow()
|
||||
{
|
||||
ShadowType = ShadowType.In,
|
||||
CanFocus = true,
|
||||
Expand = true,
|
||||
MarginStart = 30,
|
||||
MarginEnd = 30,
|
||||
MarginBottom = 15,
|
||||
};
|
||||
|
||||
//
|
||||
// _tableStore
|
||||
//
|
||||
_tableStore = new ListStore(typeof(bool), typeof(Gdk.Pixbuf), typeof(string), typeof(Gdk.RGBA));
|
||||
|
||||
//
|
||||
// _usersTreeView
|
||||
//
|
||||
_usersTreeView = new TreeView(_tableStore)
|
||||
{
|
||||
HoverSelection = true,
|
||||
HeadersVisible = false,
|
||||
};
|
||||
_usersTreeView.RowActivated += UsersTreeView_Activated;
|
||||
|
||||
//
|
||||
// _bottomBox
|
||||
//
|
||||
_bottomBox = new Box(Orientation.Horizontal, 0)
|
||||
{
|
||||
MarginStart = 30,
|
||||
MarginEnd = 30,
|
||||
MarginBottom = 15,
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// _closeButton
|
||||
//
|
||||
_closeButton = new Button()
|
||||
{
|
||||
Label = "Close",
|
||||
CanFocus = true,
|
||||
ReceivesDefault = true,
|
||||
HeightRequest = 35,
|
||||
WidthRequest = 80,
|
||||
};
|
||||
_closeButton.Clicked += CloseButton_Pressed;
|
||||
|
||||
ShowComponent();
|
||||
}
|
||||
|
||||
private void ShowComponent()
|
||||
{
|
||||
_usersTreeViewWindow.Add(_usersTreeView);
|
||||
|
||||
_usersTreeViewBox.Add(_usersTreeViewWindow);
|
||||
_bottomBox.PackStart(_addButton, false, false, 0);
|
||||
_bottomBox.PackEnd(_closeButton, false, false, 0);
|
||||
|
||||
_mainBox.PackStart(_availableUsersLabel, false, false, 0);
|
||||
_mainBox.Add(_usersTreeViewBox);
|
||||
_mainBox.Add(_bottomBox);
|
||||
|
||||
Add(_mainBox);
|
||||
|
||||
ShowAll();
|
||||
}
|
||||
}
|
||||
}
|
271
src/Ryujinx.Gtk3/UI/Windows/UserProfilesSelectorWindow.cs
Normal file
271
src/Ryujinx.Gtk3/UI/Windows/UserProfilesSelectorWindow.cs
Normal file
|
@ -0,0 +1,271 @@
|
|||
using Gtk;
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using Ryujinx.UI.Common.Configuration;
|
||||
using Ryujinx.UI.Widgets;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
|
||||
namespace Ryujinx.UI.Windows
|
||||
{
|
||||
public partial class UserProfilesSelectorWindow : Window
|
||||
{
|
||||
private readonly AccountManager _accountManager;
|
||||
private readonly ContentManager _contentManager;
|
||||
|
||||
private byte[] _bufferImageProfile;
|
||||
private string _tempNewProfileName;
|
||||
|
||||
private Gdk.RGBA _selectedColor;
|
||||
|
||||
private readonly ManualResetEvent _avatarsPreloadingEvent = new(false);
|
||||
|
||||
public UserProfilesSelectorWindow(AccountManager accountManager, ContentManager contentManager, VirtualFileSystem virtualFileSystem) : base($"Ryujinx {Program.Version} - Manage User Profiles")
|
||||
{
|
||||
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.UI.Common.Resources.Logo_Ryujinx.png");
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
_selectedColor.Red = 0.212;
|
||||
_selectedColor.Green = 0.843;
|
||||
_selectedColor.Blue = 0.718;
|
||||
_selectedColor.Alpha = 1;
|
||||
|
||||
_accountManager = accountManager;
|
||||
_contentManager = contentManager;
|
||||
|
||||
CellRendererToggle userSelectedToggle = new();
|
||||
userSelectedToggle.Toggled += UserSelectedToggle_Toggled;
|
||||
|
||||
// NOTE: Uncomment following line when multiple selection of user profiles is supported.
|
||||
//_usersTreeView.AppendColumn("Selected", userSelectedToggle, "active", 0);
|
||||
_usersTreeView.AppendColumn("User Icon", new CellRendererPixbuf(), "pixbuf", 1);
|
||||
_usersTreeView.AppendColumn("User Info", new CellRendererText(), "text", 2, "background-rgba", 3);
|
||||
|
||||
_tableStore.SetSortColumnId(0, SortType.Descending);
|
||||
|
||||
RefreshList();
|
||||
|
||||
if (_contentManager.GetCurrentFirmwareVersion() != null)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
AvatarWindow.PreloadAvatars(contentManager, virtualFileSystem);
|
||||
_avatarsPreloadingEvent.Set();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshList()
|
||||
{
|
||||
_tableStore.Clear();
|
||||
|
||||
foreach (UserProfile userProfile in _accountManager.GetAllUsers())
|
||||
{
|
||||
_tableStore.AppendValues(userProfile.AccountState == AccountState.Open, new Gdk.Pixbuf(userProfile.Image, 96, 96), $"{userProfile.Name}\n{userProfile.UserId}", Gdk.RGBA.Zero);
|
||||
|
||||
if (userProfile.AccountState == AccountState.Open)
|
||||
{
|
||||
|
||||
_usersTreeView.Model.GetIterFirst(out TreeIter firstIter);
|
||||
_tableStore.SetValue(firstIter, 3, _selectedColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Events
|
||||
//
|
||||
|
||||
private void UsersTreeView_Activated(object o, RowActivatedArgs args)
|
||||
{
|
||||
SelectUserTreeView();
|
||||
}
|
||||
|
||||
private void UserSelectedToggle_Toggled(object o, ToggledArgs args)
|
||||
{
|
||||
SelectUserTreeView();
|
||||
}
|
||||
|
||||
private void SelectUserTreeView()
|
||||
{
|
||||
// Get selected item informations.
|
||||
_usersTreeView.Selection.GetSelected(out TreeIter selectedIter);
|
||||
|
||||
string userId = _tableStore.GetValue(selectedIter, 2).ToString().Split("\n")[1];
|
||||
|
||||
// Open the selected one.
|
||||
_accountManager.OpenUser(new UserId(userId));
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
private void EditProfileNameButton_Pressed(object sender, EventArgs e)
|
||||
{
|
||||
_saveProfileNameButton.Sensitive = false;
|
||||
|
||||
_accountManager.SetUserName(GetSelectedUserId(), _selectedUserNameEntry.Text);
|
||||
|
||||
RefreshList();
|
||||
}
|
||||
|
||||
private void ProcessProfileImage(byte[] buffer)
|
||||
{
|
||||
using Image image = Image.Load(buffer);
|
||||
|
||||
image.Mutate(x => x.Resize(256, 256));
|
||||
|
||||
using MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream();
|
||||
|
||||
image.SaveAsJpeg(streamJpg);
|
||||
|
||||
_bufferImageProfile = streamJpg.ToArray();
|
||||
}
|
||||
|
||||
private void ProfileImageFileChooser()
|
||||
{
|
||||
FileChooserNative fileChooser = new("Import Custom Profile Image", this, FileChooserAction.Open, "Import", "Cancel")
|
||||
{
|
||||
SelectMultiple = false,
|
||||
};
|
||||
|
||||
FileFilter filter = new()
|
||||
{
|
||||
Name = "Custom Profile Images",
|
||||
};
|
||||
filter.AddPattern("*.jpg");
|
||||
filter.AddPattern("*.jpeg");
|
||||
filter.AddPattern("*.png");
|
||||
filter.AddPattern("*.bmp");
|
||||
|
||||
fileChooser.AddFilter(filter);
|
||||
|
||||
if (fileChooser.Run() == (int)ResponseType.Accept)
|
||||
{
|
||||
ProcessProfileImage(File.ReadAllBytes(fileChooser.Filename));
|
||||
}
|
||||
|
||||
fileChooser.Dispose();
|
||||
}
|
||||
|
||||
private void SelectProfileImage(bool newUser = false)
|
||||
{
|
||||
if (_contentManager.GetCurrentFirmwareVersion() == null)
|
||||
{
|
||||
ProfileImageFileChooser();
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<int, string> buttons = new()
|
||||
{
|
||||
{ 0, "Import Image File" },
|
||||
{ 1, "Select Firmware Avatar" },
|
||||
};
|
||||
|
||||
ResponseType responseDialog = GtkDialog.CreateCustomDialog("Profile Image Selection",
|
||||
"Choose a Profile Image",
|
||||
"You may import a custom profile image, or select an avatar from the system firmware.",
|
||||
buttons, MessageType.Question);
|
||||
|
||||
if (responseDialog == 0)
|
||||
{
|
||||
ProfileImageFileChooser();
|
||||
}
|
||||
else if (responseDialog == (ResponseType)1)
|
||||
{
|
||||
AvatarWindow avatarWindow = new()
|
||||
{
|
||||
NewUser = newUser,
|
||||
};
|
||||
|
||||
avatarWindow.DeleteEvent += AvatarWindow_DeleteEvent;
|
||||
|
||||
avatarWindow.SetSizeRequest((int)(avatarWindow.DefaultWidth * Program.WindowScaleFactor), (int)(avatarWindow.DefaultHeight * Program.WindowScaleFactor));
|
||||
avatarWindow.Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeProfileImageButton_Pressed(object sender, EventArgs e)
|
||||
{
|
||||
if (_contentManager.GetCurrentFirmwareVersion() != null)
|
||||
{
|
||||
_avatarsPreloadingEvent.WaitOne();
|
||||
}
|
||||
|
||||
SelectProfileImage();
|
||||
|
||||
if (_bufferImageProfile != null)
|
||||
{
|
||||
SetUserImage();
|
||||
}
|
||||
}
|
||||
|
||||
private void AvatarWindow_DeleteEvent(object sender, DeleteEventArgs args)
|
||||
{
|
||||
_bufferImageProfile = ((AvatarWindow)sender).SelectedProfileImage;
|
||||
|
||||
if (_bufferImageProfile != null)
|
||||
{
|
||||
if (((AvatarWindow)sender).NewUser)
|
||||
{
|
||||
AddUser();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetUserImage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddUser()
|
||||
{
|
||||
_accountManager.AddUser(_tempNewProfileName, _bufferImageProfile);
|
||||
|
||||
_bufferImageProfile = null;
|
||||
_tempNewProfileName = "";
|
||||
|
||||
RefreshList();
|
||||
}
|
||||
|
||||
private void SetUserImage()
|
||||
{
|
||||
_accountManager.SetUserImage(GetSelectedUserId(), _bufferImageProfile);
|
||||
|
||||
_bufferImageProfile = null;
|
||||
|
||||
RefreshList();
|
||||
}
|
||||
|
||||
private UserId GetSelectedUserId()
|
||||
{
|
||||
if (_usersTreeView.Model.GetIterFirst(out TreeIter iter))
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((bool)_tableStore.GetValue(iter, 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (_usersTreeView.Model.IterNext(ref iter));
|
||||
}
|
||||
|
||||
return new UserId(_tableStore.GetValue(iter, 2).ToString().Split("\n")[1]);
|
||||
}
|
||||
|
||||
private void CloseButton_Pressed(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
/// <summary>
|
||||
/// The current version of the file format
|
||||
/// </summary>
|
||||
public const int CurrentVersion = 51;
|
||||
public const int CurrentVersion = 52;
|
||||
|
||||
/// <summary>
|
||||
/// Version of the configuration file format
|
||||
|
@ -162,6 +162,11 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
/// </summary>
|
||||
public bool ShowConfirmExit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show Profiles Dialog at Startup
|
||||
/// </summary>
|
||||
public bool ShowProfilesAtStartup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables save window size, position and state on close.
|
||||
/// </summary>
|
||||
|
|
|
@ -187,6 +187,12 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
/// </summary>
|
||||
public ReactiveObject<bool> IsAscendingOrder { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets if Grid is ordered in Ascending Order
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> ShowProfilesAtStartup { get; private set; }
|
||||
|
||||
|
||||
public UISection()
|
||||
{
|
||||
GuiColumns = new Columns();
|
||||
|
@ -205,6 +211,7 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
IsAscendingOrder = new ReactiveObject<bool>();
|
||||
LanguageCode = new ReactiveObject<string>();
|
||||
ShowConsole = new ReactiveObject<bool>();
|
||||
ShowProfilesAtStartup = new ReactiveObject<bool>();
|
||||
ShowConsole.Event += static (s, e) => { ConsoleHelper.SetConsoleWindowState(e.NewValue); };
|
||||
}
|
||||
}
|
||||
|
@ -766,6 +773,7 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
PreferredGpu = Graphics.PreferredGpu,
|
||||
MultiplayerLanInterfaceId = Multiplayer.LanInterfaceId,
|
||||
MultiplayerMode = Multiplayer.Mode,
|
||||
ShowProfilesAtStartup = UI.ShowProfilesAtStartup,
|
||||
};
|
||||
|
||||
return configurationFile;
|
||||
|
@ -853,6 +861,7 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
UI.IsAscendingOrder.Value = true;
|
||||
UI.StartFullscreen.Value = false;
|
||||
UI.ShowConsole.Value = true;
|
||||
UI.ShowProfilesAtStartup.Value = false;
|
||||
UI.WindowStartup.WindowSizeWidth.Value = 1280;
|
||||
UI.WindowStartup.WindowSizeHeight.Value = 760;
|
||||
UI.WindowStartup.WindowPositionX.Value = 0;
|
||||
|
@ -1477,6 +1486,15 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
if (configurationFileFormat.Version < 52)
|
||||
{
|
||||
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 52.");
|
||||
|
||||
configurationFileFormat.ShowProfilesAtStartup = false;
|
||||
|
||||
configurationFileUpdated = true;
|
||||
}
|
||||
|
||||
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
|
||||
Graphics.ResScale.Value = configurationFileFormat.ResScale;
|
||||
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
|
||||
|
@ -1555,6 +1573,7 @@ namespace Ryujinx.UI.Common.Configuration
|
|||
UI.ApplicationSort.Value = configurationFileFormat.ApplicationSort;
|
||||
UI.StartFullscreen.Value = configurationFileFormat.StartFullscreen;
|
||||
UI.ShowConsole.Value = configurationFileFormat.ShowConsole;
|
||||
UI.ShowProfilesAtStartup.Value = configurationFileFormat.ShowProfilesAtStartup;
|
||||
UI.WindowStartup.WindowSizeWidth.Value = configurationFileFormat.WindowStartup.WindowSizeWidth;
|
||||
UI.WindowStartup.WindowSizeHeight.Value = configurationFileFormat.WindowStartup.WindowSizeHeight;
|
||||
UI.WindowStartup.WindowPositionX.Value = configurationFileFormat.WindowStartup.WindowPositionX;
|
||||
|
|
|
@ -14,4 +14,4 @@
|
|||
<sty:FluentAvaloniaTheme PreferSystemTheme="False" />
|
||||
<StyleInclude Source="/Assets/Styles/Styles.xaml"/>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
</Application>
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "تمكين وجود ديسكورد الغني",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "التحقق من وجود تحديثات عند التشغيل",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "إظهار مربع حوار \"تأكيد الخروج\"",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "تذكر حجم/موضع النافذة",
|
||||
"SettingsTabGeneralHideCursor": "إخفاء المؤشر:",
|
||||
"SettingsTabGeneralHideCursorNever": "مطلقا",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Aktiviere die Statusanzeige für Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Beim Start nach Updates suchen",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Zeige den \"Beenden bestätigen\"-Dialog",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Fenstergröße/-position merken",
|
||||
"SettingsTabGeneralHideCursor": "Mauszeiger ausblenden",
|
||||
"SettingsTabGeneralHideCursorNever": "Niemals",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Ενεργοποίηση Εμπλουτισμένης Παρουσίας Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Έλεγχος για Ενημερώσεις στην Εκκίνηση",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Εμφάνιση διαλόγου \"Επιβεβαίωση Εξόδου\".",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "Απόκρυψη Κέρσορα:",
|
||||
"SettingsTabGeneralHideCursorNever": "Ποτέ",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Enable Discord Rich Presence",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Check for Updates on Launch",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Show \"Confirm Exit\" Dialog",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "Hide Cursor:",
|
||||
"SettingsTabGeneralHideCursorNever": "Never",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Habilitar estado en Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Buscar actualizaciones al iniciar",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Mostrar diálogo de confirmación al cerrar",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "Esconder el cursor:",
|
||||
"SettingsTabGeneralHideCursorNever": "Nunca",
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
"SettingsTabGeneralGeneral": "Général",
|
||||
"SettingsTabGeneralEnableDiscordRichPresence": "Activer Discord Rich Presence",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Vérifier les mises à jour au démarrage",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Afficher les profiles au démarrage",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Afficher le message de \"Confirmation de sortie\"",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "Masquer le Curseur :",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "הפעלת תצוגה עשירה בדיסקורד",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "בדוק אם קיימים עדכונים בהפעלה",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "הראה דיאלוג \"אשר יציאה\"",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "הסתר את הסמן",
|
||||
"SettingsTabGeneralHideCursorNever": "אף פעם",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Attiva Discord Rich Presence",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Controlla aggiornamenti all'avvio",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Mostra dialogo \"Conferma Uscita\"",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "Nascondi il cursore:",
|
||||
"SettingsTabGeneralHideCursorNever": "Mai",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Discord リッチプレゼンスを有効にする",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "起動時にアップデートを確認する",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "\"終了を確認\" ダイアログを表示する",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "マウスカーソルを非表示",
|
||||
"SettingsTabGeneralHideCursorNever": "決して",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "디스코드 활동 상태 활성화",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "시작 시, 업데이트 확인",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "\"종료 확인\" 대화 상자 표시",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "창 크기/위치 기억",
|
||||
"SettingsTabGeneralHideCursor": "마우스 커서 숨기기",
|
||||
"SettingsTabGeneralHideCursorNever": "절대 안 함",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Włącz Bogatą Obecność Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Sprawdzaj aktualizacje przy uruchomieniu",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Pokazuj okno dialogowe \"Potwierdź wyjście\"",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "Ukryj kursor:",
|
||||
"SettingsTabGeneralHideCursorNever": "Nigdy",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Habilitar Rich Presence do Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Verificar se há atualizações ao iniciar",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Exibir diálogo de confirmação ao sair",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Lembrar tamanho/posição da Janela",
|
||||
"SettingsTabGeneralHideCursor": "Esconder o cursor do mouse:",
|
||||
"SettingsTabGeneralHideCursorNever": "Nunca",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Статус активности в Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Проверять наличие обновлений при запуске",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Подтверждать выход из приложения",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Запомнить размер/положение окна",
|
||||
"SettingsTabGeneralHideCursor": "Скрывать курсор",
|
||||
"SettingsTabGeneralHideCursorNever": "Никогда",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "เปิดใช้งาน Discord Rich Presence",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "ตรวจหาการอัปเดตเมื่อเปิดโปรแกรม",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "แสดง \"ยืนยันการออก\" กล่องข้อความโต้ตอบ",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "ซ่อน เคอร์เซอร์:",
|
||||
"SettingsTabGeneralHideCursorNever": "ไม่มี",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Discord Zengin İçerik'i Etkinleştir",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Her Açılışta Güncellemeleri Denetle",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "\"Çıkışı Onayla\" Diyaloğunu Göster",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "İşaretçiyi Gizle:",
|
||||
"SettingsTabGeneralHideCursorNever": "Hiçbir Zaman",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "Увімкнути розширену присутність Discord",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "Перевіряти наявність оновлень під час запуску",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "Показати діалогове вікно «Підтвердити вихід».",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "Remember Window Size/Position",
|
||||
"SettingsTabGeneralHideCursor": "Сховати вказівник:",
|
||||
"SettingsTabGeneralHideCursorNever": "Ніколи",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "启用 Discord 在线状态展示",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "启动时检查更新",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "退出游戏时需要确认",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "记住窗口大小和位置",
|
||||
"SettingsTabGeneralHideCursor": "隐藏鼠标指针:",
|
||||
"SettingsTabGeneralHideCursorNever": "从不隐藏",
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"SettingsTabGeneralEnableDiscordRichPresence": "啟用 Discord 動態狀態展示",
|
||||
"SettingsTabGeneralCheckUpdatesOnLaunch": "啟動時檢查更新",
|
||||
"SettingsTabGeneralShowConfirmExitDialog": "顯示「確認結束」對話方塊",
|
||||
"SettingsTabGeneralShoProfilesAtStartup": "Show Profiles at Startup",
|
||||
"SettingsTabGeneralRememberWindowState": "記住視窗大小/位置",
|
||||
"SettingsTabGeneralHideCursor": "隱藏滑鼠游標:",
|
||||
"SettingsTabGeneralHideCursorNever": "從不",
|
||||
|
|
|
@ -164,4 +164,10 @@
|
|||
<ItemGroup>
|
||||
<AdditionalFiles Include="Assets\Locales\en_US.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="UI\Views\User\UserSimpleSelectorView.axaml.cs">
|
||||
<DependentUpon>UserSimpleSelectorView.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
50
src/Ryujinx/UI/ViewModels/ProfilesViewModel.cs
Normal file
50
src/Ryujinx/UI/ViewModels/ProfilesViewModel.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
using Avalonia.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.UI.ViewModels
|
||||
{
|
||||
public class ProfilesViewModel : BaseModel
|
||||
{
|
||||
|
||||
private UserProfile _selectedProfile;
|
||||
|
||||
public event Action CloseWindow;
|
||||
public event Action ApplyProfile;
|
||||
|
||||
public ProfilesViewModel()
|
||||
{
|
||||
Profiles = new AvaloniaList<UserProfile>();
|
||||
Profiles.Clear();
|
||||
}
|
||||
|
||||
public ProfilesViewModel(IEnumerable<UserProfile> profiles)
|
||||
{
|
||||
Profiles = new AvaloniaList<UserProfile>();
|
||||
Profiles.Clear();
|
||||
Profiles.AddRange(profiles);
|
||||
}
|
||||
|
||||
public AvaloniaList<UserProfile> Profiles
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public UserProfile SelectedProfile
|
||||
{
|
||||
get => _selectedProfile;
|
||||
set
|
||||
{
|
||||
_selectedProfile = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
CloseWindow?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -130,6 +130,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
public bool EnableDiscordIntegration { get; set; }
|
||||
public bool CheckUpdatesOnStart { get; set; }
|
||||
|
||||
public bool ShowProfilesAtStartup { get; set; }
|
||||
public bool ShowConfirmExit { get; set; }
|
||||
public bool RememberWindowState { get; set; }
|
||||
public int HideCursor { get; set; }
|
||||
|
@ -391,6 +393,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
EnableDiscordIntegration = config.EnableDiscordIntegration;
|
||||
CheckUpdatesOnStart = config.CheckUpdatesOnStart;
|
||||
ShowConfirmExit = config.ShowConfirmExit;
|
||||
ShowProfilesAtStartup = config.UI.ShowProfilesAtStartup;
|
||||
RememberWindowState = config.RememberWindowState;
|
||||
HideCursor = (int)config.HideCursor.Value;
|
||||
|
||||
|
@ -483,6 +486,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
|
||||
config.CheckUpdatesOnStart.Value = CheckUpdatesOnStart;
|
||||
config.ShowConfirmExit.Value = ShowConfirmExit;
|
||||
config.UI.ShowProfilesAtStartup.Value = ShowProfilesAtStartup;
|
||||
config.RememberWindowState.Value = RememberWindowState;
|
||||
config.HideCursor.Value = (HideCursorMode)HideCursor;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<UserControl
|
||||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsUiView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
|
@ -33,6 +33,9 @@
|
|||
<CheckBox IsChecked="{Binding CheckUpdatesOnStart}">
|
||||
<TextBlock Text="{locale:Locale SettingsTabGeneralCheckUpdatesOnLaunch}" />
|
||||
</CheckBox>
|
||||
<CheckBox IsChecked="{Binding ShowProfilesAtStartup}">
|
||||
<TextBlock Text="{locale:Locale SettingsTabGeneralShoProfilesAtStartup}" />
|
||||
</CheckBox>
|
||||
<CheckBox IsChecked="{Binding ShowConfirmExit}">
|
||||
<TextBlock Text="{locale:Locale SettingsTabGeneralShowConfirmExitDialog}" />
|
||||
</CheckBox>
|
||||
|
|
104
src/Ryujinx/UI/Views/User/UserSimpleSelectorView.axaml
Normal file
104
src/Ryujinx/UI/Views/User/UserSimpleSelectorView.axaml
Normal file
|
@ -0,0 +1,104 @@
|
|||
<UserControl
|
||||
x:Class="Ryujinx.Ava.UI.Views.User.UserSimpleSelectorView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
|
||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
d:DesignHeight="450"
|
||||
MinWidth="500"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
Focusable="True"
|
||||
x:DataType="viewModels:ProfilesViewModel">
|
||||
<UserControl.Resources>
|
||||
<helpers:BitmapArrayValueConverter x:Key="ByteImage" />
|
||||
</UserControl.Resources>
|
||||
<Design.DataContext>
|
||||
<viewModels:ProfilesViewModel />
|
||||
</Design.DataContext>
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Border
|
||||
CornerRadius="5"
|
||||
BorderBrush="{DynamicResource AppListHoverBackgroundColor}"
|
||||
BorderThickness="1">
|
||||
<ListBox
|
||||
MaxHeight="300"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
SelectionChanged="ProfilesList_SelectionChanged"
|
||||
Background="Transparent"
|
||||
ItemsSource="{Binding Profiles}">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
<ListBox.Styles>
|
||||
<Style Selector="ListBoxItem">
|
||||
<Setter Property="Margin" Value="5 5 0 5" />
|
||||
<Setter Property="CornerRadius" Value="5" />
|
||||
</Style>
|
||||
<Style Selector="Rectangle#SelectionIndicator">
|
||||
<Setter Property="Opacity" Value="0" />
|
||||
</Style>
|
||||
</ListBox.Styles>
|
||||
<ListBox.DataTemplates>
|
||||
<DataTemplate
|
||||
DataType="models:UserProfile">
|
||||
<Grid
|
||||
PointerEntered="Grid_PointerEntered"
|
||||
PointerExited="Grid_OnPointerExited">
|
||||
<Border
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ClipToBounds="True"
|
||||
CornerRadius="5"
|
||||
Background="{Binding BackgroundColor}">
|
||||
<StackPanel
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Image
|
||||
Width="96"
|
||||
Height="96"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Stretch"
|
||||
MaxWidth="90"
|
||||
Text="{Binding Name}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
MaxLines="2"
|
||||
Margin="5" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.DataTemplates>
|
||||
</ListBox>
|
||||
</Border>
|
||||
<StackPanel
|
||||
Grid.Row="1"
|
||||
Margin="0 24 0 0"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
Command="{Binding Close}"
|
||||
Content="{locale:Locale UserProfilesClose}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
84
src/Ryujinx/UI/Views/User/UserSimpleSelectorView.axaml.cs
Normal file
84
src/Ryujinx/UI/Views/User/UserSimpleSelectorView.axaml.cs
Normal file
|
@ -0,0 +1,84 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||
using System.Linq;
|
||||
using Button = Avalonia.Controls.Button;
|
||||
using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Views.User
|
||||
{
|
||||
public partial class UserSimpleSelectorView : UserControl
|
||||
{
|
||||
|
||||
public ProfilesViewModel ViewModel { get; set; }
|
||||
|
||||
private readonly AccountManager _accountManager;
|
||||
|
||||
public UserSimpleSelectorView(AccountManager accountManager)
|
||||
{
|
||||
_accountManager = accountManager;
|
||||
ViewModel = new ProfilesViewModel();
|
||||
var profiles = _accountManager
|
||||
.GetAllUsers()
|
||||
.Select(p => new Models.UserProfile(p, null))
|
||||
.OrderBy(p => p.Name);
|
||||
|
||||
ViewModel.Profiles.AddRange(profiles);
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void Grid_PointerEntered(object sender, PointerEventArgs e)
|
||||
{
|
||||
if (sender is Grid grid)
|
||||
{
|
||||
if (grid.DataContext is UserProfile profile)
|
||||
{
|
||||
profile.IsPointerOver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Grid_OnPointerExited(object sender, PointerEventArgs e)
|
||||
{
|
||||
if (sender is Grid grid)
|
||||
{
|
||||
if (grid.DataContext is UserProfile profile)
|
||||
{
|
||||
profile.IsPointerOver = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProfilesList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is ListBox listBox)
|
||||
{
|
||||
int selectedIndex = listBox.SelectedIndex;
|
||||
|
||||
if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
|
||||
{
|
||||
if (ViewModel.Profiles[selectedIndex] is UserProfile userProfile)
|
||||
{
|
||||
_accountManager?.OpenUser(userProfile.UserId);
|
||||
|
||||
foreach (BaseModel profile in ViewModel.Profiles)
|
||||
{
|
||||
if (profile is UserProfile uProfile)
|
||||
{
|
||||
uProfile.UpdateState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using Avalonia.Controls;
|
|||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Platform;
|
||||
using Avalonia.Styling;
|
||||
using Avalonia.Threading;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using Ryujinx.Ava.Common;
|
||||
|
@ -11,6 +12,7 @@ using Ryujinx.Ava.Input;
|
|||
using Ryujinx.Ava.UI.Applet;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using Ryujinx.Ava.UI.Views.User;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
|
@ -292,8 +294,38 @@ namespace Ryujinx.Ava.UI.Windows
|
|||
}
|
||||
}
|
||||
|
||||
private async Task ShowProfilesDialog()
|
||||
{
|
||||
await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
//await ContentDialogHelper.ShowWindowAsync(new ProfilesWindows(AccountManager)));
|
||||
var content = new UserSimpleSelectorView(AccountManager);
|
||||
ContentDialog contentDialog = new()
|
||||
{
|
||||
Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle],
|
||||
PrimaryButtonText = "",
|
||||
SecondaryButtonText = "",
|
||||
CloseButtonText = "",
|
||||
DataContext = content.ViewModel,
|
||||
Content = content,
|
||||
Padding = new Thickness(0),
|
||||
};
|
||||
content.ViewModel.CloseWindow += contentDialog.Hide;
|
||||
Style footer = new(x => x.Name("DialogSpace").Child().OfType<Border>());
|
||||
footer.Setters.Add(new Setter(IsVisibleProperty, false));
|
||||
|
||||
contentDialog.Styles.Add(footer);
|
||||
|
||||
await contentDialog.ShowAsync();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task CheckLaunchState()
|
||||
{
|
||||
if (ConfigurationState.Instance.UI.ShowProfilesAtStartup)
|
||||
{
|
||||
await ShowProfilesDialog();
|
||||
}
|
||||
if (OperatingSystem.IsLinux() && LinuxHelper.VmMaxMapCount < LinuxHelper.RecommendedVmMaxMapCount)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Application, $"The value of vm.max_map_count is lower than {LinuxHelper.RecommendedVmMaxMapCount}. ({LinuxHelper.VmMaxMapCount})");
|
||||
|
|
Loading…
Add table
Reference in a new issue