start of modify keybinding

This commit is contained in:
Pankaj Bhojwani
2024-09-17 18:35:40 -07:00
parent 44bc11206b
commit 5a188c220e
4 changed files with 246 additions and 50 deletions

View File

@@ -69,17 +69,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void KeyBindingViewModel::ToggleEditMode()
{
IsInEditMode(true);
//// toggle edit mode
//IsInEditMode(!_IsInEditMode);
//if (_IsInEditMode)
//{
// // if we're in edit mode,
// // - pre-populate the text box with the current keys
// // - reset the combo box with the current action
// ProposedKeys(_CurrentKeys);
// ProposedAction(box_value(_CurrentAction));
//}
// toggle edit mode
IsInEditMode(!_IsInEditMode);
if (_IsInEditMode)
{
// if we're in edit mode,
// - pre-populate the text box with the current keys
// - reset the combo box with the current action
ProposedKeys(_CurrentKeys);
ProposedAction(box_value(_CurrentAction));
}
}
void KeyBindingViewModel::AttemptAcceptChanges()
@@ -108,15 +107,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
CommandViewModel::CommandViewModel(Command cmd, std::vector<Control::KeyChord> keyChordList) :
_command{ cmd }
CommandViewModel::CommandViewModel(Command cmd, std::vector<Control::KeyChord> keyChordList, const Editor::ActionsViewModel actionsPageVM) :
_command{ cmd },
_actionsPageVM{ actionsPageVM }
{
std::vector<Editor::KeyChordViewModel> keyChordVMs;
for (const auto keys : keyChordList)
{
auto container{ make_self<KeyChordViewModel>(keys) };
//_RegisterEvents(container); todo: implement the event handlers
keyChordVMs.push_back(*container);
auto kcVM{ make<KeyChordViewModel>(keys) };
_RegisterEvents(kcVM);
keyChordVMs.push_back(kcVM);
}
_KeyChordViewModelList = single_threaded_observable_vector(std::move(keyChordVMs));
}
@@ -152,11 +152,45 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
EditRequested.raise(*this, *this);
}
void CommandViewModel::_RegisterEvents(Editor::KeyChordViewModel kcVM)
{
if (const auto actionsPageVM{ _actionsPageVM.get() })
{
kcVM.ModifyKeyChordRequested([actionsPageVM](const Editor::KeyChordViewModel& sender, const Editor::ModifyKeyChordEventArgs& args) {
actionsPageVM.AttemptModifyKeyBinding(sender, args);
});
}
}
KeyChordViewModel::KeyChordViewModel(Control::KeyChord currentKeys) :
_CurrentKeys{ currentKeys }
{
}
void KeyChordViewModel::ToggleEditMode()
{
// toggle edit mode
IsInEditMode(!_IsInEditMode);
if (_IsInEditMode)
{
// if we're in edit mode,
// - pre-populate the text box with the current keys
ProposedKeys(_CurrentKeys);
}
}
void KeyChordViewModel::AttemptAcceptChanges()
{
const auto args{ make_self<ModifyKeyChordEventArgs>(_CurrentKeys, // OldKeys
_ProposedKeys) }; // NewKeys
ModifyKeyChordRequested.raise(*this, *args);
}
void KeyChordViewModel::CancelChanges()
{
ToggleEditMode();
}
ActionsViewModel::ActionsViewModel(Model::CascadiaSettings settings) :
_Settings{ settings }
{
@@ -187,7 +221,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
std::vector<Control::KeyChord> keyChordList;
// todo: need to loop through all the keybindings that point to this command here
keyChordList.emplace_back(keys);
auto cmdVM{ make_self<CommandViewModel>(cmd, keyChordList) };
auto cmdVM{ make_self<CommandViewModel>(cmd, keyChordList, *this) };
_RegisterCmdVMEvents(cmdVM);
commandList.push_back(*cmdVM);
}
@@ -240,6 +274,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return _CurrentCommand;
}
void ActionsViewModel::AttemptModifyKeyBinding(const Editor::KeyChordViewModel& senderVM, const Editor::ModifyKeyChordEventArgs& /*args*/)
{
senderVM.ToggleEditMode();
}
void ActionsViewModel::_KeyBindingViewModelPropertyChangedHandler(const IInspectable& sender, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args)
{
const auto senderVM{ sender.as<Editor::KeyBindingViewModel>() };
@@ -248,32 +287,31 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
if (senderVM.IsInEditMode())
{
CurrentPage(ActionsSubPage::Edit);
// Ensure that...
// 1. we move focus to the edit mode controls
// 2. any actions that were newly added are removed
// 3. this is the only entry that is in edit mode
//for (int32_t i = _KeyBindingList.Size() - 1; i >= 0; --i)
//{
// const auto& kbdVM{ _KeyBindingList.GetAt(i) };
// if (senderVM == kbdVM)
// {
// // This is the view model entry that went into edit mode.
// // Emit an event to let the page know to move focus to
// // this VM's container.
// FocusContainer.raise(*this, senderVM);
// }
// else if (kbdVM.IsNewlyAdded())
// {
// // Remove any actions that were newly added
// _KeyBindingList.RemoveAt(i);
// }
// else
// {
// // Exit edit mode for all other containers
// get_self<KeyBindingViewModel>(kbdVM)->DisableEditMode();
// }
//}
for (int32_t i = _KeyBindingList.Size() - 1; i >= 0; --i)
{
const auto& kbdVM{ _KeyBindingList.GetAt(i) };
if (senderVM == kbdVM)
{
// This is the view model entry that went into edit mode.
// Emit an event to let the page know to move focus to
// this VM's container.
FocusContainer.raise(*this, senderVM);
}
else if (kbdVM.IsNewlyAdded())
{
// Remove any actions that were newly added
_KeyBindingList.RemoveAt(i);
}
else
{
// Exit edit mode for all other containers
get_self<KeyBindingViewModel>(kbdVM)->DisableEditMode();
}
}
}
else
{

View File

@@ -8,6 +8,7 @@
#include "CommandViewModel.g.h"
#include "KeyChordViewModel.g.h"
#include "ModifyKeyBindingEventArgs.g.h"
#include "ModifyKeyChordEventArgs.g.h"
#include "Utils.h"
#include "ViewModelHelpers.h"
@@ -44,6 +45,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
WINRT_PROPERTY(hstring, NewActionName);
};
struct ModifyKeyChordEventArgs : ModifyKeyChordEventArgsT<ModifyKeyChordEventArgs>
{
public:
ModifyKeyChordEventArgs(const Control::KeyChord& oldKeys, const Control::KeyChord& newKeys) :
_OldKeys{ oldKeys },
_NewKeys{ newKeys } {}
WINRT_PROPERTY(Control::KeyChord, OldKeys, nullptr);
WINRT_PROPERTY(Control::KeyChord, NewKeys, nullptr);
};
struct KeyBindingViewModel : KeyBindingViewModelT<KeyBindingViewModel>, ViewModelHelper<KeyBindingViewModel>
{
public:
@@ -112,7 +124,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
struct CommandViewModel : CommandViewModelT<CommandViewModel>, ViewModelHelper<CommandViewModel>
{
public:
CommandViewModel(winrt::Microsoft::Terminal::Settings::Model::Command cmd, std::vector<Control::KeyChord> keyChordList);
CommandViewModel(winrt::Microsoft::Terminal::Settings::Model::Command cmd,
std::vector<Control::KeyChord> keyChordList,
const Editor::ActionsViewModel actionsPageVM);
winrt::hstring Name();
void Name(const winrt::hstring& newName);
@@ -129,6 +143,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
private:
winrt::Microsoft::Terminal::Settings::Model::Command _command;
weak_ref<Editor::ActionsViewModel> _actionsPageVM{ nullptr };
void _RegisterEvents(Editor::KeyChordViewModel kcVM);
};
struct KeyChordViewModel : KeyChordViewModelT<KeyChordViewModel>, ViewModelHelper<KeyChordViewModel>
@@ -138,6 +154,16 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
hstring KeyChordText() { return Model::KeyChordSerialization::ToString(_CurrentKeys); };
void ToggleEditMode();
void AttemptAcceptChanges();
void CancelChanges();
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsInEditMode, false);
VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, ProposedKeys);
public:
til::typed_event<Editor::KeyChordViewModel, Editor::ModifyKeyChordEventArgs> ModifyKeyChordRequested;
private:
Control::KeyChord _CurrentKeys;
};
@@ -153,6 +179,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void CurrentCommand(const Editor::CommandViewModel& newCommand);
Editor::CommandViewModel CurrentCommand();
void AttemptModifyKeyBinding(const Editor::KeyChordViewModel& senderVM, const Editor::ModifyKeyChordEventArgs& args);
til::typed_event<IInspectable, IInspectable> FocusContainer;
til::typed_event<IInspectable, IInspectable> UpdateBackground;

