edit inbox action works

This commit is contained in:
Pankaj Bhojwani
2025-04-30 16:14:20 -07:00
parent 410ef5ae8d
commit 3b5bed8331
9 changed files with 121 additions and 40 deletions

View File

@@ -51,7 +51,7 @@ inline const std::set<winrt::Microsoft::Terminal::Settings::Model::ShortcutActio
enumList.emplace_back(entry); \
if (_Value && unboxedValue == enumValue) \
{ \
EnumValue(entry); \
_EnumValue = entry; \
} \
} \
std::sort(enumList.begin(), enumList.end(), EnumEntryReverseComparator<enumType>()); \
@@ -69,7 +69,7 @@ inline const std::set<winrt::Microsoft::Terminal::Settings::Model::ShortcutActio
} \
else \
{ \
EnumValue(nullEntry); \
_EnumValue = nullEntry; \
} \
for (const auto [enumKey, enumValue] : mappings) \
{ \
@@ -78,7 +78,7 @@ inline const std::set<winrt::Microsoft::Terminal::Settings::Model::ShortcutActio
enumList.emplace_back(entry); \
if (_Value && unboxedValue == enumValue) \
{ \
EnumValue(entry); \
_EnumValue = entry; \
} \
} \
std::sort(enumList.begin(), enumList.end(), EnumEntryReverseComparator<enumType>()); \
@@ -116,7 +116,7 @@ inline const std::set<winrt::Microsoft::Terminal::Settings::Model::ShortcutActio
} \
std::sort(flagList.begin(), flagList.end(), FlagEntryReverseComparator<enumType>()); \
_FlagList = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::FlagEntry>(std::move(flagList)); \
_NotifyChanges(L"FlagList", L"Value");
_NotifyChanges(L"FlagList");
#define INITIALIZE_NULLABLE_FLAG_LIST_AND_VALUE(enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \
std::vector<winrt::Microsoft::Terminal::Settings::Editor::FlagEntry> flagList; \
@@ -189,7 +189,7 @@ inline const std::set<winrt::Microsoft::Terminal::Settings::Model::ShortcutActio
}); \
flagList.emplace_back(nullEntry); \
_FlagList = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::FlagEntry>(std::move(flagList)); \
_NotifyChanges(L"FlagList", L"Value");
_NotifyChanges(L"FlagList");
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
@@ -307,10 +307,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
const auto shortcutActionString = _AvailableActionsAndNamesMap.Lookup(_command.ActionAndArgs().Action());
ProposedShortcutAction(winrt::box_value(shortcutActionString));
const auto actionArgsVM = make_self<ActionArgsViewModel>(_command.ActionAndArgs());
_RegisterActionArgsVMEvents(*actionArgsVM);
actionArgsVM->Initialize();
ActionArgsVM(*actionArgsVM);
_CreateAndInitializeActionArgsVMHelper();
// Add a property changed handler to our own property changed event.
// This allows us to create a new ActionArgsVM when the shortcut action changes
@@ -327,14 +324,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// there are some other cases as well
Model::ActionAndArgs newActionAndArgs{ actionEnum, emptyArgs };
_command.ActionAndArgs(newActionAndArgs);
const auto actionArgsVM = make_self<ActionArgsViewModel>(newActionAndArgs);
_RegisterActionArgsVMEvents(*actionArgsVM);
actionArgsVM->Initialize();
ActionArgsVM(*actionArgsVM);
if (_IsNewCommand)
{
_command.GenerateID();
}
else if (!IsUserAction())
{
_ReplaceCommandWithUserCopy();
return;
}
_CreateAndInitializeActionArgsVMHelper();
}
});
}
@@ -440,6 +439,35 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_command.GenerateID();
});
}
else if (!IsUserAction())
{
actionArgsVM.WrapperValueChanged([this](const IInspectable& /*sender*/, const IInspectable& /*args*/) {
_ReplaceCommandWithUserCopy();
});
}
}
void CommandViewModel::_ReplaceCommandWithUserCopy()
{
// the user is attempting to edit an in-box action
// to handle this, we create a new command with the new values that has the same ID as the in-box action
// swap out our underlying command with the copy, tell the ActionsVM that the copy needs to be added to the action map
if (const auto actionsPageVM{ _actionsPageVM.get() })
{
const auto newCmd = Model::Command::CopyAsUserCommand(_command);
_command = newCmd;
actionsPageVM.AttemptAddCopiedCommand(_command);
_CreateAndInitializeActionArgsVMHelper();
}
}
void CommandViewModel::_CreateAndInitializeActionArgsVMHelper()
{
const auto actionArgsVM = make_self<ActionArgsViewModel>(_command.ActionAndArgs());
_RegisterActionArgsVMEvents(*actionArgsVM);
actionArgsVM->Initialize();
ActionArgsVM(*actionArgsVM);
_NotifyChanges(L"DisplayName");
}
ArgWrapper::ArgWrapper(const winrt::hstring& name, const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value) :
@@ -625,27 +653,40 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void ArgWrapper::StringBindBack(const winrt::hstring& newValue)
{
Value(box_value(newValue));
if (UnboxString(_Value) != newValue)
{
Value(box_value(newValue));
}
}
void ArgWrapper::GuidBindBack(const winrt::hstring& newValue)
{
// todo: probably need some validation?
Value(box_value(winrt::guid{ newValue }));
if (UnboxGuid(_Value) != newValue)
{
// todo: probably need some validation?
Value(box_value(winrt::guid{ newValue }));
}
}
void ArgWrapper::Int32BindBack(const double newValue)
{
Value(box_value(static_cast<int32_t>(newValue)));
if (UnboxInt32(_Value) != newValue)
{
Value(box_value(static_cast<int32_t>(newValue)));
}
}
void ArgWrapper::Int32OptionalBindBack(const double newValue)
{
if (!isnan(newValue))
{
Value(box_value(static_cast<int32_t>(newValue)));
const auto currentValue = UnboxInt32Optional(_Value);
if (isnan(currentValue) || static_cast<int32_t>(currentValue) != static_cast<int32_t>(newValue))
{
Value(box_value(static_cast<int32_t>(newValue)));
}
}
else
else if (!_Value)
{
Value(nullptr);
}
@@ -653,16 +694,23 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void ArgWrapper::UInt32BindBack(const double newValue)
{
Value(box_value(static_cast<uint32_t>(newValue)));
if (UnboxUInt32(_Value) != newValue)
{
Value(box_value(static_cast<uint32_t>(newValue)));
}
}
void ArgWrapper::UInt32OptionalBindBack(const double newValue)
{
if (!isnan(newValue))
{
Value(box_value(static_cast<uint32_t>(newValue)));
const auto currentValue = UnboxUInt32Optional(_Value);
if (isnan(currentValue) || static_cast<uint32_t>(currentValue) != static_cast<uint32_t>(newValue))
{
Value(box_value(static_cast<uint32_t>(newValue)));
}
}
else
else if (!_Value)
{
Value(nullptr);
}
@@ -670,21 +718,31 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void ArgWrapper::UInt64BindBack(const double newValue)
{
Value(box_value(static_cast<uint64_t>(newValue)));
if (UnboxUInt64(_Value) != newValue)
{
Value(box_value(static_cast<uint64_t>(newValue)));
}
}
void ArgWrapper::FloatBindBack(const double newValue)
{
Value(box_value(static_cast<float>(newValue)));
if (UnboxFloat(_Value) != newValue)
{
Value(box_value(static_cast<float>(newValue)));
}
}
void ArgWrapper::BoolBindBack(const Windows::Foundation::IReference<bool> newValue)
void ArgWrapper::BoolOptionalBindBack(const Windows::Foundation::IReference<bool> newValue)
{
if (newValue)
{
Value(box_value(newValue));
const auto currentValue = UnboxBoolOptional(_Value);
if (!currentValue || currentValue.Value() != newValue.Value())
{
Value(box_value(newValue));
}
}
else
else if (_Value)
{
Value(nullptr);
}
@@ -694,9 +752,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
if (newValue)
{
Value(box_value(newValue));
const auto currentValue = UnboxTerminalCoreColorOptional(_Value);
if (!currentValue || currentValue.Value() != newValue.Value())
{
Value(box_value(newValue));
}
}
else
else if (_Value)
{
Value(nullptr);
}
@@ -726,7 +788,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
Value(box_value(Windows::Foundation::IReference<Windows::UI::Color>{ winuiColor }));
}
else
else if (_Value)
{
Value(nullptr);
}
@@ -1097,6 +1159,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_Settings.ActionMap().AddKeyBinding(keys, cmdID);
}
void ActionsViewModel::AttemptAddCopiedCommand(const Model::Command& newCommand)
{
// The command VM calls this when the user has edited an in-box action
// newCommand is a copy of the in-box action that was edited, but with OriginTag::User
// add it to the action map
_Settings.ActionMap().AddAction(newCommand, nullptr);
}
void ActionsViewModel::_KeyBindingViewModelPropertyChangedHandler(const IInspectable& sender, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args)
{
const auto senderVM{ sender.as<Editor::KeyBindingViewModel>() };

View File

@@ -163,6 +163,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
weak_ref<Editor::ActionsViewModel> _actionsPageVM{ nullptr };
void _RegisterKeyChordVMEvents(Editor::KeyChordViewModel kcVM);
void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM);
void _ReplaceCommandWithUserCopy();
void _CreateAndInitializeActionArgsVMHelper();
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> _AvailableActionsAndNamesMap;
std::unordered_map<winrt::hstring, Model::ShortcutAction> _NameToActionMap;
};
@@ -205,7 +207,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void UInt32OptionalBindBack(const double newValue);
void UInt64BindBack(const double newValue);
void FloatBindBack(const double newValue);
void BoolBindBack(const Windows::Foundation::IReference<bool> newValue);
void BoolOptionalBindBack(const Windows::Foundation::IReference<bool> newValue);
void TerminalCoreColorBindBack(const winrt::Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> newValue);
void WindowsUIColorBindBack(const winrt::Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> newValue);
@@ -284,6 +286,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void AttemptModifyKeyChord(const Editor::KeyChordViewModel& senderVM, const Editor::ModifyKeyChordEventArgs& args);
void AttemptDeleteKeyChord(const Control::KeyChord& keys);
void AttemptAddKeyChord(const Control::KeyChord& keys, const winrt::hstring& cmdID);
void AttemptAddCopiedCommand(const Model::Command& newCommand);
til::typed_event<IInspectable, IInspectable> FocusContainer;
til::typed_event<IInspectable, IInspectable> UpdateBackground;

