UI: Show what each value is in the Game Info dialog, add game icon

This commit is contained in:
Evan Husted 2025-02-04 22:47:12 -06:00
parent 1972a47f39
commit bd08a111a8
8 changed files with 155 additions and 112 deletions

View File

@ -2578,7 +2578,7 @@
"ar_SA": "", "ar_SA": "",
"de_DE": "", "de_DE": "",
"el_GR": "", "el_GR": "",
"en_US": "Show Game Stats", "en_US": "Show Game Info",
"es_ES": "", "es_ES": "",
"fr_FR": "", "fr_FR": "",
"he_IL": "", "he_IL": "",
@ -2603,7 +2603,7 @@
"ar_SA": "", "ar_SA": "",
"de_DE": "", "de_DE": "",
"el_GR": "", "el_GR": "",
"en_US": "Show the other various information about the currently selected game that is missing from the Grid view layout.", "en_US": "Show stats & details about the currently selected game.",
"es_ES": "", "es_ES": "",
"fr_FR": "", "fr_FR": "",
"he_IL": "", "he_IL": "",

View File

@ -26,7 +26,6 @@
Icon="{ext:Icon mdi-gamepad}" Icon="{ext:Icon mdi-gamepad}"
ToolTip.Tip="{ext:Locale GameListContextMenuShowCompatEntryToolTip}"/> ToolTip.Tip="{ext:Locale GameListContextMenuShowCompatEntryToolTip}"/>
<MenuItem <MenuItem
IsVisible="{Binding IsGrid}"
Click="OpenApplicationData_Click" Click="OpenApplicationData_Click"
Header="{ext:Locale GameListContextMenuShowGameData}" Header="{ext:Locale GameListContextMenuShowGameData}"
Icon="{ext:Icon mdi-chart-line}" Icon="{ext:Icon mdi-chart-line}"

View File

