Compare commits

...

10 Commits

Author SHA1 Message Date
Otozinclus
2bf48f57d2 Add more games to metal list (#447)
Mario Kart 8 Deluxe and Deltarune got tested by Isaac with help from
Peri previosly (His video: https://www.youtube.com/watch?v=GEVre_0ZVUg
)

Captain Toad, Cuphead and Animal Crossing I tested myself (side-by-side
Video comparison: https://youtu.be/auNS9MmZMPI )

Additional information:

Cuphead has flickering issues with certain UI elements on Vulkan via
MoltenVK. Metal fixes those and introduces no new issues, according to
my testing.

Animal Crossing is accurate, except for it having broken backgrounds in
interiors, causing them to appear as white instead of black. This is
caused by a hardware level sampler bug, that isaac never got to find a
workaround for.
However, this issue happens with Vulkan via MoltenVK as well, both Metal
and Vulkan have this issue, therefore Metal shouldn't have any downside
compared to using Vulkan in this game.
2024-12-25 14:19:53 -06:00
Evan Husted
412d4065b8 UI: Abstract applet launch logic for future potential applets
Optimize locale loading (remove always loading english, that was only needed with the old system)
2024-12-25 00:56:01 -06:00
Evan Husted
e6644626fc UI: Fix negative space savings in XCI trimmer 2024-12-25 00:06:29 -06:00
Evan Husted
0bacdb8765 Improve locale file parsing error descriptions 2024-12-24 22:19:58 -06:00
Evan Husted
0ca4d6e921 misc: Move StatusBarSeparator into Controls namespace, rename to MiniVerticalSeparator
add bulk property change event method
give each markup extension its own property name
2024-12-24 21:55:12 -06:00
Evan Husted
f0aa7eedf6 lol 2024-12-24 21:15:13 -06:00
Evan Husted
41acc4b1f3 UI: misc: Collapse repeated identical Border usages into a helper control. 2024-12-24 21:14:17 -06:00
Evan Husted
7aede70ba9 UI: Make custom title bar window controls extend exactly as long as the menu bar is tall 2024-12-24 21:00:41 -06:00
Evan Husted
a0a4f78cff UI: Thin down the borders of the app icon a little bit and trim down the file size significantly. 2024-12-24 20:47:14 -06:00
Evan Husted
16a60fdf12 UI: Rename App to RyujinxApp
Add more NotificationHelper methods
Simplify ID copy logic
2024-12-24 13:39:48 -06:00
32 changed files with 285 additions and 223 deletions

View File

@@ -1034,16 +1034,16 @@ namespace Ryujinx.HLE.FileSystem
switch (fileName) switch (fileName)
{ {
case "prod.keys": case "prod.keys":
verified = verifyKeys(lines, genericPattern); verified = VerifyKeys(lines, genericPattern);
break; break;
case "title.keys": case "title.keys":
verified = verifyKeys(lines, titlePattern); verified = VerifyKeys(lines, titlePattern);
break; break;
case "console.keys": case "console.keys":
verified = verifyKeys(lines, genericPattern); verified = VerifyKeys(lines, genericPattern);
break; break;
case "dev.keys": case "dev.keys":
verified = verifyKeys(lines, genericPattern); verified = VerifyKeys(lines, genericPattern);
break; break;
default: default:
throw new FormatException($"Keys file name \"{fileName}\" not supported. Only \"prod.keys\", \"title.keys\", \"console.keys\", \"dev.keys\" are supported."); throw new FormatException($"Keys file name \"{fileName}\" not supported. Only \"prod.keys\", \"title.keys\", \"console.keys\", \"dev.keys\" are supported.");
@@ -1056,9 +1056,10 @@ namespace Ryujinx.HLE.FileSystem
{ {
throw new FileNotFoundException($"Keys file not found at \"{filePath}\"."); throw new FileNotFoundException($"Keys file not found at \"{filePath}\".");
} }
}
private bool verifyKeys(string[] lines, string regex) return;
bool VerifyKeys(string[] lines, string regex)
{ {
foreach (string line in lines) foreach (string line in lines)
{ {
@@ -1069,6 +1070,7 @@ namespace Ryujinx.HLE.FileSystem
} }
return true; return true;
} }
}
public bool AreKeysAlredyPresent(string pathToCheck) public bool AreKeysAlredyPresent(string pathToCheck)
{ {

View File

@@ -0,0 +1,64 @@
using LibHac.Common;
using LibHac.Ncm;
using LibHac.Ns;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem;
using Ryujinx.UI.App.Common;
namespace Ryujinx.UI.Common.Helper
{
public readonly struct AppletMetadata
{
private readonly ContentManager _contentManager;
public string Name { get; }
public ulong ProgramId { get; }
public string Version { get; }
public AppletMetadata(ContentManager contentManager, string name, ulong programId, string version = "1.0.0")
: this(name, programId, version)
{
_contentManager = contentManager;
}
public AppletMetadata(string name, ulong programId, string version = "1.0.0")
{
Name = name;
ProgramId = programId;
Version = version;
}
public string GetContentPath(ContentManager contentManager)
=> (contentManager ?? _contentManager)
.GetInstalledContentPath(ProgramId, StorageId.BuiltInSystem, NcaContentType.Program);
public bool CanStart(ContentManager contentManager, out ApplicationData appData, out BlitStruct<ApplicationControlProperty> appControl)
{
contentManager ??= _contentManager;
if (contentManager == null)
{
appData = null;
appControl = new BlitStruct<ApplicationControlProperty>(0);
return false;
}
appData = new()
{
Name = Name,
Id = ProgramId,
Path = GetContentPath(contentManager)
};
if (string.IsNullOrEmpty(appData.Path))
{
appControl = new BlitStruct<ApplicationControlProperty>(0);
return false;
}
appControl = StructHelpers.CreateCustomNacpData(Name, Version);
return true;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 609 KiB

View File

@@ -33,7 +33,7 @@
<EmbeddedResource Include="Resources\Icon_XCI.png" /> <EmbeddedResource Include="Resources\Icon_XCI.png" />
<EmbeddedResource Include="Resources\Logo_Amiibo.png" /> <EmbeddedResource Include="Resources\Logo_Amiibo.png" />
<EmbeddedResource Include="Resources\Logo_Ryujinx.png" /> <EmbeddedResource Include="Resources\Logo_Ryujinx.png" />
<EmbeddedResource Include="Resources\Logo_Thiccjinx.png" /> <EmbeddedResource Include="Resources\Logo_Ryujinx_AntiAlias.png" />
<EmbeddedResource Include="Resources\Logo_Discord_Dark.png" /> <EmbeddedResource Include="Resources\Logo_Discord_Dark.png" />
<EmbeddedResource Include="Resources\Logo_Discord_Light.png" /> <EmbeddedResource Include="Resources\Logo_Discord_Light.png" />
<EmbeddedResource Include="Resources\Logo_GitHub_Dark.png" /> <EmbeddedResource Include="Resources\Logo_GitHub_Dark.png" />

View File

@@ -146,7 +146,7 @@ namespace Ryujinx.Ava.Common
var cancellationToken = new CancellationTokenSource(); var cancellationToken = new CancellationTokenSource();
UpdateWaitWindow waitingDialog = new( UpdateWaitWindow waitingDialog = new(
App.FormatTitle(LocaleKeys.DialogNcaExtractionTitle), RyujinxApp.FormatTitle(LocaleKeys.DialogNcaExtractionTitle),
LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, ncaSectionType, Path.GetFileName(titleFilePath)), LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, ncaSectionType, Path.GetFileName(titleFilePath)),
cancellationToken); cancellationToken);
@@ -268,10 +268,9 @@ namespace Ryujinx.Ava.Common
{ {
Dispatcher.UIThread.Post(waitingDialog.Close); Dispatcher.UIThread.Post(waitingDialog.Close);
NotificationHelper.Show( NotificationHelper.ShowInformation(
App.FormatTitle(LocaleKeys.DialogNcaExtractionTitle), RyujinxApp.FormatTitle(LocaleKeys.DialogNcaExtractionTitle),
$"{titleName}\n\n{LocaleManager.Instance[LocaleKeys.DialogNcaExtractionSuccessMessage]}", $"{titleName}\n\n{LocaleManager.Instance[LocaleKeys.DialogNcaExtractionSuccessMessage]}");
NotificationType.Information);
} }
} }

View File

@@ -1,7 +1,6 @@
using Gommon; using Gommon;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Configuration;
using System; using System;
@@ -17,7 +16,6 @@ namespace Ryujinx.Ava.Common.Locale
private const string DefaultLanguageCode = "en_US"; private const string DefaultLanguageCode = "en_US";
private readonly Dictionary<LocaleKeys, string> _localeStrings; private readonly Dictionary<LocaleKeys, string> _localeStrings;
private Dictionary<LocaleKeys, string> _localeDefaultStrings;
private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues; private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
private string _localeLanguageCode; private string _localeLanguageCode;
@@ -27,7 +25,6 @@ namespace Ryujinx.Ava.Common.Locale
public LocaleManager() public LocaleManager()
{ {
_localeStrings = new Dictionary<LocaleKeys, string>(); _localeStrings = new Dictionary<LocaleKeys, string>();
_localeDefaultStrings = new Dictionary<LocaleKeys, string>();
_dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>(); _dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>();
Load(); Load();
@@ -38,8 +35,6 @@ namespace Ryujinx.Ava.Common.Locale
var localeLanguageCode = !string.IsNullOrEmpty(ConfigurationState.Instance.UI.LanguageCode.Value) ? var localeLanguageCode = !string.IsNullOrEmpty(ConfigurationState.Instance.UI.LanguageCode.Value) ?
ConfigurationState.Instance.UI.LanguageCode.Value : CultureInfo.CurrentCulture.Name.Replace('-', '_'); ConfigurationState.Instance.UI.LanguageCode.Value : CultureInfo.CurrentCulture.Name.Replace('-', '_');
// Load en_US as default, if the target language translation is missing or incomplete.
LoadDefaultLanguage();
LoadLanguage(localeLanguageCode); LoadLanguage(localeLanguageCode);
// Save whatever we ended up with. // Save whatever we ended up with.
@@ -66,26 +61,14 @@ namespace Ryujinx.Ava.Common.Locale
} }
catch catch
{ {
// If formatting failed use the default text instead. // If formatting the text failed,
if (_localeDefaultStrings.TryGetValue(key, out value)) // continue to the below line & return the text without formatting.
try
{
return string.Format(value, dynamicValue);
}
catch
{
// If formatting the default text failed return the key.
return key.ToString();
}
} }
return value; return value;
} }
// If the locale doesn't contain the key return the default one. return key.ToString(); // If the locale text doesn't exist return the key.
return _localeDefaultStrings.TryGetValue(key, out string defaultValue)
? defaultValue
: key.ToString(); // If the locale text doesn't exist return the key.
} }
set set
{ {
@@ -109,16 +92,11 @@ namespace Ryujinx.Ava.Common.Locale
{ {
_dynamicValues[key] = values; _dynamicValues[key] = values;
OnPropertyChanged("Item"); OnPropertyChanged("Translation");
return this[key]; return this[key];
} }
private void LoadDefaultLanguage()
{
_localeDefaultStrings = LoadJsonLanguage(DefaultLanguageCode);
}
public void LoadLanguage(string languageCode) public void LoadLanguage(string languageCode)
{ {
var locale = LoadJsonLanguage(languageCode); var locale = LoadJsonLanguage(languageCode);
@@ -126,7 +104,7 @@ namespace Ryujinx.Ava.Common.Locale
if (locale == null) if (locale == null)
{ {
_localeLanguageCode = DefaultLanguageCode; _localeLanguageCode = DefaultLanguageCode;
locale = _localeDefaultStrings; locale = LoadJsonLanguage(_localeLanguageCode);
} }
else else
{ {
@@ -138,17 +116,13 @@ namespace Ryujinx.Ava.Common.Locale
_localeStrings[key] = val; _localeStrings[key] = val;
} }
OnPropertyChanged("Item"); OnPropertyChanged("Translation");
LocaleChanged?.Invoke(); LocaleChanged?.Invoke();
} }
#nullable enable
private static LocalesJson? _localeData; private static LocalesJson? _localeData;
#nullable disable
private static Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode) private static Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode)
{ {
var localeStrings = new Dictionary<LocaleKeys, string>(); var localeStrings = new Dictionary<LocaleKeys, string>();
@@ -158,18 +132,29 @@ namespace Ryujinx.Ava.Common.Locale
foreach (LocalesEntry locale in _localeData.Value.Locales) foreach (LocalesEntry locale in _localeData.Value.Locales)
{ {
if (locale.Translations.Count != _localeData.Value.Languages.Count) if (locale.Translations.Count < _localeData.Value.Languages.Count)
{ {
throw new Exception($"Locale key {{{locale.ID}}} is missing languages! Has {locale.Translations.Count} translations, expected {_localeData.Value.Languages.Count}!"); throw new Exception($"Locale key {{{locale.ID}}} is missing languages! Has {locale.Translations.Count} translations, expected {_localeData.Value.Languages.Count}!");
} }
if (locale.Translations.Count > _localeData.Value.Languages.Count)
{
throw new Exception($"Locale key {{{locale.ID}}} has too many languages! Has {locale.Translations.Count} translations, expected {_localeData.Value.Languages.Count}!");
}
if (!Enum.TryParse<LocaleKeys>(locale.ID, out var localeKey)) if (!Enum.TryParse<LocaleKeys>(locale.ID, out var localeKey))
continue; continue;
localeStrings[localeKey] = var str = locale.Translations.TryGetValue(languageCode, out string val) && !string.IsNullOrEmpty(val)
locale.Translations.TryGetValue(languageCode, out string val) && val != string.Empty
? val ? val
: locale.Translations[DefaultLanguageCode]; : locale.Translations[DefaultLanguageCode];
if (string.IsNullOrEmpty(str))
{
throw new Exception($"Locale key '{locale.ID}' has no valid translations for desired language {languageCode}! {DefaultLanguageCode} is an empty string or null");
}
localeStrings[localeKey] = str;
} }
return localeStrings; return localeStrings;

View File

@@ -14,7 +14,7 @@ namespace Ryujinx.Ava.Common.Markup
{ {
internal abstract class BasicMarkupExtension<T> : MarkupExtension internal abstract class BasicMarkupExtension<T> : MarkupExtension
{ {
public virtual string Name => "Item"; public abstract string Name { get; }
public virtual Action<object, T?>? Setter => null; public virtual Action<object, T?>? Setter => null;
protected abstract T? Value { get; } protected abstract T? Value { get; }

View File

@@ -6,16 +6,19 @@ namespace Ryujinx.Ava.Common.Markup
{ {
internal class IconExtension(string iconString) : BasicMarkupExtension<Icon> internal class IconExtension(string iconString) : BasicMarkupExtension<Icon>
{ {
public override string Name => "Icon";
protected override Icon Value => new() { Value = iconString }; protected override Icon Value => new() { Value = iconString };
} }
internal class SpinningIconExtension(string iconString) : BasicMarkupExtension<Icon> internal class SpinningIconExtension(string iconString) : BasicMarkupExtension<Icon>
{ {
public override string Name => "SIcon";
protected override Icon Value => new() { Value = iconString, Animation = IconAnimation.Spin }; protected override Icon Value => new() { Value = iconString, Animation = IconAnimation.Spin };
} }
internal class LocaleExtension(LocaleKeys key) : BasicMarkupExtension<string> internal class LocaleExtension(LocaleKeys key) : BasicMarkupExtension<string>
{ {
public override string Name => "Translation";
protected override string Value => LocaleManager.Instance[key]; protected override string Value => LocaleManager.Instance[key];
protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension) protected override void ConfigureBindingExtension(CompiledBindingExtension bindingExtension)

View File

@@ -65,7 +65,7 @@ namespace Ryujinx.Ava
} }
public static AppBuilder BuildAvaloniaApp() => public static AppBuilder BuildAvaloniaApp() =>
AppBuilder.Configure<App>() AppBuilder.Configure<RyujinxApp>()
.UsePlatformDetect() .UsePlatformDetect()
.With(new X11PlatformOptions .With(new X11PlatformOptions
{ {
@@ -100,7 +100,7 @@ namespace Ryujinx.Ava
// Delete backup files after updating. // Delete backup files after updating.
Task.Run(Updater.CleanupUpdate); Task.Run(Updater.CleanupUpdate);
Console.Title = $"{App.FullAppName} Console {Version}"; Console.Title = $"{RyujinxApp.FullAppName} Console {Version}";
// Hook unhandled exception and process exit events. // Hook unhandled exception and process exit events.
AppDomain.CurrentDomain.UnhandledException += (sender, e) AppDomain.CurrentDomain.UnhandledException += (sender, e)
@@ -225,7 +225,7 @@ namespace Ryujinx.Ava
private static void PrintSystemInfo() private static void PrintSystemInfo()
{ {
Logger.Notice.Print(LogClass.Application, $"{App.FullAppName} Version: {Version}"); Logger.Notice.Print(LogClass.Application, $"{RyujinxApp.FullAppName} Version: {Version}");
SystemInfo.Gather().Print(); SystemInfo.Gather().Print();
var enabledLogLevels = Logger.GetEnabledLevels().ToArray(); var enabledLogLevels = Logger.GetEnabledLevels().ToArray();

View File

@@ -1,5 +1,5 @@
<Application <Application
x:Class="Ryujinx.Ava.App" x:Class="Ryujinx.Ava.RyujinxApp"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sty="using:FluentAvalonia.Styling"> xmlns:sty="using:FluentAvalonia.Styling">

View File

@@ -1,5 +1,6 @@
using Avalonia; using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input.Platform;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Styling; using Avalonia.Styling;
@@ -19,7 +20,7 @@ using System.Diagnostics;
namespace Ryujinx.Ava namespace Ryujinx.Ava
{ {
public class App : Application public class RyujinxApp : Application
{ {
internal static string FormatTitle(LocaleKeys? windowTitleKey = null) internal static string FormatTitle(LocaleKeys? windowTitleKey = null)
=> windowTitleKey is null => windowTitleKey is null
@@ -32,8 +33,11 @@ namespace Ryujinx.Ava
.ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>() .ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>()
.MainWindow.Cast<MainWindow>(); .MainWindow.Cast<MainWindow>();
public static IClassicDesktopStyleApplicationLifetime DesktopLifetime => Current! public static bool IsClipboardAvailable(out IClipboard clipboard)
.ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>(); {
clipboard = MainWindow.Clipboard;
return clipboard != null;
}
public static void SetTaskbarProgress(TaskBarProgressBarState state) => MainWindow.PlatformFeatures.SetTaskBarProgressBarState(state); public static void SetTaskbarProgress(TaskBarProgressBarState state) => MainWindow.PlatformFeatures.SetTaskBarProgressBarState(state);
public static void SetTaskbarProgressValue(ulong current, ulong total) => MainWindow.PlatformFeatures.SetTaskBarProgressBarValue(current, total); public static void SetTaskbarProgressValue(ulong current, ulong total) => MainWindow.PlatformFeatures.SetTaskBarProgressBarValue(current, total);
@@ -135,7 +139,7 @@ namespace Ryujinx.Ava
}; };
public static ThemeVariant DetectSystemTheme() => public static ThemeVariant DetectSystemTheme() =>
Current is App { PlatformSettings: not null } app Current is RyujinxApp { PlatformSettings: not null } app
? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant) ? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant)
: ThemeVariant.Default; : ThemeVariant.Default;
} }

View File

@@ -44,16 +44,18 @@ namespace Ryujinx.Ava.UI.Controls
if (sender is not Button { Content: TextBlock idText }) if (sender is not Button { Content: TextBlock idText })
return; return;
if (App.MainWindow.Clipboard is { } clipboard) if (!RyujinxApp.IsClipboardAvailable(out var clipboard))
{ return;
var appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text); var appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text);
if (appData is null) if (appData is null)
return; return;
await clipboard.SetTextAsync(appData.IdString); await clipboard.SetTextAsync(appData.IdString);
NotificationHelper.Show("Copied Title ID", $"{appData.Name} ({appData.IdString})", NotificationType.Information); NotificationHelper.ShowInformation(
} "Copied Title ID",
$"{appData.Name} ({appData.IdString})");
} }
} }
} }

View File

@@ -0,0 +1,19 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
namespace Ryujinx.Ava.UI.Controls
{
public class MiniVerticalSeparator : Border
{
public MiniVerticalSeparator()
{
Width = 2;
Height = 12;
Margin = new Thickness();
BorderBrush = Brushes.Gray;
Background = Brushes.Gray;
BorderThickness = new Thickness(1);
}
}
}

View File

@@ -62,9 +62,46 @@ namespace Ryujinx.Ava.UI.Helpers
_notifications.Add(new Notification(title, text, type, delay, onClick, onClose)); _notifications.Add(new Notification(title, text, type, delay, onClick, onClose));
} }
public static void ShowError(string message) public static void ShowError(string message) =>
{ ShowError(
Show(LocaleManager.Instance[LocaleKeys.DialogErrorTitle], $"{LocaleManager.Instance[LocaleKeys.DialogErrorMessage]}\n\n{message}", NotificationType.Error); LocaleManager.Instance[LocaleKeys.DialogErrorTitle],
} $"{LocaleManager.Instance[LocaleKeys.DialogErrorMessage]}\n\n{message}"
);
public static void ShowInformation(string title, string text, bool waitingExit = false, Action onClick = null, Action onClose = null) =>
Show(
title,
text,
NotificationType.Information,
waitingExit,
onClick,
onClose);
public static void ShowSuccess(string title, string text, bool waitingExit = false, Action onClick = null, Action onClose = null) =>
Show(
title,
text,
NotificationType.Success,
waitingExit,
onClick,
onClose);
public static void ShowWarning(string title, string text, bool waitingExit = false, Action onClick = null, Action onClose = null) =>
Show(
title,
text,
NotificationType.Warning,
waitingExit,
onClick,
onClose);
public static void ShowError(string title, string text, bool waitingExit = false, Action onClick = null, Action onClose = null) =>
Show(
title,
text,
NotificationType.Error,
waitingExit,
onClick,
onClose);
} }
} }

