flags work

This commit is contained in:
Pankaj Bhojwani
2025-02-13 16:03:00 -08:00
parent 87c79b3b18
commit 4623575b79
9 changed files with 170 additions and 18 deletions

View File

@@ -44,6 +44,37 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
std::sort(enumList.begin(), enumList.end(), EnumEntryReverseComparator<enumType>()); \
_EnumList = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(std::move(enumList));
#define INITIALIZE_FLAG_LIST_AND_VALUE(enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \
std::vector<winrt::Microsoft::Terminal::Settings::Editor::FlagEntry> flagList; \
const auto mappings = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::enumMappingsName(); \
enumType unboxedValue; \
if (value) \
{ \
unboxedValue = unbox_value<enumType>(value); \
} \
for (const auto [flagKey, flagValue] : mappings) \
{ \
if (flagKey != L"all" && flagKey != L"none") \
{ \
const auto flagName = LocalizedNameForEnumName(resourceSectionAndType, flagKey, resourceProperty); \
bool isSet = value ? WI_IsAnyFlagSet(unboxedValue, flagValue) : false; \
auto entry = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::FlagEntry>(flagName, winrt::box_value<enumType>(flagValue), isSet); \
entry.PropertyChanged([&, flagValue](const IInspectable& sender, const PropertyChangedEventArgs& args) { \
const auto itemProperty{ args.PropertyName() }; \
if (itemProperty == L"IsSet") \
{ \
const auto flagWrapper = sender.as<Microsoft::Terminal::Settings::Editor::FlagEntry>(); \
auto unboxed = unbox_value<enumType>(_Value); \
flagWrapper.IsSet() ? WI_SetAllFlags(unboxed, flagValue) : WI_ClearAllFlags(unboxed, flagValue); \
Value(box_value(unboxed)); \
} \
}); \
flagList.emplace_back(entry); \
} \
} \
std::sort(flagList.begin(), flagList.end(), FlagEntryReverseComparator<enumType>()); \
_FlagList = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::FlagEntry>(std::move(flagList));
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
KeyBindingViewModel::KeyBindingViewModel(const IObservableVector<hstring>& availableActions) :
@@ -175,7 +206,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
const auto emptyArgs = CascadiaSettings::GetEmptyArgsForAction(actionEnum);
// todo: for sendInput, where "input" is a required argument, this will set it to an empty string which does not satisfy the requirement
// i.e. if the user hits "save" immediately after switching to sendInput as the action (without adding something to the input field), they'll get an error
emptyArgs.SetAllArgsToDefault();
if (emptyArgs)
{
emptyArgs.SetAllArgsToDefault();
}
Model::ActionAndArgs newActionAndArgs{ actionEnum, emptyArgs };
_command.ActionAndArgs(newActionAndArgs);
ActionArgsVM(make<ActionArgsViewModel>(newActionAndArgs));
@@ -256,9 +290,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
});
}
ArgWrapper::ArgWrapper(const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value)
ArgWrapper::ArgWrapper(const winrt::hstring& name, const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value)
{
Value(value);
_name = name;
_type = type;
_required = required;
if (_type == L"Model::ResizeDirection")
@@ -287,7 +322,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
else if (_type == L"SuggestionsSource")
{
INITIALIZE_ENUM_LIST_AND_VALUE(SuggestionsSource, Model::SuggestionsSource, L"Actions_SuggestionsSource", L"Content");
INITIALIZE_FLAG_LIST_AND_VALUE(SuggestionsSource, Model::SuggestionsSource, L"Actions_SuggestionsSource", L"Content");
}
else if (_type == L"FindMatchDirection")
{
@@ -324,7 +359,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
if (_EnumValue != enumValue)
{
_EnumValue = enumValue;
Value(enumValue.as<Editor::EnumEntry>().EnumValue());
Value(_EnumValue.as<Editor::EnumEntry>().EnumValue());
}
}
@@ -342,9 +377,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
const auto argAtIndex = shortcutArgs.GetArgAt(i);
const auto argDescription = shortcutArgs.GetArgDescriptionAt(i);
const auto argName = argDescription.Name;
const auto argType = argDescription.Type;
const auto argRequired = argDescription.Required;
const auto item = make<ArgWrapper>(argType, argRequired, argAtIndex);
const auto item = make<ArgWrapper>(argName, argType, argRequired, argAtIndex);
item.PropertyChanged([&, i](const IInspectable& sender, const PropertyChangedEventArgs& args) {
const auto itemProperty{ args.PropertyName() };
if (itemProperty == L"Value")

View File

@@ -168,7 +168,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper>
{
public:
ArgWrapper(const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value);
ArgWrapper(const winrt::hstring& name, const winrt::hstring& type, const bool required, const Windows::Foundation::IInspectable& value);
winrt::hstring Name() const noexcept { return _name; };
winrt::hstring Type() const noexcept { return _type; };
@@ -176,6 +178,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::EnumEntry> EnumList() const noexcept { return _EnumList; };
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::FlagEntry> FlagList() const noexcept { return _FlagList; };
void StringBindBack(const winrt::hstring& newValue) { Value(box_value(newValue)); };
void DoubleBindBack(const double newValue) { Value(box_value(static_cast<uint32_t>(newValue))); };
@@ -203,10 +207,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::IInspectable, Value, nullptr);
private:
winrt::hstring _name;
winrt::hstring _type;
bool _required;
Windows::Foundation::IInspectable _EnumValue{ nullptr };
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::EnumEntry> _EnumList;
Windows::Foundation::Collections::IObservableVector<Microsoft::Terminal::Settings::Editor::FlagEntry> _FlagList;
};
struct ActionArgsViewModel : ActionArgsViewModelT<ActionArgsViewModel>, ViewModelHelper<ActionArgsViewModel>

View File

@@ -78,11 +78,13 @@ namespace Microsoft.Terminal.Settings.Editor
runtimeclass ArgWrapper : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String Name { get; };
String Type { get; };
Boolean Required { get; };
IInspectable Value;
IInspectable EnumValue;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> EnumList { get; };
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.FlagEntry> FlagList { get; };
void StringBindBack(String newValue);
void DoubleBindBack(Double newValue);
void DoubleOptionalBindBack(Double newValue);

View File

@@ -63,7 +63,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
argType == L"MoveTabDirection" ||
argType == L"Microsoft::Terminal::Control::ScrollToMarkDirection" ||
argType == L"CommandPaletteLaunchMode" ||
argType == L"SuggestionsSource" ||
argType == L"FindMatchDirection" ||
argType == L"Model::DesktopBehavior" ||
argType == L"Model::MonitorBehavior" ||
@@ -72,11 +71,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
return EnumTemplate();
}
else if (argType == L"SuggestionsSource")
{
return FlagTemplate();
}
else if (argType == L"Windows::Foundation::IReference<Control::CopyFormat>")
{
return nullptr;
}
}
return nullptr;
return NoArgTemplate();
}
}