View File

@@ -61,7 +61,6 @@ namespace Microsoft.Terminal.Settings.Editor
String Name;
String ID;
Boolean IsUserAction { get; };
// icon
// keybindings
IObservableVector<KeyChordViewModel> KeyChordViewModelList { get; };
// action args
@@ -115,7 +114,7 @@ namespace Microsoft.Terminal.Settings.Editor
void UInt32OptionalBindBack(Double newValue);
void UInt64BindBack(Double newValue);
void FloatBindBack(Double newValue);
void BoolBindBack(Windows.Foundation.IReference<Boolean> newValue);
void BoolOptionalBindBack(Windows.Foundation.IReference<Boolean> newValue);
void TerminalCoreColorBindBack(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> newValue);
void WindowsUIColorBindBack(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> newValue);
@@ -173,6 +172,7 @@ namespace Microsoft.Terminal.Settings.Editor
void AttemptAddKeyChord(Microsoft.Terminal.Control.KeyChord keys, String cmdID);
void AttemptModifyKeyChord(KeyChordViewModel senderVM, ModifyKeyChordEventArgs args);
void AttemptDeleteKeyChord(Microsoft.Terminal.Control.KeyChord keys);
void AttemptAddCopiedCommand(Microsoft.Terminal.Settings.Model.Command newCommand);
IObservableVector<CommandViewModel> CommandList { get; };
void CmdListItemClicked(IInspectable sender, Windows.UI.Xaml.Controls.ItemClickEventArgs args);