View File

@@ -1,6 +1,7 @@
using Avalonia; using Avalonia;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
using Gommon;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.UI.Common.Models; using Ryujinx.UI.Common.Models;
using System; using System;
@@ -32,11 +33,11 @@ namespace Ryujinx.Ava.UI.Helpers
if (app.CurrentSavingsB < app.PotentialSavingsB) if (app.CurrentSavingsB < app.PotentialSavingsB)
{ {
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCICanSaveLabel, (app.PotentialSavingsB - app.CurrentSavingsB) / _bytesPerMB); return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCICanSaveLabel, ((app.PotentialSavingsB - app.CurrentSavingsB) / _bytesPerMB).CoerceAtLeast(0));
} }
else else
{ {
return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCISavingLabel, app.CurrentSavingsB / _bytesPerMB); return LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.TitleXCISavingLabel, (app.CurrentSavingsB / _bytesPerMB).CoerceAtLeast(0));
} }
} }

View File

@@ -33,11 +33,16 @@ namespace Ryujinx.Ava.UI.Renderer
public static readonly string[] KnownGreatMetalTitles = public static readonly string[] KnownGreatMetalTitles =
[ [
"01006f8002326000", // Animal Crossings: New Horizons
"01009bf0072d4000", // Captain Toad: Treasure Tracker
"0100a5c00d162000", // Cuphead
"010023800d64a000", // Deltarune
"010028600EBDA000", // Mario 3D World
"0100152000022000", // Mario Kart 8 Deluxe
"01005CA01580E000", // Persona 5
"01008C0016544000", // Sea of Stars
"01006A800016E000", // Smash Ultimate "01006A800016E000", // Smash Ultimate
"0100000000010000", // Super Mario Odyessy "0100000000010000", // Super Mario Odyessy
"01008C0016544000", // Sea of Stars
"01005CA01580E000", // Persona 5
"010028600EBDA000", // Mario 3D World
]; ];
public GraphicsBackend Backend => public GraphicsBackend Backend =>

