access maps through page vm

This commit is contained in:
Pankaj Bhojwani 2025-06-19 15:01:53 -07:00
parent ad0f79dbb8
commit 849eb1df4d
3 changed files with 66 additions and 38 deletions

View File

@ -189,16 +189,22 @@ inline const std::set<winrt::Microsoft::Terminal::Settings::Model::ShortcutActio
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{ {
CommandViewModel::CommandViewModel(Command cmd, std::vector<Control::KeyChord> keyChordList, const Editor::ActionsViewModel actionsPageVM, const Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring>& availableShortcutActionsAndNames) : CommandViewModel::CommandViewModel(Command cmd, std::vector<Control::KeyChord> keyChordList, const Editor::ActionsViewModel actionsPageVM) :
_command{ cmd }, _command{ cmd },
_keyChordList{ keyChordList }, _keyChordList{ keyChordList },
_actionsPageVM{ actionsPageVM }, _actionsPageVM{ actionsPageVM }
_AvailableActionsAndNamesMap{ availableShortcutActionsAndNames }
{ {
} }
void CommandViewModel::Initialize() void CommandViewModel::Initialize()
{ {
const auto actionsPageVM{ _actionsPageVM.get() };
if (!actionsPageVM)
{
// The parent page is gone, just return early
return;
}
const auto shortcutActionsAndNames = actionsPageVM.AvailableShortcutActionsAndNames();
std::vector<Editor::KeyChordViewModel> keyChordVMs; std::vector<Editor::KeyChordViewModel> keyChordVMs;
for (const auto keys : _keyChordList) for (const auto keys : _keyChordList)
{ {
@ -209,43 +215,45 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_KeyChordViewModelList = single_threaded_observable_vector(std::move(keyChordVMs)); _KeyChordViewModelList = single_threaded_observable_vector(std::move(keyChordVMs));
std::vector<hstring> shortcutActions; std::vector<hstring> shortcutActions;
for (const auto [action, name] : _AvailableActionsAndNamesMap) for (const auto [action, name] : shortcutActionsAndNames)
{ {
shortcutActions.emplace_back(name); shortcutActions.emplace_back(name);
_NameToActionMap.emplace(name, action);
} }
std::sort(shortcutActions.begin(), shortcutActions.end()); std::sort(shortcutActions.begin(), shortcutActions.end());
_AvailableShortcutActions = single_threaded_observable_vector(std::move(shortcutActions)); _AvailableShortcutActions = single_threaded_observable_vector(std::move(shortcutActions));
const auto shortcutActionString = _AvailableActionsAndNamesMap.Lookup(_command.ActionAndArgs().Action()); const auto shortcutActionString = shortcutActionsAndNames.Lookup(_command.ActionAndArgs().Action());
ProposedShortcutActionName(winrt::box_value(shortcutActionString)); ProposedShortcutActionName(winrt::box_value(shortcutActionString));
_CreateAndInitializeActionArgsVMHelper(); _CreateAndInitializeActionArgsVMHelper();
// Add a property changed handler to our own property changed event. // Add a property changed handler to our own property changed event.
// This allows us to create a new ActionArgsVM when the shortcut action changes // This allows us to create a new ActionArgsVM when the shortcut action changes
PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) { PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
const auto viewModelProperty{ args.PropertyName() }; if (const auto actionsPageVM{ _actionsPageVM.get() })
if (viewModelProperty == L"ProposedShortcutActionName")
{ {
const auto actionString = unbox_value<hstring>(ProposedShortcutActionName()); const auto viewModelProperty{ args.PropertyName() };
const auto actionEnum = _NameToActionMap.at(actionString); if (viewModelProperty == L"ProposedShortcutActionName")
const auto emptyArgs = ActionArgFactory::GetEmptyArgsForAction(actionEnum);
// todo: probably need some better default values for empty args
// eg. for sendInput, where "input" is a required argument, "input" gets set 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
// there are some other cases as well
Model::ActionAndArgs newActionAndArgs{ actionEnum, emptyArgs };
_command.ActionAndArgs(newActionAndArgs);
if (_IsNewCommand)
{ {
_command.GenerateID(); const auto actionString = unbox_value<hstring>(ProposedShortcutActionName());
const auto actionEnum = actionsPageVM.NameToActionMap().Lookup(actionString);
const auto emptyArgs = ActionArgFactory::GetEmptyArgsForAction(actionEnum);
// todo: probably need some better default values for empty args
// eg. for sendInput, where "input" is a required argument, "input" gets set 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
// there are some other cases as well
Model::ActionAndArgs newActionAndArgs{ actionEnum, emptyArgs };
_command.ActionAndArgs(newActionAndArgs);
if (_IsNewCommand)
{
_command.GenerateID();
}
else if (!IsUserAction())
{
_ReplaceCommandWithUserCopy(true);
return;
}
_CreateAndInitializeActionArgsVMHelper();
} }
else if (!IsUserAction())
{
_ReplaceCommandWithUserCopy(true);
return;
}
_CreateAndInitializeActionArgsVMHelper();
} }
}); });
} }
@ -999,9 +1007,32 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
ActionsViewModel::ActionsViewModel(Model::CascadiaSettings settings) : ActionsViewModel::ActionsViewModel(Model::CascadiaSettings settings) :
_Settings{ settings } _Settings{ settings }
{ {
// Initialize the action->name and name->action maps before initializing the CommandVMs, they're going to need the maps
_AvailableActionsAndNamesMap = Model::ActionArgFactory::AvailableShortcutActionsAndNames();
for (const auto unimplemented : UnimplementedShortcutActions)
{
_AvailableActionsAndNamesMap.Remove(unimplemented);
}
std::unordered_map<winrt::hstring, Model::ShortcutAction> actionNames;
for (const auto [action, name] : _AvailableActionsAndNamesMap)
{
actionNames.emplace(name, action);
}
_NameToActionMap = winrt::single_threaded_map(std::move(actionNames));
_MakeCommandVMsHelper(); _MakeCommandVMsHelper();
} }
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> ActionsViewModel::AvailableShortcutActionsAndNames()
{
return _AvailableActionsAndNamesMap;
}
Windows::Foundation::Collections::IMap<winrt::hstring, Model::ShortcutAction> ActionsViewModel::NameToActionMap()
{
return _NameToActionMap;
}
void ActionsViewModel::UpdateSettings(const Model::CascadiaSettings& settings) void ActionsViewModel::UpdateSettings(const Model::CascadiaSettings& settings)
{ {
_Settings = settings; _Settings = settings;
@ -1047,13 +1078,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void ActionsViewModel::_MakeCommandVMsHelper() void ActionsViewModel::_MakeCommandVMsHelper()
{ {
// Populate AvailableActionsAndNames
_AvailableActionsAndNamesMap = Model::ActionArgFactory::AvailableShortcutActionsAndNames();
for (const auto unimplemented : UnimplementedShortcutActions)
{
_AvailableActionsAndNamesMap.Remove(unimplemented);
}
const auto& allCommands{ _Settings.ActionMap().AllCommands() }; const auto& allCommands{ _Settings.ActionMap().AllCommands() };
std::vector<Editor::CommandViewModel> commandList; std::vector<Editor::CommandViewModel> commandList;
commandList.reserve(allCommands.Size()); commandList.reserve(allCommands.Size());
@ -1066,7 +1090,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{ {
keyChordList.emplace_back(keys); keyChordList.emplace_back(keys);
} }
auto cmdVM{ make_self<CommandViewModel>(cmd, keyChordList, *this, _AvailableActionsAndNamesMap) }; auto cmdVM{ make_self<CommandViewModel>(cmd, keyChordList, *this) };
_RegisterCmdVMEvents(cmdVM); _RegisterCmdVMEvents(cmdVM);
cmdVM->Initialize(); cmdVM->Initialize();
commandList.push_back(*cmdVM); commandList.push_back(*cmdVM);
@ -1085,7 +1109,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
const auto args = ActionArgFactory::GetEmptyArgsForAction(shortcutAction); const auto args = ActionArgFactory::GetEmptyArgsForAction(shortcutAction);
newCmd.ActionAndArgs(Model::ActionAndArgs{ shortcutAction, args }); newCmd.ActionAndArgs(Model::ActionAndArgs{ shortcutAction, args });
_Settings.ActionMap().AddAction(newCmd, nullptr); _Settings.ActionMap().AddAction(newCmd, nullptr);
auto cmdVM{ make_self<CommandViewModel>(newCmd, std::vector<Control::KeyChord>{}, *this, _AvailableActionsAndNamesMap) }; auto cmdVM{ make_self<CommandViewModel>(newCmd, std::vector<Control::KeyChord>{}, *this) };
cmdVM->IsNewCommand(true); cmdVM->IsNewCommand(true);
_RegisterCmdVMEvents(cmdVM); _RegisterCmdVMEvents(cmdVM);
cmdVM->Initialize(); cmdVM->Initialize();

View File

@ -87,8 +87,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
public: public:
CommandViewModel(winrt::Microsoft::Terminal::Settings::Model::Command cmd, CommandViewModel(winrt::Microsoft::Terminal::Settings::Model::Command cmd,
std::vector<Control::KeyChord> keyChordList, std::vector<Control::KeyChord> keyChordList,
const Editor::ActionsViewModel actionsPageVM, const Editor::ActionsViewModel actionsPageVM);
const Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring>& availableShortcutActionsAndNames);
void Initialize(); void Initialize();
winrt::hstring DisplayName(); winrt::hstring DisplayName();
@ -129,8 +128,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM); void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM);
void _ReplaceCommandWithUserCopy(bool reinitialize); void _ReplaceCommandWithUserCopy(bool reinitialize);
void _CreateAndInitializeActionArgsVMHelper(); void _CreateAndInitializeActionArgsVMHelper();
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> _AvailableActionsAndNamesMap;
std::unordered_map<winrt::hstring, Model::ShortcutAction> _NameToActionMap;
}; };
struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper> struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper>
@ -272,6 +269,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void AttemptAddOrModifyKeyChord(const Editor::KeyChordViewModel& senderVM, winrt::hstring commandID, const Control::KeyChord& newKeys, const Control::KeyChord& oldKeys); void AttemptAddOrModifyKeyChord(const Editor::KeyChordViewModel& senderVM, winrt::hstring commandID, const Control::KeyChord& newKeys, const Control::KeyChord& oldKeys);
void AttemptAddCopiedCommand(const Model::Command& newCommand); void AttemptAddCopiedCommand(const Model::Command& newCommand);
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> AvailableShortcutActionsAndNames();
Windows::Foundation::Collections::IMap<winrt::hstring, Model::ShortcutAction> NameToActionMap();
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::CommandViewModel>, CommandList); WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::CommandViewModel>, CommandList);
WINRT_OBSERVABLE_PROPERTY(ActionsSubPage, CurrentPage, _propertyChangedHandlers, ActionsSubPage::Base); WINRT_OBSERVABLE_PROPERTY(ActionsSubPage, CurrentPage, _propertyChangedHandlers, ActionsSubPage::Base);
@ -279,6 +279,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Editor::CommandViewModel _CurrentCommand{ nullptr }; Editor::CommandViewModel _CurrentCommand{ nullptr };
Model::CascadiaSettings _Settings; Model::CascadiaSettings _Settings;
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> _AvailableActionsAndNamesMap; Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> _AvailableActionsAndNamesMap;
Windows::Foundation::Collections::IMap<winrt::hstring, Model::ShortcutAction> _NameToActionMap;
void _MakeCommandVMsHelper(); void _MakeCommandVMsHelper();
void _RegisterCmdVMEvents(com_ptr<implementation::CommandViewModel>& cmdVM); void _RegisterCmdVMEvents(com_ptr<implementation::CommandViewModel>& cmdVM);

View File

@ -153,5 +153,8 @@ namespace Microsoft.Terminal.Settings.Editor
IObservableVector<CommandViewModel> CommandList { get; }; IObservableVector<CommandViewModel> CommandList { get; };
void CmdListItemClicked(IInspectable sender, Windows.UI.Xaml.Controls.ItemClickEventArgs args); void CmdListItemClicked(IInspectable sender, Windows.UI.Xaml.Controls.ItemClickEventArgs args);
Windows.Foundation.Collections.IMap<Microsoft.Terminal.Settings.Model.ShortcutAction, String> AvailableShortcutActionsAndNames();
Windows.Foundation.Collections.IMap<String, Microsoft.Terminal.Settings.Model.ShortcutAction> NameToActionMap();
} }
} }