diff --git a/docs/Changelog.md b/docs/Changelog.md index 2233be1..7dce404 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -26,7 +26,7 @@ customizing the conf directory location. - Improved support for third party osc scripts like uosc. - Support of the mpv property `focused`. -- Fix Ctrl+Alt and right mouse button usage in input learn window. +- Various improvements and fixes in the input bindings editor. # v6.0.3.2 Beta (2022-10-14) diff --git a/src/MpvNet.Windows/Conf.cs b/src/MpvNet.Windows/Conf.cs index 700f361..844c1b4 100644 --- a/src/MpvNet.Windows/Conf.cs +++ b/src/MpvNet.Windows/Conf.cs @@ -82,7 +82,7 @@ public class ConfParser { public static List Parse(string content) { - string[] lines = content.Split(new[] { "\r\n" }, StringSplitOptions.None); + string[] lines = content.Split('\n'); var sections = new List(); ConfSection? currentGroup = null; diff --git a/src/MpvNet.Windows/GuiCommand.cs b/src/MpvNet.Windows/GuiCommand.cs index 681d6fe..97fb9fb 100644 --- a/src/MpvNet.Windows/GuiCommand.cs +++ b/src/MpvNet.Windows/GuiCommand.cs @@ -52,8 +52,7 @@ public class GuiCommand ["show-commands"] = args => ShowCommands(), // deprecated ["show-history"] = args => ShowHistory(), // deprecated ["show-playlist"] = args => ShowPlaylist(), // deprecated - - //["show-command-palette"] = args => ShowCommandPalette(), + ["show-command-palette"] = args => ShowCommandPalette(), // deprecated }; public void ShowDialog(Type winType) @@ -294,4 +293,9 @@ public class GuiCommand public void ShowPlaylist() => Msg.ShowInfo("This feature was moved to a user script,\nwhich can be found here:\n\n" + "https://github.com/stax76/mpv-scripts#command_palette"); + + // deprecated + public void ShowCommandPalette() => + Msg.ShowInfo("This feature was moved to a user script,\nwhich can be found here:\n\n" + + "https://github.com/stax76/mpv-scripts#command_palette"); } diff --git a/src/MpvNet.Windows/UI/Theme.cs b/src/MpvNet.Windows/UI/Theme.cs index 97f42df..02efb12 100644 --- a/src/MpvNet.Windows/UI/Theme.cs +++ b/src/MpvNet.Windows/UI/Theme.cs @@ -23,6 +23,13 @@ public class Theme public Brush? MenuBackground { get; set; } public Brush? MenuHighlight { get; set; } + public Color BackgroundColor { get; set; } + public Color ForegroundColor { get; set; } + public Color Foreground2Color { get; set; } + public Color HeadingColor { get; set; } + public Color MenuBackgroundColor { get; set; } + public Color MenuHighlightColor { get; set; } + public Brush GetBrush(string key) { return new SolidColorBrush((Color)ColorConverter.ConvertFromString(Dictionary[key])); @@ -84,6 +91,13 @@ public class Theme Current.Heading = Current.GetBrush("heading"); Current.MenuBackground = Current.GetBrush("menu-background"); Current.MenuHighlight = Current.GetBrush("menu-highlight"); + + Current.BackgroundColor = Current.GetColor("background"); + Current.ForegroundColor = Current.GetColor("foreground"); + Current.Foreground2Color = Current.GetColor("foreground2"); + Current.HeadingColor = Current.GetColor("heading"); + Current.MenuBackgroundColor = Current.GetColor("menu-background"); + Current.MenuHighlightColor = Current.GetColor("menu-highlight"); } static List Load(string? content) @@ -91,12 +105,12 @@ public class Theme List list = new List(); Theme? theme = null; - foreach (string currentLine in (content ?? "").Split(new[] { '\r', '\n' })) + foreach (string currentLine in (content ?? "").Split('\r', '\n')) { string line = currentLine.Trim(); if (line.StartsWith("[") && line.EndsWith("]")) - list.Add(theme = new Theme() { Name = line.Substring(1, line.Length - 2).Trim() }); + list.Add(theme = new Theme() { Name = line[1..^1].Trim() }); if (line.Contains('=') && theme != null) { diff --git a/src/MpvNet.Windows/WPF/ConfWindow.xaml b/src/MpvNet.Windows/WPF/ConfWindow.xaml index 451f01f..0ea61b7 100644 --- a/src/MpvNet.Windows/WPF/ConfWindow.xaml +++ b/src/MpvNet.Windows/WPF/ConfWindow.xaml @@ -46,7 +46,7 @@ diff --git a/src/MpvNet.Windows/WPF/ConfWindow.xaml.cs b/src/MpvNet.Windows/WPF/ConfWindow.xaml.cs index 5f344fe..3a60529 100644 --- a/src/MpvNet.Windows/WPF/ConfWindow.xaml.cs +++ b/src/MpvNet.Windows/WPF/ConfWindow.xaml.cs @@ -82,7 +82,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged public static TreeNode? AddNode(IList nodes, string path) { - string[] parts = path.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries); + string[] parts = path.Split('/', StringSplitOptions.RemoveEmptyEntries); for (int x = 0; x < parts.Length; x++) { @@ -416,7 +416,7 @@ public partial class ConfWindow : Window, INotifyPropertyChanged if (e.Key == Key.Escape) Close(); - if (e.Key == Key.F3 || e.Key == Key.F6 || (e.Key == Key.F && Keyboard.IsKeyDown(Key.LeftCtrl))) + if (e.Key == Key.F3 || e.Key == Key.F6 || (e.Key == Key.F && Keyboard.Modifiers == ModifierKeys.Control)) { Keyboard.Focus(SearchControl.SearchTextBox); SearchControl.SearchTextBox.SelectAll(); diff --git a/src/MpvNet.Windows/WPF/Controls/CommandPaletteControl.xaml b/src/MpvNet.Windows/WPF/Controls/CommandPaletteControl.xaml index e989a8d..be9fadb 100644 --- a/src/MpvNet.Windows/WPF/Controls/CommandPaletteControl.xaml +++ b/src/MpvNet.Windows/WPF/Controls/CommandPaletteControl.xaml @@ -46,15 +46,16 @@ /> - + - - - @@ -81,17 +34,16 @@ - + + + + + + - + - - - - - - - + + + + + + - + diff --git a/src/MpvNet.Windows/WPF/InputWindow.xaml.cs b/src/MpvNet.Windows/WPF/InputWindow.xaml.cs index ba097eb..2e9e950 100644 --- a/src/MpvNet.Windows/WPF/InputWindow.xaml.cs +++ b/src/MpvNet.Windows/WPF/InputWindow.xaml.cs @@ -4,6 +4,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; + using MpvNet.Windows.UI; namespace MpvNet.Windows.WPF; @@ -14,6 +15,7 @@ public partial class InputWindow : Window string StartupContent; public List Bindings { get; } public Theme? Theme => Theme.Current; + Binding? _focusedBinding; public InputWindow() { @@ -34,23 +36,6 @@ public partial class InputWindow : Window DataGrid.ItemsSource = CollectionView; } - void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) - { - CollectionView.Refresh(); - - if (SearchControl.SearchTextBox.Text == "?") - { - SearchControl.SearchTextBox.Text = ""; - - Msg.ShowInfo("Filtering" + BR2 + - "Reduce the filter scope with:" + BR2 + - "i input" + BR2 + - "m menu" + BR2 + - "c command" + BR2 + - "If only one character is entered input search is performed."); - } - } - bool Filter(Binding item) { if (item.Command == "") @@ -86,18 +71,43 @@ public partial class InputWindow : Window return false; } - void ButtonClick(object sender, RoutedEventArgs e) + void ShowLearnWindow(Binding? binding) { - Binding? item = ((Button)e.Source).DataContext as Binding; - - if (item == null) - return; - LearnWindow window = new LearnWindow(); window.Owner = this; - window.InputItem = item; + window.InputItem = binding; window.ShowDialog(); - Keyboard.Focus(SearchControl.SearchTextBox); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + + if (e.Key == Key.Escape) + Close(); + + if (e.Key == Key.F3 || e.Key == Key.F6 || (e.Key == Key.F && Keyboard.Modifiers == ModifierKeys.Control)) + { + Keyboard.Focus(SearchControl.SearchTextBox); + SearchControl.SearchTextBox.SelectAll(); + } + } + + void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e) + { + CollectionView.Refresh(); + + if (SearchControl.SearchTextBox.Text == "?") + { + SearchControl.SearchTextBox.Text = ""; + + Msg.ShowInfo("Filtering" + BR2 + + "Reduce the filter scope with:" + BR2 + + "i input" + BR2 + + "m menu" + BR2 + + "c command" + BR2 + + "If only one character is entered input search is performed."); + } } void Window_Loaded(object sender, RoutedEventArgs e) => Keyboard.Focus(SearchControl.SearchTextBox); @@ -120,26 +130,37 @@ public partial class InputWindow : Window Msg.ShowInfo("Changes will be available on next startup."); } - void DataGrid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e) + void DataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) { - DataGrid grid = (DataGrid)sender; - - if (e.Command == DataGrid.DeleteCommand) - if (Msg.ShowQuestion($"Confirm to delete: {(grid.SelectedItem as Binding)!.Input} ({(grid.SelectedItem as Binding)!.Path})") != MessageBoxResult.OK) - e.Handled = true; + if (e.Column.DisplayIndex == 1) + e.Cancel = true; } - protected override void OnKeyDown(KeyEventArgs e) + void DataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { - base.OnKeyDown(e); + if (e.AddedCells.Count > 0) + _focusedBinding = e.AddedCells[0].Item as Binding; + } - if (e.Key == Key.Escape) - Close(); + void DataGridCell_PreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Enter) + e.Handled = true; - if (e.Key == Key.F3 || e.Key == Key.F6 || (e.Key == Key.F && Keyboard.IsKeyDown(Key.LeftCtrl))) + switch (e.Key) { - Keyboard.Focus(SearchControl.SearchTextBox); - SearchControl.SearchTextBox.SelectAll(); + case Key.Left: + case Key.Up: + case Key.Right: + case Key.Down: + case Key.Tab: + break; + default: + ShowLearnWindow(_focusedBinding); + break; } } + + void DataGridCell_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) => + ShowLearnWindow(_focusedBinding); } diff --git a/src/MpvNet.Windows/WPF/LearnWindow.xaml b/src/MpvNet.Windows/WPF/LearnWindow.xaml index c31a25b..4d23d4d 100644 --- a/src/MpvNet.Windows/WPF/LearnWindow.xaml +++ b/src/MpvNet.Windows/WPF/LearnWindow.xaml @@ -7,9 +7,9 @@ mc:Ignorable="d" Title="Learn Input" - Height="150" - Width="350" - FontSize="16" + Height="200" + Width="400" + FontSize="15" WindowStartupLocation="CenterOwner" ResizeMode="NoResize" Loaded="Window_Loaded" @@ -17,7 +17,7 @@ Background="{Binding Theme.Background}" MouseWheel="Window_MouseWheel" MouseUp="Window_MouseUp" - MouseDoubleClick="Window_MouseDoubleClick" PreviewKeyDown="Window_PreviewKeyDown" + MouseDoubleClick="Window_MouseDoubleClick" > @@ -30,25 +30,27 @@ + + >Waiting for key/mouse input. - - - + + + + \ No newline at end of file diff --git a/src/MpvNet.Windows/WPF/LearnWindow.xaml.cs b/src/MpvNet.Windows/WPF/LearnWindow.xaml.cs index b38ff7b..30482f7 100644 --- a/src/MpvNet.Windows/WPF/LearnWindow.xaml.cs +++ b/src/MpvNet.Windows/WPF/LearnWindow.xaml.cs @@ -102,8 +102,11 @@ public partial class LearnWindow : Window bool firstEmpty = false; Keys key = (Keys)vk; - if (key == Keys.ControlKey || key == Keys.ShiftKey || - key == Keys.Menu || key == Keys.None) + if (key == Keys.ControlKey || + key == Keys.ShiftKey || + key == Keys.Menu || + key == Keys.None || + key == Keys.Tab) return; @@ -189,7 +192,6 @@ public partial class LearnWindow : Window void SetKey(string? key) { NewKey = key!; - MenuTextBlock.Text = InputItem?.Path; KeyTextBlock.Text = key; } @@ -229,6 +231,8 @@ public partial class LearnWindow : Window Close(); } + void CancelButton_Click(object sender, RoutedEventArgs e) => Close(); + void Window_MouseWheel(object sender, MouseWheelEventArgs e) { if (e.Delta > 0) @@ -280,15 +284,6 @@ public partial class LearnWindow : Window } } - void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) - { - if (e.Key == Key.Tab) - { - OnKeyDown((uint)Keys.Tab); - e.Handled = true; - } - } - string GetModifierText() { string ret = ""; diff --git a/src/MpvNet.Windows/WPF/Resources.xaml b/src/MpvNet.Windows/WPF/Resources.xaml index be7411d..666c04f 100644 --- a/src/MpvNet.Windows/WPF/Resources.xaml +++ b/src/MpvNet.Windows/WPF/Resources.xaml @@ -13,15 +13,17 @@ - + - + diff --git a/src/MpvNet.Windows/WinForms/MainForm.cs b/src/MpvNet.Windows/WinForms/MainForm.cs index 30c2963..bcf9355 100644 --- a/src/MpvNet.Windows/WinForms/MainForm.cs +++ b/src/MpvNet.Windows/WinForms/MainForm.cs @@ -735,6 +735,9 @@ public partial class MainForm : Form foreach (Binding binding in App.InputConf.GetMenuBindings()) { + if (!binding.IsMenu) + continue; + Binding tempBinding = binding; var menuItem = MenuHelp.Add(ContextMenu?.Items, tempBinding.Path); @@ -1209,8 +1212,6 @@ public partial class MainForm : Form TaskHelp.Run(WinMpvHelp.CopyMpvNetCom); WasShown = true; StrongReferenceMessenger.Default.Send(new MainWindowIsLoadedMessage()); - //Player.Command("script-message-to mpvnet show-conf-editor"); - //testwin.ShowDialog(); } void ContextMenu_Closed(object sender, System.Windows.RoutedEventArgs e) => MenuAutoResetEvent.Set(); diff --git a/src/MpvNet/Binding.cs b/src/MpvNet/Binding.cs index 7c6c692..25f32bd 100644 --- a/src/MpvNet/Binding.cs +++ b/src/MpvNet/Binding.cs @@ -11,9 +11,11 @@ public class Binding : ObservableObject public bool IsMenu { get; set; } + string _input = ""; + public Binding() { - Path = ""; Command = ""; Comment = ""; + Path = Command = Comment = Input = ""; } public Binding(string folder = "", @@ -23,9 +25,15 @@ public class Binding : ObservableObject string comment = "") { if (folder != "" && name != "") + { Path = folder + " > " + name; + IsMenu = true; + } else if (name != "") + { Path = name; + IsMenu = true; + } else Path = ""; @@ -34,11 +42,11 @@ public class Binding : ObservableObject Comment = comment == "" ? Path : comment; } - string _input = ""; - public string Input { get => _input; set => SetProperty(ref _input, value); } + + public bool IsEmpty() => Path == "" && Command == "" && Comment == "" && Input == ""; } diff --git a/src/MpvNet/InputHelp.cs b/src/MpvNet/InputHelp.cs index 5d0c3d6..672588c 100644 --- a/src/MpvNet/InputHelp.cs +++ b/src/MpvNet/InputHelp.cs @@ -195,20 +195,35 @@ public static class InputHelp foreach (Binding binding in bindings) { - string cmd = binding.Command.Trim(); + if (binding.IsEmpty()) + { + sb.AppendLine(); + continue; + } + + if (binding.Comment != "" && + binding.Command == "" && + binding.Input == "" && + binding.Path == "") + { + sb.AppendLine("#" + binding.Comment.Trim()); + continue; + } + + string command = binding.Command.Trim(); string input = binding.Input.Trim(); - string comment = binding.IsMenu ? "menu: " + binding.Path : binding.Comment.Trim(); + string comment = binding.IsMenu ? "menu: " + binding.Path : binding.Path.Trim(); input = input == "" ? "_" : input; string line = input.PadRight(10) + " "; - line += cmd == "" ? "ignore" : cmd; - + line += command == "" ? "ignore" : command; + if (comment != "") - line = line.PadRight(40) + " # " + comment; + line = line.PadRight(40) + " #" + comment; sb.AppendLine(line); } - return sb.ToString(); + return sb.ToString().TrimEnd() + BR; } public static List Parse(string content) @@ -218,14 +233,25 @@ public static class InputHelp if (string.IsNullOrEmpty(content)) return bindings; - foreach (string it in content.Split('\r', '\n')) + foreach (string it in content.Split('\n')) { string line = it.Trim(); - if (line.StartsWith("#") || !line.Contains(' ')) - continue; - Binding binding = new Binding(); + + if (line == "") + { + bindings.Add(binding); + continue; + } + + if (line.StartsWith("#")) + { + binding.Comment = line[1..].Trim(); + bindings.Add(binding); + continue; + } + binding.Input = line[..line.IndexOf(" ")]; if (binding.Input == "_") @@ -260,7 +286,7 @@ public static class InputHelp } else if (line.Contains('#')) { - binding.Comment = line[(line.IndexOf("#") + 1)..].Trim(); + binding.Path = line[(line.IndexOf("#") + 1)..].Trim(); line = line[..line.IndexOf("#")]; } @@ -325,6 +351,7 @@ public static class InputHelp return defaults; } + // only used by dead command palette public static List GetBindingsFromContent(string content) { var bindings = new List();