瀏覽代碼

Instant reload fixes

Krzysztof Krysiński 2 年之前
父節點
當前提交
543db332dd

+ 2 - 1
src/PixiEditor/Helpers/Converters/BlendModeToStringConverter.cs

@@ -1,6 +1,7 @@
 using System.Globalization;
 using PixiEditor.ChangeableDocument.Enums;
 using PixiEditor.Helpers.Extensions;
+using PixiEditor.Localization;
 
 namespace PixiEditor.Helpers.Converters;
 internal class BlendModeToStringConverter : SingleInstanceConverter<BlendModeToStringConverter>
@@ -9,7 +10,7 @@ internal class BlendModeToStringConverter : SingleInstanceConverter<BlendModeToS
     {
         if (value is not BlendMode mode)
             return "<null>";
-        return mode.LocalizedName();
+        return new LocalizedString(mode.LocalizedKeys()).Value;
     }
 
     public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

+ 18 - 18
src/PixiEditor/Helpers/Extensions/BlendModeEx.cs

@@ -4,27 +4,27 @@ using PixiEditor.Localization;
 namespace PixiEditor.Helpers.Extensions;
 internal static class BlendModeEx
 {
-    public static string LocalizedName(this BlendMode mode)
+    public static string LocalizedKeys(this BlendMode mode)
     {
         return mode switch
         {
-            BlendMode.Normal => new LocalizedString("NORMAL_BLEND_MODE"),
-            BlendMode.Darken => new LocalizedString("DARKEN_BLEND_MODE"),
-            BlendMode.Multiply => new LocalizedString("MULTIPLY_BLEND_MODE"),
-            BlendMode.ColorBurn => new LocalizedString("COLOR_BURN_BLEND_MODE"),
-            BlendMode.Lighten => new LocalizedString("LIGHTEN_BLEND_MODE"),
-            BlendMode.Screen => new LocalizedString("SCREEN_BLEND_MODE"),
-            BlendMode.ColorDodge => new LocalizedString("COLOR_DODGE_BLEND_MODE"),
-            BlendMode.LinearDodge => new LocalizedString("LINEAR_DODGE_BLEND_MODE"),
-            BlendMode.Overlay => new LocalizedString("OVERLAY_BLEND_MODE"),
-            BlendMode.SoftLight => new LocalizedString("SOFT_LIGHT_BLEND_MODE"),
-            BlendMode.HardLight => new LocalizedString("HARD_LIGHT_BLEND_MODE"),
-            BlendMode.Difference => new LocalizedString("DIFFERENCE_BLEND_MODE"),
-            BlendMode.Exclusion => new LocalizedString("EXCLUSION_BLEND_MODE"),
-            BlendMode.Hue => new LocalizedString("HUE_BLEND_MODE"),
-            BlendMode.Saturation => new LocalizedString("SATURATION_BLEND_MODE"),
-            BlendMode.Luminosity => new LocalizedString("LUMINOSITY_BLEND_MODE"),
-            BlendMode.Color => new LocalizedString("COLOR_BLEND_MODE"),
+            BlendMode.Normal => "NORMAL_BLEND_MODE",
+            BlendMode.Darken => "DARKEN_BLEND_MODE",
+            BlendMode.Multiply => "MULTIPLY_BLEND_MODE",
+            BlendMode.ColorBurn => "COLOR_BURN_BLEND_MODE",
+            BlendMode.Lighten => "LIGHTEN_BLEND_MODE",
+            BlendMode.Screen => "SCREEN_BLEND_MODE",
+            BlendMode.ColorDodge => "COLOR_DODGE_BLEND_MODE",
+            BlendMode.LinearDodge => "LINEAR_DODGE_BLEND_MODE",
+            BlendMode.Overlay => "OVERLAY_BLEND_MODE",
+            BlendMode.SoftLight => "SOFT_LIGHT_BLEND_MODE",
+            BlendMode.HardLight => "HARD_LIGHT_BLEND_MODE",
+            BlendMode.Difference => "DIFFERENCE_BLEND_MODE",
+            BlendMode.Exclusion => "EXCLUSION_BLEND_MODE",
+            BlendMode.Hue => "HUE_BLEND_MODE",
+            BlendMode.Saturation => "SATURATION_BLEND_MODE",
+            BlendMode.Luminosity => "LUMINOSITY_BLEND_MODE",
+            BlendMode.Color => "COLOR_BLEND_MODE",
             _ => "NOT_SUPPORTED_BLEND_MODE"
         };
     }

+ 9 - 9
src/PixiEditor/Models/Commands/CommandController.cs

@@ -71,9 +71,9 @@ internal class CommandController
         }
     }
 