@ -2,115 +2,123 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers" xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:appLibrary="using:Ryujinx.Ava.Utilities.AppLibrary" xmlns:appLibrary="using:Ryujinx.Ava.Utilities.AppLibrary"
xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.UI.Controls.ApplicationDataView" x:Class="Ryujinx.Ava.UI.Controls.ApplicationDataView"
x:DataType="appLibrary:ApplicationData"> x:DataType="viewModels:ApplicationDataViewModel">
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal">
<Grid <Image Margin="0"
RowDefinitions="Auto, Auto, Auto, Auto" MaxWidth="256"
ColumnDefinitions="*"> MinWidth="256"
<TextBlock Grid.Row="0" Source="{Binding AppData.Icon, Converter={x:Static helpers:BitmapArrayValueConverter.Instance}}" />
HorizontalAlignment="Center" <Border Margin="5, 0" Width="2" Height="256" BorderBrush="Gray" Background="Gray" />
Padding="0, -2, 0, 5" <StackPanel Orientation="Vertical">
Classes="h1" <Grid
Text="{Binding Name}" /> RowDefinitions="Auto, Auto, Auto, Auto"
<TextBlock Grid.Row="1" ColumnDefinitions="*">
HorizontalAlignment="Center" <TextBlock Grid.Row="0"
Text="{Binding Version}" HorizontalAlignment="Center"
TextAlignment="Start" Padding="0, -2, 0, 5"
TextWrapping="Wrap" /> Classes="h1"
<TextBlock Grid.Row="2" Text="{Binding AppData.Name}" />
HorizontalAlignment="Center" <TextBlock Grid.Row="1"
Text="{Binding Developer}" HorizontalAlignment="Center"
TextAlignment="Start" Text="{Binding FormattedVersion}"
TextWrapping="Wrap" /> TextAlignment="Start"
<StackPanel Grid.ColumnSpan="2" Grid.Row="3" TextWrapping="Wrap" />
HorizontalAlignment="Center" <TextBlock Grid.Row="2"
Orientation="Horizontal" Margin="0 10, 0, 0" HorizontalAlignment="Center"
Spacing="5"> Text="{Binding FormattedDeveloper}"
<Button TextAlignment="Start"
Click="PlayabilityStatus_OnClick" TextWrapping="Wrap" />
HorizontalContentAlignment="Left" <StackPanel Grid.ColumnSpan="2" Grid.Row="3"
VerticalAlignment="Center" HorizontalAlignment="Center"
IsVisible="{Binding HasPlayabilityInfo}" Orientation="Horizontal" Margin="0 10, 0, 0"
Background="{DynamicResource AppListBackgroundColor}" Spacing="5">
Padding="0"> <Button
Click="PlayabilityStatus_OnClick"
HorizontalContentAlignment="Left"
VerticalAlignment="Center"
IsVisible="{Binding AppData.HasPlayabilityInfo}"
Background="{DynamicResource AppListBackgroundColor}"
Padding="0">
<TextBlock
Margin="1.5"
Tag="{Binding AppData.IdString}"
Text="{Binding AppData.LocalizedStatus}"
Foreground="{Binding AppData.PlayabilityStatus, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
TextAlignment="Start"
TextWrapping="Wrap" />
<Button.Styles>
<Style Selector="Button">
<Setter Property="MinWidth"
Value="0" />
<!-- avoids very wide buttons from the overall project avalonia style -->
</Style>
</Button.Styles>
</Button>
<Button
Click="IdString_OnClick"
HorizontalContentAlignment="Left"
VerticalAlignment="Center"
Background="{DynamicResource AppListBackgroundColor}"
Padding="0">
<TextBlock
Margin="1.5"
HorizontalAlignment="Stretch"
Text="{Binding AppData.IdString}"
TextAlignment="Start"
TextWrapping="Wrap" />
</Button>
</StackPanel>
</Grid>
<Separator Margin="0, 10, 0, 10" Height="2" BorderBrush="Gray" Background="Gray" />
<Grid ColumnDefinitions="Auto,*,Auto">
<StackPanel Grid.Column="0"
Margin="10,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Orientation="Vertical"
Spacing="5">
<TextBlock <TextBlock
Margin="1.5"
Tag="{Binding IdString}"
Text="{Binding LocalizedStatus}"
Foreground="{Binding PlayabilityStatus, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
TextAlignment="Start"
TextWrapping="Wrap" />
<Button.Styles>
<Style Selector="Button">
<Setter Property="MinWidth"
Value="0" />
<!-- avoids very wide buttons from the overall project avalonia style -->
</Style>
</Button.Styles>
</Button>
<Button
Click="IdString_OnClick"
HorizontalContentAlignment="Left"
VerticalAlignment="Center"
Background="{DynamicResource AppListBackgroundColor}"
Padding="0">
<TextBlock
Margin="1.5"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Text="{Binding IdString}" Text="{Binding FormattedFileExtension}"
TextAlignment="Start" TextAlignment="Start"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</Button> <TextBlock
</StackPanel> HorizontalAlignment="Stretch"
</Grid> IsVisible="{Binding AppData.HasLdnGames}"
<Separator Margin="0, 10, 0, 10" /> Text="{Binding FormattedLdnInfo}"
<Grid ColumnDefinitions="Auto,*,Auto"> TextAlignment="Start"
<StackPanel Grid.Column="0" TextWrapping="Wrap" />
Margin="10,0,0,0" </StackPanel>
HorizontalAlignment="Left" <StackPanel
VerticalAlignment="Top" Grid.Column="2"
Orientation="Vertical" Margin="0,0,10,0"
Spacing="5"> HorizontalAlignment="Right"
<TextBlock VerticalAlignment="Top"
HorizontalAlignment="Stretch" Orientation="Vertical"
Text="{Binding FileExtension}" Spacing="5">
TextAlignment="Start" <TextBlock
TextWrapping="Wrap" /> HorizontalAlignment="Stretch"
<TextBlock Text="{Binding FormattedLastPlayed}"
HorizontalAlignment="Stretch" TextAlignment="End"
Text="{Binding Converter={helpers:MultiplayerInfoConverter}}" TextWrapping="Wrap" />
TextAlignment="Start" <TextBlock
TextWrapping="Wrap" /> HorizontalAlignment="Stretch"
</StackPanel> Text="{Binding FormattedPlayTime}"
<StackPanel IsVisible="{Binding AppData.HasPlayedPreviously}"
Grid.Column="2" TextAlignment="End"
Margin="0,0,10,0" TextWrapping="Wrap" />
HorizontalAlignment="Right" <TextBlock
VerticalAlignment="Top" HorizontalAlignment="Stretch"
Orientation="Vertical" Text="{Binding FormattedFileSize}"
Spacing="5"> TextAlignment="End"
<TextBlock TextWrapping="Wrap" />
HorizontalAlignment="Stretch" </StackPanel>
Text="{Binding LastPlayedString}" </Grid>
TextAlignment="End" </StackPanel>
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding TimePlayedString}"
IsVisible="{Binding HasPlayedPreviously}"
TextAlignment="End"
TextWrapping="Wrap" />
<TextBlock
HorizontalAlignment="Stretch"
Text="{Binding FileSizeString}"
TextAlignment="End"
TextWrapping="Wrap" />
</StackPanel>
</Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@ -26,7 +26,8 @@ namespace Ryujinx.Ava.UI.Controls
PrimaryButtonText = string.Empty, PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose], CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
Content = new ApplicationDataView { DataContext = appData } MinWidth = 256,
Content = new ApplicationDataView { DataContext = new ApplicationDataViewModel(appData) }
}; };
Style closeButton = new(x => x.Name("CloseButton")); Style closeButton = new(x => x.Name("CloseButton"));

