Skip to content

Commit 2f6108d

Browse files
settings actions editor
1 parent d973836 commit 2f6108d

26 files changed

+3320
-2
lines changed

src/cascadia/TerminalSettingsEditor/ActionsViewModel.cpp

Lines changed: 1191 additions & 0 deletions
Large diffs are not rendered by default.

src/cascadia/TerminalSettingsEditor/ActionsViewModel.h

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44
#pragma once
55

66
#include "ActionsViewModel.g.h"
7+
#include "NavigateToCommandArgs.g.h"
78
#include "KeyBindingViewModel.g.h"
9+
#include "CommandViewModel.g.h"
10+
#include "ArgWrapper.g.h"
11+
#include "ActionArgsViewModel.g.h"
12+
#include "KeyChordViewModel.g.h"
813
#include "ModifyKeyBindingEventArgs.g.h"
14+
#include "ModifyKeyChordEventArgs.g.h"
915
#include "Utils.h"
1016
#include "ViewModelHelpers.h"
1117

@@ -19,6 +25,29 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
1925
}
2026
};
2127

28+
struct CommandViewModelComparator
29+
{
30+
bool operator()(const Editor::CommandViewModel& lhs, const Editor::CommandViewModel& rhs) const
31+
{
32+
return lhs.DisplayName() < rhs.DisplayName();
33+
}
34+
};
35+
36+
struct NavigateToCommandArgs : NavigateToCommandArgsT<NavigateToCommandArgs>
37+
{
38+
public:
39+
NavigateToCommandArgs(CommandViewModel command, Editor::IHostedInWindow windowRoot) :
40+
_Command(command),
41+
_WindowRoot(windowRoot) {}
42+
43+
Editor::IHostedInWindow WindowRoot() const noexcept { return _WindowRoot; }
44+
Editor::CommandViewModel Command() const noexcept { return _Command; }
45+
46+
private:
47+
Editor::IHostedInWindow _WindowRoot;
48+
Editor::CommandViewModel _Command{ nullptr };
49+
};
50+
2251
struct ModifyKeyBindingEventArgs : ModifyKeyBindingEventArgsT<ModifyKeyBindingEventArgs>
2352
{
2453
public:
@@ -34,6 +63,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
3463
WINRT_PROPERTY(hstring, NewActionName);
3564
};
3665

66+
struct ModifyKeyChordEventArgs : ModifyKeyChordEventArgsT<ModifyKeyChordEventArgs>
67+
{
68+
public:
69+
ModifyKeyChordEventArgs(const Control::KeyChord& oldKeys, const Control::KeyChord& newKeys) :
70+
_OldKeys{ oldKeys },
71+
_NewKeys{ newKeys } {}
72+
73+
WINRT_PROPERTY(Control::KeyChord, OldKeys, nullptr);
74+
WINRT_PROPERTY(Control::KeyChord, NewKeys, nullptr);
75+
};
76+
3777
struct KeyBindingViewModel : KeyBindingViewModelT<KeyBindingViewModel>, ViewModelHelper<KeyBindingViewModel>
3878
{
3979
public:
@@ -99,32 +139,220 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
99139
hstring _KeyChordText{};
100140
};
101141

