mtkennerly / ludusavi-playnite

Playnite plugin for save backups via Ludusavi
MIT License
141 stars 9 forks source link

Add icons to menu items #76

Open darklinkpower opened 3 weeks ago

darklinkpower commented 3 weeks ago

I think it would be a good UX improvement to display items alongside menu items. Playnite supports different values: https://api.playnite.link/docs/tutorials/extensions/menus.html?tabs=csharp#icons

Personally I like to use textblock using the available FontIcoFont font in Playnite because they can be styled by Playnite and themes. As a suggestion I'll share how I implemented it using application resources:

image

https://github.com/darklinkpower/PlayniteExtensionsCollection/blob/f2ca28640aef0d1a2dc8603bb345d732171cf818/source/Library/JastUsaLibrary/JastUsaLibrary.cs#L252-L257

                    new GameMenuItem
                    {
                        Description = ResourceProvider.GetString("LOC_JUL_DialogMessageBrowseForGameOption"),
                        MenuSection = menuSection,
                        Icon = PlayniteUtilities.GetIcoFontGlyphResource('\uEC5B'),
                        Action = a =>

This calls the method here that handles adding and returning the resource key after adding it: https://github.com/darklinkpower/PlayniteExtensionsCollection/blob/f2ca28640aef0d1a2dc8603bb345d732171cf818/source/Common/PlayniteUtilitiesCommon/PlayniteUtilities.cs#L370-L400

        private static HashSet<string> _addedIcoFontResources = new HashSet<string>();

        public static void AddTextIcoFontResource(string key, char character)
        {
            AddTextIcoFontResource(key, character.ToString());
        }

        public static void AddTextIcoFontResource(string key, string text)
        {
            if (Application.Current.Resources.Contains(key))
            {
                return;
            }

            Application.Current.Resources.Add(key, new TextBlock
            {
                Text = text,
                FontSize = 16,
                FontFamily = ResourceProvider.GetResource("FontIcoFont") as FontFamily
            });
        }

        public static string GetIcoFontGlyphResource(char character)
        {
            var key = $"IcoFontResource - {character}";
            if (!_addedIcoFontResources.Contains(key))
            {
                AddTextIcoFontResource(key, character);
                _addedIcoFontResources.Add(key);
            }

            return key;
        }

To see the available icons and their code, I use the program Character Map UWP:

image

mtkennerly commented 3 weeks ago

Hmm, is there any way to set an icon for the parent of a nested item? I want "restore save data..." to have an icon, but I can only seem to add it for the individual backups.

image

new GameMenuItem
{
    Description = Etc.GetBackupDisplayLine(backup),
    MenuSection = string.Format("{0} | {1}", translator.Ludusavi(), translator.RestoreSelectedGames_Label()),
    Action = ...
}

If I add an extra GameMenuItem just for "restore save data..." (with an icon but with no action), then I get one with the icon and one without 😅

mtkennerly commented 3 weeks ago

I've opened a ticket for this: https://github.com/JosefNemec/Playnite/issues/3762

darklinkpower commented 3 weeks ago

Yeah unfortunately currently it's not possible to set icons to items parents.