Przeglądaj źródła

Removed ability to asign a shortcut to multiple commands

CPKreuz 3 lat temu
rodzic
commit
27ddc25f3f

+ 2 - 0
PixiEditor/Models/Commands/CommandCollection.cs

@@ -56,6 +56,8 @@ namespace PixiEditor.Models.Commands
 
         public void RemoveShortcut(Command command, KeyCombination shortcut) => _commandShortcuts.Remove(shortcut, command);
 
+        public void ClearShortcut(KeyCombination shortcut) => _commandShortcuts.Clear(shortcut);
+
         public IEnumerable<KeyValuePair<KeyCombination, IEnumerable<Command>>> GetShortcuts() =>
             _commandShortcuts;
 

+ 20 - 0
PixiEditor/Models/Commands/CommandController.cs

@@ -230,6 +230,9 @@ namespace PixiEditor.Models.Commands
             }
         }
 
+        /// <summary>
+        /// Removes the old shortcut to this command and adds the new one
+        /// </summary>
         public void UpdateShortcut(Command command, KeyCombination newShortcut)
         {
             Commands.RemoveShortcut(command, command.Shortcut);
@@ -237,5 +240,22 @@ namespace PixiEditor.Models.Commands
             command.Shortcut = newShortcut;
             shortcutFile.SaveShortcuts();
         }
+
+        /// <summary>
+        /// Delets all shortcuts of <paramref name="newShortcut"/> and adds <paramref name="command"/>
+        /// </summary>
+        public void ReplaceShortcut(Command command, KeyCombination newShortcut)
+        {
+            foreach (Command other in Commands[newShortcut])
+            {
+                other.Shortcut = KeyCombination.None;
+            }
+
+            Commands.ClearShortcut(newShortcut);
+            Commands.RemoveShortcut(command, command.Shortcut);
+            Commands.AddShortcut(command, newShortcut);
+            command.Shortcut = newShortcut;
+            shortcutFile.SaveShortcuts();
+        }
     }
 }

+ 74 - 0
PixiEditor/Models/Dialogs/OptionsDialog.cs

@@ -0,0 +1,74 @@
+using PixiEditor.Views.Dialogs;
+using System.Collections;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace PixiEditor.Models.Dialogs
+{
+    public class OptionsDialog<T> : CustomDialog, IEnumerable<T>
+    {
+        private Dictionary<T, Action<T>> _results = new();
+
+        public string Title { get; set; }
+
+        public object Content { get; set; }
+
+        public T Result { get; private set; }
+
+        public OptionsDialog(string title, object content)
+        {
+            Title = title;
+
+            if (content is not Visual)
+            {
+                Content = new TextBlock()
+                {
+                    Text = content.ToString(),
+                    FontSize = 15,
+                    TextAlignment = System.Windows.TextAlignment.Center,
+                    TextTrimming = System.Windows.TextTrimming.WordEllipsis,
+                    TextWrapping = System.Windows.TextWrapping.WrapWithOverflow,
+                    HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
+                    VerticalAlignment = System.Windows.VerticalAlignment.Center,
+                };
+            }
+            else
+            {
+                Content = content;
+            }
+        }
+
+        public OptionsDialog(string title, object content, IEnumerable<KeyValuePair<T, Action<T>>> options) : this(title, content)
+        {
+            _results = new(options);
+        }
+
+        public Action<T> this[T name]
+        {
+            get => _results[name];
+            set => _results.Add(name, value);
+        }
+
+        public override bool ShowDialog()
+        {
+            var popup = new OptionPopup(Title, Content, new(_results.Keys.Select(x => (object)x)));
+            var popupResult = popup.ShowDialog();
+
+            Result = (T)popup.Result;
+            if (Result != null)
+            {
+                _results[Result]?.Invoke(Result);
+            }
+
+            return popupResult.GetValueOrDefault(false);
+        }
+
+        public void Add(T name) => _results.Add(name, null);
+
+        public void Add(T name, Action<T> action) => _results.Add(name, action);
+
+        public IEnumerator<T> GetEnumerator() => _results.Keys.GetEnumerator();
+
+        IEnumerator IEnumerable.GetEnumerator() => _results.Keys.GetEnumerator();
+    }
+}

+ 44 - 0
PixiEditor/Views/Dialogs/OptionsPopup.xaml

@@ -0,0 +1,44 @@
+<Window x:Class="PixiEditor.Views.Dialogs.OptionPopup"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:PixiEditor.Views.Dialogs"
+        xmlns:uc="clr-namespace:PixiEditor.Views.UserControls"
+        mc:Ignorable="d"
+        SizeToContent="WidthAndHeight"
+        x:Name="popup"
+        Background="{StaticResource AccentColor}" Foreground="White">
+
+    <WindowChrome.WindowChrome>
+        <WindowChrome CaptionHeight="32"  GlassFrameThickness="0.1"
+                      ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
+    </WindowChrome.WindowChrome>
+
+    <Grid>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="Auto"/>
+            <RowDefinition/>
+            <RowDefinition Height="Auto"/>
+        </Grid.RowDefinitions>
+
+        <local:DialogTitleBar TitleText="{Binding Title, ElementName=popup}" CloseCommand="{Binding CancelCommand, ElementName=popup}"/>
+
+        <ContentPresenter Content="{Binding PopupContent, ElementName=popup}"
+                          Grid.Row="1" Margin="15"/>
+
+        <ItemsControl ItemsSource="{Binding Options, ElementName=popup}" Grid.Row="2" Margin="15">
+            <ItemsControl.ItemTemplate>
+                <DataTemplate>
+                    <Button Content="{Binding}" Style="{StaticResource DarkRoundButton}" Margin="5,0"
+                            Command="{Binding CloseCommand, ElementName=popup}" CommandParameter="{Binding}"/>
+                </DataTemplate>
+            </ItemsControl.ItemTemplate>
+            <ItemsControl.ItemsPanel>
+                <ItemsPanelTemplate>
+                    <uc:AlignableWrapPanel HorizontalAlignment="Center" HorizontalContentAlignment="Center"/>
+                </ItemsPanelTemplate>
+            </ItemsControl.ItemsPanel>
+        </ItemsControl>
+    </Grid>
+</Window>