142+
struct CommandViewModel : CommandViewModelT<CommandViewModel>, ViewModelHelper<CommandViewModel>
143+
{
144+
public:
145+
CommandViewModel(winrt::Microsoft::Terminal::Settings::Model::Command cmd,
146+
std::vector<Control::KeyChord> keyChordList,
147+
const Editor::ActionsViewModel actionsPageVM,
148+
const Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring>& availableShortcutActionsAndNames);
149+
void Initialize();
150+
151+
winrt::hstring DisplayName();
152+
winrt::hstring Name();
153+
void Name(const winrt::hstring& newName);
154+
155+
winrt::hstring ID();
156+
void ID(const winrt::hstring& newID);
157+
158+
bool IsUserAction();
159+
160+
void Edit_Click();
161+
til::typed_event<Editor::CommandViewModel, IInspectable> EditRequested;
162+
163+
void Delete_Click();
164+
til::typed_event<Editor::CommandViewModel, IInspectable> DeleteRequested;
165+
166+
void AddKeybinding_Click();
167+
168+
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeRequested;
169+
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeNamesRequested;
170+
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateWindowRootRequested;
171+
172+
VIEW_MODEL_OBSERVABLE_PROPERTY(IInspectable, ProposedShortcutAction);
173+
VIEW_MODEL_OBSERVABLE_PROPERTY(Editor::ActionArgsViewModel, ActionArgsVM, nullptr);
174+
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<hstring>, AvailableShortcutActions, nullptr);
175+
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::KeyChordViewModel>, KeyChordViewModelList, nullptr);
176+
WINRT_PROPERTY(bool, IsNewCommand, false);
177+
178+
private:
179+
winrt::Microsoft::Terminal::Settings::Model::Command _command;
180+
std::vector<Control::KeyChord> _keyChordList;
181+
weak_ref<Editor::ActionsViewModel> _actionsPageVM{ nullptr };
182+
void _RegisterKeyChordVMEvents(Editor::KeyChordViewModel kcVM);
183+
void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM);
184+
void _ReplaceCommandWithUserCopy(bool reinitialize);
185+
void _CreateAndInitializeActionArgsVMHelper();
186+
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> _AvailableActionsAndNamesMap;
187+
std::unordered_map<winrt::hstring, Model::ShortcutAction> _NameToActionMap;
188+
};
189+
190+
struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper>
191+
{
192+
public:
193+
ArgWrapper(const winrt::hstring& name, const winrt::hstring& type, const bool required, const Model::ArgTag tag, const Windows::Foundation::IInspectable& value);
194+
void Initialize();
195+
196+
winrt::hstring Name() const noexcept { return _name; };
197+
winrt::hstring Type() const noexcept { return _type; };
198+
Model::ArgTag Tag() const noexcept { return _tag; };
199+
bool Required() const noexcept { return _required; };
200+
201+
// We cannot use the macro here because we need to implement additional logic for the setter
202+
Windows::Foundation::IInspectable EnumValue() const noexcept { return _EnumValue; };
203+
void EnumValue(const Windows::Foundation::IInspectable& value);
204+
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::EnumEntry> EnumList() const noexcept { return _EnumList; };
205+
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::FlagEntry> FlagList() const noexcept { return _FlagList; };
206+
207+
// unboxing functions
208+
winrt::hstring UnboxString(const Windows::Foundation::IInspectable& value);
209+
winrt::hstring UnboxGuid(const Windows::Foundation::IInspectable& value);
210+
int32_t UnboxInt32(const Windows::Foundation::IInspectable& value);
211+
float UnboxInt32Optional(const Windows::Foundation::IInspectable& value);
212+
uint32_t UnboxUInt32(const Windows::Foundation::IInspectable& value);
213+
float UnboxUInt32Optional(const Windows::Foundation::IInspectable& value);
214+
float UnboxUInt64(const Windows::Foundation::IInspectable& value);
215+
float UnboxFloat(const Windows::Foundation::IInspectable& value);
216+
bool UnboxBool(const Windows::Foundation::IInspectable& value);
217+
winrt::Windows::Foundation::IReference<bool> UnboxBoolOptional(const Windows::Foundation::IInspectable& value);
218+
winrt::Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> UnboxTerminalCoreColorOptional(const Windows::Foundation::IInspectable& value);
219+
winrt::Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> UnboxWindowsUIColorOptional(const Windows::Foundation::IInspectable& value);
220+
221+
// bind back functions
222+
void StringBindBack(const winrt::hstring& newValue);
223+
void GuidBindBack(const winrt::hstring& newValue);
224+
void Int32BindBack(const double newValue);
225+
void Int32OptionalBindBack(const double newValue);
226+
void UInt32BindBack(const double newValue);
227+
void UInt32OptionalBindBack(const double newValue);
228+
void UInt64BindBack(const double newValue);
229+
void FloatBindBack(const double newValue);
230+
void BoolOptionalBindBack(const Windows::Foundation::IReference<bool> newValue);
231+
void TerminalCoreColorBindBack(const winrt::Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> newValue);
232+
void WindowsUIColorBindBack(const winrt::Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> newValue);
233+
234+
safe_void_coroutine Browse_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
235+
236+
// some argWrappers need to know additional information (like the default color scheme or the list of all color scheme names)
237+
// to avoid populating all ArgWrappers with that information, instead we emit an event when we need that information
238+
// (these events then get propagated up to the ActionsVM) and then the actionsVM will populate the value in us
239+
// since there's an actionArgsVM above us and a commandVM above that, the event does get propagated through a few times but that's
240+
// probably better than having every argWrapper contain the information by default
241+
til::typed_event<IInspectable, Editor::ArgWrapper> ColorSchemeRequested;
242+
til::typed_event<IInspectable, Editor::ArgWrapper> ColorSchemeNamesRequested;
243+
til::typed_event<IInspectable, Editor::ArgWrapper> WindowRootRequested;
244+
245+
VIEW_MODEL_OBSERVABLE_PROPERTY(Editor::ColorSchemeViewModel, DefaultColorScheme, nullptr);
246+
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::IInspectable, Value, nullptr);
247+
WINRT_PROPERTY(Windows::Foundation::Collections::IVector<winrt::hstring>, ColorSchemeNamesList, nullptr);
248+
WINRT_PROPERTY(Editor::IHostedInWindow, WindowRoot, nullptr);
249+
250+
private:
251+
winrt::hstring _name;
252+
winrt::hstring _type;
253+
Model::ArgTag _tag;
254+
bool _required;
255+
Windows::Foundation::IInspectable _EnumValue{ nullptr };
256+
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::EnumEntry> _EnumList;
257+
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::FlagEntry> _FlagList;
258+
};
259+
260+
struct ActionArgsViewModel : ActionArgsViewModelT<ActionArgsViewModel>, ViewModelHelper<ActionArgsViewModel>
261+
{
262+
public:
263+
ActionArgsViewModel(const Microsoft::Terminal::Settings::Model::ActionAndArgs actionAndArgs);
264+
void Initialize();
265+
266+
bool HasArgs() const noexcept;
267+
void ReplaceActionAndArgs(Model::ActionAndArgs newActionAndArgs);
268+
269+
til::typed_event<IInspectable, IInspectable> WrapperValueChanged;
270+
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeRequested;
271+
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeNamesRequested;
272+
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateWindowRootRequested;
273+
274+
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::ArgWrapper>, ArgValues, nullptr);
275+
276+
private:
277+
Model::ActionAndArgs _actionAndArgs{ nullptr };
278+
};
279+
280+
struct KeyChordViewModel : KeyChordViewModelT<KeyChordViewModel>, ViewModelHelper<KeyChordViewModel>
281+
{
282+
public:
283+
KeyChordViewModel(Control::KeyChord CurrentKeys);
284+
285+
void CurrentKeys(const Control::KeyChord& newKeys);
286+
Control::KeyChord CurrentKeys() const noexcept;
287+
288+
void ToggleEditMode();
289+
void AttemptAcceptChanges();
290+
void CancelChanges();
291+
void DeleteKeyChord();
292+
293+
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsInEditMode, false);
294+
VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, ProposedKeys);
295+
VIEW_MODEL_OBSERVABLE_PROPERTY(winrt::hstring, KeyChordText);
296+
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::UI::Xaml::Controls::Flyout, AcceptChangesFlyout, nullptr);
297+
298+
public:
299+
til::typed_event<Editor::KeyChordViewModel, Terminal::Control::KeyChord> AddKeyChordRequested;
300+
til::typed_event<Editor::KeyChordViewModel, Editor::ModifyKeyChordEventArgs> ModifyKeyChordRequested;
301+
til::typed_event<Editor::KeyChordViewModel, Terminal::Control::KeyChord> DeleteKeyChordRequested;
302+
303+
private:
304+
Control::KeyChord _currentKeys;
305+
};
306+
102307
struct ActionsViewModel : ActionsViewModelT<ActionsViewModel>, ViewModelHelper<ActionsViewModel>
103308
{
104309
public:
105310
ActionsViewModel(Model::CascadiaSettings settings);
311+
void UpdateSettings(const Model::CascadiaSettings& settings);
106312

107313
void OnAutomationPeerAttached();
108314
void AddNewKeybinding();
315+
void AddNewCommand();
316+
317+
void CurrentCommand(const Editor::CommandViewModel& newCommand);
318+
Editor::CommandViewModel CurrentCommand();
319+
void CmdListItemClicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Controls::ItemClickEventArgs& e);
320+
321+
void AttemptDeleteKeyChord(const Control::KeyChord& keys);
322+
void AttemptAddOrModifyKeyChord(const Editor::KeyChordViewModel& senderVM, winrt::hstring commandID, const Control::KeyChord& newKeys, const Control::KeyChord& oldKeys);
323+
void AttemptAddCopiedCommand(const Model::Command& newCommand);
109324

