Skip to content

Commit

Permalink
UI: Remove title bar, put icon next to File button. Added icons to mo…
Browse files Browse the repository at this point in the history
…st dropdown menu actions. Title bar content is now displayed when hovering the logo in the title bar.
  • Loading branch information
GreemDev committed Oct 17, 2024
1 parent 235083a commit 045f9a3
Show file tree
Hide file tree
Showing 21 changed files with 382 additions and 391 deletions.
4 changes: 3 additions & 1 deletion src/Ryujinx.UI.Common/App/ApplicationData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace Ryujinx.UI.App.Common
{
public class ApplicationData
{
public static Func<string> LocalizedNever = () => "Never";

public bool Favorite { get; set; }
public byte[] Icon { get; set; }
public string Name { get; set; } = "Unknown";
Expand All @@ -34,7 +36,7 @@ public class ApplicationData

public string TimePlayedString => ValueFormatUtils.FormatTimeSpan(TimePlayed);

public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed);
public string LastPlayedString => ValueFormatUtils.FormatDateTime(LastPlayed) ?? LocalizedNever();

public string FileSizeString => ValueFormatUtils.FormatFileSize(FileSize);

Expand Down
3 changes: 3 additions & 0 deletions src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using ARMeilleure;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
Expand Down Expand Up @@ -1645,6 +1646,8 @@ public static void Initialize()
}

Instance = new ConfigurationState();

Instance.System.EnableLowPowerPtc.Event += (_, evnt) => Optimizations.LowPower = evnt.NewValue;
}
}
}
8 changes: 1 addition & 7 deletions src/Ryujinx.UI.Common/Helper/ValueFormatUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,7 @@ public static string FormatDateTime(DateTime? utcDateTime, CultureInfo culture =
{
culture ??= CultureInfo.CurrentCulture;

if (!utcDateTime.HasValue)
{
// In the Avalonia UI, this is turned into a localized version of "Never" by LocalizedNeverConverter.
return "Never";
}

return utcDateTime.Value.ToLocalTime().ToString(culture);
return utcDateTime?.ToLocalTime().ToString(culture);
}

/// <summary>
Expand Down
26 changes: 26 additions & 0 deletions src/Ryujinx/Common/Icon/IconExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Avalonia.Data.Core;
using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings;
using System;

namespace Ryujinx.Ava.Common.Icon
{
internal class IconExtension(string iconString) : MarkupExtension
{
private ClrPropertyInfo PropertyInfo
=> new(
"Item",
_ => new Projektanker.Icons.Avalonia.Icon { Value = iconString },
null,
typeof(Projektanker.Icons.Avalonia.Icon)
);

public override object ProvideValue(IServiceProvider serviceProvider) =>
new CompiledBindingExtension(
new CompiledBindingPathBuilder()
.Property(PropertyInfo, PropertyInfoAccessorFactory.CreateInpcPropertyAccessor)
.Build()
).ProvideValue(serviceProvider);
}
}
46 changes: 26 additions & 20 deletions src/Ryujinx/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
using ARMeilleure;
using Avalonia;
using Avalonia.Threading;
using DiscordRPC;
using Projektanker.Icons.Avalonia;
using Projektanker.Icons.Avalonia.FontAwesome;
using Projektanker.Icons.Avalonia.MaterialDesign;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common;
Expand All @@ -11,6 +16,7 @@
using Ryujinx.Graphics.Vulkan.MoltenVK;
using Ryujinx.Modules;
using Ryujinx.SDL2.Common;
using Ryujinx.UI.App.Common;
using Ryujinx.UI.Common;
using Ryujinx.UI.Common.Configuration;
using Ryujinx.UI.Common.Helper;
Expand Down Expand Up @@ -51,31 +57,32 @@ public static int Main(string[] args)

LoggerAdapter.Register();

IconProvider.Current
.Register<FontAwesomeIconProvider>()
.Register<MaterialDesignIconProvider>();

return BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}

