can change action, can edit args

This commit is contained in:
Pankaj Bhojwani
2025-01-29 13:03:18 -08:00
parent 14f12098fe
commit 54292253c8
9 changed files with 92 additions and 44 deletions

View File

@@ -126,9 +126,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
CurrentAction(cmd.Name());
std::vector<hstring> shortcutActions;
for (const auto [_, name] : _AvailableActionsAndNamesMap)
for (const auto [action, name] : _AvailableActionsAndNamesMap)
{
shortcutActions.emplace_back(name);
_NameToActionMap.emplace(name, action);
}
_AvailableShortcutActions = single_threaded_observable_vector(std::move(shortcutActions));
@@ -147,21 +148,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
if (viewModelProperty == L"ProposedShortcutAction")
{
// todo: maybe just put this logic in the ProposedShortcutAction setter?
// todo: need a translator between string and enum
// todo: need a 'default arg struct' generator?
Model::ActionAndArgs newActionAndArgs{};
const auto actionString = unbox_value<hstring>(ProposedShortcutAction());
if (actionString == L"Send Input")
{
newActionAndArgs.Action(Model::ShortcutAction::SendInput);
newActionAndArgs.Args(Model::SendInputArgs{ L"" });
}
else if (actionString == L"Close Tab")
{
const uint32_t index{ 0 };
newActionAndArgs.Action(Model::ShortcutAction::CloseTab);
newActionAndArgs.Args(Model::CloseTabArgs{ index });
}
const auto actionEnum = _NameToActionMap.at(actionString);
Model::ActionAndArgs newActionAndArgs{ actionEnum, CascadiaSettings::GetEmptyArgsForAction(actionEnum) };
_command.ActionAndArgs(newActionAndArgs);
ActionArgsVM(make<ActionArgsViewModel>(newActionAndArgs));
}
@@ -253,20 +243,24 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
std::vector<Editor::ArgWrapper> argValues;
for (uint32_t i = 0; i < shortcutArgsNumItems; i++)
{
const auto argType = shortcutArgs.GetArgDescriptionAt(i).Type;
const auto item = make<ArgWrapper>(argType, shortcutArgs.GetArgAt(i));
item.PropertyChanged([&](const IInspectable& sender, const PropertyChangedEventArgs& args) {
const auto itemProperty{ args.PropertyName() };
if (itemProperty == L"Value")
{
const auto argWrapper = sender.as<Microsoft::Terminal::Settings::Editor::ArgWrapper>();
const auto newValue = argWrapper.Value();
// todo: this works but for some reason we have to hit "Save" twice (just for the first time...)?
_actionAndArgs.Args().SetArgAt(i, newValue);
}
});
argValues.push_back(item);
const auto argAtIndex = shortcutArgs.GetArgAt(i);
if (argAtIndex)
{
const auto argType = shortcutArgs.GetArgDescriptionAt(i).Type;
const auto item = make<ArgWrapper>(argType, argAtIndex);
item.PropertyChanged([&, i](const IInspectable& sender, const PropertyChangedEventArgs& args) {
const auto itemProperty{ args.PropertyName() };
if (itemProperty == L"Value")
{
const auto argWrapper = sender.as<Microsoft::Terminal::Settings::Editor::ArgWrapper>();
const auto newValue = argWrapper.Value();
_actionAndArgs.Args().SetArgAt(i, newValue);
}
});
argValues.push_back(item);
}
}
_ArgValues = single_threaded_observable_vector(std::move(argValues));
}
}

View File

@@ -162,6 +162,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void _RegisterKeyChordVMEvents(Editor::KeyChordViewModel kcVM);
void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM);
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> _AvailableActionsAndNamesMap;
std::unordered_map<winrt::hstring, Model::ShortcutAction> _NameToActionMap;
};
struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper>

View File

@@ -15,10 +15,32 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
EditAction::EditAction()
{
InitializeComponent();
_itemTemplateSelector = Resources().Lookup(winrt::box_value(L"ArgsTemplateSelector")).try_as<ArgsTemplateSelectors>();
_listItemTemplate = Resources().Lookup(winrt::box_value(L"ListItemTemplate")).try_as<DataTemplate>();
}
void EditAction::OnNavigatedTo(const NavigationEventArgs& e)
{
_ViewModel = e.Parameter().as<Editor::CommandViewModel>();
}
void EditAction::_choosingItemContainer(
const Windows::UI::Xaml::Controls::ListViewBase& /*sender*/,
const Windows::UI::Xaml::Controls::ChoosingItemContainerEventArgs& args)
{
const auto dataTemplate = _itemTemplateSelector.SelectTemplate(args.Item());
const auto itemContainer = args.ItemContainer();
// todo: do we need the same caching logic as in command palette?
if (!itemContainer || itemContainer.ContentTemplate() != dataTemplate)
{
ElementFactoryGetArgs factoryArgs{};
const auto listViewItem = _listItemTemplate.GetElement(factoryArgs).try_as<Controls::ListViewItem>();
listViewItem.ContentTemplate(dataTemplate);
args.ItemContainer(listViewItem);
}
args.IsContainerPrepared(true);
}
}

View File

@@ -19,6 +19,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(Editor::CommandViewModel, ViewModel, PropertyChanged.raise, nullptr);
private:
friend struct EditActionT<EditAction>; // for Xaml to bind events
Windows::UI::Xaml::DataTemplate _listItemTemplate;
winrt::Microsoft::Terminal::Settings::Editor::ArgsTemplateSelectors _itemTemplateSelector{ nullptr };
void _choosingItemContainer(const Windows::UI::Xaml::Controls::ListViewBase& sender, const Windows::UI::Xaml::Controls::ChoosingItemContainerEventArgs& args);
};
}