-    private static List<(string internalName, string displayName)> FindCommandGroups(IEnumerable<Type> typesToSearchForAttributes)
+    private static List<(string internalName, LocalizedString displayName)> FindCommandGroups(IEnumerable<Type> typesToSearchForAttributes)
     {
-        List<(string internalName, string displayName)> result = new();
+        List<(string internalName, LocalizedString displayName)> result = new();
 
         foreach (var type in typesToSearchForAttributes)
         {
@@ -115,7 +115,7 @@ internal class CommandController
             NoticeDialog.Show("SHORTCUTS_CORRUPTED", "SHORTCUTS_CORRUPTED_TITLE");
         }
         var compiledCommandList = new CommandNameList();
-        List<(string internalName, string displayName)> commandGroupsData = FindCommandGroups(compiledCommandList.Groups);
+        List<(string internalName, LocalizedString displayName)> commandGroupsData = FindCommandGroups(compiledCommandList.Groups);
         OneToManyDictionary<string, Command> commands = new(); // internal name of the corr. group -> command in that group
 
         LoadEvaluators(serviceProvider, compiledCommandList);
@@ -133,14 +133,14 @@ internal class CommandController
                 continue;
             }
 
-            string groupDisplayName = groupData.displayName;
+            LocalizedString groupDisplayName = groupData.displayName;
             CommandGroups.Add(new CommandGroup(groupDisplayName, storedCommands));
         }
         
-        CommandGroups.Add(new CommandGroup(new LocalizedString("MISC"), miscList));
+        CommandGroups.Add(new CommandGroup("MISC", miscList));
     }
 