View File

@@ -51,7 +51,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public AboutWindowViewModel() public AboutWindowViewModel()
{ {
Version = App.FullAppName + "\n" + Program.Version; Version = RyujinxApp.FullAppName + "\n" + Program.Version;
UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value); UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value);
ThemeManager.ThemeChanged += ThemeManager_ThemeChanged; ThemeManager.ThemeChanged += ThemeManager_ThemeChanged;
@@ -64,7 +64,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private void UpdateLogoTheme(string theme) private void UpdateLogoTheme(string theme)
{ {
bool isDarkTheme = theme == "Dark" || (theme == "Auto" && App.DetectSystemTheme() == ThemeVariant.Dark); bool isDarkTheme = theme == "Dark" || (theme == "Auto" && RyujinxApp.DetectSystemTheme() == ThemeVariant.Dark);
string basePath = "resm:Ryujinx.UI.Common.Resources."; string basePath = "resm:Ryujinx.UI.Common.Resources.";
string themeSuffix = isDarkTheme ? "Dark.png" : "Light.png"; string themeSuffix = isDarkTheme ? "Dark.png" : "Light.png";

View File

@@ -1,3 +1,4 @@
using System;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -11,5 +12,13 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
protected void OnPropertiesChanged(params ReadOnlySpan<string> propertyNames)
{
foreach (var propertyName in propertyNames)
{
OnPropertyChanged(propertyName);
}
}
} }
} }

