aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Ava/UI/Controls
diff options
context:
space:
mode:
authorIsaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>2023-01-11 00:20:19 -0500
committerGitHub <noreply@github.com>2023-01-11 06:20:19 +0100
commit934b5a64e5638ae5228acb52faf48efadefdea8d (patch)
treecc65eab75c5a9a7c3438de3302ab1f6cbcec1599 /Ryujinx.Ava/UI/Controls
parentcee667b491f87c48546f348bad8c6f16cdf6d628 (diff)
Ava GUI: User Profile Manager + Other Fixes (#4166)
* Fix redundancies * Add back elses * Loading Screen fixes * Redesign User Profile Manager - Backported long selection bar in Grid/List view not working - Backported UserSelector is jank * Fix SelectionIndicator * Fix DataType * Fix SaveManager bug * Remove debug log * Load saves on UIThread * Reduce UI thread blocking * Fix locale keys * Use block namespaces * Fix close button width * Make UserProfile ordering consistent * Alphabetical order * Adjust layout, remove green circle for blue selector * Fix some inconsistencies * Fix no inital selected profile * Adjust appearance of edit button * Adjust SaveManager * Remove redundant warning dialog * Make firmware avatar selector clearer * View redesign again :hero_depressed: * Consistency adjustments * Adjust margins * Make `UserProfileImageSelector` consistent * Make `UserFirmwareAvatarSelector` consistent * Fix long grid view selector * Switch case * Remove long selection bar Handled in #4178 * Consistency * Started dialog titles * Fixes * Remaining titles * Update Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml Co-authored-by: Mary-nyan <thog@protonmail.com> * Fix build * Hide UserRecoverer if no LostProfiles are found * UserEditor Avatar Placeholder * Watermark + locale adjustment * Border radius * Remove unnecessary styles * Fix firmware avatar image order * Cleanup `ColorPickerButton` * Make `UserId` copy/paste able * Make `FirmwareAvatarSelector` 6 images wide * Make selection bar better * Unsaved changes dialogue * Fix indentation * Remove extra check * Address suggestions * Reorganise - Remove unused views - Rename views to match convention - Fix weird namespacing * Update Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml Co-authored-by: Ac_K <Acoustik666@gmail.com> * UserRecovererView empty placeholder * Update Ryujinx.Ava/UI/Views/User/UserSelectorView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Views/User/UserSaveManagerView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Views/User/UserRecovererView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Views/User/UserFirmwareAvatarSelectorView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/ViewModels/UserFirmwareAvatarSelectorViewModel.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Models/UserProfile.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Remove AddModel * Update Ryujinx.Ava/Assets/Locales/en_US.json Co-authored-by: Ac_K <Acoustik666@gmail.com> * Fix bug Co-authored-by: Mary-nyan <thog@protonmail.com> Co-authored-by: Ac_K <Acoustik666@gmail.com>
Diffstat (limited to 'Ryujinx.Ava/UI/Controls')
-rw-r--r--Ryujinx.Ava/UI/Controls/GameGridView.axaml24
-rw-r--r--Ryujinx.Ava/UI/Controls/GameListView.axaml29
-rw-r--r--Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml3
-rw-r--r--Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs139
-rw-r--r--Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml57
-rw-r--r--Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml.cs105
-rw-r--r--Ryujinx.Ava/UI/Controls/SaveManager.axaml175
-rw-r--r--Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs160
-rw-r--r--Ryujinx.Ava/UI/Controls/UserEditor.axaml86
-rw-r--r--Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs118
-rw-r--r--Ryujinx.Ava/UI/Controls/UserRecoverer.axaml72
-rw-r--r--Ryujinx.Ava/UI/Controls/UserRecoverer.axaml.cs44
-rw-r--r--Ryujinx.Ava/UI/Controls/UserSelector.axaml145
-rw-r--r--Ryujinx.Ava/UI/Controls/UserSelector.axaml.cs77
14 files changed, 135 insertions, 1099 deletions
diff --git a/Ryujinx.Ava/UI/Controls/GameGridView.axaml b/Ryujinx.Ava/UI/Controls/GameGridView.axaml
index c757f066..862bc6d3 100644
--- a/Ryujinx.Ava/UI/Controls/GameGridView.axaml
+++ b/Ryujinx.Ava/UI/Controls/GameGridView.axaml
@@ -112,32 +112,8 @@
</ListBox.ItemsPanel>
<ListBox.Styles>
<Style Selector="ListBoxItem">
- <Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="5" />
<Setter Property="CornerRadius" Value="4" />
- <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
- <Style.Animations>
- <Animation Duration="0:0:0.7">
- <KeyFrame Cue="0%">
- <Setter Property="MaxWidth" Value="0" />
- <Setter Property="Opacity" Value="0.0" />
- </KeyFrame>
- <KeyFrame Cue="50%">
- <Setter Property="MaxWidth" Value="1000" />
- <Setter Property="Opacity" Value="0.3" />
- </KeyFrame>
- <KeyFrame Cue="100%">
- <Setter Property="MaxWidth" Value="1000" />
- <Setter Property="Opacity" Value="1.0" />
- </KeyFrame>
- </Animation>
- </Style.Animations>
- </Style>
- <Style Selector="ListBoxItem:selected /template/ ContentPresenter">
- <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
- </Style>
- <Style Selector="ListBoxItem:pointerover /template/ ContentPresenter">
- <Setter Property="Background" Value="{DynamicResource AppListHoverBackgroundColor}" />
</Style>
<Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.GridItemSelectorSize}" />
diff --git a/Ryujinx.Ava/UI/Controls/GameListView.axaml b/Ryujinx.Ava/UI/Controls/GameListView.axaml
index 9fb5497b..bb4e37b0 100644
--- a/Ryujinx.Ava/UI/Controls/GameListView.axaml
+++ b/Ryujinx.Ava/UI/Controls/GameListView.axaml
@@ -111,35 +111,6 @@
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Styles>
- <Style Selector="ListBoxItem">
- <Setter Property="Padding" Value="0" />
- <Setter Property="Margin" Value="0" />
- <Setter Property="CornerRadius" Value="5" />
- <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
- <Setter Property="BorderThickness" Value="2"/>
- <Style.Animations>
- <Animation Duration="0:0:0.7">
- <KeyFrame Cue="0%">
- <Setter Property="MaxHeight" Value="0" />
- <Setter Property="Opacity" Value="0.0" />
- </KeyFrame>
- <KeyFrame Cue="50%">
- <Setter Property="MaxHeight" Value="1000" />
- <Setter Property="Opacity" Value="0.3" />
- </KeyFrame>
- <KeyFrame Cue="100%">
- <Setter Property="MaxHeight" Value="1000" />
- <Setter Property="Opacity" Value="1.0" />
- </KeyFrame>
- </Animation>
- </Style.Animations>
- </Style>
- <Style Selector="ListBoxItem:selected /template/ ContentPresenter">
- <Setter Property="Background" Value="{DynamicResource AppListBackgroundColor}" />
- </Style>
- <Style Selector="ListBoxItem:pointerover /template/ ContentPresenter">
- <Setter Property="Background" Value="{DynamicResource AppListHoverBackgroundColor}" />
- </Style>
<Style Selector="ListBoxItem:selected /template/ Border#SelectionIndicator">
<Setter Property="MinHeight" Value="{Binding $parent[UserControl].DataContext.ListItemSelectorSize}" />
</Style>
diff --git a/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml b/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml
index 90720478..bf34b303 100644
--- a/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml
+++ b/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml
@@ -12,5 +12,6 @@
<ui:Frame
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
- x:Name="ContentFrame" />
+ x:Name="ContentFrame">
+ </ui:Frame>
</UserControl> \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs b/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
index 0c300267..6911a4d4 100644
--- a/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
+++ b/Ryujinx.Ava/UI/Controls/NavigationDialogHost.axaml.cs
@@ -1,13 +1,25 @@
using Avalonia;
using Avalonia.Controls;
+using Avalonia.Styling;
+using Avalonia.Threading;
+using FluentAvalonia.Core;
using FluentAvalonia.UI.Controls;
using LibHac;
+using LibHac.Common;
+using LibHac.Fs;
+using LibHac.Fs.Shim;
using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Helpers;
+using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Ava.UI.Views.User;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using System;
using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Linq;
+using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
namespace Ryujinx.Ava.UI.Controls
{
@@ -31,14 +43,14 @@ namespace Ryujinx.Ava.UI.Controls
ContentManager = contentManager;
VirtualFileSystem = virtualFileSystem;
HorizonClient = horizonClient;
- ViewModel = new UserProfileViewModel(this);
-
+ ViewModel = new UserProfileViewModel();
+ LoadProfiles();
if (contentManager.GetCurrentFirmwareVersion() != null)
{
Task.Run(() =>
{
- AvatarProfileViewModel.PreloadAvatars(contentManager, virtualFileSystem);
+ UserFirmwareAvatarSelectorViewModel.PreloadAvatars(contentManager, virtualFileSystem);
});
}
InitializeComponent();
@@ -51,7 +63,7 @@ namespace Ryujinx.Ava.UI.Controls
ContentFrame.GoBack();
}
- ViewModel.LoadProfiles();
+ LoadProfiles();
}
public void Navigate(Type sourcePageType, object parameter)
@@ -68,7 +80,7 @@ namespace Ryujinx.Ava.UI.Controls
Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle],
PrimaryButtonText = "",
SecondaryButtonText = "",
- CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose],
+ CloseButtonText = "",
Content = content,
Padding = new Thickness(0)
};
@@ -78,6 +90,11 @@ namespace Ryujinx.Ava.UI.Controls
content.ViewModel.Dispose();
};
+ Style footer = new(x => x.Name("DialogSpace").Child().OfType<Border>());
+ footer.Setters.Add(new Setter(IsVisibleProperty, false));
+
+ contentDialog.Styles.Add(footer);
+
await contentDialog.ShowAsync();
}
@@ -85,7 +102,117 @@ namespace Ryujinx.Ava.UI.Controls
{
base.OnAttachedToVisualTree(e);
- Navigate(typeof(UserSelector), this);
+ Navigate(typeof(UserSelectorViews), this);
+ }
+
+ public void LoadProfiles()
+ {
+ ViewModel.Profiles.Clear();
+ ViewModel.LostProfiles.Clear();
+
+ var profiles = AccountManager.GetAllUsers().OrderBy(x => x.Name);
+
+ foreach (var profile in profiles)
+ {
+ ViewModel.Profiles.Add(new UserProfile(profile, this));
+ }
+
+ var saveDataFilter = SaveDataFilter.Make(programId: default, saveType: SaveDataType.Account, default, saveDataId: default, index: default);
+
+ using var saveDataIterator = new UniqueRef<SaveDataIterator>();
+
+ HorizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref(), SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
+
+ Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10];
+
+ HashSet<HLE.HOS.Services.Account.Acc.UserId> lostAccounts = new();
+
+ while (true)
+ {
+ saveDataIterator.Get.ReadSaveDataInfo(out long readCount, saveDataInfo).ThrowIfFailure();
+
+ if (readCount == 0)
+ {
+ break;
+ }
+
+ for (int i = 0; i < readCount; i++)
+ {
+ var save = saveDataInfo[i];
+ var id = new HLE.HOS.Services.Account.Acc.UserId((long)save.UserId.Id.Low, (long)save.UserId.Id.High);
+ if (ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault( x=> x.UserId == id) == null)
+ {
+ lostAccounts.Add(id);
+ }
+ }
+ }
+
+ foreach(var account in lostAccounts)
+ {
+ ViewModel.LostProfiles.Add(new UserProfile(new HLE.HOS.Services.Account.Acc.UserProfile(account, "", null), this));
+ }
+
+ ViewModel.Profiles.Add(new BaseModel());
+ }
+
+ public async void DeleteUser(UserProfile userProfile)
+ {
+ var lastUserId = AccountManager.LastOpenedUser.UserId;
+
+ if (userProfile.UserId == lastUserId)
+ {
+ // If we are deleting the currently open profile, then we must open something else before deleting.
+ var profile = ViewModel.Profiles.Cast<UserProfile>().FirstOrDefault(x => x.UserId != lastUserId);
+
+ if (profile == null)
+ {
+ async void Action()
+ {
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUserProfileDeletionWarningMessage]);
+ }
+
+ Dispatcher.UIThread.Post(Action);
+
+ return;
+ }
+
+ AccountManager.OpenUser(profile.UserId);
+ }
+
+ var result = await ContentDialogHelper.CreateConfirmationDialog(
+ LocaleManager.Instance[LocaleKeys.DialogUserProfileDeletionConfirmMessage],
+ "",
+ LocaleManager.Instance[LocaleKeys.InputDialogYes],
+ LocaleManager.Instance[LocaleKeys.InputDialogNo],
+ "");
+
+ if (result == UserResult.Yes)
+ {
+ GoBack();
+ AccountManager.DeleteUser(userProfile.UserId);
+ }
+
+ LoadProfiles();
+ }
+
+ public void AddUser()
+ {
+ Navigate(typeof(UserEditorView), (this, (UserProfile)null, true));
+ }
+
+ public void EditUser(UserProfile userProfile)
+ {
+ Navigate(typeof(UserEditorView), (this, userProfile, false));
+ }
+
+ public void RecoverLostAccounts()
+ {
+ Navigate(typeof(UserRecovererView), this);
+ }
+
+ public void ManageSaves()
+ {
+ Navigate(typeof(UserSaveManagerView), (this, AccountManager, HorizonClient, VirtualFileSystem));
}
}
} \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml b/Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml
deleted file mode 100644
index 56f8152a..00000000
--- a/Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml
+++ /dev/null
@@ -1,57 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- mc:Ignorable="d"
- x:Class="Ryujinx.Ava.UI.Controls.ProfileImageSelectionDialog"
- Focusable="True">
- <Grid
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- Margin="5,10,5, 5">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="70" />
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <TextBlock
- FontWeight="Bold"
- FontSize="18"
- HorizontalAlignment="Center"
- Grid.Row="1"
- Text="{locale:Locale ProfileImageSelectionHeader}" />
- <TextBlock
- FontWeight="Bold"
- Grid.Row="2"
- Margin="10"
- MaxWidth="400"
- TextWrapping="Wrap"
- HorizontalAlignment="Center"
- TextAlignment="Center"
- Text="{locale:Locale ProfileImageSelectionNote}" />
- <StackPanel
- Margin="5,0"
- Spacing="10"
- Grid.Row="4"
- HorizontalAlignment="Center"
- Orientation="Horizontal">
- <Button
- Name="Import"
- Click="Import_OnClick"
- Width="200">
- <TextBlock Text="{locale:Locale ProfileImageSelectionImportImage}" />
- </Button>
- <Button
- Name="SelectFirmwareImage"
- IsEnabled="{Binding FirmwareFound}"
- Click="SelectFirmwareImage_OnClick"
- Width="200">
- <TextBlock Text="{locale:Locale ProfileImageSelectionSelectAvatar}" />
- </Button>
- </StackPanel>
- </Grid>
-</UserControl> \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml.cs b/Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml.cs
deleted file mode 100644
index 46a2f507..00000000
--- a/Ryujinx.Ava/UI/Controls/ProfileImageSelectionDialog.axaml.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.VisualTree;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.Windows;
-using Ryujinx.HLE.FileSystem;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Processing;
-using System.IO;
-using Image = SixLabors.ImageSharp.Image;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class ProfileImageSelectionDialog : UserControl
- {
- private ContentManager _contentManager;
- private NavigationDialogHost _parent;
- private TempProfile _profile;
-
- public bool FirmwareFound => _contentManager.GetCurrentFirmwareVersion() != null;
-
- public ProfileImageSelectionDialog()
- {
- InitializeComponent();
- AddHandler(Frame.NavigatedToEvent, (s, e) =>
- {
- NavigatedTo(e);
- }, RoutingStrategies.Direct);
- }
-
- private void NavigatedTo(NavigationEventArgs arg)
- {
- if (Program.PreviewerDetached)
- {
- switch (arg.NavigationMode)
- {
- case NavigationMode.New:
- (_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
- _contentManager = _parent.ContentManager;
- break;
- case NavigationMode.Back:
- _parent.GoBack();
- break;
- }
-
- DataContext = this;
- }
- }
-
- private async void Import_OnClick(object sender, RoutedEventArgs e)
- {
- OpenFileDialog dialog = new();
- dialog.Filters.Add(new FileDialogFilter
- {
- Name = LocaleManager.Instance[LocaleKeys.AllSupportedFormats],
- Extensions = { "jpg", "jpeg", "png", "bmp" }
- });
- dialog.Filters.Add(new FileDialogFilter { Name = "JPEG", Extensions = { "jpg", "jpeg" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "PNG", Extensions = { "png" } });
- dialog.Filters.Add(new FileDialogFilter { Name = "BMP", Extensions = { "bmp" } });
-
- dialog.AllowMultiple = false;
-
- string[] image = await dialog.ShowAsync(((TopLevel)_parent.GetVisualRoot()) as Window);
-
- if (image != null)
- {
- if (image.Length > 0)
- {
- string imageFile = image[0];
-
- _profile.Image = ProcessProfileImage(File.ReadAllBytes(imageFile));
- }
-
- _parent.GoBack();
- }
- }
-
- private void SelectFirmwareImage_OnClick(object sender, RoutedEventArgs e)
- {
- if (FirmwareFound)
- {
- _parent.Navigate(typeof(AvatarWindow), (_parent, _profile));
- }
- }
-
- private static byte[] ProcessProfileImage(byte[] buffer)
- {
- using (Image image = Image.Load(buffer))
- {
- image.Mutate(x => x.Resize(256, 256));
-
- using (MemoryStream streamJpg = new())
- {
- image.SaveAsJpeg(streamJpg);
-
- return streamJpg.ToArray();
- }
- }
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/SaveManager.axaml b/Ryujinx.Ava/UI/Controls/SaveManager.axaml
deleted file mode 100644
index 64674b65..00000000
--- a/Ryujinx.Ava/UI/Controls/SaveManager.axaml
+++ /dev/null
@@ -1,175 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- mc:Ignorable="d"
- d:DesignWidth="800"
- d:DesignHeight="450"
- Height="400"
- Width="550"
- x:Class="Ryujinx.Ava.UI.Controls.SaveManager"
- Focusable="True">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </UserControl.Resources>
- <Grid>
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition />
- </Grid.RowDefinitions>
- <Grid
- Grid.Row="0"
- HorizontalAlignment="Stretch">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <StackPanel
- Spacing="10"
- Orientation="Horizontal"
- HorizontalAlignment="Left"
- VerticalAlignment="Center">
- <Label
- Content="{locale:Locale CommonSort}"
- VerticalAlignment="Center" />
- <ComboBox SelectedIndex="{Binding SortIndex}" Width="100">
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale Name}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale Size}" />
- </ComboBoxItem>
- </ComboBox>
- <ComboBox SelectedIndex="{Binding OrderIndex}" Width="150">
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale OrderAscending}" />
- </ComboBoxItem>
- <ComboBoxItem>
- <Label
- VerticalAlignment="Center"
- HorizontalContentAlignment="Left"
- Content="{locale:Locale OrderDescending}" />
- </ComboBoxItem>
- </ComboBox>
- </StackPanel>
- <Grid
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- Margin="10,0, 0, 0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition/>
- </Grid.ColumnDefinitions>
- <Label
- Content="{locale:Locale Search}"
- VerticalAlignment="Center"/>
- <TextBox
- Margin="5,0,0,0"
- Grid.Column="1"
- HorizontalAlignment="Stretch"
- Text="{Binding Search}"/>
- </Grid>
- </Grid>
- <Border
- Grid.Row="1"
- Margin="0,5"
- BorderThickness="1"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <ListBox
- Name="SaveList"
- Items="{Binding View}"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <ListBox.ItemTemplate>
- <DataTemplate x:DataType="models:SaveModel">
- <Grid HorizontalAlignment="Stretch" Margin="0,5">
- <Grid.ColumnDefinitions>
- <ColumnDefinition />
- <ColumnDefinition Width="Auto" />
- </Grid.ColumnDefinitions>
- <StackPanel Grid.Column="0" Orientation="Horizontal">
- <Border
- Height="42"
- Margin="2"
- Width="42"
- Padding="10"
- IsVisible="{Binding !InGameList}">
- <ui:SymbolIcon
- Symbol="Help"
- FontSize="30"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Border>
- <Image
- IsVisible="{Binding InGameList}"
- Margin="2"
- Width="42"
- Height="42"
- Source="{Binding Icon,
- Converter={StaticResource ByteImage}}" />
- <TextBlock
- MaxLines="3"
- Width="320"
- Margin="5"
- TextWrapping="Wrap"
- Text="{Binding Title}" VerticalAlignment="Center" />
- </StackPanel>
- <StackPanel
- Grid.Column="1"
- Spacing="10"
- HorizontalAlignment="Right"
- Orientation="Horizontal">
- <Label
- Content="{Binding SizeString}"
- IsVisible="{Binding SizeAvailable}"
- VerticalAlignment="Center"
- HorizontalAlignment="Right" />
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Name="OpenLocation"
- Command="{Binding OpenLocation}">
- <ui:SymbolIcon
- Symbol="OpenFolder"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- <Button
- VerticalAlignment="Center"
- HorizontalAlignment="Right"
- Padding="10"
- MinWidth="0"
- MinHeight="0"
- Name="Delete"
- Command="{Binding Delete}">
- <ui:SymbolIcon
- Symbol="Delete"
- HorizontalAlignment="Center"
- VerticalAlignment="Center" />
- </Button>
- </StackPanel>
- </Grid>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Border>
- </Grid>
-</UserControl> \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs b/Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs
deleted file mode 100644
index 9910481c..00000000
--- a/Ryujinx.Ava/UI/Controls/SaveManager.axaml.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-using Avalonia.Controls;
-using DynamicData;
-using DynamicData.Binding;
-using LibHac;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Shim;
-using Ryujinx.Ava.Common;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.HLE.FileSystem;
-using Ryujinx.Ui.App.Common;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Threading.Tasks;
-using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class SaveManager : UserControl
- {
- private readonly UserProfile _userProfile;
- private readonly HorizonClient _horizonClient;
- private readonly VirtualFileSystem _virtualFileSystem;
- private int _sortIndex;
- private int _orderIndex;
- private ObservableCollection<SaveModel> _view = new ObservableCollection<SaveModel>();
- private string _search;
-
- public ObservableCollection<SaveModel> Saves { get; set; } = new ObservableCollection<SaveModel>();
-
- public ObservableCollection<SaveModel> View
- {
- get => _view;
- set => _view = value;
- }
-
- public int SortIndex
- {
- get => _sortIndex;
- set
- {
- _sortIndex = value;
- Sort();
- }
- }
-
- public int OrderIndex
- {
- get => _orderIndex;
- set
- {
- _orderIndex = value;
- Sort();
- }
- }
-
- public string Search
- {
- get => _search;
- set
- {
- _search = value;
- Sort();
- }
- }
-
- public SaveManager()
- {
- InitializeComponent();
- }
-
- public SaveManager(UserProfile userProfile, HorizonClient horizonClient, VirtualFileSystem virtualFileSystem)
- {
- _userProfile = userProfile;
- _horizonClient = horizonClient;
- _virtualFileSystem = virtualFileSystem;
- InitializeComponent();
-
- DataContext = this;
-
- Task.Run(LoadSaves);
- }
-
- public void LoadSaves()
- {
- Saves.Clear();
- var saveDataFilter = SaveDataFilter.Make(programId: default, saveType: SaveDataType.Account,
- new UserId((ulong)_userProfile.UserId.High, (ulong)_userProfile.UserId.Low), saveDataId: default, index: default);
-
- using var saveDataIterator = new UniqueRef<SaveDataIterator>();
-
- _horizonClient.Fs.OpenSaveDataIterator(ref saveDataIterator.Ref(), SaveDataSpaceId.User, in saveDataFilter).ThrowIfFailure();
-
- Span<SaveDataInfo> saveDataInfo = stackalloc SaveDataInfo[10];
-
- while (true)
- {
- saveDataIterator.Get.ReadSaveDataInfo(out long readCount, saveDataInfo).ThrowIfFailure();
-
- if (readCount == 0)
- {
- break;
- }
-
- for (int i = 0; i < readCount; i++)
- {
- var save = saveDataInfo[i];
- if (save.ProgramId.Value != 0)
- {
- var saveModel = new SaveModel(save, _horizonClient, _virtualFileSystem);
- Saves.Add(saveModel);
- saveModel.DeleteAction = () => { Saves.Remove(saveModel); };
- }
-
- Sort();
- }
- }
- }
-
- private void Sort()
- {
- Saves.AsObservableChangeSet()
- .Filter(Filter)
- .Sort(GetComparer())
- .Bind(out var view).AsObservableList();
-
- _view.Clear();
- _view.AddRange(view);
- }
-
- private IComparer<SaveModel> GetComparer()
- {
- switch (SortIndex)
- {
- case 0:
- return OrderIndex == 0
- ? SortExpressionComparer<SaveModel>.Ascending(save => save.Title)
- : SortExpressionComparer<SaveModel>.Descending(save => save.Title);
- case 1:
- return OrderIndex == 0
- ? SortExpressionComparer<SaveModel>.Ascending(save => save.Size)
- : SortExpressionComparer<SaveModel>.Descending(save => save.Size);
- default:
- return null;
- }
- }
-
- private bool Filter(object arg)
- {
- if (arg is SaveModel save)
- {
- return string.IsNullOrWhiteSpace(_search) || save.Title.ToLower().Contains(_search.ToLower());
- }
-
- return false;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/UserEditor.axaml b/Ryujinx.Ava/UI/Controls/UserEditor.axaml
deleted file mode 100644
index 155f1cfe..00000000
--- a/Ryujinx.Ava/UI/Controls/UserEditor.axaml
+++ /dev/null
@@ -1,86 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Controls.UserEditor"
- 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"
- Margin="0"
- MinWidth="500"
- Padding="0"
- mc:Ignorable="d"
- Focusable="True">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </UserControl.Resources>
- <Grid Margin="0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto" />
- <ColumnDefinition />
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="*" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <StackPanel
- HorizontalAlignment="Left"
- VerticalAlignment="Stretch"
- Orientation="Vertical">
- <Image
- Name="ProfileImage"
- Width="96"
- Height="96"
- Margin="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Source="{Binding Image, Converter={StaticResource ByteImage}}" />
- <Button
- Name="ChangePictureButton"
- Margin="5"
- HorizontalAlignment="Stretch"
- Click="ChangePictureButton_Click"
- Content="{locale:Locale UserProfilesChangeProfileImage}" />
- <Button
- Name="AddPictureButton"
- Margin="5"
- HorizontalAlignment="Stretch"
- Click="ChangePictureButton_Click"
- Content="{locale:Locale UserProfilesSetProfileImage}" />
- </StackPanel>
- <StackPanel
- Grid.Row="0"
- Grid.Column="1"
- Margin="5,10"
- HorizontalAlignment="Stretch"
- Orientation="Vertical"
- Spacing="10">
- <TextBlock Text="{locale:Locale UserProfilesName}" />
- <TextBox
- Name="NameBox"
- Width="300"
- HorizontalAlignment="Stretch"
- MaxLength="{Binding MaxProfileNameLength}"
- Text="{Binding Name}" />
- <TextBlock Name="IdText" Text="{locale:Locale UserProfilesUserId}" />
- <TextBlock Name="IdLabel" Text="{Binding UserId}" />
- </StackPanel>
- <StackPanel
- Grid.Row="1"
- Grid.Column="0"
- Grid.ColumnSpan="2"
- HorizontalAlignment="Right"
- Orientation="Horizontal"
- Spacing="10">
- <Button
- Name="SaveButton"
- Click="SaveButton_Click"
- Content="{locale:Locale Save}" />
- <Button
- Name="CloseButton"
- HorizontalAlignment="Right"
- Click="CloseButton_Click"
- Content="{locale:Locale Discard}" />
- </StackPanel>
- </Grid>
-</UserControl>
diff --git a/Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs b/Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs
deleted file mode 100644
index 18bb8b22..00000000
--- a/Ryujinx.Ava/UI/Controls/UserEditor.axaml.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Data;
-using Avalonia.Interactivity;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class UserEditor : UserControl
- {
- private NavigationDialogHost _parent;
- private UserProfile _profile;
- private bool _isNewUser;
-
- public TempProfile TempProfile { get; set; }
- public uint MaxProfileNameLength => 0x20;
-
- public UserEditor()
- {
- InitializeComponent();
- AddHandler(Frame.NavigatedToEvent, (s, e) =>
- {
- NavigatedTo(e);
- }, RoutingStrategies.Direct);
- }
-
- private void NavigatedTo(NavigationEventArgs arg)
- {
- if (Program.PreviewerDetached)
- {
- switch (arg.NavigationMode)
- {
- case NavigationMode.New:
- var args = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
- _isNewUser = args.isNewUser;
- _profile = args.profile;
- TempProfile = new TempProfile(_profile);
-
- _parent = args.parent;
- break;
- }
-
- DataContext = TempProfile;
-
- AddPictureButton.IsVisible = _isNewUser;
- IdLabel.IsVisible = _profile != null;
- IdText.IsVisible = _profile != null;
- ChangePictureButton.IsVisible = !_isNewUser;
- }
- }
-
- private void CloseButton_Click(object sender, RoutedEventArgs e)
- {
- _parent?.GoBack();
- }
-
- private async void SaveButton_Click(object sender, RoutedEventArgs e)
- {
- DataValidationErrors.ClearErrors(NameBox);
- bool isInvalid = false;
-
- if (string.IsNullOrWhiteSpace(TempProfile.Name))
- {
- DataValidationErrors.SetError(NameBox, new DataValidationException(LocaleManager.Instance[LocaleKeys.UserProfileEmptyNameError]));
-
- isInvalid = true;
- }
-
- if (TempProfile.Image == null)
- {
- await ContentDialogHelper.CreateWarningDialog(LocaleManager.Instance[LocaleKeys.UserProfileNoImageError], "");
-
- isInvalid = true;
- }
-
- if(isInvalid)
- {
- return;
- }
-
- if (_profile != null && !_isNewUser)
- {
- _profile.Name = TempProfile.Name;
- _profile.Image = TempProfile.Image;
- _profile.UpdateState();
- _parent.AccountManager.SetUserName(_profile.UserId, _profile.Name);
- _parent.AccountManager.SetUserImage(_profile.UserId, _profile.Image);
- }
- else if (_isNewUser)
- {
- _parent.AccountManager.AddUser(TempProfile.Name, TempProfile.Image, TempProfile.UserId);
- }
- else
- {
- return;
- }
-
- _parent?.GoBack();
- }
-
- public void SelectProfileImage()
- {
- _parent.Navigate(typeof(ProfileImageSelectionDialog), (_parent, TempProfile));
- }
-
- private void ChangePictureButton_Click(object sender, RoutedEventArgs e)
- {
- if (_profile != null || _isNewUser)
- {
- SelectProfileImage();
- }
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/UserRecoverer.axaml b/Ryujinx.Ava/UI/Controls/UserRecoverer.axaml
deleted file mode 100644
index 69f3d36a..00000000
--- a/Ryujinx.Ava/UI/Controls/UserRecoverer.axaml
+++ /dev/null
@@ -1,72 +0,0 @@
-<UserControl
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- mc:Ignorable="d"
- d:DesignWidth="800"
- d:DesignHeight="450"
- MinWidth="500"
- MinHeight="400"
- x:Class="Ryujinx.Ava.UI.Controls.UserRecoverer"
- Focusable="True">
- <Design.DataContext>
- <viewModels:UserProfileViewModel />
- </Design.DataContext>
- <Grid HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition/>
- </Grid.RowDefinitions>
- <Button Grid.Row="0"
- Margin="5"
- Height="30"
- Width="50"
- MinWidth="50"
- HorizontalAlignment="Left"
- Command="{Binding GoBack}">
- <ui:SymbolIcon Symbol="Back"/>
- </Button>
- <TextBlock Grid.Row="1"
- Text="{locale:Locale UserProfilesRecoverHeading}"/>
- <ListBox
- Margin="5"
- Grid.Row="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- Items="{Binding LostProfiles}">
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Border
- Margin="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ClipToBounds="True"
- CornerRadius="5">
- <Grid Margin="0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition/>
- <ColumnDefinition Width="Auto"/>
- </Grid.ColumnDefinitions>
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding UserId}"
- TextAlignment="Left"
- TextWrapping="Wrap" />
- <Button Grid.Column="1"
- HorizontalAlignment="Right"
- Command="{Binding Recover}"
- CommandParameter="{Binding}"
- Content="{locale:Locale Recover}"/>
- </Grid>
- </Border>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- </Grid>
-</UserControl>
diff --git a/Ryujinx.Ava/UI/Controls/UserRecoverer.axaml.cs b/Ryujinx.Ava/UI/Controls/UserRecoverer.axaml.cs
deleted file mode 100644
index 9f29fddb..00000000
--- a/Ryujinx.Ava/UI/Controls/UserRecoverer.axaml.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Avalonia;
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using Avalonia.Markup.Xaml;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class UserRecoverer : UserControl
- {
- private UserProfileViewModel _viewModel;
- private NavigationDialogHost _parent;
-
- public UserRecoverer()
- {
- InitializeComponent();
- AddHandler(Frame.NavigatedToEvent, (s, e) =>
- {
- NavigatedTo(e);
- }, RoutingStrategies.Direct);
- }
-
- private void NavigatedTo(NavigationEventArgs arg)
- {
- if (Program.PreviewerDetached)
- {
- switch (arg.NavigationMode)
- {
- case NavigationMode.New:
- var args = ((NavigationDialogHost parent, UserProfileViewModel viewModel))arg.Parameter;
-
- _viewModel = args.viewModel;
- _parent = args.parent;
- break;
- }
-
- DataContext = _viewModel;
- }
- }
- }
-}
diff --git a/Ryujinx.Ava/UI/Controls/UserSelector.axaml b/Ryujinx.Ava/UI/Controls/UserSelector.axaml
deleted file mode 100644
index 002d27a0..00000000
--- a/Ryujinx.Ava/UI/Controls/UserSelector.axaml
+++ /dev/null
@@ -1,145 +0,0 @@
-<UserControl
- x:Class="Ryujinx.Ava.UI.Controls.UserSelector"
- 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:flex="clr-namespace:Avalonia.Flexbox;assembly=Avalonia.Flexbox"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
- xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
- d:DesignHeight="450"
- MinWidth="500"
- d:DesignWidth="800"
- mc:Ignorable="d"
- Focusable="True">
- <UserControl.Resources>
- <helpers:BitmapArrayValueConverter x:Key="ByteImage" />
- </UserControl.Resources>
- <Design.DataContext>
- <viewModels:UserProfileViewModel />
- </Design.DataContext>
- <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <ListBox
- Margin="5"
- MaxHeight="300"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Center"
- DoubleTapped="ProfilesList_DoubleTapped"
- Items="{Binding Profiles}"
- SelectionChanged="SelectingItemsControl_SelectionChanged">
- <ListBox.ItemsPanel>
- <ItemsPanelTemplate>
- <flex:FlexPanel
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- AlignContent="FlexStart"
- JustifyContent="Center" />
- </ItemsPanelTemplate>
- </ListBox.ItemsPanel>
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Grid>
- <Border
- Margin="2"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch"
- ClipToBounds="True"
- CornerRadius="5">
- <Grid Margin="0">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto" />
- <RowDefinition Height="Auto" />
- </Grid.RowDefinitions>
- <Image
- Grid.Row="0"
- Width="96"
- Height="96"
- Margin="0"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Top"
- Source="{Binding Image, Converter={StaticResource ByteImage}}" />
- <StackPanel
- Grid.Row="1"
- Height="30"
- Margin="5"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <TextBlock
- HorizontalAlignment="Stretch"
- Text="{Binding Name}"
- TextAlignment="Center"
- TextWrapping="Wrap" />
- </StackPanel>
- </Grid>
- </Border>
- <Border
- Width="10"
- Height="10"
- Margin="5"
- HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Background="LimeGreen"
- CornerRadius="5"
- IsVisible="{Binding IsOpened}" />
- </Grid>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox>
- <Grid
- Grid.Row="1"
- HorizontalAlignment="Center">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="Auto"/>
- </Grid.RowDefinitions>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="Auto"/>
- </Grid.ColumnDefinitions>
- <Button
- HorizontalAlignment="Stretch"
- Grid.Row="0"
- Grid.Column="0"
- Margin="2"
- Command="{Binding AddUser}"
- Content="{locale:Locale UserProfilesAddNewProfile}" />
- <Button
- HorizontalAlignment="Stretch"
- Grid.Row="0"
- Margin="2"
- Grid.Column="1"
- Command="{Binding EditUser}"
- Content="{locale:Locale UserProfilesEditProfile}"
- IsEnabled="{Binding IsSelectedProfiledEditable}" />
- <Button
- HorizontalAlignment="Stretch"
- Grid.Row="1"
- Grid.Column="0"
- Margin="2"
- Content="{locale:Locale UserProfilesManageSaves}"
- Command="{Binding ManageSaves}" />
- <Button
- HorizontalAlignment="Stretch"
- Grid.Row="1"
- Grid.Column="1"
- Margin="2"
- Command="{Binding DeleteUser}"
- Content="{locale:Locale UserProfilesDeleteSelectedProfile}"
- IsEnabled="{Binding IsSelectedProfileDeletable}" />
- <Button
- HorizontalAlignment="Stretch"
- Grid.Row="2"
- Grid.ColumnSpan="2"
- Grid.Column="0"
- Margin="2"
- Command="{Binding RecoverLostAccounts}"
- Content="{locale:Locale UserProfilesRecoverLostAccounts}" />
- </Grid>
- </Grid>
-</UserControl> \ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Controls/UserSelector.axaml.cs b/Ryujinx.Ava/UI/Controls/UserSelector.axaml.cs
deleted file mode 100644
index bd8c561e..00000000
--- a/Ryujinx.Ava/UI/Controls/UserSelector.axaml.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Interactivity;
-using FluentAvalonia.UI.Controls;
-using FluentAvalonia.UI.Navigation;
-using Ryujinx.Ava.UI.ViewModels;
-using UserProfile = Ryujinx.Ava.UI.Models.UserProfile;
-
-namespace Ryujinx.Ava.UI.Controls
-{
- public partial class UserSelector : UserControl
- {
- private NavigationDialogHost _parent;
- public UserProfileViewModel ViewModel { get; set; }
-
- public UserSelector()
- {
- InitializeComponent();
-
- if (Program.PreviewerDetached)
- {
- AddHandler(Frame.NavigatedToEvent, (s, e) =>
- {
- NavigatedTo(e);
- }, RoutingStrategies.Direct);
- }
- }
-
- private void NavigatedTo(NavigationEventArgs arg)
- {
- if (Program.PreviewerDetached)
- {
- if (arg.NavigationMode == NavigationMode.New)
- {
- _parent = (NavigationDialogHost)arg.Parameter;
- ViewModel = _parent.ViewModel;
- }
-
- DataContext = ViewModel;
- }
- }
-
- private void ProfilesList_DoubleTapped(object sender, RoutedEventArgs e)
- {
- if (sender is ListBox listBox)
- {
- int selectedIndex = listBox.SelectedIndex;
-
- if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
- {
- ViewModel.SelectedProfile = ViewModel.Profiles[selectedIndex];
-
- _parent?.AccountManager?.OpenUser(ViewModel.SelectedProfile.UserId);
-
- ViewModel.LoadProfiles();
-
- foreach (UserProfile profile in ViewModel.Profiles)
- {
- profile.UpdateState();
- }
- }
- }
- }
-
- private void SelectingItemsControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
- if (sender is ListBox listBox)
- {
- int selectedIndex = listBox.SelectedIndex;
-
- if (selectedIndex >= 0 && selectedIndex < ViewModel.Profiles.Count)
- {
- ViewModel.HighlightedProfile = ViewModel.Profiles[selectedIndex];
- }
- }
- }
- }
-} \ No newline at end of file