-    private void LoadTools(IServiceProvider serviceProvider, List<(string internalName, string displayName)> commandGroupsData, OneToManyDictionary<string, Command> commands,
+    private void LoadTools(IServiceProvider serviceProvider, List<(string internalName, LocalizedString displayName)> commandGroupsData, OneToManyDictionary<string, Command> commands,
         ShortcutsTemplate template)
     {
         foreach (var toolInstance in serviceProvider.GetServices<ToolViewModel>())
@@ -156,7 +156,7 @@ internal class CommandController
 
             string internalName = $"PixiEditor.Tools.Select.{type.Name}";
 
-            LocalizedString displayName = new("SELECT_TOOL", toolInstance.DisplayName);
+            LocalizedString displayName = new("SELECT_TOOL", toolInstance.DisplayName.Value);
 
             var command = new Command.ToolCommand()
             {
@@ -181,7 +181,7 @@ internal class CommandController
             .FirstOrDefault(x => x.Commands.Contains(internalName), new Shortcut(defaultShortcut, (List<string>)null))
             .KeyCombination;
 
-    private void AddCommandToCommandsCollection(Command command, List<(string internalName, string displayName)> commandGroupsData, OneToManyDictionary<string, Command> commands)
+    private void AddCommandToCommandsCollection(Command command, List<(string internalName, LocalizedString displayName)> commandGroupsData, OneToManyDictionary<string, Command> commands)
     {
         (string internalName, string displayName) group = commandGroupsData.FirstOrDefault(x => command.InternalName.StartsWith(x.internalName));
         if (group == default)
@@ -190,7 +190,7 @@ internal class CommandController
             commands.Add(group.internalName, command);
     }
 
-    private void LoadCommands(IServiceProvider serviceProvider, CommandNameList compiledCommandList, List<(string internalName, string displayName)> commandGroupsData, OneToManyDictionary<string, Command> commands, ShortcutsTemplate template)
+    private void LoadCommands(IServiceProvider serviceProvider, CommandNameList compiledCommandList, List<(string internalName, LocalizedString displayName)> commandGroupsData, OneToManyDictionary<string, Command> commands, ShortcutsTemplate template)
     {
         foreach (var type in compiledCommandList.Commands)
         {

+ 19 - 6
src/PixiEditor/Models/Commands/CommandGroup.cs

@@ -1,16 +1,24 @@
 using System.Collections;
+using System.ComponentModel;
 using System.Windows.Input;
+using PixiEditor.Localization;
 using PixiEditor.Models.Commands.Commands;
 using PixiEditor.Models.DataHolders;
 
 namespace PixiEditor.Models.Commands;
 
-internal class CommandGroup : IEnumerable<Command>
+internal class CommandGroup : NotifyableObject
 {
     private readonly Command[] commands;
     private readonly Command[] visibleCommands;
 
-    public string DisplayName { get; set; }
+    private LocalizedString displayName;
+
+    public LocalizedString DisplayName
+    {
+        get => displayName;
+        set => SetProperty(ref displayName, value);
+    }
 
     public bool HasAssignedShortcuts { get; set; }
 
@@ -18,17 +26,24 @@ internal class CommandGroup : IEnumerable<Command>
 
     public IEnumerable<Command> VisibleCommands => visibleCommands;
 
-    public CommandGroup(string displayName, IEnumerable<Command> commands)
+    public CommandGroup(LocalizedString displayName, IEnumerable<Command> commands)
     {
         DisplayName = displayName;
         this.commands = commands.ToArray();
-        visibleCommands = commands.Where(x => !string.IsNullOrEmpty(x.DisplayName)).ToArray();
+        visibleCommands = commands.Where(x => !string.IsNullOrEmpty(x.DisplayName.Value)).ToArray();
 
         foreach (var command in commands)
         {
             HasAssignedShortcuts |= command.Shortcut.Key != Key.None;
             command.ShortcutChanged += Command_ShortcutChanged;
         }
+
+        ILocalizationProvider.Current.OnLanguageChanged += OnLanguageChanged;
+    }
+
+    private void OnLanguageChanged(Language obj)
+    {
+        DisplayName = new LocalizedString(DisplayName.Key);
     }
 
     private void Command_ShortcutChanged(Command cmd, ShortcutChangedEventArgs args)
@@ -50,6 +65,4 @@ internal class CommandGroup : IEnumerable<Command>
     }
 
     public IEnumerator<Command> GetEnumerator() => Commands.GetEnumerator();
-
-    IEnumerator IEnumerable.GetEnumerator() => Commands.GetEnumerator();
 }

+ 15 - 3
src/PixiEditor/Models/Commands/Commands/Command.cs

@@ -19,9 +19,9 @@ internal abstract partial class Command : NotifyableObject
 
     public IconEvaluator IconEvaluator { get; init; }
 
-    public LocalizedString DisplayName { get; init; }
+    public LocalizedString DisplayName { get; set; }
 
-    public LocalizedString Description { get; init; }
+    public LocalizedString Description { get; set; }
 
     public CommandMethods Methods { get; init; }
 
@@ -43,8 +43,20 @@ internal abstract partial class Command : NotifyableObject
 
     public abstract object GetParameter();
 
-    protected Command(Action<object> onExecute, CanExecuteEvaluator canExecute) =>
+    protected Command(Action<object> onExecute, CanExecuteEvaluator canExecute)
+    {
         Methods = new(this, onExecute, canExecute);
+        ILocalizationProvider.Current.OnLanguageChanged += OnLanguageChanged;
+    }
+
+    private void OnLanguageChanged(Language obj)
+    {
+        DisplayName = new LocalizedString(DisplayName.Key);
+        Description = new LocalizedString(Description.Key);
+
+        RaisePropertyChanged(nameof(DisplayName));
+        RaisePropertyChanged(nameof(Description));
+    }
 
     public void Execute() => Methods.Execute(GetParameter());
 

+ 2 - 1
src/PixiEditor/Styles/PixiListBoxItemStyle.xaml

@@ -1,5 +1,6 @@
 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+                    xmlns:views="clr-namespace:PixiEditor.Views">
     <Style TargetType="ListBoxItem" x:Key="PixiListBoxItemStyle">
         <Setter Property="OverridesDefaultStyle" Value="True"/>
         <Setter Property="Foreground" Value="White"/>

+ 1 - 1
src/PixiEditor/ViewModels/SettingsWindowViewModel.cs

@@ -247,7 +247,7 @@ internal class SettingsWindowViewModel : ViewModelBase
     {
         private Visibility visibility;
 
-        public string DisplayName { get; set; }
+        public LocalizedString DisplayName { get; set; }
 
         public List<CommandSearchResult> Commands { get; set; }
 

+ 1 - 0
src/PixiEditor/Views/Dialogs/DialogTitleBar.xaml.cs

@@ -1,6 +1,7 @@
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Input;
+using PixiEditor.Localization;
 
 namespace PixiEditor.Views.Dialogs;
 

+ 4 - 2
src/PixiEditor/Views/Dialogs/SettingGroups/ShortcutsBinder.xaml

@@ -7,6 +7,8 @@
              xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters"
              xmlns:views="clr-namespace:PixiEditor.Views"
              xmlns:userControls="clr-namespace:PixiEditor.Views.UserControls"
+             xmlns:commands="clr-namespace:PixiEditor.Models.Commands"
+             xmlns:commands1="clr-namespace:PixiEditor.Models.Commands.Commands"
              mc:Ignorable="d"
              d:DesignHeight="600" d:DesignWidth="400">
     <ScrollViewer x:Name="commandScroll" FocusVisualStyle="{x:Null}">
@@ -34,12 +36,12 @@
                                    views:Translator.Key="NOTHING_FOUND"  d:Text="Nothing found."/>
                         <ItemsControl ItemsSource="{Binding Commands}" Foreground="White" Focusable="False">
                             <ItemsControl.ItemTemplate>
-                                <DataTemplate>
+                                <DataTemplate DataType="{x:Type commands:CommandGroup}">
                                     <StackPanel Margin="0,0,0,20" Visibility="{Binding Visibility}">
                                         <TextBlock Text="{Binding DisplayName}" FontSize="22" FontWeight="SemiBold"/>
                                         <ItemsControl ItemsSource="{Binding Commands}" Focusable="False">
                                             <ItemsControl.ItemTemplate>
-                                                <DataTemplate>
+                                                <DataTemplate DataType="{x:Type commands1:Command}">
                                                     <Grid Margin="0,5,5,0" Visibility="{Binding Visibility}">
                                                         <TextBlock Text="{Binding Command.DisplayName}" ToolTip="{Binding Command.Description}"/>
                                                         <userControls:ShortcutBox Width="120" Command="{Binding Command}" HorizontalAlignment="Right" Focusable="False"/>

+ 1 - 1
src/PixiEditor/Views/Dialogs/SettingsWindow.xaml

@@ -46,7 +46,7 @@
         </i:Interaction.Behaviors>
 
         <dial:DialogTitleBar DockPanel.Dock="Top"
-            TitleText="Settings" CloseCommand="{x:Static SystemCommands.CloseWindowCommand}"/>
+            TitleText="SETTINGS" CloseCommand="{x:Static SystemCommands.CloseWindowCommand}"/>
 
         <ListBox DockPanel.Dock="Left" x:Name="pages" 
                  Background="Transparent" BorderThickness="0" Width="150" ItemContainerStyle="{StaticResource PixiListBoxItemStyle}"

+ 4 - 2
src/PixiEditor/Views/MainWindow.xaml

@@ -26,6 +26,7 @@
     xmlns:commandSearch="clr-namespace:PixiEditor.Views.UserControls.CommandSearch"
     xmlns:palettes="clr-namespace:PixiEditor.Views.UserControls.Palettes"
     xmlns:views="clr-namespace:PixiEditor.Views"
+    xmlns:system="clr-namespace:System;assembly=System.Runtime"
     d:DataContext="{d:DesignInstance Type=vm:ViewModelMain}"
     mc:Ignorable="d"
     WindowStyle="None"
@@ -662,7 +663,7 @@
                                                       CanClose="False" CanAutoHide="False" x:Name="colorPickerPanel"
                                                       CanDockAsTabbedDocument="False" CanFloat="True">
                                             <usercontrols:SmallColorPicker SelectedColor="{Binding ColorsSubViewModel.PrimaryColor, Mode=TwoWay, Converter={StaticResource BackendColorToMediaColorConverter}}"
-                                                                         SecondaryColor="{Binding ColorsSubViewModel.SecondaryColor, Mode=TwoWay, Converter={StaticResource BackendColorToMediaColorConverter}}" 
+                                                                         SecondaryColor="{Binding ColorsSubViewModel.SecondaryColor, Mode=TwoWay, Converter={StaticResource BackendColorToMediaColorConverter}}"
                                                                          Style="{StaticResource DefaultColorPickerStyle}" x:Name="mainColorPicker">
                                                 <b:Interaction.Behaviors>
                                                     <behaviours:GlobalShortcutFocusBehavior/>
@@ -769,7 +770,8 @@
                                     Style="{StaticResource ToolButtonStyle}"
                                     Command="{cmds:Command PixiEditor.Tools.SelectTool, UseProvided=True}"
                                     CommandParameter="{Binding}"
-                                    ToolTip="{Binding Tooltip}">
+                                    views:Translator.TooltipLocalizedString="{Binding Tooltip}"
+                                    views:Translator.TooltipKey="{Binding Tooltip.Key}">
                                     <Button.Background>
                                         <ImageBrush
                                             RenderOptions.BitmapScalingMode="Fant"

+ 92 - 56
src/PixiEditor/Views/Translator.cs

@@ -10,12 +10,55 @@ namespace PixiEditor.Views;
 
 public class Translator : UIElement
 {
+    public static readonly DependencyProperty KeyProperty = DependencyProperty.RegisterAttached(
+        "Key",
+        typeof(string),
+        typeof(Translator),
+        new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.AffectsRender, KeyPropertyChangedCallback));
+
+    public static readonly DependencyProperty TooltipKeyProperty = DependencyProperty.RegisterAttached(
+        "TooltipKey", typeof(string), typeof(Translator), 
+        new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.AffectsRender, TooltipKeyPropertyChangedCallback));
+
+    public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached(
+        "Value",
+        typeof(string),
+        typeof(Translator),
+        new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.AffectsRender));
+
+    public static readonly DependencyProperty TooltipLocalizedStringProperty = DependencyProperty.RegisterAttached(
+        "TooltipLocalizedString",
+        typeof(LocalizedString),
+        typeof(Translator),
+        new FrameworkPropertyMetadata(default(LocalizedString), FrameworkPropertyMetadataOptions.AffectsRender, TooltipLocalizedStringPropertyChangedCallback));
+
+    private static void TooltipLocalizedStringPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+    {
+        d.SetValue(FrameworkElement.ToolTipProperty, GetTooltipLocalizedString(d).Value);
+        ILocalizationProvider.Current.OnLanguageChanged += (lang) => OnLanguageChangedTooltipString(d, lang);
+    }
+
+    private static void OnLanguageChangedTooltipString(DependencyObject dependencyObject, Language lang)
+    {
+        LocalizedString localizedString = GetTooltipLocalizedString(dependencyObject);
+        LocalizedString newLocalizedString = new(localizedString.Key, localizedString.Parameters);
+
+        dependencyObject.SetValue(FrameworkElement.ToolTipProperty, newLocalizedString.Value);
+    }
+
+
+    private static void TooltipKeyPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+    {
+        d.SetValue(FrameworkElement.ToolTipProperty, new LocalizedString(GetTooltipKey(d)).Value);
+        ILocalizationProvider.Current.OnLanguageChanged += (lang) => OnLanguageChangedTooltipKey(d, lang);
+    }
+
     private static void OnLanguageChangedKey(DependencyObject obj, Language newLanguage)
     {
         string key = GetKey(obj);
         if (key != null)
         {
-            obj.SetValue(ValueProperty, new LocalizedString(key).Value);
+            UpdateKey(obj, key);
         }
     }
 
@@ -28,22 +71,6 @@ public class Translator : UIElement
         }
     }
 
-    public static readonly DependencyProperty KeyProperty = DependencyProperty.RegisterAttached(
-        "Key",
-        typeof(string),
-        typeof(Translator),
-        new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.AffectsRender, KeyPropertyChangedCallback));
-
-    public static readonly DependencyProperty TooltipKeyProperty = DependencyProperty.RegisterAttached(
-        "TooltipKey", typeof(string), typeof(Translator), 
-        new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.AffectsRender, TooltipKeyPropertyChangedCallback));
-
-    private static void TooltipKeyPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
-    {
-        d.SetValue(FrameworkElement.ToolTipProperty, new LocalizedString(GetTooltipKey(d)).Value);
-        ILocalizationProvider.Current.OnLanguageChanged += (lang) => OnLanguageChangedTooltipKey(d, lang);
-    }
-
     public static void SetTooltipKey(DependencyObject element, string value)
     {
         element.SetValue(TooltipKeyProperty, value);
@@ -58,54 +85,53 @@ public class Translator : UIElement
     {
         if (e.NewValue is string key)
         {
-            LocalizedString localizedString = new(key);
-            Binding binding = new()
-            {
-                Path = new PropertyPath("(0)", Translator.ValueProperty),
-                RelativeSource = new RelativeSource(RelativeSourceMode.Self)
-            };
-
-            if(d is TextBox textBox)
-            {
-                textBox.SetBinding(TextBox.TextProperty, binding);
-            }
-            else if (d is TextBlock textBlock)
-            {
-                textBlock.SetBinding(TextBlock.TextProperty, binding);
-            }
-            else if (d is Run run)
-            {
-                run.SetBinding(Run.TextProperty, binding);
-            }
-            else if (d is ContentControl contentControl)
-            {
-                contentControl.SetBinding(ContentControl.ContentProperty, binding);
-            }
-            else if (d is HeaderedItemsControl menuItem)
-            {
-                menuItem.SetBinding(HeaderedItemsControl.HeaderProperty, binding);
-            }
-            else if (d is LayoutContent layoutContent)
-            {
-                layoutContent.SetValue(LayoutContent.TitleProperty, localizedString.Value);
-            }
-
-            d.SetValue(ValueProperty, localizedString.Value);
+            UpdateKey(d, key);
             ILocalizationProvider.Current.OnLanguageChanged += (lang) => OnLanguageChangedKey(d, lang);
         }
     }
 
-    public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached(
-        "Value",
-        typeof(string),
-        typeof(Translator),
-        new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.AffectsRender));
+    private static void UpdateKey(DependencyObject d, string key)
+    {
+        LocalizedString localizedString = new(key);
+        Binding binding = new()
+        {
+            Path = new PropertyPath("(0)", ValueProperty),
+            RelativeSource = new RelativeSource(RelativeSourceMode.Self)
+        };
+
+        if (d is TextBox textBox)
+        {
+            textBox.SetBinding(TextBox.TextProperty, binding);
+        }
+        else if (d is TextBlock textBlock)
+        {
+            textBlock.SetBinding(TextBlock.TextProperty, binding);
+        }
+        else if (d is Run run)
+        {
+            run.SetBinding(Run.TextProperty, binding);
+        }
+        else if (d is ContentControl contentControl)
+        {
+            contentControl.SetBinding(ContentControl.ContentProperty, binding);
+        }
+        else if (d is HeaderedItemsControl menuItem)
+        {
+            menuItem.SetBinding(HeaderedItemsControl.HeaderProperty, binding);
+        }
+        else if (d is LayoutContent layoutContent)
+        {
+            layoutContent.SetValue(LayoutContent.TitleProperty, localizedString.Value);
+        }
+
+        d.SetValue(ValueProperty, localizedString.Value);
+    }
 
     public static void SetKey(DependencyObject element, string value)
     {
         element.SetValue(KeyProperty, value);
     }