View File

@@ -131,7 +131,7 @@ namespace Ryujinx.Ava.UI.ViewModels
// For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left. // For an example of this, download canary 1.2.95, then open the settings menu, and look at the icon in the top-left.
// The border gets reduced to colored pixels in the 4 corners. // The border gets reduced to colored pixels in the 4 corners.
public static readonly Bitmap IconBitmap = public static readonly Bitmap IconBitmap =
new(Assembly.GetAssembly(typeof(ConfigurationState))!.GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Thiccjinx.png")!); new(Assembly.GetAssembly(typeof(ConfigurationState))!.GetManifestResourceStream("Ryujinx.UI.Common.Resources.Logo_Ryujinx_AntiAlias.png")!);
public MainWindow Window { get; init; } public MainWindow Window { get; init; }
@@ -2051,7 +2051,7 @@ namespace Ryujinx.Ava.UI.ViewModels
Dispatcher.UIThread.InvokeAsync(() => Dispatcher.UIThread.InvokeAsync(() =>
{ {
Title = App.FormatTitle(); Title = RyujinxApp.FormatTitle();
}); });
} }

View File

@@ -71,8 +71,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
_resolutionScale = value; _resolutionScale = value;
OnPropertyChanged(nameof(CustomResolutionScale)); OnPropertiesChanged(nameof(CustomResolutionScale), nameof(IsCustomResolutionScaleActive));
OnPropertyChanged(nameof(IsCustomResolutionScaleActive));
} }
} }
@@ -181,8 +180,9 @@ namespace Ryujinx.Ava.UI.ViewModels
int newInterval = (int)((value / 100f) * 60); int newInterval = (int)((value / 100f) * 60);
_customVSyncInterval = newInterval; _customVSyncInterval = newInterval;
_customVSyncIntervalPercentageProxy = value; _customVSyncIntervalPercentageProxy = value;
OnPropertyChanged((nameof(CustomVSyncInterval))); OnPropertiesChanged(
OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText))); nameof(CustomVSyncInterval),
nameof(CustomVSyncIntervalPercentageText));
} }
} }
@@ -190,7 +190,7 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
get get
{ {
string text = CustomVSyncIntervalPercentageProxy.ToString() + "%"; string text = CustomVSyncIntervalPercentageProxy + "%";
return text; return text;
} }
} }
@@ -221,8 +221,9 @@ namespace Ryujinx.Ava.UI.ViewModels
_customVSyncInterval = value; _customVSyncInterval = value;
int newPercent = (int)((value / 60f) * 100); int newPercent = (int)((value / 60f) * 100);
_customVSyncIntervalPercentageProxy = newPercent; _customVSyncIntervalPercentageProxy = newPercent;
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy)); OnPropertiesChanged(
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText)); nameof(CustomVSyncIntervalPercentageProxy),
nameof(CustomVSyncIntervalPercentageText));
OnPropertyChanged(); OnPropertyChanged();
} }
} }