View File

@ -140,6 +140,7 @@
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<TextBlock <TextBlock
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
IsVisible="{Binding HasLdnGames}"
Text="{Binding Converter={helpers:MultiplayerInfoConverter}}" Text="{Binding Converter={helpers:MultiplayerInfoConverter}}"
TextAlignment="Start" TextAlignment="Start"
TextWrapping="Wrap"/> TextWrapping="Wrap"/>

View File

@ -12,12 +12,9 @@ namespace Ryujinx.Ava.UI.Helpers
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{ {
if (value is ApplicationData applicationData) if (value is ApplicationData { HasLdnGames: true } applicationData)
{ {
if (applicationData.PlayerCount != 0 && applicationData.GameCount != 0) return $"Hosted Games: {applicationData.GameCount}\nOnline Players: {applicationData.PlayerCount}";
{
return $"Hosted Games: {applicationData.GameCount}\nOnline Players: {applicationData.PlayerCount}";
}
} }
return ""; return "";

View File

@ -0,0 +1,34 @@
using Gommon;
using Ryujinx.Ava.Utilities.AppLibrary;
namespace Ryujinx.Ava.UI.ViewModels
{
public class ApplicationDataViewModel : BaseModel
{
private const string FormatVersion = "Current Version: {0}";
private const string FormatDeveloper = "Developed by {0}";
private const string FormatExtension = "Game type: {0}";
private const string FormatLastPlayed = "Last played: {0}";
private const string FormatPlayTime = "Play time: {0}";
private const string FormatSize = "Size: {0}";
private const string FormatHostedGames = "Hosted Games: {0}";
private const string FormatPlayerCount = "Online Players: {0}";
public ApplicationData AppData { get; }
public ApplicationDataViewModel(ApplicationData appData) => AppData = appData;
public string FormattedVersion => FormatVersion.Format(AppData.Version);
public string FormattedDeveloper => FormatDeveloper.Format(AppData.Developer);
public string FormattedFileExtension => FormatExtension.Format(AppData.FileExtension);
public string FormattedLastPlayed => FormatLastPlayed.Format(AppData.LastPlayedString);
public string FormattedPlayTime => FormatPlayTime.Format(AppData.TimePlayedString);
public string FormattedFileSize => FormatSize.Format(AppData.FileSizeString);
public string FormattedLdnInfo =>
$"{FormatHostedGames.Format(AppData.GameCount)}\n{FormatPlayerCount.Format(AppData.PlayerCount)}";
}
}

View File

@ -49,6 +49,9 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
public int PlayerCount { get; set; } public int PlayerCount { get; set; }
public int GameCount { get; set; } public int GameCount { get; set; }
public bool HasLdnGames => PlayerCount != 0 && GameCount != 0;
public TimeSpan TimePlayed { get; set; } public TimeSpan TimePlayed { get; set; }
public DateTime? LastPlayed { get; set; } public DateTime? LastPlayed { get; set; }
public string FileExtension { get; set; } public string FileExtension { get; set; }