Avalonia - Use content dialog for user profile manager (#3455)

* remove content dialog placeholder from all windows

* remove redundant window argument

* redesign user profile window

* wip

* use avalonia auto name generator

* add edit and new user options

* move profile image selection to content dialog

* remove usings

* fix updater

* address review

* adjust avatar dialog size

* add validation for user editor

* fix typo

* Shorten some labels
This commit is contained in:
Emmanuel Hansen
2022-07-24 17:38:38 +00:00
committed by GitHub
parent 3a3380fa25
commit 6e02cac952
46 changed files with 968 additions and 953 deletions

View File

@@ -17,43 +17,43 @@
SizeToContent="Width"
WindowStartupLocation="CenterOwner"
mc:Ignorable="d">
<Grid
<Grid
Margin="15"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
Grid.Row="1"
Grid.Column="0"
Margin="20"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="0"
@@ -61,21 +61,21 @@
MinWidth="50"
Margin="5,10,20,10"
Source="resm:Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
<TextBlock
Grid.Row="0"
Grid.Column="1"
Margin="0,20,0,0"
FontSize="35"
Text="Ryujinx"
TextAlignment="Center" />
<TextBlock
<TextBlock
Grid.Row="1"
Grid.Column="1"
Margin="0,0,0,0"
FontSize="16"
Text="(REE-YOU-JINX)"
TextAlignment="Center" />
<Button
<Button
Grid.Row="2"
Grid.Column="1"
Margin="0"
@@ -83,27 +83,27 @@
Background="Transparent"
Click="Button_OnClick"
Tag="https://www.ryujinx.org/">
<TextBlock
<TextBlock
Text="www.ryujinx.org"
TextAlignment="Center"
TextDecorations="Underline"
ToolTip.Tip="{locale:Locale AboutUrlTooltipMessage}" />
</Button>
</Grid>
<TextBlock
</Button>
</Grid>
<TextBlock
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding Version}"
TextAlignment="Center" />
<TextBlock
<TextBlock
Grid.Row="2"
Margin="20"
HorizontalAlignment="Center"
MaxLines="2"
Text="{locale:Locale AboutDisclaimerMessage}"
TextAlignment="Center" />
<TextBlock
<TextBlock
Name="AmiiboLabel"
Grid.Row="3"
Margin="20"
@@ -112,94 +112,94 @@
PointerPressed="AmiiboLabel_OnPointerPressed"
Text="{locale:Locale AboutAmiiboDisclaimerMessage}"
TextAlignment="Center" />
<StackPanel
<StackPanel
Grid.Row="4"
HorizontalAlignment="Center"
Orientation="Horizontal"
Spacing="10">
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutPatreonUrlTooltipMessage}">
<Button
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutPatreonUrlTooltipMessage}">
<Button
Height="65"
Background="Transparent"
Click="Button_OnClick"
Tag="https://www.patreon.com/ryujinx">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Patreon.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Patreon.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
Grid.Row="1"
Margin="0,5,0,0"
HorizontalAlignment="Center"
Text="Patreon" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutGithubUrlTooltipMessage}">
<Button
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutGithubUrlTooltipMessage}">
<Button
Height="65"
Background="Transparent"
Click="Button_OnClick"
Tag="https://github.com/Ryujinx/Ryujinx">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_GitHub.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_GitHub.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
Grid.Row="1"
Margin="0,5,0,0"
HorizontalAlignment="Center"
Text="GitHub" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutDiscordUrlTooltipMessage}">
<Button
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutDiscordUrlTooltipMessage}">
<Button
Height="65"
Background="Transparent"
Click="Button_OnClick"
Tag="https://discordapp.com/invite/N2FmfVc">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Discord.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Discord.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
Grid.Row="1"
Margin="0,5,0,0"
HorizontalAlignment="Center"
Text="Discord" />
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutTwitterUrlTooltipMessage}">
<Button
</Grid>
</Button>
</StackPanel>
<StackPanel Orientation="Vertical" ToolTip.Tip="{locale:Locale AboutTwitterUrlTooltipMessage}">
<Button
Height="65"
Background="Transparent"
Click="Button_OnClick"
Tag="https://twitter.com/RyujinxEmu">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Twitter.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="resm:Ryujinx.Ui.Common.Resources.Logo_Twitter.png?assembly=Ryujinx.Ui.Common" />
<TextBlock
Grid.Row="1"
Margin="0,5,0,0"
HorizontalAlignment="Center"
Text="Twitter" />
</Grid>
</Button>
</StackPanel>
</StackPanel>
</Grid>
<Border
</Grid>
</Button>
</StackPanel>
</StackPanel>
</Grid>
<Border
Grid.Row="1"
Grid.Column="1"
Width="2"
@@ -207,62 +207,62 @@
VerticalAlignment="Stretch"
BorderBrush="White"
BorderThickness="1,0,0,0">
<Separator Width="0" />
</Border>
<Grid
<Separator Width="0" />
</Border>
<Grid
Grid.Row="1"
Grid.Column="2"
Margin="20"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock
FontWeight="Bold"
Text="{locale:Locale AboutRyujinxAboutTitle}"
TextDecorations="Underline" />
<TextBlock
<TextBlock
Grid.Row="1"
Margin="20,5,5,5"
LineHeight="20"
Text="{locale:Locale AboutRyujinxAboutContent}" />
<TextBlock
<TextBlock
Grid.Row="2"
Margin="0,10,0,0"
FontWeight="Bold"
Text="{locale:Locale AboutRyujinxMaintainersTitle}"
TextDecorations="Underline" />
<TextBlock
<TextBlock
Grid.Row="3"
Margin="20,5,5,5"
LineHeight="20"
Text="{Binding Developers}" />
<Button
<Button
Grid.Row="4"
HorizontalAlignment="Right"
Background="Transparent"
Click="Button_OnClick"
Tag="https://github.com/Ryujinx/Ryujinx/graphs/contributors?type=a">
<TextBlock
<TextBlock
Text="{locale:Locale AboutRyujinxContributorsButtonHeader}"
TextAlignment="Right"
TextDecorations="Underline"
ToolTip.Tip="{locale:Locale AboutRyujinxMaintainersContentTooltipMessage}" />
</Button>
<TextBlock
</Button>
<TextBlock
Grid.Row="5"
Margin="0,0,0,0"
FontWeight="Bold"
Text="{locale:Locale AboutRyujinxSupprtersTitle}"
TextDecorations="Underline" />
<Border
<Border
Grid.Row="6"
Width="460"
Height="200"
@@ -271,12 +271,12 @@
VerticalAlignment="Stretch"
BorderBrush="White"
BorderThickness="1">
<TextBlock
<TextBlock
Name="SupportersTextBlock"
VerticalAlignment="Top"
Text="{Binding Supporters}"
TextWrapping="Wrap" />
</Border>
</Grid>
</Grid>
</Border>
</Grid>
</Grid>
</window:StyleableWindow>