View File

@@ -91,39 +91,42 @@ namespace Ryujinx.Ava.UI.ViewModels
private void SortingChanged() private void SortingChanged()
{ {
OnPropertyChanged(nameof(IsSortedByName)); OnPropertiesChanged(
OnPropertyChanged(nameof(IsSortedBySaved)); nameof(IsSortedByName),
OnPropertyChanged(nameof(SortingAscending)); nameof(IsSortedBySaved),
OnPropertyChanged(nameof(SortingField)); nameof(SortingAscending),
OnPropertyChanged(nameof(SortingFieldName)); nameof(SortingField),
nameof(SortingFieldName));
SortAndFilter(); SortAndFilter();
} }
private void DisplayedChanged() private void DisplayedChanged()
{ {
OnPropertyChanged(nameof(Status)); OnPropertiesChanged(nameof(Status), nameof(DisplayedXCIFiles), nameof(SelectedDisplayedXCIFiles));
OnPropertyChanged(nameof(DisplayedXCIFiles));
OnPropertyChanged(nameof(SelectedDisplayedXCIFiles));
} }
private void ApplicationsChanged() private void ApplicationsChanged()
{ {
OnPropertyChanged(nameof(AllXCIFiles)); OnPropertiesChanged(
OnPropertyChanged(nameof(Status)); nameof(AllXCIFiles),
OnPropertyChanged(nameof(PotentialSavings)); nameof(Status),
OnPropertyChanged(nameof(ActualSavings)); nameof(PotentialSavings),
OnPropertyChanged(nameof(CanTrim)); nameof(ActualSavings),
OnPropertyChanged(nameof(CanUntrim)); nameof(CanTrim),
nameof(CanUntrim));
DisplayedChanged(); DisplayedChanged();
SortAndFilter(); SortAndFilter();
} }
private void SelectionChanged(bool displayedChanged = true) private void SelectionChanged(bool displayedChanged = true)
{ {
OnPropertyChanged(nameof(Status)); OnPropertiesChanged(
OnPropertyChanged(nameof(CanTrim)); nameof(Status),
OnPropertyChanged(nameof(CanUntrim)); nameof(CanTrim),
OnPropertyChanged(nameof(SelectedXCIFiles)); nameof(CanUntrim),
nameof(SelectedXCIFiles));
if (displayedChanged) if (displayedChanged)
OnPropertyChanged(nameof(SelectedDisplayedXCIFiles)); OnPropertyChanged(nameof(SelectedDisplayedXCIFiles));
@@ -131,11 +134,12 @@ namespace Ryujinx.Ava.UI.ViewModels
private void ProcessingChanged() private void ProcessingChanged()
{ {
OnPropertyChanged(nameof(Processing)); OnPropertiesChanged(
OnPropertyChanged(nameof(Cancel)); nameof(Processing),
OnPropertyChanged(nameof(Status)); nameof(Cancel),
OnPropertyChanged(nameof(CanTrim)); nameof(Status),
OnPropertyChanged(nameof(CanUntrim)); nameof(CanTrim),
nameof(CanUntrim));
} }
private IEnumerable<XCITrimmerFileModel> GetSelectedDisplayedXCIFiles() private IEnumerable<XCITrimmerFileModel> GetSelectedDisplayedXCIFiles()
@@ -360,7 +364,7 @@ namespace Ryujinx.Ava.UI.ViewModels
value = _processingApplication.Value with { PercentageProgress = null }; value = _processingApplication.Value with { PercentageProgress = null };
if (value.HasValue) if (value.HasValue)
_displayedXCIFiles.ReplaceWith(value.Value); _displayedXCIFiles.ReplaceWith(value);
_processingApplication = value; _processingApplication = value;
OnPropertyChanged(); OnPropertyChanged();

View File

@@ -18,7 +18,7 @@
Height="25" Height="25"
Width="25" Width="25"
ToolTip.Tip="{Binding Title}" ToolTip.Tip="{Binding Title}"
Source="resm:Ryujinx.UI.Common.Resources.Logo_Thiccjinx.png?assembly=Ryujinx.UI.Common" /> Source="resm:Ryujinx.UI.Common.Resources.Logo_Ryujinx_AntiAlias.png?assembly=Ryujinx.UI.Common" />
<Menu <Menu
Name="Menu" Name="Menu"
Height="32" Height="32"

View File

@@ -3,8 +3,6 @@ using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Threading; using Avalonia.Threading;
using Gommon; using Gommon;
using LibHac.Ncm;
using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
@@ -12,8 +10,6 @@ using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption; using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption;
using Ryujinx.HLE;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common; using Ryujinx.UI.Common;
using Ryujinx.UI.Common.Configuration; using Ryujinx.UI.Common.Configuration;
using Ryujinx.UI.Common.Helper; using Ryujinx.UI.Common.Helper;
@@ -124,26 +120,13 @@ namespace Ryujinx.Ava.UI.Views.Main
ViewModel.LoadConfigurableHotKeys(); ViewModel.LoadConfigurableHotKeys();
} }
public static readonly AppletMetadata MiiApplet = new("miiEdit", 0x0100000000001009);
public async void OpenMiiApplet(object sender, RoutedEventArgs e) public async void OpenMiiApplet(object sender, RoutedEventArgs e)
{ {
const string AppletName = "miiEdit"; if (MiiApplet.CanStart(ViewModel.ContentManager, out var appData, out var nacpData))
const ulong AppletProgramId = 0x0100000000001009;
const string AppletVersion = "1.0.0";
string contentPath = ViewModel.ContentManager.GetInstalledContentPath(AppletProgramId, StorageId.BuiltInSystem, NcaContentType.Program);
if (!string.IsNullOrEmpty(contentPath))
{ {
ApplicationData applicationData = new() await ViewModel.LoadApplication(appData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
{
Name = AppletName,
Id = AppletProgramId,
Path = contentPath
};
var nacpData = StructHelpers.CreateCustomNacpData(AppletName, AppletVersion);
await ViewModel.LoadApplication(applicationData, ViewModel.IsFullScreen || ViewModel.StartGamesInFullscreen, nacpData);
} }
} }

View File

@@ -7,6 +7,7 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:local="clr-namespace:Ryujinx.Ava.UI.Views.Main"
xmlns:config="clr-namespace:Ryujinx.Common.Configuration;assembly=Ryujinx.Common" xmlns:config="clr-namespace:Ryujinx.Common.Configuration;assembly=Ryujinx.Common"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.UI.Views.Main.MainStatusBarView" x:Class="Ryujinx.Ava.UI.Views.Main.MainStatusBarView"
@@ -132,14 +133,7 @@
</Flyout> </Flyout>
</Button.Flyout> </Button.Flyout>
</Button> </Button>
<Border <controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock <TextBlock
Name="DockedStatus" Name="DockedStatus"
Margin="5,0,5,0" Margin="5,0,5,0"
@@ -149,14 +143,7 @@
PointerReleased="DockedStatus_PointerReleased" PointerReleased="DockedStatus_PointerReleased"
Text="{Binding DockedStatusText}" Text="{Binding DockedStatusText}"
TextAlignment="Start" /> TextAlignment="Start" />
<Border <controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<SplitButton <SplitButton
Name="AspectRatioStatus" Name="AspectRatioStatus"
Padding="5,0,5,0" Padding="5,0,5,0"
@@ -203,14 +190,7 @@
</MenuFlyout> </MenuFlyout>
</SplitButton.Flyout> </SplitButton.Flyout>
</SplitButton> </SplitButton>
<Border <controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<ToggleSplitButton <ToggleSplitButton
Name="VolumeStatus" Name="VolumeStatus"
Padding="5,0,5,0" Padding="5,0,5,0"
@@ -254,14 +234,7 @@
</Flyout> </Flyout>
</ToggleSplitButton.Flyout> </ToggleSplitButton.Flyout>
</ToggleSplitButton> </ToggleSplitButton>
<Border <controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock <TextBlock
Margin="5,0,5,0" Margin="5,0,5,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -269,14 +242,7 @@
IsVisible="{Binding !ShowLoadProgress}" IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding GameStatusText}" Text="{Binding GameStatusText}"
TextAlignment="Start" /> TextAlignment="Start" />
<Border <controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock <TextBlock
Margin="5,0,5,0" Margin="5,0,5,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -298,13 +264,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
IsVisible="{Binding ShowShaderCompilationHint}" IsVisible="{Binding ShowShaderCompilationHint}"
Text="{Binding ShaderCountText}" /> Text="{Binding ShaderCountText}" />
<Border <controls:MiniVerticalSeparator IsVisible="{Binding ShowShaderCompilationHint}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
BorderThickness="1"
IsVisible="{Binding ShowShaderCompilationHint}" />
<TextBlock <TextBlock
Margin="5,0,5,0" Margin="5,0,5,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -312,14 +272,7 @@
IsVisible="{Binding !ShowLoadProgress}" IsVisible="{Binding !ShowLoadProgress}"
Text="{Binding BackendText}" Text="{Binding BackendText}"
TextAlignment="Start" /> TextAlignment="Start" />
<Border <controls:MiniVerticalSeparator IsVisible="{Binding !ShowLoadProgress}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
Background="Gray"
BorderThickness="1"
IsVisible="{Binding !ShowLoadProgress}" />
<TextBlock <TextBlock
Margin="5,0,0,0" Margin="5,0,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -334,13 +287,7 @@
VerticalAlignment="Center" VerticalAlignment="Center"
IsVisible="{Binding ShowFirmwareStatus}" IsVisible="{Binding ShowFirmwareStatus}"
Orientation="Horizontal"> Orientation="Horizontal">
<Border <controls:MiniVerticalSeparator IsVisible="{Binding IsGameRunning}" />
Width="2"
Height="12"
Margin="0"
BorderBrush="Gray"
BorderThickness="1"
IsVisible="{Binding IsGameRunning}" />
<TextBlock <TextBlock
Name="FirmwareStatus" Name="FirmwareStatus"
Margin="5, 0, 0, 0" Margin="5, 0, 0, 0"

