mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-20 05:54:23 +00:00
edit inbox action works
This commit is contained in:
@@ -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>() };
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>() };
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
{
|
||||
Command();
|
||||
static Command NewUserCommand();
|
||||
static Command CopyAsUserCommand(Command originalCmd);
|
||||
|
||||
String Name;
|
||||
Boolean HasName();
|
||||
|
||||
Reference in New Issue
Block a user