-    
+
     public static string GetKey(DependencyObject element)
     {
         return (string)element.GetValue(KeyProperty);
@@ -115,4 +141,14 @@ public class Translator : UIElement
     {
         return (string)element.GetValue(ValueProperty);
     }
+
+    public static LocalizedString GetTooltipLocalizedString(DependencyObject element)
+    {
+        return (LocalizedString)element.GetValue(TooltipLocalizedStringProperty);
+    }
+
+    public static void SetTooltipLocalizedString(UIElement element, LocalizedString value)
+    {
+        element.SetValue(TooltipLocalizedStringProperty, value);
+    }
 }

+ 21 - 17
src/PixiEditor/Views/UserControls/BlendModeComboBox.cs

@@ -57,31 +57,35 @@ internal class BlendModeComboBox : ComboBox
     {
         var items = new List<UIElement>() 
         {
-            new ComboBoxItem() { Content = BlendMode.Normal.LocalizedName(), Tag = BlendMode.Normal },
+            new ComboBoxItem() { Content = BlendMode.Normal.LocalizedKeys(), Tag = BlendMode.Normal },
             new Separator(),
-            new ComboBoxItem() { Content = BlendMode.Darken.LocalizedName(), Tag = BlendMode.Darken },
-            new ComboBoxItem() { Content = BlendMode.Multiply.LocalizedName(), Tag = BlendMode.Multiply },
-            new ComboBoxItem() { Content = BlendMode.ColorBurn.LocalizedName(), Tag = BlendMode.ColorBurn },
+            new ComboBoxItem() { Content = BlendMode.Darken.LocalizedKeys(), Tag = BlendMode.Darken },
+            new ComboBoxItem() { Content = BlendMode.Multiply.LocalizedKeys(), Tag = BlendMode.Multiply },
+            new ComboBoxItem() { Content = BlendMode.ColorBurn.LocalizedKeys(), Tag = BlendMode.ColorBurn },
             new Separator(),
-            new ComboBoxItem() { Content = BlendMode.Lighten.LocalizedName(), Tag = BlendMode.Lighten },
-            new ComboBoxItem() { Content = BlendMode.Screen.LocalizedName(), Tag = BlendMode.Screen },
-            new ComboBoxItem() { Content = BlendMode.ColorDodge.LocalizedName(), Tag = BlendMode.ColorDodge },
-            new ComboBoxItem() { Content = BlendMode.LinearDodge.LocalizedName(), Tag = BlendMode.LinearDodge },
+            new ComboBoxItem() { Content = BlendMode.Lighten.LocalizedKeys(), Tag = BlendMode.Lighten },
+            new ComboBoxItem() { Content = BlendMode.Screen.LocalizedKeys(), Tag = BlendMode.Screen },
+            new ComboBoxItem() { Content = BlendMode.ColorDodge.LocalizedKeys(), Tag = BlendMode.ColorDodge },
+            new ComboBoxItem() { Content = BlendMode.LinearDodge.LocalizedKeys(), Tag = BlendMode.LinearDodge },
             new Separator(),
-            new ComboBoxItem() { Content = BlendMode.Overlay.LocalizedName(), Tag = BlendMode.Overlay },
-            new ComboBoxItem() { Content = BlendMode.SoftLight.LocalizedName(), Tag = BlendMode.SoftLight },
-            new ComboBoxItem() { Content = BlendMode.HardLight.LocalizedName(), Tag = BlendMode.HardLight },
+            new ComboBoxItem() { Content = BlendMode.Overlay.LocalizedKeys(), Tag = BlendMode.Overlay },
+            new ComboBoxItem() { Content = BlendMode.SoftLight.LocalizedKeys(), Tag = BlendMode.SoftLight },
+            new ComboBoxItem() { Content = BlendMode.HardLight.LocalizedKeys(), Tag = BlendMode.HardLight },
             new Separator(),
-            new ComboBoxItem() { Content = BlendMode.Difference.LocalizedName(), Tag = BlendMode.Difference },
-            new ComboBoxItem() { Content = BlendMode.Exclusion.LocalizedName(), Tag = BlendMode.Exclusion },
+            new ComboBoxItem() { Content = BlendMode.Difference.LocalizedKeys(), Tag = BlendMode.Difference },
+            new ComboBoxItem() { Content = BlendMode.Exclusion.LocalizedKeys(), Tag = BlendMode.Exclusion },
             new Separator(),
-            new ComboBoxItem() { Content = BlendMode.Hue.LocalizedName(), Tag = BlendMode.Hue },
-            new ComboBoxItem() { Content = BlendMode.Saturation.LocalizedName(), Tag = BlendMode.Saturation },
-            new ComboBoxItem() { Content = BlendMode.Luminosity.LocalizedName(), Tag = BlendMode.Luminosity },
-            new ComboBoxItem() { Content = BlendMode.Color.LocalizedName(), Tag = BlendMode.Color }
+            new ComboBoxItem() { Content = BlendMode.Hue.LocalizedKeys(), Tag = BlendMode.Hue },
+            new ComboBoxItem() { Content = BlendMode.Saturation.LocalizedKeys(), Tag = BlendMode.Saturation },
+            new ComboBoxItem() { Content = BlendMode.Luminosity.LocalizedKeys(), Tag = BlendMode.Luminosity },
+            new ComboBoxItem() { Content = BlendMode.Color.LocalizedKeys(), Tag = BlendMode.Color }
         };
         foreach (var item in items)
         {
+            if (item is ComboBoxItem)
+            {
+                Translator.SetKey((ComboBoxItem)item, ((ComboBoxItem)item).Content.ToString());
+            }
             Items.Add(item);
         }
         SelectedIndex = 0;