View File

@@ -53,7 +53,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
else if (argType == L"bool" ||
argType == L"Windows::Foundation::IReference<bool>")
{
// we don't have any bool args that are required, so just use the optional template for all of them
return BoolOptionalTemplate();
}
else if (argType == L"Windows::Foundation::IReference<int32_t>")

View File

@@ -409,7 +409,7 @@
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center"
Grid.Column="0"/>
<CheckBox IsChecked="{x:Bind UnboxBoolOptional(Value), Mode=TwoWay, BindBack=BoolBindBack}"
<CheckBox IsChecked="{x:Bind UnboxBoolOptional(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
IsThreeState="True"
Grid.Column="1"/>
</Grid>
@@ -556,9 +556,8 @@
VerticalAlignment="Center"
Grid.Column="0"
Grid.Row="0"/>
<TextBox x:Uid="Actions_NameEntryBox"
Text="{x:Bind ViewModel.Name, Mode=TwoWay}"
IsEnabled="{x:Bind ViewModel.IsUserAction}"
<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}"
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
Grid.Row="0"
Grid.Column="1"/>
<TextBlock x:Uid="Actions_ShortcutAction"
@@ -568,7 +567,6 @@
<ComboBox VerticalAlignment="Center"
ItemsSource="{x:Bind ViewModel.AvailableShortcutActions, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.ProposedShortcutAction, Mode=TwoWay}"
IsEnabled="{x:Bind ViewModel.IsUserAction}"
Grid.Row="1"
Grid.Column="1"/>
<TextBlock x:Uid="Actions_Arguments"

