diff --git a/src/cascadia/TerminalSettingsEditor/Actions.cpp b/src/cascadia/TerminalSettingsEditor/Actions.cpp index ffd2ae343c8..4f65c8cba8e 100644 --- a/src/cascadia/TerminalSettingsEditor/Actions.cpp +++ b/src/cascadia/TerminalSettingsEditor/Actions.cpp @@ -25,8 +25,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation KeyBindingViewModel(nullptr, availableActions.First().Current(), availableActions) {} KeyBindingViewModel::KeyBindingViewModel(const Control::KeyChord& keys, const hstring& actionName, const IObservableVector& availableActions) : - _Keys{ keys }, - _KeyChordText{ Model::KeyChordSerialization::ToString(keys) }, + _CurrentKeys{ keys }, + _KeyChordText{ KeyChordSerialization::ToString(keys) }, _CurrentAction{ actionName }, _ProposedAction{ box_value(actionName) }, _AvailableActions{ availableActions } @@ -36,9 +36,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // unique view model members. PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) { const auto viewModelProperty{ args.PropertyName() }; - if (viewModelProperty == L"Keys") + if (viewModelProperty == L"CurrentKeys") { - _KeyChordText = Model::KeyChordSerialization::ToString(_Keys); + _KeyChordText = KeyChordSerialization::ToString(_CurrentKeys); _NotifyChanges(L"KeyChordText"); } else if (viewModelProperty == L"IsContainerFocused" || @@ -75,8 +75,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // if we're in edit mode, // - pre-populate the text box with the current keys // - reset the combo box with the current action - ProposedKeys(KeyChordText()); - ProposedAction(box_value(CurrentAction())); + ProposedKeys(_CurrentKeys); + ProposedAction(box_value(_CurrentAction)); } } @@ -85,35 +85,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation AttemptAcceptChanges(_ProposedKeys); } - void KeyBindingViewModel::AttemptAcceptChanges(hstring newKeyChordText) + void KeyBindingViewModel::AttemptAcceptChanges(const Control::KeyChord newKeys) { - try - { - // empty string --> don't accept changes - if (newKeyChordText.empty()) - { - return; - } - - // ModifyKeyBindingEventArgs - const auto args{ make_self(_Keys, // OldKeys - KeyChordSerialization::FromString(newKeyChordText), // NewKeys: Attempt to convert the provided key chord text - _IsNewlyAdded ? hstring{} : _CurrentAction, // OldAction - unbox_value(_ProposedAction)) }; // - _ModifyKeyBindingRequestedHandlers(*this, *args); - } - catch (hresult_invalid_argument) - { - // Converting the text into a key chord failed. - // Don't accept the changes. - // TODO GH #6900: - // This is tricky. I still haven't found a way to reference the - // key chord text box. It's hidden behind the data template. - // Ideally, some kind of notification would alert the user, but - // to make it look nice, we need it to somehow target the text box. - // Alternatively, we want a full key chord editor/listener. - // If we implement that, we won't need this validation or error message. - } + const auto args{ make_self(_CurrentKeys, // OldKeys + newKeys, // NewKeys + _IsNewlyAdded ? hstring{} : _CurrentAction, // OldAction + unbox_value(_ProposedAction)) }; // NewAction + _ModifyKeyBindingRequestedHandlers(*this, *args); } void KeyBindingViewModel::CancelChanges() @@ -179,34 +157,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation _KeyBindingList = single_threaded_observable_vector(std::move(keyBindingList)); } - void Actions::KeyChordEditor_KeyDown(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e) - { - const auto& senderTB{ sender.as() }; - const auto& kbdVM{ senderTB.DataContext().as() }; - if (e.OriginalKey() == VirtualKey::Enter) - { - // Fun fact: this is happening _before_ "_ProposedKeys" gets updated - // with the two-way data binding. So we need to directly extract the text - // and tell the view model to update itself. - get_self(kbdVM)->AttemptAcceptChanges(senderTB.Text()); - - // For an unknown reason, when 'AcceptChangesFlyout' is set in the code above, - // the flyout isn't shown, forcing the 'Enter' key to do nothing. - // To get around this, detect if the flyout was set, and display it - // on the text box. - if (kbdVM.AcceptChangesFlyout() != nullptr) - { - kbdVM.AcceptChangesFlyout().ShowAt(senderTB); - } - e.Handled(true); - } - else if (e.OriginalKey() == VirtualKey::Escape) - { - kbdVM.CancelChanges(); - e.Handled(true); - } - } - void Actions::AddNew_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*eventArgs*/) { // Create the new key binding and register all of the event handlers. @@ -314,7 +264,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation // update view model auto senderVMImpl{ get_self(senderVM) }; - senderVMImpl->Keys(args.NewKeys()); + senderVMImpl->CurrentKeys(args.NewKeys()); } // If the action was changed, @@ -418,7 +368,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation for (uint32_t i = 0; i < _KeyBindingList.Size(); ++i) { const auto kbdVM{ get_self(_KeyBindingList.GetAt(i)) }; - const auto& otherKeys{ kbdVM->Keys() }; + const auto& otherKeys{ kbdVM->CurrentKeys() }; if (keys.Modifiers() == otherKeys.Modifiers() && keys.Vkey() == otherKeys.Vkey()) { return i; diff --git a/src/cascadia/TerminalSettingsEditor/Actions.h b/src/cascadia/TerminalSettingsEditor/Actions.h index 14d060a8a0d..9c4d37cf618 100644 --- a/src/cascadia/TerminalSettingsEditor/Actions.h +++ b/src/cascadia/TerminalSettingsEditor/Actions.h @@ -60,9 +60,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void ToggleEditMode(); void DisableEditMode() { IsInEditMode(false); } void AttemptAcceptChanges(); - void AttemptAcceptChanges(hstring newKeyChordText); + void AttemptAcceptChanges(const Control::KeyChord newKeys); void CancelChanges(); - void DeleteKeyBinding() { _DeleteKeyBindingRequestedHandlers(*this, _Keys); } + void DeleteKeyBinding() { _DeleteKeyBindingRequestedHandlers(*this, _CurrentKeys); } // ProposedAction: the entry selected by the combo box; may disagree with the settings model. // CurrentAction: the combo box item that maps to the settings model value. @@ -77,10 +77,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation VIEW_MODEL_OBSERVABLE_PROPERTY(hstring, CurrentAction); WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector, AvailableActions, nullptr); - // ProposedKeys: the text shown in the text box; may disagree with the settings model. - // Keys: the key chord bound in the settings model. - VIEW_MODEL_OBSERVABLE_PROPERTY(hstring, ProposedKeys); - VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, Keys, nullptr); + // ProposedKeys: the keys proposed by the control; may disagree with the settings model. + // CurrentKeys: the key chord bound in the settings model. + VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, ProposedKeys); + VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, CurrentKeys, nullptr); VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsInEditMode, false); VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsNewlyAdded, false); @@ -114,7 +114,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e); Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer(); - void KeyChordEditor_KeyDown(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& e); void AddNew_Click(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); diff --git a/src/cascadia/TerminalSettingsEditor/Actions.idl b/src/cascadia/TerminalSettingsEditor/Actions.idl index 98d8ee3e6f6..31c8570cce9 100644 --- a/src/cascadia/TerminalSettingsEditor/Actions.idl +++ b/src/cascadia/TerminalSettingsEditor/Actions.idl @@ -23,7 +23,7 @@ namespace Microsoft.Terminal.Settings.Editor Boolean ShowEditButton { get; }; Boolean IsInEditMode { get; }; Boolean IsNewlyAdded { get; }; - String ProposedKeys; + Microsoft.Terminal.Control.KeyChord ProposedKeys; Object ProposedAction; Windows.UI.Xaml.Controls.Flyout AcceptChangesFlyout; String EditButtonName { get; }; diff --git a/src/cascadia/TerminalSettingsEditor/Actions.xaml b/src/cascadia/TerminalSettingsEditor/Actions.xaml index d1d75c8a0bc..e4dd4ccc7a0 100644 --- a/src/cascadia/TerminalSettingsEditor/Actions.xaml +++ b/src/cascadia/TerminalSettingsEditor/Actions.xaml @@ -133,13 +133,9 @@ 32 15 @@ -202,7 +198,8 @@ Visibility="{x:Bind IsInEditMode, Mode=OneWay, Converter={StaticResource InvertedBooleanToVisibilityConverter}}" /> - - - + +