+ 72 - 0
PixiEditor/Views/Dialogs/OptionsPopup.xaml.cs

@@ -0,0 +1,72 @@
+using PixiEditor.Helpers;
+using System.Collections.ObjectModel;
+using System.Windows;
+
+namespace PixiEditor.Views.Dialogs
+{
+    /// <summary>
+    /// Interaction logic for AdvancedDialogPopup.xaml
+    /// </summary>
+    public partial class OptionPopup : Window
+    {
+        public static readonly DependencyProperty PopupContentProperty =
+            DependencyProperty.Register(nameof(PopupContent), typeof(object), typeof(OptionPopup));
+
+        public object PopupContent
+        {
+            get => GetValue(PopupContentProperty);
+            set => SetValue(PopupContentProperty, value);
+        }
+
+        public static readonly DependencyProperty OptionsProperty =
+            DependencyProperty.Register(nameof(Options), typeof(ObservableCollection<object>), typeof(OptionPopup));
+
+        public ObservableCollection<object> Options
+        {
+            get => (ObservableCollection<object>)GetValue(OptionsProperty);
+            set => SetValue(OptionsProperty, value);
+        }
+
+        public static readonly DependencyProperty ResultProperty =
+            DependencyProperty.Register(nameof(Result), typeof(object), typeof(OptionPopup));
+
+        public object Result
+        {
+            get => GetValue(ResultProperty);
+            set => SetValue(ResultProperty, value);
+        }
+
+        public RelayCommand CancelCommand { get; set; }
+
+        public RelayCommand CloseCommand { get; set; }
+
+        public OptionPopup(string title, object content, ObservableCollection<object> options)
+        {
+            Title = title;
+            PopupContent = content;
+            Options = options;
+            CancelCommand = new RelayCommand(Cancel);
+            CloseCommand = new RelayCommand(Close);
+            InitializeComponent();
+            ContentRendered += OptionPopup_ContentRendered;
+        }
+
+        private void OptionPopup_ContentRendered(object sender, EventArgs e)
+        {
+            InvalidateVisual();
+        }
+
+        private void Cancel(object _)
+        {
+            DialogResult = false;
+            Close();
+        }
+
+        private void Close(object parameter)
+        {
+            DialogResult = true;
+            Result = parameter;
+            Close();
+        }
+    }
+}

+ 1 - 0
PixiEditor/Views/MainWindow.xaml.cs

@@ -2,6 +2,7 @@ using Microsoft.Extensions.DependencyInjection;
 using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Dialogs;
 using PixiEditor.Models.UserPreferences;
 using PixiEditor.ViewModels;
 using System;

+ 43 - 3
PixiEditor/Views/UserControls/ShortcutBox.cs

@@ -1,4 +1,6 @@
 using PixiEditor.Models.Commands;
+using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Dialogs;
 using System.Windows;
 using System.Windows.Controls;
 
@@ -32,12 +34,50 @@ namespace PixiEditor.Views.UserControls
             }
         }
 
-        private void Box_KeyCombinationChanged(object sender, Models.DataHolders.KeyCombination e)
+        private void Box_KeyCombinationChanged(object sender, KeyCombination e)
         {
-            if (!changingCombination)
+            if (changingCombination)
             {
-                CommandController.Current.UpdateShortcut(Command, e);
+                return;
             }
+
+            changingCombination = true;
+            var controller = CommandController.Current;
+
+            if (e != KeyCombination.None)
+            {
+                if (controller.Commands[e].Any())
+                {
+                    OptionsDialog<string> dialog = new("Already assigned", $"This shortcut is already asigned to '{controller.Commands[e].First().Display}'\nDo you want to replace the shortcut or switch shortcuts?")
+                    {
+                        {
+                            "Replace", x => controller.ReplaceShortcut(Command, e) 
+                        },
+                        {
+                            "Switch", x =>
+                            {
+                                var oldCommand = controller.Commands[e].First();
+                                var oldShortcut = Command.Shortcut;
+                                controller.ReplaceShortcut(Command, e);
+                                controller.ReplaceShortcut(oldCommand, oldShortcut);
+                            }
+                        },
+                        {
+                            "Abort", x =>
+                            {
+                                box.KeyCombination = Command.Shortcut;
+                            }
+                        }
+                    };
+
+                    dialog.ShowDialog();
+                    changingCombination = false;
+                    return;
+                }
+            }
+
+            changingCombination = false;
+            controller.UpdateShortcut(Command, e);
         }
 
         private void UpdateBoxCombination()