aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Ava/Ui/Controls
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Ava/Ui/Controls')
-rw-r--r--Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs12
-rw-r--r--Ryujinx.Ava/Ui/Controls/SaveManager.axaml102
-rw-r--r--Ryujinx.Ava/Ui/Controls/SaveManager.axaml.cs160
-rw-r--r--Ryujinx.Ava/Ui/Controls/UserEditor.axaml3
-rw-r--r--Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs18
-rw-r--r--Ryujinx.Ava/Ui/Controls/UserRecoverer.axaml70
-rw-r--r--Ryujinx.Ava/Ui/Controls/UserRecoverer.axaml.cs44
-rw-r--r--Ryujinx.Ava/Ui/Controls/UserSelector.axaml51
8 files changed, 437 insertions, 23 deletions
diff --git a/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs b/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs
index 9ba631ad..ced88328 100644
--- a/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs
+++ b/Ryujinx.Ava/Ui/Controls/NavigationDialogHost.axaml.cs
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
+using LibHac;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.HLE.FileSystem;
@@ -14,6 +15,8 @@ namespace Ryujinx.Ava.Ui.Controls
{
public AccountManager AccountManager { get; }
public ContentManager ContentManager { get; }
+ public VirtualFileSystem VirtualFileSystem { get; }
+ public HorizonClient HorizonClient { get; }
public UserProfileViewModel ViewModel { get; set; }
public NavigationDialogHost()
@@ -22,10 +25,12 @@ namespace Ryujinx.Ava.Ui.Controls
}
public NavigationDialogHost(AccountManager accountManager, ContentManager contentManager,
- VirtualFileSystem virtualFileSystem)
+ VirtualFileSystem virtualFileSystem, HorizonClient horizonClient)
{
AccountManager = accountManager;
ContentManager = contentManager;
+ VirtualFileSystem = virtualFileSystem;
+ HorizonClient = horizonClient;
ViewModel = new UserProfileViewModel(this);
@@ -54,9 +59,10 @@ namespace Ryujinx.Ava.Ui.Controls
ContentFrame.Navigate(sourcePageType, parameter);
}
- public static async Task Show(AccountManager ownerAccountManager, ContentManager ownerContentManager, VirtualFileSystem ownerVirtualFileSystem)
+ public static async Task Show(AccountManager ownerAccountManager, ContentManager ownerContentManager,
+ VirtualFileSystem ownerVirtualFileSystem, HorizonClient ownerHorizonClient)
{
- var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem);
+ var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient);
ContentDialog contentDialog = new ContentDialog
{
Title = LocaleManager.Instance["UserProfileWindowTitle"],
diff --git a/Ryujinx.Ava/Ui/Controls/SaveManager.axaml b/Ryujinx.Ava/Ui/Controls/SaveManager.axaml
new file mode 100644
index 00000000..ce337c7b
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/SaveManager.axaml
@@ -0,0 +1,102 @@
+<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:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
+ 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"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+ Height="400"
+ Width="550"
+ x:Class="Ryujinx.Ava.Ui.Controls.SaveManager">
+ <UserControl.Resources>
+ <controls: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 Descending}" />
+ </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
new file mode 100644
index 00000000..499cd918
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/SaveManager.axaml.cs
@@ -0,0 +1,160 @@
+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
index 90c5c1fe..898527e6 100644
--- a/Ryujinx.Ava/Ui/Controls/UserEditor.axaml
+++ b/Ryujinx.Ava/Ui/Controls/UserEditor.axaml
@@ -10,6 +10,7 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
Margin="0"
+ MinWidth="500"
Padding="0"
mc:Ignorable="d">
<UserControl.Resources>
@@ -63,7 +64,7 @@
HorizontalAlignment="Stretch"
MaxLength="{Binding MaxProfileNameLength}"
Text="{Binding Name}" />
- <TextBlock Text="{Locale:Locale UserProfilesUserId}" />
+ <TextBlock Name="IdText" Text="{Locale:Locale UserProfilesUserId}" />
<TextBlock Name="IdLabel" Text="{Binding UserId}" />
</StackPanel>
<StackPanel
diff --git a/Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs b/Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs
index ea996da8..f5b51e4e 100644
--- a/Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs
+++ b/Ryujinx.Ava/Ui/Controls/UserEditor.axaml.cs
@@ -36,15 +36,8 @@ namespace Ryujinx.Ava.Ui.Controls
case NavigationMode.New:
var args = ((NavigationDialogHost parent, UserProfile profile, bool isNewUser))arg.Parameter;
_isNewUser = args.isNewUser;
- if (!_isNewUser)
- {
- _profile = args.profile;
- TempProfile = new TempProfile(_profile);
- }
- else
- {
- TempProfile = new TempProfile();
- }
+ _profile = args.profile;
+ TempProfile = new TempProfile(_profile);
_parent = args.parent;
break;
@@ -53,7 +46,8 @@ namespace Ryujinx.Ava.Ui.Controls
DataContext = TempProfile;
AddPictureButton.IsVisible = _isNewUser;
- IdLabel.IsVisible = !_isNewUser;
+ IdLabel.IsVisible = _profile != null;
+ IdText.IsVisible = _profile != null;
ChangePictureButton.IsVisible = !_isNewUser;
}
}
@@ -87,7 +81,7 @@ namespace Ryujinx.Ava.Ui.Controls
return;
}
- if (_profile != null)
+ if (_profile != null && !_isNewUser)
{
_profile.Name = TempProfile.Name;
_profile.Image = TempProfile.Image;
@@ -97,7 +91,7 @@ namespace Ryujinx.Ava.Ui.Controls
}
else if (_isNewUser)
{
- _parent.AccountManager.AddUser(TempProfile.Name, TempProfile.Image);
+ _parent.AccountManager.AddUser(TempProfile.Name, TempProfile.Image, TempProfile.UserId);
}
else
{
diff --git a/Ryujinx.Ava/Ui/Controls/UserRecoverer.axaml b/Ryujinx.Ava/Ui/Controls/UserRecoverer.axaml
new file mode 100644
index 00000000..6345ec67
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/UserRecoverer.axaml
@@ -0,0 +1,70 @@
+<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"
+ mc:Ignorable="d"
+ d:DesignWidth="800"
+ d:DesignHeight="450"
+ MinWidth="500"
+ MinHeight="400"
+ 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"
+ x:Class="Ryujinx.Ava.Ui.Controls.UserRecoverer">
+ <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
new file mode 100644
index 00000000..f093686d
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Controls/UserRecoverer.axaml.cs
@@ -0,0 +1,44 @@
+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
index c06bce23..bc6d8c09 100644
--- a/Ryujinx.Ava/Ui/Controls/UserSelector.axaml
+++ b/Ryujinx.Ava/Ui/Controls/UserSelector.axaml
@@ -10,6 +10,7 @@
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
d:DesignHeight="450"
+ MinWidth="500"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
@@ -25,6 +26,7 @@
</Grid.RowDefinitions>
<ListBox
Margin="5"
+ MaxHeight="300"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
DoubleTapped="ProfilesList_DoubleTapped"
@@ -88,21 +90,56 @@
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
- <StackPanel
+ <Grid
Grid.Row="1"
- Margin="10,0"
- HorizontalAlignment="Center"
- Orientation="Horizontal"
- Spacing="10">
- <Button Command="{Binding AddUser}" Content="{Locale:Locale UserProfilesAddNewProfile}" />
+ 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}" />
- </StackPanel>
+ <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