public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>()
public static AppBuilder BuildAvaloniaApp() =>
AppBuilder.Configure<App>()
.UsePlatformDetect()
.With(new X11PlatformOptions
{
EnableMultiTouch = true,
EnableIme = true,
EnableInputFocusProxy = Environment.GetEnvironmentVariable("XDG_CURRENT_DESKTOP") == "gamescope",
RenderingMode = UseHardwareAcceleration ?
new[] { X11RenderingMode.Glx, X11RenderingMode.Software } :
new[] { X11RenderingMode.Software },
RenderingMode = UseHardwareAcceleration
? [ X11RenderingMode.Glx, X11RenderingMode.Software ]
: [ X11RenderingMode.Software ],
})
.With(new Win32PlatformOptions
{
WinUICompositionBackdropCornerRadius = 8.0f,
RenderingMode = UseHardwareAcceleration ?
new[] { Win32RenderingMode.AngleEgl, Win32RenderingMode.Software } :
new[] { Win32RenderingMode.Software },
})
.UseSkia();
}
RenderingMode = UseHardwareAcceleration
? [ Win32RenderingMode.AngleEgl, Win32RenderingMode.Software ]
: [ Win32RenderingMode.Software ],
});

private static void Initialize(string[] args)
{
Expand All @@ -102,6 +109,9 @@ private static void Initialize(string[] args)
// Setup base data directory.
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);

// Set the delegate for localizing the word "never" in the UI
ApplicationData.LocalizedNever = () => LocaleManager.Instance[LocaleKeys.Never];

// Initialize the configuration.
ConfigurationState.Initialize();

Expand Down Expand Up @@ -218,14 +228,10 @@ private static void PrintSystemInfo()

Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {(Logger.GetEnabledLevels().Count == 0 ? "<None>" : string.Join(", ", Logger.GetEnabledLevels()))}");

if (AppDataManager.Mode == AppDataManager.LaunchMode.Custom)
{
Logger.Notice.Print(LogClass.Application, $"Launch Mode: Custom Path {AppDataManager.BaseDirPath}");
}
else
{
Logger.Notice.Print(LogClass.Application, $"Launch Mode: {AppDataManager.Mode}");
}
Logger.Notice.Print(LogClass.Application,
AppDataManager.Mode == AppDataManager.LaunchMode.Custom
? $"Launch Mode: Custom Path {AppDataManager.BaseDirPath}"
: $"Launch Mode: {AppDataManager.Mode}");
}

private static void ProcessUnhandledException(Exception ex, bool isTerminating)
Expand Down
7 changes: 4 additions & 3 deletions src/Ryujinx/Ryujinx.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
<PackageReference Include="Avalonia.Svg.Skia" />
<PackageReference Include="DynamicData" />
<PackageReference Include="FluentAvaloniaUI" />

<PackageReference Include="Projektanker.Icons.Avalonia" />
<PackageReference Include="Projektanker.Icons.Avalonia.FontAwesome" />
<PackageReference Include="Projektanker.Icons.Avalonia.MaterialDesign" />
<PackageReference Include="OpenTK.Core" />
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" />
Expand All @@ -69,8 +71,7 @@
<ProjectReference Include="..\Ryujinx.Graphics.OpenGL\Ryujinx.Graphics.OpenGL.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
<ProjectReference Include="..\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj" />
<ProjectReference Include="..\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\Ryujinx.UI.LocaleGenerator\Ryujinx.UI.LocaleGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/Ryujinx/UI/Applet/AvaHostUIHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText)
{
try
{
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
MainWindow.ViewModel.AppHost.NpadManager.BlockInputUpdates();
var response = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args);
if (response.Result == UserResult.Ok)
Expand All @@ -144,7 +144,7 @@ public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText)
});

dialogCloseEvent.WaitOne();
_parent.ViewModel.AppHost.NpadManager.UnblockInputUpdates();
MainWindow.ViewModel.AppHost.NpadManager.UnblockInputUpdates();

userText = error ? null : inputText;

Expand All @@ -154,7 +154,7 @@ public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText)
public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value)
{
device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value);
_parent.ViewModel.AppHost?.Stop();
MainWindow.ViewModel.AppHost?.Stop();
}