View File

@@ -294,7 +294,6 @@ protected: \
X(Windows::Foundation::IReference<Windows::UI::Color>, TabColor, "tabColor", false, nullptr) \
X(Windows::Foundation::IReference<int32_t>, ProfileIndex, "index", false, nullptr) \
X(winrt::hstring, Profile, "profile", false, L"") \
X(bool, AppendCommandLine, "appendCommandLine", false, false) \
X(Windows::Foundation::IReference<bool>, SuppressApplicationTitle, "suppressApplicationTitle", false, nullptr) \
X(winrt::hstring, ColorScheme, "colorScheme", args->SchemeName().empty(), L"") \
X(Windows::Foundation::IReference<bool>, Elevate, "elevate", false, nullptr) \
@@ -381,9 +380,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
PARTIAL_ACTION_ARG_BODY(NewTerminalArgs, NEW_TERMINAL_ARGS);
ACTION_ARG(winrt::hstring, Type, L"");
ACTION_ARG(winrt::guid, SessionId, winrt::guid{});
ACTION_ARG(bool, AppendCommandLine, false);
ACTION_ARG(uint64_t, ContentId);
static constexpr std::string_view SessionIdKey{ "sessionId" };
static constexpr std::string_view AppendCommandLineKey{ "appendCommandLine" };
static constexpr std::string_view ContentKey{ "__content" };
public:

View File

@@ -35,6 +35,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return *newCmd;
}
Model::Command Command::CopyAsUserCommand(Model::Command originalCmd)
{
auto command{ winrt::get_self<Command>(originalCmd) };
auto copy{ command->Copy() };
copy->_Origin = OriginTag::User;
return *copy;
}
com_ptr<Command> Command::Copy() const
{
auto command{ winrt::make_self<Command>() };

View File

@@ -46,6 +46,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
Command();
static Model::Command NewUserCommand();
static Model::Command CopyAsUserCommand(Model::Command originalCmd);
com_ptr<Command> Copy() const;
static winrt::com_ptr<Command> FromJson(const Json::Value& json,

View File

@@ -36,6 +36,7 @@ namespace Microsoft.Terminal.Settings.Model
{
Command();
static Command NewUserCommand();
static Command CopyAsUserCommand(Command originalCmd);
String Name;
Boolean HasName();