View File

@@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Windows
{
public class AboutWindow : StyleableWindow
public partial class AboutWindow : StyleableWindow
{
public AboutWindow()
{
@@ -39,15 +39,6 @@ namespace Ryujinx.Ava.Ui.Windows
public string Developers => string.Format(LocaleManager.Instance["AboutPageDeveloperListMore"], "gdkchan, Ac_K, Thog, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, Xpl0itR, GoffyDude, »jD«");
public TextBlock SupportersTextBlock { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
SupportersTextBlock = this.FindControl<TextBlock>("SupportersTextBlock");
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
if (sender is Button button)

View File

@@ -7,7 +7,7 @@ using Ryujinx.Ava.Ui.ViewModels;
namespace Ryujinx.Ava.Ui.Windows
{
public class AmiiboWindow : StyleableWindow
public partial class AmiiboWindow : StyleableWindow
{
public AmiiboWindow(bool showAll, string lastScannedAmiiboId, string titleId)
{
@@ -44,11 +44,6 @@ namespace Ryujinx.Ava.Ui.Windows
public Amiibo.AmiiboApi ScannedAmiibo { get; set; }
public AmiiboWindowViewModel ViewModel { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void ScanButton_Click(object sender, RoutedEventArgs e)
{
if (ViewModel.AmiiboSelectedIndex > -1)

View File

@@ -1,36 +1,35 @@
<Window xmlns="https://github.com/avaloniaui"
<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:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
x:Class="Ryujinx.Ava.Ui.Windows.AvatarWindow"
CanResize="False"
Margin="0"
Padding="0"
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
WindowStartupLocation="CenterOwner"
x:CompileBindings="True"
x:DataType="viewModels:AvatarProfileViewModel"
SizeToContent="WidthAndHeight">
x:DataType="viewModels:AvatarProfileViewModel">
<Design.DataContext>
<viewModels:AvatarProfileViewModel />
</Design.DataContext>
<Window.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
</Window.Resources>
<Grid Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<UserControl.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
</UserControl.Resources>
<Grid Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Grid.Row="1" BorderThickness="0" SelectedIndex="{Binding SelectedIndex}" Width="600" Height="500"
<ListBox Grid.Row="1" BorderThickness="0" SelectedIndex="{Binding SelectedIndex}" Height="400"
Items="{Binding Images}" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" MaxWidth="600" Margin="0" HorizontalAlignment="Center" />
<WrapPanel Orientation="Horizontal" MaxWidth="700" Margin="0" HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
@@ -45,9 +44,9 @@
<StackPanel Grid.Row="3" Orientation="Horizontal" Spacing="10" Margin="10" HorizontalAlignment="Center">
<Button Content="{Locale:Locale AvatarChoose}" Width="200" Name="ChooseButton" Click="ChooseButton_OnClick" />
<ui:ColorPickerButton Color="{Binding BackgroundColor, Mode=TwoWay}" Name="ColorButton" />
<Button HorizontalAlignment="Right" Content="{Locale:Locale AvatarClose}" Click="CloseButton_OnClick"
<Button HorizontalAlignment="Right" Content="{Locale:Locale Discard}" Click="CloseButton_OnClick"
Name="CloseButton"
Width="200" />
</StackPanel>
</Grid>
</Window>
</UserControl>

View File

@@ -1,70 +1,76 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Common.Locale;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Navigation;
using Ryujinx.Ava.Ui.Controls;
using Ryujinx.Ava.Ui.Models;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.HLE.FileSystem;
using System;
namespace Ryujinx.Ava.Ui.Windows
{
public class AvatarWindow : StyleableWindow
public partial class AvatarWindow : UserControl
{
private NavigationDialogHost _parent;
private TempProfile _profile;
public AvatarWindow(ContentManager contentManager)
{
ContentManager = contentManager;
ViewModel = new AvatarProfileViewModel(() => ViewModel.ReloadImages());
DataContext = ViewModel;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["AvatarWindowTitle"];
}
public AvatarWindow()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
AddHandler(Frame.NavigatedToEvent, (s, e) =>
{
NavigatedTo(e);
}, RoutingStrategies.Direct);
}
private void NavigatedTo(NavigationEventArgs arg)
{
if (Program.PreviewerDetached)
{
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["AvatarWindowTitle"];
if (arg.NavigationMode == NavigationMode.New)
{
(_parent, _profile) = ((NavigationDialogHost, TempProfile))arg.Parameter;
ContentManager = _parent.ContentManager;
if (Program.PreviewerDetached)
{
ViewModel = new AvatarProfileViewModel(() => ViewModel.ReloadImages());
}
DataContext = ViewModel;
}
}
}
public ContentManager ContentManager { get; }
public byte[] SelectedImage { get; set; }
public ContentManager ContentManager { get; private set; }
internal AvatarProfileViewModel ViewModel { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
protected override void OnClosed(EventArgs e)
{
ViewModel.Dispose();
base.OnClosed(e);
}
private void CloseButton_OnClick(object sender, RoutedEventArgs e)
{
Close();
ViewModel.Dispose();
_parent.GoBack();
}
private void ChooseButton_OnClick(object sender, RoutedEventArgs e)
{
if (ViewModel.SelectedIndex > -1)
{
SelectedImage = ViewModel.SelectedImage;
_profile.Image = ViewModel.SelectedImage;
Close();
ViewModel.Dispose();
_parent.GoBack();
}
}
}

View File

@@ -12,7 +12,7 @@ using System.Linq;
namespace Ryujinx.Ava.Ui.Windows
{
public class CheatWindow : StyleableWindow
public partial class CheatWindow : StyleableWindow
{
private readonly string _enabledCheatsPath;
public bool NoCheatsFound { get; }
@@ -102,11 +102,6 @@ namespace Ryujinx.Ava.Ui.Windows
this.AttachDevTools();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
public void Save()
{
if (NoCheatsFound)

View File

@@ -24,11 +24,10 @@ using Key = Ryujinx.Input.Key;
namespace Ryujinx.Ava.Ui.Windows
{
public class ControllerSettingsWindow : UserControl
public partial class ControllerSettingsWindow : UserControl
{
private bool _dialogOpen;
public Grid SettingButtons { get; set; }
private ButtonKeyAssigner _currentAssigner;
internal ControllerSettingsViewModel ViewModel { get; set; }
@@ -48,13 +47,6 @@ namespace Ryujinx.Ava.Ui.Windows
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
SettingButtons = this.FindControl<Grid>("SettingButtons");
}
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{
base.OnPointerReleased(e);
@@ -165,7 +157,6 @@ namespace Ryujinx.Ava.Ui.Windows
_dialogOpen = true;
var result = await ContentDialogHelper.CreateConfirmationDialog(
this.GetVisualRoot() as StyleableWindow,
LocaleManager.Instance["DialogControllerSettingsModifiedConfirmMessage"],
LocaleManager.Instance["DialogControllerSettingsModifiedConfirmSubMessage"],
LocaleManager.Instance["InputDialogYes"],

View File

@@ -1,7 +1,6 @@
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;
using LibHac.Common;
using LibHac.Fs;
@@ -27,7 +26,7 @@ using Path = System.IO.Path;
namespace Ryujinx.Ava.Ui.Windows
{
public class DlcManagerWindow : StyleableWindow
public partial class DlcManagerWindow : StyleableWindow
{
private readonly List<DlcContainer> _dlcContainerList;
private readonly string _dlcJsonPath;
@@ -35,7 +34,6 @@ namespace Ryujinx.Ava.Ui.Windows
public VirtualFileSystem VirtualFileSystem { get; }
public AvaloniaList<DlcModel> Dlcs { get; set; }
public Grid DlcGrid { get; private set; }
public ulong TitleId { get; }
public string TitleName { get; }
@@ -47,7 +45,7 @@ namespace Ryujinx.Ava.Ui.Windows
InitializeComponent();
AttachDebugDevTools();
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
}
@@ -72,7 +70,7 @@ namespace Ryujinx.Ava.Ui.Windows
InitializeComponent();
AttachDebugDevTools();
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["DlcWindowTitle"];
LoadDlcs();
@@ -84,15 +82,6 @@ namespace Ryujinx.Ava.Ui.Windows
this.AttachDevTools();
}
private void InitializeComponent()
{
Dlcs = new AvaloniaList<DlcModel>();
AvaloniaXamlLoader.Load(this);
DlcGrid = this.FindControl<Grid>("DlcGrid");
}
private void LoadDlcs()
{
foreach (DlcContainer dlcContainer in _dlcContainerList)
@@ -129,8 +118,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
await ContentDialogHelper.CreateErrorDialog(this,
string.Format(LocaleManager.Instance[
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance[
"DialogDlcLoadNcaErrorMessage"], ex.Message, containerPath));
});
}
@@ -180,7 +168,7 @@ namespace Ryujinx.Ava.Ui.Windows
if (!containsDlc)
{
await ContentDialogHelper.CreateErrorDialog(this, LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogDlcNoDlcErrorMessage"]);
}
}
}
@@ -189,7 +177,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
if (removeSelectedOnly)
{
Dlcs.RemoveAll(Dlcs.Where(x => x.IsEnabled).ToList());
Dlcs.RemoveAll(Dlcs.Where(x => x.IsEnabled).ToList());
}
else
{

View File

@@ -38,18 +38,6 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<controls:OffscreenTextBox Name="HiddenTextBox" Grid.Row="0" />
<ContentControl
Grid.Row="1"
Focusable="False"
IsVisible="False"
KeyboardNavigation.IsTabStop="False">
<ui:ContentDialog
Name="ContentDialog"
IsPrimaryButtonEnabled="True"
IsSecondaryButtonEnabled="True"
IsVisible="True"
KeyboardNavigation.IsTabStop="False" />
</ContentControl>
<StackPanel Grid.Row="0" IsVisible="False">
<controls:HotKeyControl Name="FullscreenHotKey" Command="{ReflectionBinding ToggleFullscreen}" />
<controls:HotKeyControl Name="FullscreenHotKey2" Command="{ReflectionBinding ToggleFullscreen}" />

View File

@@ -36,7 +36,7 @@ using InputManager = Ryujinx.Input.HLE.InputManager;
using ProgressBar = Avalonia.Controls.ProgressBar;
namespace Ryujinx.Ava.Ui.Windows
{
public class MainWindow : StyleableWindow
public partial class MainWindow : StyleableWindow
{
private bool _canUpdate;
private bool _isClosing;
@@ -62,22 +62,6 @@ namespace Ryujinx.Ava.Ui.Windows
public InputManager InputManager { get; private set; }
internal RendererControl GlRenderer { get; private set; }
public ContentControl ContentFrame { get; private set; }
public TextBlock LoadStatus { get; private set; }
public TextBlock FirmwareStatus { get; private set; }
public TextBox SearchBox { get; private set; }
public ProgressBar LoadProgressBar { get; private set; }
public Menu Menu { get; private set; }
public MenuItem UpdateMenuItem { get; private set; }
public MenuItem ActionsMenuItem { get; private set; }
public GameGridView GameGrid { get; private set; }
public GameListView GameList { get; private set; }
public OffscreenTextBox HiddenTextBox { get; private set; }
public HotKeyControl FullscreenHotKey { get; private set; }
public HotKeyControl FullscreenHotKey2 { get; private set; }
public HotKeyControl DockToggleHotKey { get; private set; }
public HotKeyControl ExitHotKey { get; private set; }
public ToggleSplitButton VolumeStatus { get; set; }
internal MainWindowViewModel ViewModel { get; private set; }
public SettingsWindow SettingsWindow { get; set; }
@@ -102,6 +86,7 @@ namespace Ryujinx.Ava.Ui.Windows
DataContext = ViewModel;
InitializeComponent();
Load();
AttachDebugDevTools();
UiHandler = new AvaHostUiHandler(this);
@@ -192,7 +177,9 @@ namespace Ryujinx.Ava.Ui.Windows
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledMessage"];
string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckLoggingEnabledConfirmMessage"];
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(mainMessage, secondaryMessage,
LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"],
LocaleManager.Instance["RyujinxConfirm"]);
if (result != UserResult.Yes)
{
@@ -205,9 +192,12 @@ namespace Ryujinx.Ava.Ui.Windows
if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value))
{
string mainMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledMessage"];
string secondaryMessage = LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledConfirmMessage"];
string secondaryMessage =
LocaleManager.Instance["DialogPerformanceCheckShaderDumpEnabledConfirmMessage"];
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(this, mainMessage, secondaryMessage, LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"], LocaleManager.Instance["RyujinxConfirm"]);
UserResult result = await ContentDialogHelper.CreateConfirmationDialog(mainMessage, secondaryMessage,
LocaleManager.Instance["InputDialogYes"], LocaleManager.Instance["InputDialogNo"],
LocaleManager.Instance["RyujinxConfirm"]);
if (result != UserResult.Yes)
{
@@ -231,7 +221,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
if (AppHost != null)
{
await ContentDialogHelper.CreateInfoDialog(this,
await ContentDialogHelper.CreateInfoDialog(
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedMessage"],
LocaleManager.Instance["DialogLoadAppGameAlreadyLoadedSubMessage"],
LocaleManager.Instance["InputDialogOk"],
@@ -254,7 +244,7 @@ namespace Ryujinx.Ava.Ui.Windows
PrepareLoadScreen();
_mainViewContent = ContentFrame.Content as Control;
_mainViewContent = Content.Content as Control;
GlRenderer = new RendererControl(3, 3, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
AppHost = new AppHost(GlRenderer, InputManager, path, VirtualFileSystem, ContentManager, AccountManager, _userChannelPersistence, this);
@@ -321,7 +311,7 @@ namespace Ryujinx.Ava.Ui.Windows
Dispatcher.UIThread.InvokeAsync(() =>
{
ContentFrame.Content = GlRenderer;
Content.Content = GlRenderer;
if (startFullscreen && WindowState != WindowState.FullScreen)
{
@@ -365,9 +355,9 @@ namespace Ryujinx.Ava.Ui.Windows
Dispatcher.UIThread.InvokeAsync(() =>
{
if (ContentFrame.Content != _mainViewContent)
if (Content.Content != _mainViewContent)
{
ContentFrame.Content = _mainViewContent;
Content.Content = _mainViewContent;
}
ViewModel.ShowMenuAndStatusBar = true;
@@ -501,27 +491,8 @@ namespace Ryujinx.Ava.Ui.Windows
ViewModel.IsAppletMenuActive = hasApplet;
}
private void InitializeComponent()
private void Load()
{
AvaloniaXamlLoader.Load(this);
ContentFrame = this.FindControl<ContentControl>("Content");
GameList = this.FindControl<GameListView>("GameList");
LoadStatus = this.FindControl<TextBlock>("LoadStatus");
FirmwareStatus = this.FindControl<TextBlock>("FirmwareStatus");
LoadProgressBar = this.FindControl<ProgressBar>("LoadProgressBar");
SearchBox = this.FindControl<TextBox>("SearchBox");
Menu = this.FindControl<Menu>("Menu");
UpdateMenuItem = this.FindControl<MenuItem>("UpdateMenuItem");
GameGrid = this.FindControl<GameGridView>("GameGrid");
HiddenTextBox = this.FindControl<OffscreenTextBox>("HiddenTextBox");
FullscreenHotKey = this.FindControl<HotKeyControl>("FullscreenHotKey");
FullscreenHotKey2 = this.FindControl<HotKeyControl>("FullscreenHotKey2");
DockToggleHotKey = this.FindControl<HotKeyControl>("DockToggleHotKey");
ExitHotKey = this.FindControl<HotKeyControl>("ExitHotKey");
VolumeStatus = this.FindControl<ToggleSplitButton>("VolumeStatus");
ActionsMenuItem = this.FindControl<MenuItem>("ActionsMenuItem");
VolumeStatus.Click += VolumeStatus_CheckedChanged;
GameGrid.ApplicationOpened += Application_Opened;
@@ -710,7 +681,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
Dispatcher.UIThread.InvokeAsync(async () =>
{
_isClosing = await ContentDialogHelper.CreateExitDialog(this);
_isClosing = await ContentDialogHelper.CreateExitDialog();
if (_isClosing)
{

View File

@@ -9,13 +9,14 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Windows
{
public class MotionSettingsWindow : UserControl
public partial class MotionSettingsWindow : UserControl
{
private readonly InputConfiguration<GamepadInputId, StickInputId> _viewmodel;
public MotionSettingsWindow()
{
InitializeComponent();
DataContext = _viewmodel;
}
public MotionSettingsWindow(ControllerSettingsViewModel viewmodel)
@@ -36,46 +37,36 @@ namespace Ryujinx.Ava.Ui.Windows
};
InitializeComponent();
}
private void InitializeComponent()
{
DataContext = _viewmodel;
AvaloniaXamlLoader.Load(this);
}
public static async Task Show(ControllerSettingsViewModel viewmodel, StyleableWindow window)
public static async Task Show(ControllerSettingsViewModel viewmodel)
{
ContentDialog contentDialog = window.ContentDialog;
string name = string.Empty;
MotionSettingsWindow content = new MotionSettingsWindow(viewmodel);
if (contentDialog != null)
ContentDialog contentDialog = new ContentDialog
{
contentDialog.Title = LocaleManager.Instance["ControllerMotionTitle"];
contentDialog.PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"];
contentDialog.SecondaryButtonText = "";
contentDialog.CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"];
contentDialog.Content = content;
contentDialog.PrimaryButtonClick += (sender, args) =>
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
config.Slot = content._viewmodel.Slot;
config.EnableMotion = content._viewmodel.EnableMotion;
config.Sensitivity = content._viewmodel.Sensitivity;
config.GyroDeadzone = content._viewmodel.GyroDeadzone;
config.AltSlot = content._viewmodel.AltSlot;
config.DsuServerHost = content._viewmodel.DsuServerHost;
config.DsuServerPort = content._viewmodel.DsuServerPort;
config.EnableCemuHookMotion = content._viewmodel.EnableCemuHookMotion;
config.MirrorInput = content._viewmodel.MirrorInput;
};
Title = LocaleManager.Instance["ControllerMotionTitle"],
PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"],
SecondaryButtonText = "",
CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"],
Content = content
};
contentDialog.PrimaryButtonClick += (sender, args) =>
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
config.Slot = content._viewmodel.Slot;
config.EnableMotion = content._viewmodel.EnableMotion;
config.Sensitivity = content._viewmodel.Sensitivity;
config.GyroDeadzone = content._viewmodel.GyroDeadzone;
config.AltSlot = content._viewmodel.AltSlot;
config.DsuServerHost = content._viewmodel.DsuServerHost;
config.DsuServerPort = content._viewmodel.DsuServerPort;
config.EnableCemuHookMotion = content._viewmodel.EnableCemuHookMotion;
config.MirrorInput = content._viewmodel.MirrorInput;
};
await contentDialog.ShowAsync();
}
await contentDialog.ShowAsync();
}
}
}

View File

@@ -9,13 +9,14 @@ using System.Threading.Tasks;
namespace Ryujinx.Ava.Ui.Windows
{
public class RumbleSettingsWindow : UserControl
public partial class RumbleSettingsWindow : UserControl
{
private readonly InputConfiguration<GamepadInputId, StickInputId> _viewmodel;
public RumbleSettingsWindow()
{
InitializeComponent();
DataContext = _viewmodel;
}
public RumbleSettingsWindow(ControllerSettingsViewModel viewmodel)
@@ -24,44 +25,34 @@ namespace Ryujinx.Ava.Ui.Windows
_viewmodel = new InputConfiguration<GamepadInputId, StickInputId>()
{
StrongRumble = config.StrongRumble,
WeakRumble = config.WeakRumble
StrongRumble = config.StrongRumble, WeakRumble = config.WeakRumble
};
InitializeComponent();
}
private void InitializeComponent()
{
DataContext = _viewmodel;
AvaloniaXamlLoader.Load(this);
}
public static async Task Show(ControllerSettingsViewModel viewmodel, StyleableWindow window)
public static async Task Show(ControllerSettingsViewModel viewmodel)
{
ContentDialog contentDialog = window.ContentDialog;
string name = string.Empty;
RumbleSettingsWindow content = new RumbleSettingsWindow(viewmodel);
if (contentDialog != null)
ContentDialog contentDialog = new ContentDialog
{
contentDialog.Title = LocaleManager.Instance["ControllerRumbleTitle"];
contentDialog.PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"];
contentDialog.SecondaryButtonText = "";
contentDialog.CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"];
contentDialog.Content = content;
contentDialog.PrimaryButtonClick += (sender, args) =>
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
config.StrongRumble = content._viewmodel.StrongRumble;
config.WeakRumble = content._viewmodel.WeakRumble;
};
await contentDialog.ShowAsync();
}
Title = LocaleManager.Instance["ControllerRumbleTitle"],
PrimaryButtonText = LocaleManager.Instance["ControllerSettingsSave"],
SecondaryButtonText = "",
CloseButtonText = LocaleManager.Instance["ControllerSettingsClose"],
Content = content,
};
contentDialog.PrimaryButtonClick += (sender, args) =>
{
var config = viewmodel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
config.StrongRumble = content._viewmodel.StrongRumble;
config.WeakRumble = content._viewmodel.WeakRumble;
};
await contentDialog.ShowAsync();
}
}
}

View File

@@ -31,16 +31,11 @@
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentControl
<ContentPresenter
x:Name="ContentPresenter"
Grid.Row="1"
Focusable="False"
IsVisible="False"
KeyboardNavigation.IsTabStop="False">
<ui:ContentDialog Name="ContentDialog"
IsPrimaryButtonEnabled="True"
IsSecondaryButtonEnabled="True"
IsVisible="False" />
</ContentControl>
KeyboardNavigation.IsTabStop="False"/>
<Grid Name="Pages" IsVisible="False" Grid.Row="2">
<ScrollViewer Name="UiPage"
Margin="0,0,10,0"

View File

@@ -1,5 +1,6 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Data.Converters;
@@ -28,24 +29,8 @@ using TimeZone = Ryujinx.Ava.Ui.Models.TimeZone;
namespace Ryujinx.Ava.Ui.Windows
{
public class SettingsWindow : StyleableWindow
public partial class SettingsWindow : StyleableWindow
{
private ListBox _gameList;
private TextBox _pathBox;
private AutoCompleteBox _timeZoneBox;
private ControllerSettingsWindow _controllerSettings;
// Pages
private Control _uiPage;
private Control _inputPage;
private Control _hotkeysPage;
private Control _systemPage;
private Control _cpuPage;
private Control _graphicsPage;
private Control _audioPage;
private Control _networkPage;
private Control _loggingPage;
private NavigationView _navPanel;
private ButtonKeyAssigner _currentAssigner;
internal SettingsViewModel ViewModel { get; set; }
@@ -58,6 +43,7 @@ namespace Ryujinx.Ava.Ui.Windows
DataContext = ViewModel;
InitializeComponent();
Load();
AttachDebugDevTools();
FuncMultiValueConverter<string, string> converter = new(parts => string.Format("{0} {1} {2}", parts.ToArray()));
@@ -66,7 +52,7 @@ namespace Ryujinx.Ava.Ui.Windows
tzMultiBinding.Bindings.Add(new Binding("Location"));
tzMultiBinding.Bindings.Add(new Binding("Abbreviation"));
_timeZoneBox.ValueMemberBinding = tzMultiBinding;
TimeZoneBox.ValueMemberBinding = tzMultiBinding;
}
public SettingsWindow()
@@ -75,6 +61,7 @@ namespace Ryujinx.Ava.Ui.Windows
DataContext = ViewModel;
InitializeComponent();
Load();
AttachDebugDevTools();
}
@@ -84,31 +71,11 @@ namespace Ryujinx.Ava.Ui.Windows
this.AttachDevTools();
}
private void InitializeComponent()
private void Load()
{
AvaloniaXamlLoader.Load(this);
_pathBox = this.FindControl<TextBox>("PathBox");
_gameList = this.FindControl<ListBox>("GameList");
_timeZoneBox = this.FindControl<AutoCompleteBox>("TimeZoneBox");
_controllerSettings = this.FindControl<ControllerSettingsWindow>("ControllerSettings");
_uiPage = this.FindControl<Control>("UiPage");
_inputPage = this.FindControl<Control>("InputPage");
_hotkeysPage = this.FindControl<Control>("HotkeysPage");
_systemPage = this.FindControl<Control>("SystemPage");
_cpuPage = this.FindControl<Control>("CpuPage");
_graphicsPage = this.FindControl<Control>("GraphicsPage");
_audioPage = this.FindControl<Control>("AudioPage");
_networkPage = this.FindControl<Control>("NetworkPage");
_loggingPage = this.FindControl<Control>("LoggingPage");
var pageGrid = this.FindControl<Grid>("Pages");
pageGrid.Children.Clear();
_navPanel = this.FindControl<NavigationView>("NavPanel");
_navPanel.SelectionChanged += NavPanelOnSelectionChanged;
_navPanel.SelectedItem = _navPanel.MenuItems.ElementAt(0);
Pages.Children.Clear();
NavPanel.SelectionChanged += NavPanelOnSelectionChanged;
NavPanel.SelectedItem = NavPanel.MenuItems.ElementAt(0);
}
private void Button_Checked(object sender, RoutedEventArgs e)
@@ -174,31 +141,31 @@ namespace Ryujinx.Ava.Ui.Windows
switch (navitem.Tag.ToString())
{
case "UiPage":
_navPanel.Content = _uiPage;
NavPanel.Content = UiPage;
break;
case "InputPage":
_navPanel.Content = _inputPage;
NavPanel.Content = InputPage;
break;
case "HotkeysPage":
_navPanel.Content = _hotkeysPage;
NavPanel.Content = HotkeysPage;
break;
case "SystemPage":
_navPanel.Content = _systemPage;
NavPanel.Content = SystemPage;
break;
case "CpuPage":
_navPanel.Content = _cpuPage;
NavPanel.Content = CpuPage;
break;
case "GraphicsPage":
_navPanel.Content = _graphicsPage;
NavPanel.Content = GraphicsPage;
break;
case "AudioPage":
_navPanel.Content = _audioPage;
NavPanel.Content = AudioPage;
break;
case "NetworkPage":
_navPanel.Content = _networkPage;
NavPanel.Content = NetworkPage;
break;
case "LoggingPage":
_navPanel.Content = _loggingPage;
NavPanel.Content = LoggingPage;
break;
}
}
@@ -206,7 +173,7 @@ namespace Ryujinx.Ava.Ui.Windows
private async void AddButton_OnClick(object sender, RoutedEventArgs e)
{
string path = _pathBox.Text;
string path = PathBox.Text;
if (!string.IsNullOrWhiteSpace(path) && Directory.Exists(path) && !ViewModel.GameDirectories.Contains(path))
{
@@ -225,7 +192,7 @@ namespace Ryujinx.Ava.Ui.Windows
private void RemoveButton_OnClick(object sender, RoutedEventArgs e)
{
List<string> selected = new(_gameList.SelectedItems.Cast<string>());
List<string> selected = new(GameList.SelectedItems.Cast<string>());
foreach (string path in selected)
{
@@ -279,7 +246,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
ViewModel.SaveSettings();
_controllerSettings?.SaveCurrentProfile();
ControllerSettings?.SaveCurrentProfile();
if (Owner is MainWindow window)
{
@@ -289,7 +256,7 @@ namespace Ryujinx.Ava.Ui.Windows
protected override void OnClosed(EventArgs e)
{
_controllerSettings.Dispose();
ControllerSettings.Dispose();
_currentAssigner?.Cancel();
_currentAssigner = null;
base.OnClosed(e);

View File

@@ -11,7 +11,6 @@ namespace Ryujinx.Ava.Ui.Windows
{
public class StyleableWindow : Window
{
public ContentDialog ContentDialog { get; private set; }
public IBitmap IconImage { get; set; }
public StyleableWindow()
@@ -26,15 +25,9 @@ namespace Ryujinx.Ava.Ui.Windows
IconImage = new Bitmap(stream);
}
public void LoadDialog()
{
ContentDialog = this.FindControl<ContentDialog>("ContentDialog");
}
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
ContentDialog = this.FindControl<ContentDialog>("ContentDialog");
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)

View File

@@ -28,14 +28,14 @@ using Avalonia.Threading;
namespace Ryujinx.Ava.Ui.Windows
{
public class TitleUpdateWindow : StyleableWindow
public partial class TitleUpdateWindow : StyleableWindow
{
private readonly string _updateJsonPath;
private TitleUpdateMetadata _titleUpdateWindowData;
public VirtualFileSystem VirtualFileSystem { get; }
internal AvaloniaList<TitleUpdateModel> TitleUpdates { get; set; }
internal AvaloniaList<TitleUpdateModel> TitleUpdates { get; set; } = new AvaloniaList<TitleUpdateModel>();
public string TitleId { get; }
public string TitleName { get; }
@@ -84,13 +84,6 @@ namespace Ryujinx.Ava.Ui.Windows
this.AttachDevTools();
}
private void InitializeComponent()
{
TitleUpdates = new AvaloniaList<TitleUpdateModel>();
AvaloniaXamlLoader.Load(this);
}
private void LoadUpdates()
{
TitleUpdates.Add(new TitleUpdateModel(default, string.Empty, true));
@@ -154,8 +147,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
Dispatcher.UIThread.Post(async () =>
{
await ContentDialogHelper.CreateErrorDialog(this,
LocaleManager.Instance["DialogUpdateAddUpdateErrorMessage"]);
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance["DialogUpdateAddUpdateErrorMessage"]);
});
}
}
@@ -163,8 +155,7 @@ namespace Ryujinx.Ava.Ui.Windows
{
Dispatcher.UIThread.Post(async () =>
{
await ContentDialogHelper.CreateErrorDialog(this,
string.Format(LocaleManager.Instance["DialogDlcLoadNcaErrorMessage"], ex.Message, path));
await ContentDialogHelper.CreateErrorDialog(string.Format(LocaleManager.Instance["DialogDlcLoadNcaErrorMessage"], ex.Message, path));
});
}
}

View File

@@ -11,7 +11,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Ava.Ui.Windows
{
public class UpdaterWindow : StyleableWindow
public partial class UpdaterWindow : StyleableWindow
{
private readonly string _buildUrl;
private readonly MainWindow _mainWindow;
@@ -36,21 +36,6 @@ namespace Ryujinx.Ava.Ui.Windows
_buildUrl = buildUrl;
}
public TextBlock MainText { get; set; }
public TextBlock SecondaryText { get; set; }
public ProgressBar ProgressBar { get; set; }
public StackPanel ButtonBox { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
MainText = this.FindControl<TextBlock>("MainText");
SecondaryText = this.FindControl<TextBlock>("SecondaryText");
ProgressBar = this.FindControl<ProgressBar>("ProgressBar");
ButtonBox = this.FindControl<StackPanel>("ButtonBox");
}
[DllImport("libc", SetLastError = true)]
private static extern int chmod(string path, uint mode);

View File

@@ -1,107 +0,0 @@
<window:StyleableWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
x:Class="Ryujinx.Ava.Ui.Windows.UserProfileWindow"
xmlns:Locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.Ui.ViewModels"
xmlns:controls="clr-namespace:Ryujinx.Ava.Ui.Controls"
xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
CanResize="False"
Width="850" MinHeight="550" Height="550"
WindowStartupLocation="CenterOwner"
SizeToContent="Manual"
MinWidth="600">
<Design.DataContext>
<viewModels:UserProfileViewModel />
</Design.DataContext>
<Window.Resources>
<controls:BitmapArrayValueConverter x:Key="ByteImage" />
</Window.Resources>
<Grid Margin="15" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ContentControl
Focusable="False"
IsVisible="False"
KeyboardNavigation.IsTabStop="False">
<ui:ContentDialog Name="ContentDialog"
IsPrimaryButtonEnabled="True"
IsSecondaryButtonEnabled="True"
IsVisible="False" />
</ContentControl>
<TextBlock Text="{Locale:Locale UserProfilesSelectedUserProfile}" />
<Grid Grid.Row="1" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Height="96" Width="96"
Source="{Binding SelectedProfile.Image, Converter={StaticResource ByteImage}}" />
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Grid.Column="1" Spacing="10"
Margin="5, 10">
<TextBox Name="NameBox" Text="{Binding SelectedProfile.Name, Mode=OneWay}"
HorizontalAlignment="Stretch" />
<TextBlock Text="{Binding SelectedProfile.UserId}" />
</StackPanel>
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Grid.Column="2" Spacing="10"
Margin="5">
<Button Content="{Locale:Locale UserProfilesSaveProfileName}" Name="SetNameButton"
Click="SetNameButton_OnClick" />
<Button Name="SelectProfileImage" Command="{Binding ChooseProfileImage}"
Content="{Locale:Locale UserProfilesChangeProfileImage}" />
</StackPanel>
</Grid>
</Grid>
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Locale:Locale UserProfilesAvailableUserProfiles}" />
<ListBox Grid.Row="1" Margin="10" Name="ProfilesList" DoubleTapped="ProfilesList_DoubleTapped"
Items="{Binding Profiles}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="{DynamicResource ThemeAccentColorBrush}"
Grid.ColumnSpan="2"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinHeight="5" MinWidth="5"
IsVisible="{Binding IsOpened}" />
<Image Grid.Column="0" Height="96" Width="96"
Source="{Binding Image, Converter={StaticResource ByteImage}}" />
<StackPanel Margin="10" Orientation="Vertical" HorizontalAlignment="Stretch"
VerticalAlignment="Center" Grid.Column="1">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding UserId}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<StackPanel Grid.Row="3" Orientation="Horizontal" Margin="10,0" Spacing="10" HorizontalAlignment="Stretch">
<Button Content="{Locale:Locale UserProfilesAddNewProfile}" Command="{Binding AddUser}" />
<Button IsEnabled="{Binding IsSelectedProfileDeletable}"
Content="{Locale:Locale UserProfilesDeleteSelectedProfile}" Command="{Binding DeleteUser}" />
<Button HorizontalAlignment="Right" Content="{Locale:Locale UserProfilesClose}" Click="CloseButton_OnClick"
Name="CloseButton" />
</StackPanel>
</Grid>
</window:StyleableWindow>

View File

@@ -1,102 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.ViewModels;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using System.Threading.Tasks;
using UserProfile = Ryujinx.Ava.Ui.Models.UserProfile;
namespace Ryujinx.Ava.Ui.Windows
{
public class UserProfileWindow : StyleableWindow
{
private TextBox _nameBox;
public UserProfileWindow(AccountManager accountManager, ContentManager contentManager,
VirtualFileSystem virtualFileSystem)
{
AccountManager = accountManager;
ContentManager = contentManager;
ViewModel = new UserProfileViewModel(this);
DataContext = ViewModel;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
if (contentManager.GetCurrentFirmwareVersion() != null)
{
Task.Run(() =>
{
AvatarProfileViewModel.PreloadAvatars(contentManager, virtualFileSystem);
});
}
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UserProfileWindowTitle"];
}
public UserProfileWindow()
{
ViewModel = new UserProfileViewModel();
DataContext = ViewModel;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
Title = $"Ryujinx {Program.Version} - " + LocaleManager.Instance["UserProfileWindowTitle"];
}
public AccountManager AccountManager { get; }
public ContentManager ContentManager { get; }
public UserProfileViewModel ViewModel { get; set; }
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
_nameBox = this.FindControl<TextBox>("NameBox");
}
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];
AccountManager.OpenUser(ViewModel.SelectedProfile.UserId);
ViewModel.LoadProfiles();
foreach (UserProfile profile in ViewModel.Profiles)
{
profile.UpdateState();
}
}
}
}
private void CloseButton_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
private void SetNameButton_OnClick(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrWhiteSpace(_nameBox.Text))
{
ViewModel.SelectedProfile.Name = _nameBox.Text;
AccountManager.SetUserName(ViewModel.SelectedProfile.UserId, _nameBox.Text);
}
}
}
}