Merge branch 'allow-change-icon' into 'master'
feat: add ability to change app icon See merge request [ryubing/ryujinx!128](https://git.ryujinx.app/ryubing/ryujinx/-/merge_requests/128)
@ -12067,6 +12067,56 @@
|
||||
"zh_TW": "淺色"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabGeneralIcon",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Application icon:",
|
||||
"es_ES": "Icono de aplicación:",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabGeneralIconTooltip",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "An app restart may be required for the app icon to display properly across Ryujinx.",
|
||||
"es_ES": "Podría ser necesario reiniciar la aplicación para que el icono se muestre correctamente en todo Ryujinx.",
|
||||
"fr_FR": "",
|
||||
"he_IL": "",
|
||||
"it_IT": "",
|
||||
"ja_JP": "",
|
||||
"ko_KR": "",
|
||||
"no_NO": "",
|
||||
"pl_PL": "",
|
||||
"pt_BR": "",
|
||||
"ru_RU": "",
|
||||
"sv_SE": "",
|
||||
"th_TH": "",
|
||||
"tr_TR": "",
|
||||
"uk_UA": "",
|
||||
"zh_CN": "",
|
||||
"zh_TW": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "ControllerSettingsConfigureGeneral",
|
||||
"Translations": {
|
||||
|
||||
24
src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryugay.svg
Normal file
|
After Width: | Height: | Size: 890 KiB |
4
src/Ryujinx/Assets/Icons/AppIcons/Bordered Ryupride.svg
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
src/Ryujinx/Assets/Icons/AppIcons/Ryubi.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
src/Ryujinx/Assets/Icons/AppIcons/Ryufluid.webp
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src/Ryujinx/Assets/Icons/AppIcons/Ryulesbian.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src/Ryujinx/Assets/Icons/AppIcons/Ryupan.webp
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/Ryujinx/Assets/Icons/AppIcons/Ryupride.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
src/Ryujinx/Assets/Icons/AppIcons/Ryutrans.webp
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
23
src/Ryujinx/Common/Models/ApplicationIcon.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Avalonia.Media.Imaging;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
|
||||
namespace Ryujinx.Ava.Common.Models
|
||||
{
|
||||
public class ApplicationIcon
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Filename { get; set; }
|
||||
public string FullPath
|
||||
{
|
||||
get => $"Ryujinx/Assets/Icons/AppIcons/{Filename}";
|
||||
}
|
||||
|
||||
public Bitmap Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
return RyujinxLogo.GetBitmapForLogo(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,6 +164,7 @@
|
||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConPair.svg" />
|
||||
<EmbeddedResource Include="Assets\Icons\Controller_JoyConRight.svg" />
|
||||
<EmbeddedResource Include="Assets\Icons\Controller_ProCon.svg" />
|
||||
<EmbeddedResource Include="Assets\Icons\AppIcons\*" />
|
||||
<EmbeddedResource Include="Assets\UIImages\Icon_NCA.png" />
|
||||
<EmbeddedResource Include="Assets\UIImages\Icon_NRO.png" />
|
||||
<EmbeddedResource Include="Assets\UIImages\Icon_NSO.png" />
|
||||
|
||||
@ -356,6 +356,11 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
/// </summary>
|
||||
public string BaseStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the currently selected window icon
|
||||
/// </summary>
|
||||
public string SelectedWindowIcon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Chooses the view mode of the game list // Not Used
|
||||
/// </summary>
|
||||
|
||||
@ -134,6 +134,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
UI.ShownFileTypes.NSO.Value = shouldLoadFromFile ? cff.ShownFileTypes.NSO : UI.ShownFileTypes.NSO.Value;
|
||||
UI.LanguageCode.Value = shouldLoadFromFile ? cff.LanguageCode : UI.LanguageCode.Value;
|
||||
UI.BaseStyle.Value = shouldLoadFromFile ? cff.BaseStyle : UI.BaseStyle.Value;
|
||||
UI.SelectedWindowIcon.Value = shouldLoadFromFile ? cff.SelectedWindowIcon : UI.SelectedWindowIcon.Value;
|
||||
UI.GameListViewMode.Value = shouldLoadFromFile ? cff.GameListViewMode : UI.GameListViewMode.Value;
|
||||
UI.ShowNames.Value = shouldLoadFromFile ? cff.ShowNames : UI.ShowNames.Value;
|
||||
UI.IsAscendingOrder.Value = shouldLoadFromFile ? cff.IsAscendingOrder : UI.IsAscendingOrder.Value;
|
||||
|
||||
@ -151,6 +151,11 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
/// </summary>
|
||||
public ReactiveObject<string> BaseStyle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected window icon.
|
||||
/// </summary>
|
||||
public ReactiveObject<string> SelectedWindowIcon { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Start games in fullscreen mode
|
||||
/// </summary>
|
||||
@ -200,6 +205,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
ShownFileTypes = new ShownFileTypeSettings();
|
||||
WindowStartup = new WindowStartupSettings();
|
||||
BaseStyle = new ReactiveObject<string>();
|
||||
SelectedWindowIcon = new ReactiveObject<string>();
|
||||
StartFullscreen = new ReactiveObject<bool>();
|
||||
StartNoUI = new ReactiveObject<bool>();
|
||||
GameListViewMode = new ReactiveObject<int>();
|
||||
|
||||
@ -126,6 +126,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
},
|
||||
LanguageCode = UI.LanguageCode,
|
||||
BaseStyle = UI.BaseStyle,
|
||||
SelectedWindowIcon = UI.SelectedWindowIcon,
|
||||
GameListViewMode = UI.GameListViewMode,
|
||||
ShowNames = UI.ShowNames,
|
||||
GridSize = UI.GridSize,
|
||||
|
||||
@ -1,28 +1,146 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.Systems.Configuration;
|
||||
using Ryujinx.Ava.UI.ViewModels;
|
||||
using System.Reflection;
|
||||
using Ryujinx.Common;
|
||||
using SkiaSharp;
|
||||
using Svg.Skia;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Controls
|
||||
{
|
||||
public class RyujinxLogo : Image
|
||||
{
|
||||
// The UI specifically uses a thicker bordered variant of the icon to avoid crunching out the border at lower resolutions.
|
||||
// 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.
|
||||
public static readonly Bitmap Bitmap =
|
||||
new(Assembly.GetAssembly(typeof(MainWindowViewModel))!
|
||||
.GetManifestResourceStream("Ryujinx.Assets.UIImages.Logo_Ryujinx_AntiAlias.png")!);
|
||||
public static ReactiveObject<Bitmap> CurrentLogoBitmap { get; private set; } = new();
|
||||
|
||||
public RyujinxLogo()
|
||||
{
|
||||
Margin = new Thickness(7, 7, 7, 0);
|
||||
Height = 25;
|
||||
Width = 25;
|
||||
Source = Bitmap;
|
||||
Source = CurrentLogoBitmap.Value;
|
||||
IsVisible = !ConfigurationState.Instance.ShowOldUI;
|
||||
ConfigurationState.Instance.UI.SelectedWindowIcon.Event += WindowIconChanged_Event;
|
||||
CurrentLogoBitmap.Event += CurrentLogoBitmapChanged_Event;
|
||||
}
|
||||
|
||||
private void CurrentLogoBitmapChanged_Event(object _, ReactiveEventArgs<Bitmap> e)
|
||||
{
|
||||
Source = e.NewValue;
|
||||
}
|
||||
|
||||
public static void RefreshAppIconFromSettings()
|
||||
{
|
||||
SetNewAppIcon(ConfigurationState.Instance.UI.SelectedWindowIcon.Value);
|
||||
}
|
||||
|
||||
private static void SetNewAppIcon(string newIconName)
|
||||
{
|
||||
string defaultIconName = "Bordered Ryupride";
|
||||
if (string.IsNullOrEmpty(newIconName))
|
||||
{
|
||||
SetDefaultAppIcon(defaultIconName);
|
||||
}
|
||||
|
||||
ApplicationIcon selectedIcon = RyujinxApp.AvailableApplicationIcons.FirstOrDefault(x => x.Name == newIconName);
|
||||
if (selectedIcon == null)
|
||||
{
|
||||
// Always try to fallback to "Bordered Ryupride" as a default
|
||||
// If not found, fallback to first found icon
|
||||
if (newIconName != defaultIconName)
|
||||
{
|
||||
SetDefaultAppIcon(defaultIconName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (RyujinxApp.AvailableApplicationIcons.Count > 0)
|
||||
{
|
||||
SetDefaultAppIcon(RyujinxApp.AvailableApplicationIcons.First().Name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Stream activeIconStream = EmbeddedResources.GetStream(selectedIcon.FullPath);
|
||||
if (activeIconStream != null)
|
||||
{
|
||||
Bitmap logoBitmap = GetBitmapForLogo(selectedIcon);
|
||||
if (logoBitmap != null)
|
||||
{
|
||||
CurrentLogoBitmap.Value = logoBitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetDefaultAppIcon(string defaultIconName)
|
||||
{
|
||||
// Doing this triggers the WindowIconChanged_Event, which will then
|
||||
// call SetNewAppIcon again
|
||||
ConfigurationState.Instance.UI.SelectedWindowIcon.Value = defaultIconName;
|
||||
}
|
||||
|
||||
private void WindowIconChanged_Event(object _, ReactiveEventArgs<string> rArgs) => SetNewAppIcon(rArgs.NewValue);
|
||||
|
||||
public static Bitmap GetBitmapForLogo(ApplicationIcon icon)
|
||||
{
|
||||
Stream activeIconStream = EmbeddedResources.GetStream(icon.FullPath);
|
||||
if (activeIconStream == null)
|
||||
return null;
|
||||
|
||||
// SVG files need to be converted to an image first
|
||||
if (icon.FullPath.EndsWith(".svg", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Stream pngStream = ConvertSvgToPng(activeIconStream);
|
||||
return new Bitmap(pngStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Bitmap(activeIconStream);
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream ConvertSvgToPng(Stream svgStream)
|
||||
{
|
||||
int width = 256;
|
||||
int height = 256;
|
||||
|
||||
// Load SVG
|
||||
var svg = new SKSvg();
|
||||
svg.Load(svgStream);
|
||||
|
||||
// Determine size
|
||||
var picture = svg.Picture;
|
||||
if (picture == null)
|
||||
throw new InvalidOperationException("Invalid SVG data");
|
||||
|
||||
var picWidth = width > 0 ? width : (int)svg.Picture.CullRect.Width;
|
||||
var picHeight = height > 0 ? height : (int)svg.Picture.CullRect.Height;
|
||||
|
||||
// Create bitmap
|
||||
using var bitmap = new SKBitmap(picWidth, picHeight);
|
||||
using var canvas = new SKCanvas(bitmap);
|
||||
canvas.Clear(SKColors.Transparent);
|
||||
|
||||
// Scale to fit
|
||||
float scaleX = (float)picWidth / svg.Picture.CullRect.Width;
|
||||
float scaleY = (float)picHeight / svg.Picture.CullRect.Height;
|
||||
canvas.Scale(scaleX, scaleY);
|
||||
|
||||
canvas.DrawPicture(svg.Picture);
|
||||
canvas.Flush();
|
||||
|
||||
// Encode PNG into memory stream
|
||||
var outputStream = new MemoryStream();
|
||||
using (var image = SKImage.FromBitmap(bitmap))
|
||||
using (var data = image.Encode(SKEncodedImageFormat.Png, 100))
|
||||
{
|
||||
data.SaveTo(outputStream);
|
||||
}
|
||||
|
||||
outputStream.Position = 0;
|
||||
return outputStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,9 @@ using Avalonia.Threading;
|
||||
using FluentAvalonia.UI.Windowing;
|
||||
using Gommon;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.Systems.Configuration;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.Views.Dialog;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
@ -16,7 +18,10 @@ using Ryujinx.Ava.Utilities;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Ava
|
||||
{
|
||||
@ -52,6 +57,9 @@ namespace Ryujinx.Ava
|
||||
{
|
||||
Name = FormatTitle();
|
||||
|
||||
RetrieveAvailableAppIcons();
|
||||
RyujinxLogo.RefreshAppIconFromSettings();
|
||||
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
if (OperatingSystem.IsMacOS())
|
||||
@ -72,7 +80,6 @@ namespace Ryujinx.Ava
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
ApplyConfiguredTheme(ConfigurationState.Instance.UI.BaseStyle);
|
||||
|
||||
ConfigurationState.Instance.UI.BaseStyle.Event += ThemeChanged_Event;
|
||||
}
|
||||
}
|
||||
@ -151,5 +158,27 @@ namespace Ryujinx.Ava
|
||||
{
|
||||
await AboutView.Show();
|
||||
}
|
||||
|
||||
public static List<ApplicationIcon> AvailableApplicationIcons { get; set; } = [];
|
||||
private static void RetrieveAvailableAppIcons()
|
||||
{
|
||||
AvailableApplicationIcons.Clear();
|
||||
string resourceAssemblyPrefix = "Ryujinx.Assets.Icons.AppIcons.";
|
||||
|
||||
IEnumerable<string> availableAppIconResources = EmbeddedResources
|
||||
.GetAllAvailableResources("Ryujinx/Assets")
|
||||
.Where(x => x.StartsWith(resourceAssemblyPrefix));
|
||||
|
||||
foreach (string resource in availableAppIconResources)
|
||||
{
|
||||
string filename = resource.Remove(0, resourceAssemblyPrefix.Length);
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filename);
|
||||
AvailableApplicationIcons.Add(new ApplicationIcon()
|
||||
{
|
||||
Name = fileNameWithoutExtension,
|
||||
Filename = filename
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,12 +9,14 @@ using Ryujinx.Audio.Backends.OpenAL;
|
||||
using Ryujinx.Audio.Backends.SDL3;
|
||||
using Ryujinx.Audio.Backends.SoundIo;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Common.Models;
|
||||
using Ryujinx.Ava.Systems.Configuration;
|
||||
using Ryujinx.Ava.Systems.Configuration.System;
|
||||
using Ryujinx.Ava.Systems.Configuration.UI;
|
||||
using Ryujinx.Ava.UI.Helpers;
|
||||
using Ryujinx.Ava.UI.Models.Input;
|
||||
using Ryujinx.Ava.UI.Windows;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Configuration.Multiplayer;
|
||||
using Ryujinx.Common.GraphicsDriver;
|
||||
@ -507,6 +509,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
|
||||
Task.Run(CheckSoundBackends);
|
||||
Task.Run(PopulateNetworkInterfaces);
|
||||
ApplicationIcons = new(RyujinxApp.AvailableApplicationIcons);
|
||||
|
||||
if (Program.PreviewerDetached)
|
||||
{
|
||||
@ -632,6 +635,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
HideCursor = (int)config.HideCursor.Value;
|
||||
UpdateCheckerType = (int)config.UpdateCheckerType.Value;
|
||||
FocusLostActionType = (int)config.FocusLostActionType.Value;
|
||||
AppIconSelectedIndex = _appIcons.ToList().FindIndex(x => x.Name == config.UI.SelectedWindowIcon.Value);
|
||||
|
||||
GameDirectories.Clear();
|
||||
GameDirectories.AddRange(config.UI.GameDirs.Value);
|
||||
@ -750,6 +754,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
config.FocusLostActionType.Value = (FocusLostType)FocusLostActionType;
|
||||
config.UI.GameDirs.Value = [.. GameDirectories];
|
||||
config.UI.AutoloadDirs.Value = [.. AutoloadDirectories];
|
||||
config.UI.SelectedWindowIcon.Value = _appIcons[_appIconSelectedIndex].Name;
|
||||
|
||||
config.UI.BaseStyle.Value = BaseStyleIndex switch
|
||||
{
|
||||
@ -937,5 +942,27 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||
RevertIfNotSaved(IsCustomConfig, IsGameRunning);
|
||||
CloseWindow?.Invoke();
|
||||
}
|
||||
|
||||
private AvaloniaList<ApplicationIcon> _appIcons = [];
|
||||
public AvaloniaList<ApplicationIcon> ApplicationIcons
|
||||
{
|
||||
get => _appIcons;
|
||||
set
|
||||
{
|
||||
_appIcons = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private int _appIconSelectedIndex;
|
||||
public int AppIconSelectedIndex
|
||||
{
|
||||
get => _appIconSelectedIndex;
|
||||
set
|
||||
{
|
||||
_appIconSelectedIndex = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,6 +141,32 @@
|
||||
</ComboBox>
|
||||
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
IsEnabled="{Binding !IsGameTitleNotNull}"
|
||||
Opacity="{Binding PanelOpacity}"
|
||||
Margin="0, 15, 0, 10"
|
||||
ToolTip.Tip="{ext:Locale SettingsTabGeneralIconTooltip}"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Text="{ext:Locale SettingsTabGeneralIcon}"
|
||||
Width="150" />
|
||||
<ComboBox
|
||||
MinWidth="100"
|
||||
HorizontalAlignment="Left"
|
||||
ItemsSource="{Binding ApplicationIcons}"
|
||||
SelectedIndex="{Binding AppIconSelectedIndex}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal" >
|
||||
<Image Source="{Binding Icon}" Width="24" Height="24" Margin="0,0,8,0" />
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<TextBlock Classes="globalConfigMarker" IsVisible="{Binding IsGameTitleNotNull}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<Border Grid.Column="1"
|
||||
|
||||
@ -3,11 +3,13 @@ using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform;
|
||||
using FluentAvalonia.UI.Windowing;
|
||||
using Ryujinx.Ava.Common.Locale;
|
||||
using Ryujinx.Ava.Systems.Configuration;
|
||||
using Ryujinx.Ava.UI.Controls;
|
||||
using Ryujinx.Common;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Ava.UI.Windows
|
||||
@ -39,7 +41,8 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
TitleBar.Height = titleBarHeight.Value;
|
||||
}
|
||||
|
||||
Icon = RyujinxLogo.Bitmap;
|
||||
Icon = RyujinxLogo.CurrentLogoBitmap.Value;
|
||||
RyujinxLogo.CurrentLogoBitmap.Event += WindowIconChanged_Event;
|
||||
}
|
||||
|
||||
private void LocaleChanged()
|
||||
@ -53,6 +56,12 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.SystemChrome | ExtendClientAreaChromeHints.OSXThickTitleBar;
|
||||
}
|
||||
|
||||
private void WindowIconChanged_Event(object _, ReactiveEventArgs<Bitmap> rArgs) => UpdateIcon(rArgs.NewValue);
|
||||
private void UpdateIcon(Bitmap newIcon)
|
||||
{
|
||||
Icon = newIcon;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class StyleableWindow : Window
|
||||
@ -73,7 +82,8 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
LocaleManager.Instance.LocaleChanged += LocaleChanged;
|
||||
LocaleChanged();
|
||||
|
||||
Icon = new WindowIcon(RyujinxLogo.Bitmap);
|
||||
Icon = new WindowIcon(RyujinxLogo.CurrentLogoBitmap.Value);
|
||||
RyujinxLogo.CurrentLogoBitmap.Event += WindowIconChanged_Event;
|
||||
}
|
||||
|
||||
private void LocaleChanged()
|
||||
@ -87,5 +97,11 @@ namespace Ryujinx.Ava.UI.Windows
|
||||
|
||||
ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.SystemChrome | ExtendClientAreaChromeHints.OSXThickTitleBar;
|
||||
}
|
||||
|
||||
private void WindowIconChanged_Event(object _, ReactiveEventArgs<Bitmap> rArgs) => UpdateIcon(rArgs.NewValue);
|
||||
private void UpdateIcon(Bitmap newIcon)
|
||||
{
|
||||
Icon = new WindowIcon(newIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||