View File

@@ -14,6 +14,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::UI::Xaml::DependencyObject&);
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable&);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, NoArgTemplate);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, Int32Template);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, UInt32Template);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, UInt32OptionalTemplate);
@@ -22,6 +23,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, BoolTemplate);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, BoolOptionalTemplate);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, EnumTemplate);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, FlagTemplate);
};
}

View File

@@ -7,6 +7,7 @@ namespace Microsoft.Terminal.Settings.Editor
{
ArgsTemplateSelectors();
Windows.UI.Xaml.DataTemplate NoArgTemplate;
Windows.UI.Xaml.DataTemplate Int32Template;
Windows.UI.Xaml.DataTemplate UInt32Template;
Windows.UI.Xaml.DataTemplate UInt32OptionalTemplate;
@@ -15,5 +16,6 @@ namespace Microsoft.Terminal.Settings.Editor
Windows.UI.Xaml.DataTemplate BoolTemplate;
Windows.UI.Xaml.DataTemplate BoolOptionalTemplate;
Windows.UI.Xaml.DataTemplate EnumTemplate;
Windows.UI.Xaml.DataTemplate FlagTemplate;
}
}

View File

@@ -225,10 +225,18 @@
<ListViewItem HorizontalContentAlignment="Stretch" />
</DataTemplate>
<DataTemplate x:Key="NoArgTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem />
</DataTemplate>
<DataTemplate x:Key="Int32Template"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<muxc:NumberBox Value="{x:Bind mtu:Converters.UnboxInt32(Value), Mode=TwoWay, BindBack=DoubleBindBack}"
Style="{StaticResource NumberBoxSettingStyle}"
Minimum="0"
@@ -242,7 +250,10 @@
<DataTemplate x:Key="UInt32Template"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<muxc:NumberBox Value="{x:Bind mtu:Converters.UnboxUInt32(Value), Mode=TwoWay, BindBack=DoubleBindBack}"
Style="{StaticResource NumberBoxSettingStyle}"
Minimum="0"
@@ -256,7 +267,10 @@
<DataTemplate x:Key="UInt32OptionalTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<muxc:NumberBox Value="{x:Bind mtu:Converters.UnboxUInt32Optional(Value), Mode=TwoWay, BindBack=DoubleOptionalBindBack}"
Style="{StaticResource NumberBoxSettingStyle}"
Minimum="0"
@@ -270,7 +284,10 @@
<DataTemplate x:Key="FloatTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<muxc:NumberBox Value="{x:Bind mtu:Converters.UnboxFloat(Value), Mode=TwoWay, BindBack=FloatBindBack}"
Style="{StaticResource NumberBoxSettingStyle}"
Minimum="0"
@@ -284,7 +301,10 @@
<DataTemplate x:Key="StringTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<TextBox Text="{x:Bind mtu:Converters.UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}" />
</StackPanel>
</ListViewItem>
@@ -293,7 +313,10 @@
<DataTemplate x:Key="BoolTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<CheckBox IsChecked="{x:Bind mtu:Converters.UnboxBool(Value), Mode=TwoWay, BindBack=BoolBindBack}" />
</StackPanel>
</ListViewItem>
@@ -302,7 +325,10 @@
<DataTemplate x:Key="BoolOptionalTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<CheckBox IsChecked="{x:Bind mtu:Converters.UnboxBoolOptional(Value), Mode=TwoWay, BindBack=BoolBindBack}"
IsThreeState="True" />
</StackPanel>
@@ -317,7 +343,10 @@
<DataTemplate x:Key="EnumTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<ComboBox ItemTemplate="{StaticResource EnumComboBoxTemplate}"
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
SelectedItem="{x:Bind EnumValue, Mode=TwoWay}"
@@ -326,7 +355,31 @@
</ListViewItem>
</DataTemplate>
<DataTemplate x:Key="FlagItemTemplate"
x:DataType="local:FlagEntry">
<StackPanel Orientation="Horizontal"
Spacing="8">
<CheckBox IsChecked="{x:Bind IsSet, Mode=TwoWay}"/>
<TextBlock Text="{x:Bind FlagName, Mode=OneWay}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="FlagTemplate"
x:DataType="local:ArgWrapper">
<ListViewItem>
<StackPanel Orientation="Horizontal"
Spacing="8">
<TextBlock Text="{x:Bind Name}"
VerticalAlignment="Center" />
<ListView ItemTemplate="{StaticResource FlagItemTemplate}"
SelectionMode="None"
ItemsSource="{x:Bind FlagList, Mode=OneWay}" />
</StackPanel>
</ListViewItem>
</DataTemplate>
<local:ArgsTemplateSelectors x:Key="ArgsTemplateSelector"
NoArgTemplate="{StaticResource NoArgTemplate}"
Int32Template="{StaticResource Int32Template}"
UInt32Template="{StaticResource UInt32Template}"
UInt32OptionalTemplate="{StaticResource UInt32OptionalTemplate}"
@@ -334,7 +387,8 @@
StringTemplate="{StaticResource StringTemplate}"
BoolTemplate="{StaticResource BoolTemplate}"
BoolOptionalTemplate="{StaticResource BoolOptionalTemplate}"
EnumTemplate="{StaticResource EnumTemplate}" />
EnumTemplate="{StaticResource EnumTemplate}"
FlagTemplate="{StaticResource FlagTemplate}" />
</ResourceDictionary>
</Page.Resources>
@@ -358,7 +412,9 @@
ChoosingItemContainer="_choosingItemContainer"
SelectionMode="None"
AllowDrop="False"
CanReorderItems="False" />
CanDragItems="False"
CanReorderItems="False">
</ListView>
<ListView ItemTemplate="{StaticResource KeyChordTemplate}"
ItemsSource="{x:Bind ViewModel.KeyChordViewModelList, Mode=OneWay}"
SelectionMode="None">

