Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the "Auto" theme option in setting #6611

Merged
merged 31 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0800490
Add "Follow OS theme" option
yell0wsuit Apr 6, 2024
3ed8d5b
Update App.axaml.cs
yell0wsuit Apr 6, 2024
6deeba6
Add "Follow OS theme" option
yell0wsuit Apr 6, 2024
91fcb70
Update App.axaml.cs
yell0wsuit Apr 6, 2024
54c0630
Merge branch 'master' of https://github.com/yell0wsuit/Ryujinx
yell0wsuit Apr 6, 2024
b240865
Remove `this`
yell0wsuit Apr 6, 2024
d2571fb
Remove annotation for nullable reference
yell0wsuit Apr 6, 2024
a0cd133
Change into switch expression to make it concise
yell0wsuit Apr 6, 2024
b401425
Merge branch 'Ryujinx:master' into master
yell0wsuit Apr 7, 2024
6c78193
Change comments to XML docs
yell0wsuit Apr 7, 2024
7c0f261
Update en_US.json
yell0wsuit Apr 7, 2024
9808450
Fix icons in About dialog do not response to "auto" theme
yell0wsuit Apr 7, 2024
f6475f8
Newline at the end
yell0wsuit Apr 7, 2024
29db8d7
newline moment
yell0wsuit Apr 7, 2024
b969d2a
Update ThemeManager.cs
yell0wsuit Apr 7, 2024
8a86f51
bait to switch to lf
yell0wsuit Apr 7, 2024
bea19e3
change to lf
yell0wsuit Apr 7, 2024
b02c52a
temp. revert
yell0wsuit Apr 7, 2024
8113901
Add back ThemeManager.cs common, pls pass the format check
yell0wsuit Apr 7, 2024
0bf9205
I found the mistake: should have put `ThemeManager.OnThemeChanged();`…
yell0wsuit Apr 7, 2024
ce10776
test formatting
yell0wsuit Apr 7, 2024
d11806b
Update App.axaml.cs
yell0wsuit Apr 7, 2024
144945f
Ok i seem to forget to add version lol
yell0wsuit Apr 7, 2024
fe01898
Fix info CA1816
yell0wsuit Apr 7, 2024
7a3e54c
Merge branch 'master' into master
yell0wsuit Apr 7, 2024
6aa59a6
Merge branch 'master' into master
yell0wsuit Apr 8, 2024
64e8e31
Merge branch 'master' into master
yell0wsuit Apr 9, 2024
bf016d9
Merge branch 'master' into master
yell0wsuit Apr 16, 2024
cdd428d
Merge branch 'master' into master
yell0wsuit Apr 18, 2024
065f073
Merge branch 'master' into master
yell0wsuit Apr 19, 2024
07f902b
Merge branch 'master' into master
yell0wsuit May 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 32 additions & 2 deletions src/Ryujinx/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Platform;
using Avalonia.Styling;
using Avalonia.Threading;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
Expand Down Expand Up @@ -84,21 +86,26 @@ private void ThemeChanged_Event(object sender, ReactiveEventArgs<string> e)
ApplyConfiguredTheme();
}

private void ApplyConfiguredTheme()
public void ApplyConfiguredTheme()
{
try
{
string baseStyle = ConfigurationState.Instance.UI.BaseStyle;

if (string.IsNullOrWhiteSpace(baseStyle))
{
ConfigurationState.Instance.UI.BaseStyle.Value = "Dark";
ConfigurationState.Instance.UI.BaseStyle.Value = "Auto";

baseStyle = ConfigurationState.Instance.UI.BaseStyle;
}

ThemeVariant systemTheme = DetectSystemTheme();

ThemeManager.OnThemeChanged();

RequestedThemeVariant = baseStyle switch
{
"Auto" => systemTheme,
"Light" => ThemeVariant.Light,
"Dark" => ThemeVariant.Dark,
_ => ThemeVariant.Default,
Expand All @@ -111,5 +118,28 @@ private void ApplyConfiguredTheme()
ShowRestartDialog();
}
}

/// <summary>
/// Converts a PlatformThemeVariant value to the corresponding ThemeVariant value.
/// </summary>
public static ThemeVariant ConvertThemeVariant(PlatformThemeVariant platformThemeVariant) =>
platformThemeVariant switch
{
PlatformThemeVariant.Dark => ThemeVariant.Dark,
PlatformThemeVariant.Light => ThemeVariant.Light,
_ => ThemeVariant.Default,
};

public static ThemeVariant DetectSystemTheme()
{
if (Application.Current is App app)
{
var colorValues = app.PlatformSettings.GetColorValues();

return ConvertThemeVariant(colorValues.ThemeVariant);
}

return ThemeVariant.Default;
}
}
}
1 change: 1 addition & 0 deletions src/Ryujinx/Assets/Locales/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@
"GameListContextMenuToggleFavorite": "Toggle Favorite",
"GameListContextMenuToggleFavoriteToolTip": "Toggle Favorite status of Game",
"SettingsTabGeneralTheme": "Theme:",
"SettingsTabGeneralThemeAuto": "Auto",
"SettingsTabGeneralThemeDark": "Dark",
"SettingsTabGeneralThemeLight": "Light",
"ControllerSettingsConfigureGeneral": "Configure",
Expand Down
14 changes: 14 additions & 0 deletions src/Ryujinx/Common/ThemeManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace Ryujinx.Ava.Common
{
public static class ThemeManager
{
public static event EventHandler ThemeChanged;

public static void OnThemeChanged()
{
ThemeChanged?.Invoke(null, EventArgs.Empty);
}
}
}
50 changes: 34 additions & 16 deletions src/Ryujinx/UI/ViewModels/AboutWindowViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using Avalonia.Styling;
using Avalonia.Threading;
using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Common.Utilities;
using Ryujinx.UI.Common.Configuration;
Expand All @@ -11,7 +13,7 @@

