RyujinxApp.axaml.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using Avalonia;
  2. using Avalonia.Controls.ApplicationLifetimes;
  3. using Avalonia.Input.Platform;
  4. using Avalonia.Markup.Xaml;
  5. using Avalonia.Platform;
  6. using Avalonia.Styling;
  7. using Avalonia.Threading;
  8. using FluentAvalonia.UI.Windowing;
  9. using Gommon;
  10. using Ryujinx.Ava.Common;
  11. using Ryujinx.Ava.Common.Locale;
  12. using Ryujinx.Ava.UI.Helpers;
  13. using Ryujinx.Ava.UI.Windows;
  14. using Ryujinx.Ava.Utilities;
  15. using Ryujinx.Ava.Utilities.Configuration;
  16. using Ryujinx.Common;
  17. using Ryujinx.Common.Logging;
  18. using System;
  19. using System.Diagnostics;
  20. namespace Ryujinx.Ava
  21. {
  22. public class RyujinxApp : Application
  23. {
  24. internal static string FormatTitle(LocaleKeys? windowTitleKey = null)
  25. => windowTitleKey is null
  26. ? $"{FullAppName} {Program.Version}"
  27. : $"{FullAppName} {Program.Version} - {LocaleManager.Instance[windowTitleKey.Value]}";
  28. public static readonly string FullAppName = ReleaseInformation.IsCanaryBuild ? "Ryujinx Canary" : "Ryujinx";
  29. public static MainWindow MainWindow => Current!
  30. .ApplicationLifetime.Cast<IClassicDesktopStyleApplicationLifetime>()
  31. .MainWindow.Cast<MainWindow>();
  32. public static bool IsClipboardAvailable(out IClipboard clipboard)
  33. {
  34. clipboard = MainWindow.Clipboard;
  35. return clipboard != null;
  36. }
  37. public static void SetTaskbarProgress(TaskBarProgressBarState state) => MainWindow.PlatformFeatures.SetTaskBarProgressBarState(state);
  38. public static void SetTaskbarProgressValue(ulong current, ulong total) => MainWindow.PlatformFeatures.SetTaskBarProgressBarValue(current, total);
  39. public static void SetTaskbarProgressValue(long current, long total) => SetTaskbarProgressValue(Convert.ToUInt64(current), Convert.ToUInt64(total));
  40. public override void Initialize()
  41. {
  42. Name = FormatTitle();
  43. AvaloniaXamlLoader.Load(this);
  44. if (OperatingSystem.IsMacOS())
  45. {
  46. Process.Start("/usr/bin/defaults", "write org.ryujinx.Ryujinx ApplePressAndHoldEnabled -bool false");
  47. }
  48. }
  49. public override void OnFrameworkInitializationCompleted()
  50. {
  51. if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
  52. {
  53. desktop.MainWindow = new MainWindow();
  54. }
  55. base.OnFrameworkInitializationCompleted();
  56. if (Program.PreviewerDetached)
  57. {
  58. ApplyConfiguredTheme(ConfigurationState.Instance.UI.BaseStyle);
  59. ConfigurationState.Instance.UI.BaseStyle.Event += ThemeChanged_Event;
  60. }
  61. }
  62. private void ShowRestartDialog()
  63. {
  64. _ = Dispatcher.UIThread.InvokeAsync(async () =>
  65. {
  66. if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
  67. {
  68. UserResult result = await ContentDialogHelper.CreateConfirmationDialog(
  69. LocaleManager.Instance[LocaleKeys.DialogThemeRestartMessage],
  70. LocaleManager.Instance[LocaleKeys.DialogThemeRestartSubMessage],
  71. LocaleManager.Instance[LocaleKeys.InputDialogYes],
  72. LocaleManager.Instance[LocaleKeys.InputDialogNo],
  73. LocaleManager.Instance[LocaleKeys.DialogRestartRequiredMessage]);
  74. if (result == UserResult.Yes)
  75. {
  76. _ = Process.Start(Environment.ProcessPath!, CommandLineState.Arguments);
  77. desktop.Shutdown();
  78. Environment.Exit(0);
  79. }
  80. }
  81. });
  82. }
  83. private void ThemeChanged_Event(object _, ReactiveEventArgs<string> rArgs) => ApplyConfiguredTheme(rArgs.NewValue);
  84. public void ApplyConfiguredTheme(string baseStyle)
  85. {
  86. try
  87. {
  88. if (string.IsNullOrWhiteSpace(baseStyle))
  89. {
  90. ConfigurationState.Instance.UI.BaseStyle.Value = "Auto";
  91. baseStyle = ConfigurationState.Instance.UI.BaseStyle;
  92. }
  93. ThemeManager.OnThemeChanged();
  94. RequestedThemeVariant = baseStyle switch
  95. {
  96. "Auto" => DetectSystemTheme(),
  97. "Light" => ThemeVariant.Light,
  98. "Dark" => ThemeVariant.Dark,
  99. _ => ThemeVariant.Default,
  100. };
  101. }
  102. catch (Exception)
  103. {
  104. Logger.Warning?.Print(LogClass.Application, "Failed to apply theme. A restart is needed to apply the selected theme.");
  105. ShowRestartDialog();
  106. }
  107. }
  108. /// <summary>
  109. /// Converts a PlatformThemeVariant value to the corresponding ThemeVariant value.
  110. /// </summary>
  111. public static ThemeVariant ConvertThemeVariant(PlatformThemeVariant platformThemeVariant) =>
  112. platformThemeVariant switch
  113. {
  114. PlatformThemeVariant.Dark => ThemeVariant.Dark,
  115. PlatformThemeVariant.Light => ThemeVariant.Light,
  116. _ => ThemeVariant.Default,
  117. };
  118. public static ThemeVariant DetectSystemTheme() =>
  119. Current is RyujinxApp { PlatformSettings: not null } app
  120. ? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant)
  121. : ThemeVariant.Default;
  122. }
  123. }