View File

@@ -235,24 +235,31 @@
<local:ActionsTemplateSelectors x:Key="ActionsTemplateSelector"
SendInputTemplate="{StaticResource SendInputTemplate}"
CloseTabTemplate="{StaticResource CloseTabTemplate}"/>
<DataTemplate x:Key="ListItemTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem HorizontalContentAlignment="Stretch" />
</DataTemplate>
<DataTemplate x:Key="UInt32Template"
x:DataType="local:ArgWrapper">
<StackPanel Orientation="Horizontal">
<muxc:NumberBox Value="{x:Bind mtu:Converters.UnboxUInt32(Value), Mode=TwoWay, BindBack=DoubleBindBack}"
Style="{StaticResource NumberBoxSettingStyle}"
Minimum="0"
Maximum="999"
LargeChange="1"
SmallChange="1"/>
</StackPanel>
<ListViewItem>
<StackPanel Orientation="Horizontal">
<muxc:NumberBox Value="{x:Bind mtu:Converters.UnboxUInt32(Value), Mode=TwoWay, BindBack=DoubleBindBack}"
Style="{StaticResource NumberBoxSettingStyle}"
Minimum="0"
Maximum="999"
LargeChange="1"
SmallChange="1"/>
</StackPanel>
</ListViewItem>
</DataTemplate>
<DataTemplate x:Key="StringTemplate"
x:DataType="local:ArgWrapper">
<StackPanel Orientation="Horizontal">
<TextBox Text="{x:Bind mtu:Converters.UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}" />
</StackPanel>
<ListViewItem>
<StackPanel Orientation="Horizontal">
<TextBox Text="{x:Bind mtu:Converters.UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}" />
</StackPanel>
</ListViewItem>
</DataTemplate>
<local:ArgsTemplateSelectors x:Key="ArgsTemplateSelector"
@@ -276,8 +283,11 @@
SelectedItem="{x:Bind ViewModel.ProposedShortcutAction, Mode=TwoWay}"
IsEnabled="{x:Bind ViewModel.IsUserAction}"
Visibility="{x:Bind ViewModel.IsUserAction}"/>
<muxc:ItemsRepeater ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}"
ItemTemplate="{StaticResource ArgsTemplateSelector}" />
<ListView ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}"
ChoosingItemContainer="_choosingItemContainer"
SelectionMode="None"
AllowDrop="False"
CanReorderItems="False" />
<ListView ItemTemplate="{StaticResource KeyChordTemplate}"
ItemsSource="{x:Bind ViewModel.KeyChordViewModelList, Mode=OneWay}"
SelectionMode="None">

View File

@@ -76,7 +76,7 @@ struct InitListPlaceholder
#define EQUALS_ARGS(type, name, jsonKey, required, ...) \
&&(otherAsUs->_##name == _##name)
// getter and setter for each property by name
// getter and setter for each property by index
#define GET_ARG_BY_INDEX(type, name, jsonKey, required, ...) \
if (index == curIndex++) \
{ \
@@ -86,7 +86,7 @@ struct InitListPlaceholder
} \
else \
{ \
return nullptr; \
return winrt::box_value(type{ __VA_ARGS__ }); \
} \
}
@@ -138,7 +138,7 @@ struct InitListPlaceholder
// * GlobalSummonArgs has the QuakeModeFromJson helper
#define ACTION_ARG_BODY(className, argsMacro) \
className() = default; \
className() { argsMacro(APPEND_ARG_DESCRIPTION) }; \
className( \
argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \
argsMacro(CTOR_INIT) _placeholder{} { \

View File

@@ -994,6 +994,18 @@ winrt::Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstr
return single_threaded_map(std::move(availableShortcutActionsAndNames));
}
Model::IActionArgs CascadiaSettings::GetEmptyArgsForAction(Model::ShortcutAction shortcutAction)
{
switch (shortcutAction)
{
case Model::ShortcutAction::SendInput:
return winrt::make<SendInputArgs>();
case Model::ShortcutAction::MovePane:
return winrt::make<MovePaneArgs>();
default:
return nullptr;
}
}
// Method Description:
// - Determines if we're on an OS platform that supports

View File

@@ -116,6 +116,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
static bool IsPortableMode();
static Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> AvailableShortcutActionsAndNames();
static Model::IActionArgs GetEmptyArgsForAction(Model::ShortcutAction shortcutAction);
CascadiaSettings() noexcept = default;
CascadiaSettings(const winrt::hstring& userJSON, const winrt::hstring& inboxJSON);

View File

@@ -5,6 +5,7 @@ import "GlobalAppSettings.idl";
import "Profile.idl";
import "TerminalWarnings.idl";
import "DefaultTerminal.idl";
import "ActionArgs.idl";
namespace Microsoft.Terminal.Settings.Model
{
@@ -21,6 +22,7 @@ namespace Microsoft.Terminal.Settings.Model
static String ApplicationVersion { get; };
static Windows.Foundation.Collections.IMap<Microsoft.Terminal.Settings.Model.ShortcutAction, String> AvailableShortcutActionsAndNames { get; };
static IActionArgs GetEmptyArgsForAction(Microsoft.Terminal.Settings.Model.ShortcutAction shortcutAction);
CascadiaSettings(String userJSON, String inboxJSON);