namespace Ryujinx.Ava.UI.ViewModels
{
public class AboutWindowViewModel : BaseModel
public class AboutWindowViewModel : BaseModel, IDisposable
{
private Bitmap _githubLogo;
private Bitmap _discordLogo;
Expand Down Expand Up @@ -86,23 +88,39 @@ public string Version
public AboutWindowViewModel()
{
Version = Program.Version;
UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value);
Dispatcher.UIThread.InvokeAsync(DownloadPatronsJson);

if (ConfigurationState.Instance.UI.BaseStyle.Value == "Light")
{
GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Light.png?assembly=Ryujinx.UI.Common")));
DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Light.png?assembly=Ryujinx.UI.Common")));
PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Light.png?assembly=Ryujinx.UI.Common")));
TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Light.png?assembly=Ryujinx.UI.Common")));
}
else
{
GithubLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_GitHub_Dark.png?assembly=Ryujinx.UI.Common")));
DiscordLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Discord_Dark.png?assembly=Ryujinx.UI.Common")));
PatreonLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Patreon_Dark.png?assembly=Ryujinx.UI.Common")));
TwitterLogo = new Bitmap(AssetLoader.Open(new Uri("resm:Ryujinx.UI.Common.Resources.Logo_Twitter_Dark.png?assembly=Ryujinx.UI.Common")));
}
ThemeManager.ThemeChanged += ThemeManager_ThemeChanged;
}

Dispatcher.UIThread.InvokeAsync(DownloadPatronsJson);
private void ThemeManager_ThemeChanged(object sender, EventArgs e)
{
Dispatcher.UIThread.Post(() => UpdateLogoTheme(ConfigurationState.Instance.UI.BaseStyle.Value));
}

private void UpdateLogoTheme(string theme)
{
bool isDarkTheme = theme == "Dark" || (theme == "Auto" && App.DetectSystemTheme() == ThemeVariant.Dark);

string basePath = "resm:Ryujinx.UI.Common.Resources.";
string themeSuffix = isDarkTheme ? "Dark.png" : "Light.png";

GithubLogo = LoadBitmap($"{basePath}Logo_GitHub_{themeSuffix}?assembly=Ryujinx.UI.Common");
DiscordLogo = LoadBitmap($"{basePath}Logo_Discord_{themeSuffix}?assembly=Ryujinx.UI.Common");
PatreonLogo = LoadBitmap($"{basePath}Logo_Patreon_{themeSuffix}?assembly=Ryujinx.UI.Common");
TwitterLogo = LoadBitmap($"{basePath}Logo_Twitter_{themeSuffix}?assembly=Ryujinx.UI.Common");
}

private Bitmap LoadBitmap(string uri)
{
return new Bitmap(Avalonia.Platform.AssetLoader.Open(new Uri(uri)));
}

public void Dispose()
{
ThemeManager.ThemeChanged -= ThemeManager_ThemeChanged;
GC.SuppressFinalize(this);
}

private async Task DownloadPatronsJson()
Expand Down
16 changes: 14 additions & 2 deletions src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,13 @@ public void LoadCurrentConfiguration()
GameDirectories.Clear();
GameDirectories.AddRange(config.UI.GameDirs.Value);

BaseStyleIndex = config.UI.BaseStyle == "Light" ? 0 : 1;
BaseStyleIndex = config.UI.BaseStyle.Value switch
{
"Auto" => 0,
"Light" => 1,
"Dark" => 2,
_ => 0
};

// Input
EnableDockedMode = config.System.EnableDockedMode;
Expand Down Expand Up @@ -486,7 +492,13 @@ public void SaveSettings()
config.UI.GameDirs.Value = gameDirs;
}

config.UI.BaseStyle.Value = BaseStyleIndex == 0 ? "Light" : "Dark";
config.UI.BaseStyle.Value = BaseStyleIndex switch
{
0 => "Auto",
1 => "Light",
2 => "Dark",
_ => "Auto"
};

// Input
config.System.EnableDockedMode.Value = EnableDockedMode;
Expand Down
3 changes: 3 additions & 0 deletions src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
<ComboBox SelectedIndex="{Binding BaseStyleIndex}"
HorizontalContentAlignment="Left"
MinWidth="100">
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabGeneralThemeAuto}" />
</ComboBoxItem>
<ComboBoxItem>
<TextBlock Text="{locale:Locale SettingsTabGeneralThemeLight}" />
</ComboBoxItem>
Expand Down
29 changes: 29 additions & 0 deletions src/Ryujinx/UI/Windows/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Platform;
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common;
Expand Down Expand Up @@ -92,6 +93,29 @@ public MainWindow()
}
}

/// <summary>
/// Event handler for detecting OS theme change when using "Follow OS theme" option
/// </summary>
private void OnPlatformColorValuesChanged(object sender, PlatformColorValues e)
{
if (Application.Current is App app)
{
app.ApplyConfiguredTheme();
}
}

protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
if (PlatformSettings != null)
{
/// <summary>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think XML docs does anything when unsubscribing or subscribing events.

/// Unsubscribe to the ColorValuesChanged event
/// </summary>
PlatformSettings.ColorValuesChanged -= OnPlatformColorValuesChanged;
}
}

protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
Expand Down Expand Up @@ -390,6 +414,11 @@ protected override void OnOpened(EventArgs e)

Initialize();

/// <summary>
/// Subscribe to the ColorValuesChanged event
/// </summary>
PlatformSettings.ColorValuesChanged += OnPlatformColorValuesChanged;

ViewModel.Initialize(
ContentManager,
StorageProvider,
Expand Down