View File

@@ -11,6 +11,12 @@ namespace Microsoft.Terminal.Settings.Editor
String NewActionName { get; };
}
runtimeclass ModifyKeyChordEventArgs
{
Microsoft.Terminal.Control.KeyChord OldKeys { get; };
Microsoft.Terminal.Control.KeyChord NewKeys { get; };
}
runtimeclass KeyBindingViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
// Settings Model side
@@ -63,6 +69,15 @@ namespace Microsoft.Terminal.Settings.Editor
runtimeclass KeyChordViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String KeyChordText { get; };
// UI side
Microsoft.Terminal.Control.KeyChord ProposedKeys;
Boolean IsInEditMode { get; };
void ToggleEditMode();
void AttemptAcceptChanges();
void CancelChanges();
event Windows.Foundation.TypedEventHandler<KeyChordViewModel, ModifyKeyChordEventArgs> ModifyKeyChordRequested;
}
enum ActionsSubPage
@@ -85,6 +100,8 @@ namespace Microsoft.Terminal.Settings.Editor
ActionsSubPage CurrentPage;
CommandViewModel CurrentCommand;
void AttemptModifyKeyBinding(KeyChordViewModel senderVM, ModifyKeyChordEventArgs args);
IObservableVector<CommandViewModel> CommandList { get; };
}
}

