diff --git a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp index f940fe95e2..6f9bd289db 100644 --- a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp @@ -11,6 +11,7 @@ #include "KeyChordViewModel.g.cpp" #include "LibraryResources.h" #include "../TerminalSettingsModel/AllShortcutActions.h" +#include "EnumEntry.h" using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Foundation::Collections; @@ -22,6 +23,23 @@ using namespace winrt::Windows::UI::Xaml::Data; using namespace winrt::Windows::UI::Xaml::Navigation; using namespace winrt::Microsoft::Terminal::Settings::Model; +#define INITIALIZE_ENUM_LIST_AND_VALUE(enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \ + std::vector enumList; \ + const auto mappings = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::enumMappingsName(); \ + const auto unboxedValue = unbox_value(value); \ + for (const auto [enumKey, enumValue] : mappings) \ + { \ + const auto enumName = LocalizedNameForEnumName(resourceSectionAndType, enumKey, resourceProperty); \ + auto entry = winrt::make(enumName, winrt::box_value(enumValue)); \ + enumList.emplace_back(entry); \ + if (unboxedValue == enumValue) \ + { \ + EnumValue(entry); \ + } \ + } \ + std::sort(enumList.begin(), enumList.end(), EnumEntryReverseComparator()); \ + _EnumList = winrt::single_threaded_observable_vector(std::move(enumList)); + namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { KeyBindingViewModel::KeyBindingViewModel(const IObservableVector& availableActions) : @@ -153,7 +171,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation const auto emptyArgs = CascadiaSettings::GetEmptyArgsForAction(actionEnum); // todo: for sendInput, where "input" is a required argument, this will set it to an empty string which does not satisfy the requirement // i.e. if the user hits "save" immediately after switching to sendInput as the action (without adding something to the input field), they'll get an error - emptyArgs.SetRequiredArgsToDefault(); + emptyArgs.SetAllArgsToDefault(); Model::ActionAndArgs newActionAndArgs{ actionEnum, emptyArgs }; _command.ActionAndArgs(newActionAndArgs); ActionArgsVM(make(newActionAndArgs)); @@ -234,6 +252,26 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation }); } + ArgWrapper::ArgWrapper(const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value) + { + Value(value); + _type = type; + _required = required; + if (_type == L"Model::ResizeDirection") + { + INITIALIZE_ENUM_LIST_AND_VALUE(ResizeDirection, Model::ResizeDirection, L"Actions_ResizeDirection", L"Content"); + } + } + + void ArgWrapper::EnumValue(const Windows::Foundation::IInspectable& enumValue) + { + if (_EnumValue != enumValue) + { + _EnumValue = enumValue; + Value(enumValue.as().EnumValue()); + } + } + ActionArgsViewModel::ActionArgsViewModel(const Model::ActionAndArgs actionAndArgs) : _actionAndArgs{ actionAndArgs } { diff --git a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h index 542edcc774..d042dabd85 100644 --- a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h +++ b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.h @@ -168,36 +168,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation struct ArgWrapper : ArgWrapperT, ViewModelHelper { public: - ArgWrapper(const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value) - { - Value(value); - _type = type; - _required = required; - }; + ArgWrapper(const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value); - winrt::hstring Type() - { - return _type; - } + winrt::hstring Type() const noexcept { return _type; }; - bool Required() - { - return _required; - } + bool Required() const noexcept { return _required; }; - void StringBindBack(const winrt::hstring& newValue) - { - Value(box_value(newValue)); - } + Windows::Foundation::Collections::IObservableVector EnumList() const noexcept { return _EnumList; }; - void DoubleBindBack(const double newValue) - { - Value(box_value(static_cast(newValue))); - } + void StringBindBack(const winrt::hstring& newValue) { Value(box_value(newValue)); }; + + void DoubleBindBack(const double newValue) { Value(box_value(static_cast(newValue))); }; void BoolBindBack(const Windows::Foundation::IReference newValue) { - // todo: bool doesn't work fully - 3-state checkbox not working? possibly because it's binding to a bool if (newValue) { Value(box_value(newValue)); @@ -208,11 +192,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } } + // We cannot use the macro here because we need to implement additional logic for the setter + Windows::Foundation::IInspectable EnumValue() const noexcept { return _EnumValue; }; + void EnumValue(const Windows::Foundation::IInspectable& value); + VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::IInspectable, Value, nullptr); private: winrt::hstring _type; bool _required; + Windows::Foundation::IInspectable _EnumValue{ nullptr }; + Windows::Foundation::Collections::IObservableVector _EnumList; }; struct ActionArgsViewModel : ActionArgsViewModelT, ViewModelHelper diff --git a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl index a2234af954..c2845fe975 100644 --- a/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl +++ b/src/cascadia/TerminalSettingsEditor/ActionsViewModel.idl @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import "EnumEntry.idl"; + namespace Microsoft.Terminal.Settings.Editor { runtimeclass ModifyKeyBindingEventArgs @@ -79,6 +81,8 @@ namespace Microsoft.Terminal.Settings.Editor String Type { get; }; Boolean Required { get; }; IInspectable Value; + IInspectable EnumValue; + Windows.Foundation.Collections.IObservableVector EnumList { get; }; void StringBindBack(String newValue); void DoubleBindBack(Double newValue); void BoolBindBack(Windows.Foundation.IReference newValue); diff --git a/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.cpp b/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.cpp index 769df2257c..fa6a1dcdfc 100644 --- a/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.cpp +++ b/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.cpp @@ -49,6 +49,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { return UInt32Template(); } + else if (argType == L"Model::ResizeDirection") + { + return EnumTemplate(); + } else if (argType == L"Windows::Foundation::IReference") { return nullptr; diff --git a/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.h b/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.h index a078abec87..de961d0136 100644 --- a/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.h +++ b/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.h @@ -18,6 +18,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, StringTemplate); WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, BoolTemplate); WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, BoolOptionalTemplate); + WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, EnumTemplate); }; } diff --git a/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.idl b/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.idl index 928876afcb..3e2c97bd53 100644 --- a/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.idl +++ b/src/cascadia/TerminalSettingsEditor/ArgsTemplateSelectors.idl @@ -11,5 +11,6 @@ namespace Microsoft.Terminal.Settings.Editor Windows.UI.Xaml.DataTemplate StringTemplate; Windows.UI.Xaml.DataTemplate BoolTemplate; Windows.UI.Xaml.DataTemplate BoolOptionalTemplate; + Windows.UI.Xaml.DataTemplate EnumTemplate; } } diff --git a/src/cascadia/TerminalSettingsEditor/EditAction.xaml b/src/cascadia/TerminalSettingsEditor/EditAction.xaml index 9469997edc..e113114e71 100644 --- a/src/cascadia/TerminalSettingsEditor/EditAction.xaml +++ b/src/cascadia/TerminalSettingsEditor/EditAction.xaml @@ -267,11 +267,30 @@ + + + + + + + + + + + + + BoolOptionalTemplate="{StaticResource BoolOptionalTemplate}" + EnumTemplate="{StaticResource EnumTemplate}" /> + diff --git a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw index 5ed167e493..f813fa9139 100644 --- a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw @@ -1844,6 +1844,26 @@ Action Label for a control that sets the action of a key binding. + + None + An option to choose from for the "resize direction". None option. + + + Left + An option to choose from for the "resize direction". Left option. + + + Right + An option to choose from for the "resize direction". Right option. + + + Up + An option to choose from for the "resize direction". Up option. + + + Down + An option to choose from for the "resize direction". Down option. + Send input One of the possible shortcut action types. This represents the "Send input" action. diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp index 2d39c19d16..75e5f8f99e 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp @@ -998,6 +998,10 @@ Model::IActionArgs CascadiaSettings::GetEmptyArgsForAction(Model::ShortcutAction { switch (shortcutAction) { + case Model::ShortcutAction::SwitchToTab: + return winrt::make(); + case Model::ShortcutAction::ResizePane: + return winrt::make(); case Model::ShortcutAction::SendInput: return winrt::make(); case Model::ShortcutAction::MovePane: