From 5a188c220e9c8ecbb8e7782ac22bc78c1e9a21a4 Mon Sep 17 00:00:00 2001 From: Pankaj Bhojwani Date: Tue, 17 Sep 2024 18:35:40 -0700 Subject: [PATCH] start of modify keybinding --- .../ActionsViewModel.cpp | 116 ++++++++++----- .../TerminalSettingsEditor/ActionsViewModel.h | 30 +++- .../ActionsViewModel.idl | 17 +++ .../TerminalSettingsEditor/EditAction.xaml | 133 ++++++++++++++++-- 4 files changed, 246 insertions(+), 50 deletions(-) diff --git a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp index 249e812cc5..24ba9b9fab 100644 --- a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp @@ -69,17 +69,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void KeyBindingViewModel::ToggleEditMode() { - IsInEditMode(true); - //// toggle edit mode - //IsInEditMode(!_IsInEditMode); - //if (_IsInEditMode) - //{ - // // if we're in edit mode, - // // - pre-populate the text box with the current keys - // // - reset the combo box with the current action - // ProposedKeys(_CurrentKeys); - // ProposedAction(box_value(_CurrentAction)); - //} + // toggle edit mode + IsInEditMode(!_IsInEditMode); + if (_IsInEditMode) + { + // if we're in edit mode, + // - pre-populate the text box with the current keys + // - reset the combo box with the current action + ProposedKeys(_CurrentKeys); + ProposedAction(box_value(_CurrentAction)); + } } void KeyBindingViewModel::AttemptAcceptChanges() @@ -108,15 +107,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } } - CommandViewModel::CommandViewModel(Command cmd, std::vector keyChordList) : - _command{ cmd } + CommandViewModel::CommandViewModel(Command cmd, std::vector keyChordList, const Editor::ActionsViewModel actionsPageVM) : + _command{ cmd }, + _actionsPageVM{ actionsPageVM } { std::vector keyChordVMs; for (const auto keys : keyChordList) { - auto container{ make_self(keys) }; - //_RegisterEvents(container); todo: implement the event handlers - keyChordVMs.push_back(*container); + auto kcVM{ make(keys) }; + _RegisterEvents(kcVM); + keyChordVMs.push_back(kcVM); } _KeyChordViewModelList = single_threaded_observable_vector(std::move(keyChordVMs)); } @@ -152,11 +152,45 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation EditRequested.raise(*this, *this); } + void CommandViewModel::_RegisterEvents(Editor::KeyChordViewModel kcVM) + { + if (const auto actionsPageVM{ _actionsPageVM.get() }) + { + kcVM.ModifyKeyChordRequested([actionsPageVM](const Editor::KeyChordViewModel& sender, const Editor::ModifyKeyChordEventArgs& args) { + actionsPageVM.AttemptModifyKeyBinding(sender, args); + }); + } + } + KeyChordViewModel::KeyChordViewModel(Control::KeyChord currentKeys) : _CurrentKeys{ currentKeys } { } + void KeyChordViewModel::ToggleEditMode() + { + // toggle edit mode + IsInEditMode(!_IsInEditMode); + if (_IsInEditMode) + { + // if we're in edit mode, + // - pre-populate the text box with the current keys + ProposedKeys(_CurrentKeys); + } + } + + void KeyChordViewModel::AttemptAcceptChanges() + { + const auto args{ make_self(_CurrentKeys, // OldKeys + _ProposedKeys) }; // NewKeys + ModifyKeyChordRequested.raise(*this, *args); + } + + void KeyChordViewModel::CancelChanges() + { + ToggleEditMode(); + } + ActionsViewModel::ActionsViewModel(Model::CascadiaSettings settings) : _Settings{ settings } { @@ -187,7 +221,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation std::vector keyChordList; // todo: need to loop through all the keybindings that point to this command here keyChordList.emplace_back(keys); - auto cmdVM{ make_self(cmd, keyChordList) }; + auto cmdVM{ make_self(cmd, keyChordList, *this) }; _RegisterCmdVMEvents(cmdVM); commandList.push_back(*cmdVM); } @@ -240,6 +274,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation return _CurrentCommand; } + void ActionsViewModel::AttemptModifyKeyBinding(const Editor::KeyChordViewModel& senderVM, const Editor::ModifyKeyChordEventArgs& /*args*/) + { + senderVM.ToggleEditMode(); + } + void ActionsViewModel::_KeyBindingViewModelPropertyChangedHandler(const IInspectable& sender, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args) { const auto senderVM{ sender.as() }; @@ -248,32 +287,31 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { if (senderVM.IsInEditMode()) { - CurrentPage(ActionsSubPage::Edit); // Ensure that... // 1. we move focus to the edit mode controls // 2. any actions that were newly added are removed // 3. this is the only entry that is in edit mode - //for (int32_t i = _KeyBindingList.Size() - 1; i >= 0; --i) - //{ - // const auto& kbdVM{ _KeyBindingList.GetAt(i) }; - // if (senderVM == kbdVM) - // { - // // This is the view model entry that went into edit mode. - // // Emit an event to let the page know to move focus to - // // this VM's container. - // FocusContainer.raise(*this, senderVM); - // } - // else if (kbdVM.IsNewlyAdded()) - // { - // // Remove any actions that were newly added - // _KeyBindingList.RemoveAt(i); - // } - // else - // { - // // Exit edit mode for all other containers - // get_self(kbdVM)->DisableEditMode(); - // } - //} + for (int32_t i = _KeyBindingList.Size() - 1; i >= 0; --i) + { + const auto& kbdVM{ _KeyBindingList.GetAt(i) }; + if (senderVM == kbdVM) + { + // This is the view model entry that went into edit mode. + // Emit an event to let the page know to move focus to + // this VM's container. + FocusContainer.raise(*this, senderVM); + } + else if (kbdVM.IsNewlyAdded()) + { + // Remove any actions that were newly added + _KeyBindingList.RemoveAt(i); + } + else + { + // Exit edit mode for all other containers + get_self(kbdVM)->DisableEditMode(); + } + } } else { diff --git a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h index 0ab5f9df8a..fb936ab1e1 100644 --- a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h +++ b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h @@ -8,6 +8,7 @@ #include "CommandViewModel.g.h" #include "KeyChordViewModel.g.h" #include "ModifyKeyBindingEventArgs.g.h" +#include "ModifyKeyChordEventArgs.g.h" #include "Utils.h" #include "ViewModelHelpers.h" @@ -44,6 +45,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation WINRT_PROPERTY(hstring, NewActionName); }; + struct ModifyKeyChordEventArgs : ModifyKeyChordEventArgsT + { + public: + ModifyKeyChordEventArgs(const Control::KeyChord& oldKeys, const Control::KeyChord& newKeys) : + _OldKeys{ oldKeys }, + _NewKeys{ newKeys } {} + + WINRT_PROPERTY(Control::KeyChord, OldKeys, nullptr); + WINRT_PROPERTY(Control::KeyChord, NewKeys, nullptr); + }; + struct KeyBindingViewModel : KeyBindingViewModelT, ViewModelHelper { public: @@ -112,7 +124,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation struct CommandViewModel : CommandViewModelT, ViewModelHelper { public: - CommandViewModel(winrt::Microsoft::Terminal::Settings::Model::Command cmd, std::vector keyChordList); + CommandViewModel(winrt::Microsoft::Terminal::Settings::Model::Command cmd, + std::vector keyChordList, + const Editor::ActionsViewModel actionsPageVM); winrt::hstring Name(); void Name(const winrt::hstring& newName); @@ -129,6 +143,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation private: winrt::Microsoft::Terminal::Settings::Model::Command _command; + weak_ref _actionsPageVM{ nullptr }; + void _RegisterEvents(Editor::KeyChordViewModel kcVM); }; struct KeyChordViewModel : KeyChordViewModelT, ViewModelHelper @@ -138,6 +154,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation hstring KeyChordText() { return Model::KeyChordSerialization::ToString(_CurrentKeys); }; + void ToggleEditMode(); + void AttemptAcceptChanges(); + void CancelChanges(); + + VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsInEditMode, false); + VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, ProposedKeys); + + public: + til::typed_event ModifyKeyChordRequested; + private: Control::KeyChord _CurrentKeys; }; @@ -153,6 +179,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void CurrentCommand(const Editor::CommandViewModel& newCommand); Editor::CommandViewModel CurrentCommand(); + void AttemptModifyKeyBinding(const Editor::KeyChordViewModel& senderVM, const Editor::ModifyKeyChordEventArgs& args); + til::typed_event FocusContainer; til::typed_event UpdateBackground; diff --git a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl index 8e82fce358..0d2d86c639 100644 --- a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl +++ b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl @@ -11,6 +11,12 @@ namespace Microsoft.Terminal.Settings.Editor String NewActionName { get; }; } + runtimeclass ModifyKeyChordEventArgs + { + Microsoft.Terminal.Control.KeyChord OldKeys { get; }; + Microsoft.Terminal.Control.KeyChord NewKeys { get; }; + } + runtimeclass KeyBindingViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged { // Settings Model side @@ -63,6 +69,15 @@ namespace Microsoft.Terminal.Settings.Editor runtimeclass KeyChordViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged { String KeyChordText { get; }; + + // UI side + Microsoft.Terminal.Control.KeyChord ProposedKeys; + Boolean IsInEditMode { get; }; + void ToggleEditMode(); + void AttemptAcceptChanges(); + void CancelChanges(); + + event Windows.Foundation.TypedEventHandler ModifyKeyChordRequested; } enum ActionsSubPage @@ -85,6 +100,8 @@ namespace Microsoft.Terminal.Settings.Editor ActionsSubPage CurrentPage; CommandViewModel CurrentCommand; + void AttemptModifyKeyBinding(KeyChordViewModel senderVM, ModifyKeyChordEventArgs args); + IObservableVector CommandList { get; }; } } diff --git a/src/cascadia/TerminalSettingsEditor/EditAction.xaml b/src/cascadia/TerminalSettingsEditor/EditAction.xaml index 24653d1258..ee28930487 100644 --- a/src/cascadia/TerminalSettingsEditor/EditAction.xaml +++ b/src/cascadia/TerminalSettingsEditor/EditAction.xaml @@ -26,6 +26,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 32 + 15 + + - + + + + + + + + + + + + +