110325
til::typed_event<IInspectable, IInspectable> FocusContainer;
111326
til::typed_event<IInspectable, IInspectable> UpdateBackground;
112327

113328
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::KeyBindingViewModel>, KeyBindingList);
329+
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::CommandViewModel>, CommandList);
330+
WINRT_OBSERVABLE_PROPERTY(ActionsSubPage, CurrentPage, _propertyChangedHandlers, ActionsSubPage::Base);
114331

115332
private:
333+
Editor::CommandViewModel _CurrentCommand{ nullptr };
116334
bool _AutomationPeerAttached{ false };
117335
Model::CascadiaSettings _Settings;
118336
Windows::Foundation::Collections::IObservableVector<hstring> _AvailableActionAndArgs;
119337
Windows::Foundation::Collections::IMap<hstring, Model::ActionAndArgs> _AvailableActionMap;
338+
Windows::Foundation::Collections::IMap<Model::ShortcutAction, winrt::hstring> _AvailableActionsAndNamesMap;
339+
340+
void _MakeCommandVMsHelper();
120341

121342
std::optional<uint32_t> _GetContainerIndexByKeyChord(const Control::KeyChord& keys);
122343
void _RegisterEvents(com_ptr<implementation::KeyBindingViewModel>& kbdVM);
344+
void _RegisterCmdVMEvents(com_ptr<implementation::CommandViewModel>& cmdVM);
123345