View File

@@ -62,12 +62,7 @@ namespace Ryujinx.Ava.UI.Views.Main
// Change the volume by 5% at a time // Change the volume by 5% at a time
float newValue = Window.ViewModel.Volume + (float)e.Delta.Y * 0.05f; float newValue = Window.ViewModel.Volume + (float)e.Delta.Y * 0.05f;
Window.ViewModel.Volume = newValue switch Window.ViewModel.Volume = Math.Clamp(newValue, 0, 1);
{
< 0 => 0,
> 1 => 1,
_ => newValue,
};
e.Handled = true; e.Handled = true;
} }

View File

@@ -16,7 +16,7 @@ namespace Ryujinx.Ava.UI.Windows
InitializeComponent(); InitializeComponent();
Title = App.FormatTitle(LocaleKeys.Amiibo); Title = RyujinxApp.FormatTitle(LocaleKeys.Amiibo);
} }
public AmiiboWindow() public AmiiboWindow()
@@ -27,7 +27,7 @@ namespace Ryujinx.Ava.UI.Windows
if (Program.PreviewerDetached) if (Program.PreviewerDetached)
{ {
Title = App.FormatTitle(LocaleKeys.Amiibo); Title = RyujinxApp.FormatTitle(LocaleKeys.Amiibo);
} }
} }