View File

@@ -17,6 +17,7 @@ Author(s):
#pragma once
#include "EnumEntry.g.h"
#include "FlagEntry.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
@@ -55,4 +56,41 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, EnumName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::Foundation::IInspectable, EnumValue, PropertyChanged.raise);
};
template<typename T>
struct FlagEntryComparator
{
bool operator()(const Editor::FlagEntry& lhs, const Editor::FlagEntry& rhs) const
{
return lhs.FlagValue().as<T>() < rhs.FlagValue().as<T>();
}
};
template<typename T>
struct FlagEntryReverseComparator
{
bool operator()(const Editor::FlagEntry& lhs, const Editor::FlagEntry& rhs) const
{
return lhs.FlagValue().as<T>() > rhs.FlagValue().as<T>();
}
};
struct FlagEntry : FlagEntryT<FlagEntry>
{
public:
FlagEntry(const winrt::hstring flagName, const winrt::Windows::Foundation::IInspectable& flagValue, const bool isSet) :
_FlagName{ flagName },
_FlagValue{ flagValue },
_IsSet{ isSet } {}
hstring ToString()
{
return FlagName();
}
til::property_changed_event PropertyChanged;
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, FlagName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(winrt::Windows::Foundation::IInspectable, FlagValue, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(bool, IsSet, PropertyChanged.raise);
};
}

View File

@@ -8,4 +8,11 @@ namespace Microsoft.Terminal.Settings.Editor
String EnumName { get; };
IInspectable EnumValue { get; };
}
[default_interface] runtimeclass FlagEntry : Windows.UI.Xaml.Data.INotifyPropertyChanged, Windows.Foundation.IStringable
{
String FlagName { get; };
IInspectable FlagValue { get; };
Boolean IsSet;
}
}