124346
void _KeyBindingViewModelPropertyChangedHandler(const Windows::Foundation::IInspectable& senderVM, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args);
125347
void _KeyBindingViewModelDeleteKeyBindingHandler(const Editor::KeyBindingViewModel& senderVM, const Control::KeyChord& args);
126348
void _KeyBindingViewModelModifyKeyBindingHandler(const Editor::KeyBindingViewModel& senderVM, const Editor::ModifyKeyBindingEventArgs& args);
127349
void _KeyBindingViewModelDeleteNewlyAddedKeyBindingHandler(const Editor::KeyBindingViewModel& senderVM, const IInspectable& args);
350+
351+
void _CmdVMPropertyChangedHandler(const IInspectable& sender, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args);
352+
void _CmdVMEditRequestedHandler(const Editor::CommandViewModel& senderVM, const IInspectable& args);
353+
void _CmdVMDeleteRequestedHandler(const Editor::CommandViewModel& senderVM, const IInspectable& args);
354+
void _CmdVMPropagateColorSchemeRequestedHandler(const IInspectable& sender, const Editor::ArgWrapper& wrapper);
355+
void _CmdVMPropagateColorSchemeNamesRequestedHandler(const IInspectable& sender, const Editor::ArgWrapper& wrapper);
128356
};
129357
}
130358

0 commit comments

Comments
 (0)