View File

@@ -28,7 +28,7 @@ namespace Ryujinx.Ava.UI.Windows
InitializeComponent(); InitializeComponent();
Title = App.FormatTitle(LocaleKeys.CheatWindowTitle); Title = RyujinxApp.FormatTitle(LocaleKeys.CheatWindowTitle);
} }
public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath) public CheatWindow(VirtualFileSystem virtualFileSystem, string titleId, string titleName, string titlePath)
@@ -93,7 +93,7 @@ namespace Ryujinx.Ava.UI.Windows
DataContext = this; DataContext = this;
Title = App.FormatTitle(LocaleKeys.CheatWindowTitle); Title = RyujinxApp.FormatTitle(LocaleKeys.CheatWindowTitle);
} }
public void Save() public void Save()

View File

@@ -86,18 +86,20 @@ namespace Ryujinx.Ava.UI.Windows
UiHandler = new AvaHostUIHandler(this); UiHandler = new AvaHostUIHandler(this);
ViewModel.Title = App.FormatTitle(); ViewModel.Title = RyujinxApp.FormatTitle();
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar; TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
TitleBar.TitleBarHitTestType = (ConfigurationState.Instance.ShowTitleBar) ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex; TitleBar.TitleBarHitTestType = (ConfigurationState.Instance.ShowTitleBar) ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
// Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024)
TitleBarHeight = (ConfigurationState.Instance.ShowTitleBar ? TitleBar.Height : 0);
// NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point. // NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point.
StatusBarHeight = StatusBarView.StatusBar.MinHeight; StatusBarHeight = StatusBarView.StatusBar.MinHeight;
MenuBarHeight = MenuBar.MinHeight; MenuBarHeight = MenuBar.MinHeight;
TitleBar.Height = MenuBarHeight;
// Correctly size window when 'TitleBar' is enabled (Nov. 14, 2024)
TitleBarHeight = (ConfigurationState.Instance.ShowTitleBar ? TitleBar.Height : 0);
ApplicationList.DataContext = DataContext; ApplicationList.DataContext = DataContext;
ApplicationGrid.DataContext = DataContext; ApplicationGrid.DataContext = DataContext;
@@ -117,7 +119,7 @@ namespace Ryujinx.Ava.UI.Windows
/// </summary> /// </summary>
private static void OnPlatformColorValuesChanged(object sender, PlatformColorValues e) private static void OnPlatformColorValuesChanged(object sender, PlatformColorValues e)
{ {
if (Application.Current is App app) if (Application.Current is RyujinxApp app)
app.ApplyConfiguredTheme(ConfigurationState.Instance.UI.BaseStyle); app.ApplyConfiguredTheme(ConfigurationState.Instance.UI.BaseStyle);
} }