View File

@@ -26,6 +26,39 @@
<Setter Property="CornerRadius" Value="1" />
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
<!-- Override visual states -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- Define the appearance of the button -->
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="KeyChordTextBlockStyle"
TargetType="TextBlock">
@@ -40,6 +73,39 @@
<Setter Property="CornerRadius" Value="1" />
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
<!-- Override visual states -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed" />
<VisualState x:Name="Disabled" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!-- Define the appearance of the button -->
<Border x:Name="border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="KeyChordTextBlockStyle"
TargetType="TextBlock">
@@ -63,21 +129,68 @@
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="XYFocusKeyboardNavigation" Value="Enabled" />
</Style>
<Style x:Key="KeyChordEditorStyle"
TargetType="local:KeyChordListener">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<x:Int32 x:Key="EditButtonSize">32</x:Int32>
<x:Double x:Key="EditButtonIconSize">15</x:Double>
<Style x:Key="EditButtonStyle"
BasedOn="{StaticResource DefaultButtonStyle}"
TargetType="Button">
<Setter Property="Padding" Value="0" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
</Style>
<Style x:Key="AccentEditButtonStyle"
BasedOn="{StaticResource AccentButtonStyle}"
TargetType="Button">
<Setter Property="Padding" Value="3" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
</Style>
<!-- Templates -->
<DataTemplate x:Key="KeyChordTemplate"
x:DataType="local:KeyChordViewModel">
<ListViewItem Style="{StaticResource KeyBindingContainerStyle}">
<Button Grid.Column="1"
Padding="2,0,2,0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{ThemeResource KeyChordBorderStyle}">
<TextBlock FontSize="14"
Style="{ThemeResource KeyChordTextBlockStyle}"
Text="{x:Bind KeyChordText}"
TextWrapping="WrapWholeWords"/>
</Button>
<StackPanel Padding="2,0,2,0"
VerticalAlignment="Center">
<Button Style="{ThemeResource KeyChordBorderStyle}"
Click="{x:Bind ToggleEditMode}"
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
<TextBlock FontSize="14"
Style="{ThemeResource KeyChordTextBlockStyle}"
Text="{x:Bind KeyChordText}"
TextWrapping="WrapWholeWords"/>
</Button>
<StackPanel Orientation="Horizontal"
Spacing="8"
Visibility="{x:Bind IsInEditMode, Mode=OneWay}">
<!-- Edit Mode: Key Chord Listener -->
<local:KeyChordListener Keys="{x:Bind ProposedKeys, Mode=TwoWay}"
Style="{StaticResource KeyChordEditorStyle}"/>
<!-- Cancel editing the action -->
<Button x:Uid="Actions_CancelButton"
Style="{StaticResource EditButtonStyle}"
Click="{x:Bind CancelChanges}">
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
Glyph="&#xE711;" />
</Button>
<!-- Accept changes -->
<Button x:Uid="Actions_AcceptButton"
Style="{StaticResource AccentEditButtonStyle}"
Click="{x:Bind AttemptAcceptChanges}">
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
Glyph="&#xE8FB;" />
</Button>
</StackPanel>
</StackPanel>
</ListViewItem>
</DataTemplate>
</ResourceDictionary>