public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
Expand Down
2 changes: 1 addition & 1 deletion src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public void Dispose()
Dispatcher.UIThread.Post(() =>
{
_hiddenTextBox.Clear();
_parent.ViewModel.RendererHostControl.Focus();
MainWindow.ViewModel.RendererHostControl.Focus();
_parent = null;
});
Expand Down
29 changes: 22 additions & 7 deletions src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:icon="clr-namespace:Ryujinx.Ava.Common.Icon"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
x:DataType="viewModels:MainWindowViewModel">
<MenuItem
<MenuItem
Click="RunApplication_Click"
Header="{locale:Locale GameListContextMenuRunApplication}" />
Header="{locale:Locale GameListContextMenuRunApplication}"
Icon="{icon:Icon fa-solid fa-play}"/>
<MenuItem
Click="ToggleFavorite_Click"
Header="{locale:Locale GameListContextMenuToggleFavorite}"
Icon="{icon:Icon fa-solid fa-star}"
ToolTip.Tip="{locale:Locale GameListContextMenuToggleFavoriteToolTip}" />
<MenuItem
Click="CreateApplicationShortcut_Click"
Header="{locale:Locale GameListContextMenuCreateShortcut}"
<MenuItem
Click="CreateApplicationShortcut_Click"
Header="{locale:Locale GameListContextMenuCreateShortcut}"
IsEnabled="{Binding CreateShortcutEnabled}"
ToolTip.Tip="{OnPlatform Default={locale:Locale GameListContextMenuCreateShortcutToolTip}, macOS={locale:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
Icon="{icon:Icon fa-solid fa-bookmark}"
ToolTip.Tip="{OnPlatform Default={locale:Locale GameListContextMenuCreateShortcutToolTip}, macOS={locale:Locale GameListContextMenuCreateShortcutToolTipMacOS}}" />
<Separator />
<MenuItem
Click="OpenUserSaveDirectory_Click"
Header="{locale:Locale GameListContextMenuOpenUserSaveDirectory}"
Icon="{icon:Icon mdi-folder-account}"
IsEnabled="{Binding OpenUserSaveDirectoryEnabled}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenUserSaveDirectoryToolTip}" />
<MenuItem
Expand All @@ -37,45 +42,55 @@
<MenuItem
Click="OpenTitleUpdateManager_Click"
Header="{locale:Locale GameListContextMenuManageTitleUpdates}"
Icon="{icon:Icon fa-solid fa-code-compare}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageTitleUpdatesToolTip}" />
<MenuItem
Click="OpenDownloadableContentManager_Click"
Header="{locale:Locale GameListContextMenuManageDlc}"
Icon="{icon:Icon fa-solid fa-download}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageDlcToolTip}" />
<MenuItem
Click="OpenCheatManager_Click"
Header="{locale:Locale GameListContextMenuManageCheat}"
Icon="{icon:Icon fa-solid fa-code}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageCheatToolTip}" />
<MenuItem
Click="OpenModManager_Click"
Header="{locale:Locale GameListContextMenuManageMod}"
Icon="{icon:Icon mdi-view-module}"
ToolTip.Tip="{locale:Locale GameListContextMenuManageModToolTip}" />
<Separator />
<MenuItem
Click="OpenModsDirectory_Click"
Header="{locale:Locale GameListContextMenuOpenModsDirectory}"
Icon="{icon:Icon mdi-folder-file}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenModsDirectoryToolTip}" />
<MenuItem
Click="OpenSdModsDirectory_Click"
Header="{locale:Locale GameListContextMenuOpenSdModsDirectory}"
Icon="{icon:Icon mdi-folder-file}"
ToolTip.Tip="{locale:Locale GameListContextMenuOpenSdModsDirectoryToolTip}" />
<Separator />
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}">
<MenuItem Header="{locale:Locale GameListContextMenuCacheManagement}" Icon="{icon:Icon mdi-cached}">
<MenuItem
Click="PurgePtcCache_Click"
Header="{locale:Locale GameListContextMenuCacheManagementPurgePptc}"
Icon="{icon:Icon mdi-refresh}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgePptcToolTip}" />
<MenuItem
Click="PurgeShaderCache_Click"
Header="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCache}"
Icon="{icon:Icon mdi-delete-alert}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementPurgeShaderCacheToolTip}" />
<MenuItem
Click="OpenPtcDirectory_Click"
Header="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectory}"
Icon="{icon:Icon mdi-folder-arrow-up-down}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenPptcDirectoryToolTip}" />
<MenuItem
Click="OpenShaderCacheDirectory_Click"
Header="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectory}"
Icon="{icon:Icon mdi-folder-arrow-up-down}"
ToolTip.Tip="{locale:Locale GameListContextMenuCacheManagementOpenShaderCacheDirectoryToolTip}" />
</MenuItem>
<MenuItem Header="{locale:Locale GameListContextMenuExtractData}">
Expand Down
Loading

0 comments on commit 045f9a3

Please sign in to comment.