View File

@@ -14,7 +14,7 @@ namespace Ryujinx.Ava.UI.Windows
public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager) public SettingsWindow(VirtualFileSystem virtualFileSystem, ContentManager contentManager)
{ {
Title = App.FormatTitle(LocaleKeys.Settings); Title = RyujinxApp.FormatTitle(LocaleKeys.Settings);
DataContext = ViewModel = new SettingsViewModel(virtualFileSystem, contentManager); DataContext = ViewModel = new SettingsViewModel(virtualFileSystem, contentManager);

View File

@@ -76,7 +76,7 @@ namespace Ryujinx.Ava
if (!Version.TryParse(Program.Version, out Version currentVersion)) if (!Version.TryParse(Program.Version, out Version currentVersion))
{ {
Logger.Error?.Print(LogClass.Application, $"Failed to convert the current {App.FullAppName} version!"); Logger.Error?.Print(LogClass.Application, $"Failed to convert the current {RyujinxApp.FullAppName} version!");
await ContentDialogHelper.CreateWarningDialog( await ContentDialogHelper.CreateWarningDialog(
LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedMessage], LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedMessage],
@@ -159,7 +159,7 @@ namespace Ryujinx.Ava
if (!Version.TryParse(_buildVer, out Version newVersion)) if (!Version.TryParse(_buildVer, out Version newVersion))
{ {
Logger.Error?.Print(LogClass.Application, $"Failed to convert the received {App.FullAppName} version from GitHub!"); Logger.Error?.Print(LogClass.Application, $"Failed to convert the received {RyujinxApp.FullAppName} version from GitHub!");
await ContentDialogHelper.CreateWarningDialog( await ContentDialogHelper.CreateWarningDialog(
LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage], LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage],
@@ -266,7 +266,7 @@ namespace Ryujinx.Ava
SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterDownloading], SubHeader = LocaleManager.Instance[LocaleKeys.UpdaterDownloading],
IconSource = new SymbolIconSource { Symbol = Symbol.Download }, IconSource = new SymbolIconSource { Symbol = Symbol.Download },
ShowProgressBar = true, ShowProgressBar = true,
XamlRoot = App.MainWindow, XamlRoot = RyujinxApp.MainWindow,
}; };
taskDialog.Opened += (s, e) => taskDialog.Opened += (s, e) =>
@@ -490,7 +490,7 @@ namespace Ryujinx.Ava
bytesWritten += readSize; bytesWritten += readSize;
taskDialog.SetProgressBarState(GetPercentage(bytesWritten, totalBytes), TaskDialogProgressState.Normal); taskDialog.SetProgressBarState(GetPercentage(bytesWritten, totalBytes), TaskDialogProgressState.Normal);
App.SetTaskbarProgressValue(bytesWritten, totalBytes); RyujinxApp.SetTaskbarProgressValue(bytesWritten, totalBytes);
updateFileStream.Write(buffer, 0, readSize); updateFileStream.Write(buffer, 0, readSize);
} }