mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 18:43:54 -06:00
Add nullable colors and improve Profile.Icon in settings UI (#17870)
## Summary of the Pull Request Adds some pre-existing settings ($profile.foreground, $profile.background, $profile.selectionBackground, $profile.cursorColor) to the settings UI. This was accomplished by introducing a new control: NullableColorPicker. This control allows the user to pick a color from the color scheme, set the color to null, and select a color from an advanced color picker. Improves the UI for the Profile.Icon setting by adding an "Icon Type" combo box. This allows the user to pick from multiple options: - None: sets the icon to "none" which is interpreted as no icon - Built-in Icon: presents a combo box that enumerates the Segoe MDL 2 assets - Emoji: presents a text box with a hint to open the emoji picker - File: presents a text box to input the path of the image to use Additionally, the rendered icon is displayed in the setting container. If "none", "none" is presented to the user (localized). ## References and Relevant Issues #10000 ## Detailed Description of the Pull Request / Additional comments - NullableColorPicker control - includes a built-in NullColorButton to set the current value to null - includes a "More colors..." button to display an advanced color picker - uses data templates on data templates (data templates squared?) to convert the current color scheme into a grid of color chips - color chips display a checkmark (similar to Windows settings personalization). This automatically updates its color to stay compliant with color contrast. - color chips are added to a list so we can (un)check them when a new color is selected - SettingsContainer changes - Forked `ExpanderSettingContainerStyle` to allow for a custom preview template. This way, we can display the current value in the expander and we're not just limited to text. - changed type of `CurrentValue` property from `String` to `IInspectable` - added `CurrentValueTemplate` property to control how to display the current value - Miscellaneous: - Added a few converters (`BooleanToVisibility`, `ColorToString`, `ColorToBrush`) - Added `NameWithHexCode` to `ColorTableEntry` to expose a color as `Red #RRGGBB` (used for tooltips and a11y) - Added `ForegroundPreview` (and equivalent for other colors) to AppearanceViewModel to deduce the color that will be used ## Validation Steps Performed - [X] a11y pass (NVDA, keyboard) - [X] set the color to one of the color chips - [X] set the color to null - [X] set the color to a value from the integrated color picker - [X] control updates properly when a new color scheme is selected - [X] control updates properly when a color scheme has multiple colors of the same value ## Follow-ups - [A11y] Screen readers don't read expander's preview text - Add Tab Color to settings UI - Update CursorColor preview to display #FFFFFF as "invert" - Use Leonard's font picker UI, with the Segoe icon picker, so that you can filter the list
This commit is contained in:
parent
bfab5fde4d
commit
5132f9c553
1
.github/actions/spelling/excludes.txt
vendored
1
.github/actions/spelling/excludes.txt
vendored
@ -99,6 +99,7 @@ Resources/(?!en)
|
||||
^NOTICE.md
|
||||
^oss/
|
||||
^samples/PixelShaders/Screenshots/
|
||||
^src/cascadia/TerminalSettingsEditor/SegoeFluentIconList.h$
|
||||
^src/interactivity/onecore/BgfxEngine\.
|
||||
^src/renderer/atlas/
|
||||
^src/renderer/wddmcon/WddmConRenderer\.
|
||||
|
||||
@ -221,6 +221,30 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// box, prevent it from ever being changed again.
|
||||
_NotifyChanges(L"UseDesktopBGImage", L"BackgroundImageSettingsVisible");
|
||||
}
|
||||
else if (viewModelProperty == L"Foreground")
|
||||
{
|
||||
_NotifyChanges(L"ForegroundPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"Background")
|
||||
{
|
||||
_NotifyChanges(L"BackgroundPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"SelectionBackground")
|
||||
{
|
||||
_NotifyChanges(L"SelectionBackgroundPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"CursorColor")
|
||||
{
|
||||
_NotifyChanges(L"CursorColorPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"DarkColorSchemeName" || viewModelProperty == L"LightColorSchemeName")
|
||||
{
|
||||
_NotifyChanges(L"CurrentColorScheme");
|
||||
}
|
||||
else if (viewModelProperty == L"CurrentColorScheme")
|
||||
{
|
||||
_NotifyChanges(L"ForegroundPreview", L"BackgroundPreview", L"SelectionBackgroundPreview", L"CursorColorPreview");
|
||||
}
|
||||
});
|
||||
|
||||
// Cache the original BG image path. If the user clicks "Use desktop
|
||||
@ -928,7 +952,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_NotifyChanges(L"CurrentColorScheme");
|
||||
}
|
||||
|
||||
Editor::ColorSchemeViewModel AppearanceViewModel::CurrentColorScheme()
|
||||
Editor::ColorSchemeViewModel AppearanceViewModel::CurrentColorScheme() const
|
||||
{
|
||||
const auto schemeName{ DarkColorSchemeName() };
|
||||
const auto allSchemes{ SchemesList() };
|
||||
@ -950,6 +974,42 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
LightColorSchemeName(val.Name());
|
||||
}
|
||||
|
||||
static inline Windows::UI::Color _getColorPreview(const IReference<Microsoft::Terminal::Core::Color>& modelVal, Windows::UI::Color deducedVal)
|
||||
{
|
||||
if (modelVal)
|
||||
{
|
||||
// user defined an override value
|
||||
return Windows::UI::Color{
|
||||
.A = 255,
|
||||
.R = modelVal.Value().R,
|
||||
.G = modelVal.Value().G,
|
||||
.B = modelVal.Value().B
|
||||
};
|
||||
}
|
||||
// set to null --> deduce value from color scheme
|
||||
return deducedVal;
|
||||
}
|
||||
|
||||
Windows::UI::Color AppearanceViewModel::ForegroundPreview() const
|
||||
{
|
||||
return _getColorPreview(_appearance.Foreground(), CurrentColorScheme().ForegroundColor().Color());
|
||||
}
|
||||
|
||||
Windows::UI::Color AppearanceViewModel::BackgroundPreview() const
|
||||
{
|
||||
return _getColorPreview(_appearance.Background(), CurrentColorScheme().BackgroundColor().Color());
|
||||
}
|
||||
|
||||
Windows::UI::Color AppearanceViewModel::SelectionBackgroundPreview() const
|
||||
{
|
||||
return _getColorPreview(_appearance.SelectionBackground(), CurrentColorScheme().SelectionBackgroundColor().Color());
|
||||
}
|
||||
|
||||
Windows::UI::Color AppearanceViewModel::CursorColorPreview() const
|
||||
{
|
||||
return _getColorPreview(_appearance.CursorColor(), CurrentColorScheme().CursorColor().Color());
|
||||
}
|
||||
|
||||
DependencyProperty Appearances::_AppearanceProperty{ nullptr };
|
||||
|
||||
Appearances::Appearances()
|
||||
|
||||
@ -127,9 +127,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void SetBackgroundImagePath(winrt::hstring path);
|
||||
|
||||
void ClearColorScheme();
|
||||
Editor::ColorSchemeViewModel CurrentColorScheme();
|
||||
Editor::ColorSchemeViewModel CurrentColorScheme() const;
|
||||
void CurrentColorScheme(const Editor::ColorSchemeViewModel& val);
|
||||
|
||||
Windows::UI::Color ForegroundPreview() const;
|
||||
Windows::UI::Color BackgroundPreview() const;
|
||||
Windows::UI::Color SelectionBackgroundPreview() const;
|
||||
Windows::UI::Color CursorColorPreview() const;
|
||||
|
||||
WINRT_PROPERTY(bool, IsDefault, false);
|
||||
|
||||
// These settings are not defined in AppearanceConfig, so we grab them
|
||||
@ -153,6 +158,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, BackgroundImageAlignment);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, IntenseTextStyle);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, AdjustIndistinguishableColors);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, Foreground);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, Background);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, SelectionBackground);
|
||||
OBSERVABLE_PROJECTED_SETTING(_appearance, CursorColor);
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::ColorSchemeViewModel>, SchemesList, _propertyChangedHandlers, nullptr);
|
||||
|
||||
private:
|
||||
|
||||
@ -45,6 +45,11 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
ColorSchemeViewModel CurrentColorScheme;
|
||||
IObservableVector<ColorSchemeViewModel> SchemesList;
|
||||
|
||||
Windows.UI.Color ForegroundPreview { get; };
|
||||
Windows.UI.Color BackgroundPreview { get; };
|
||||
Windows.UI.Color SelectionBackgroundPreview { get; };
|
||||
Windows.UI.Color CursorColorPreview { get; };
|
||||
|
||||
String MissingFontFaces { get; };
|
||||
String ProportionalFontFaces { get; };
|
||||
Boolean HasPowerlineCharacters { get; };
|
||||
@ -78,6 +83,11 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Settings.Model.ConvergedAlignment, BackgroundImageAlignment);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Settings.Model.IntenseStyle, IntenseTextStyle);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Microsoft.Terminal.Core.AdjustTextMode, AdjustIndistinguishableColors);
|
||||
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Foreground);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Background);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, SelectionBackground);
|
||||
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, CursorColor);
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass Appearances : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
|
||||
@ -69,138 +69,188 @@
|
||||
<!-- Grouping: Text -->
|
||||
<TextBlock x:Uid="Profile_TextHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Color Scheme -->
|
||||
<!-- This currently only display the Dark color scheme, even if the user has a pair of schemes set. -->
|
||||
<local:SettingContainer x:Uid="Profile_ColorScheme"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearColorScheme}"
|
||||
HasSettingValue="{x:Bind Appearance.HasDarkColorSchemeName, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.DarkColorSchemeNameOverrideSource, Mode=OneWay}">
|
||||
<ComboBox Padding="4"
|
||||
ItemsSource="{x:Bind Appearance.SchemesList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind Appearance.CurrentColorScheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:ColorSchemeViewModel">
|
||||
<Grid Grid.Column="0"
|
||||
Padding="8"
|
||||
VerticalAlignment="Center"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
|
||||
ColumnSpacing="1"
|
||||
CornerRadius="2"
|
||||
RowSpacing="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Content="{x:Bind ColorEntryAt(0), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Content="{x:Bind ColorEntryAt(1), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Content="{x:Bind ColorEntryAt(2), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
Content="{x:Bind ColorEntryAt(3), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="4"
|
||||
Content="{x:Bind ColorEntryAt(4), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="5"
|
||||
Content="{x:Bind ColorEntryAt(5), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="6"
|
||||
Content="{x:Bind ColorEntryAt(6), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="7"
|
||||
Content="{x:Bind ColorEntryAt(7), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Content="{x:Bind ColorEntryAt(8), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Content="{x:Bind ColorEntryAt(9), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Content="{x:Bind ColorEntryAt(10), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Content="{x:Bind ColorEntryAt(11), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="4"
|
||||
Content="{x:Bind ColorEntryAt(12), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="5"
|
||||
Content="{x:Bind ColorEntryAt(13), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="6"
|
||||
Content="{x:Bind ColorEntryAt(14), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="7"
|
||||
Content="{x:Bind ColorEntryAt(15), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<TextBlock Grid.RowSpan="2"
|
||||
Grid.Column="8"
|
||||
MaxWidth="192"
|
||||
Margin="4,0,4,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
FontFamily="Cascadia Code"
|
||||
Foreground="{x:Bind mtu:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
|
||||
Text="{x:Bind Name, Mode=OneWay}"
|
||||
TextTrimming="WordEllipsis" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
SettingOverrideSource="{x:Bind Appearance.DarkColorSchemeNameOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<ComboBox Padding="4"
|
||||
ItemsSource="{x:Bind Appearance.SchemesList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind Appearance.CurrentColorScheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:ColorSchemeViewModel">
|
||||
<Grid Grid.Column="0"
|
||||
Padding="8"
|
||||
VerticalAlignment="Center"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
|
||||
ColumnSpacing="1"
|
||||
CornerRadius="2"
|
||||
RowSpacing="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Content="{x:Bind ColorEntryAt(0), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Content="{x:Bind ColorEntryAt(1), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Content="{x:Bind ColorEntryAt(2), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="3"
|
||||
Content="{x:Bind ColorEntryAt(3), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="4"
|
||||
Content="{x:Bind ColorEntryAt(4), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="5"
|
||||
Content="{x:Bind ColorEntryAt(5), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="6"
|
||||
Content="{x:Bind ColorEntryAt(6), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="0"
|
||||
Grid.Column="7"
|
||||
Content="{x:Bind ColorEntryAt(7), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Content="{x:Bind ColorEntryAt(8), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Content="{x:Bind ColorEntryAt(9), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Content="{x:Bind ColorEntryAt(10), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="3"
|
||||
Content="{x:Bind ColorEntryAt(11), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="4"
|
||||
Content="{x:Bind ColorEntryAt(12), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="5"
|
||||
Content="{x:Bind ColorEntryAt(13), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="6"
|
||||
Content="{x:Bind ColorEntryAt(14), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Grid.Row="1"
|
||||
Grid.Column="7"
|
||||
Content="{x:Bind ColorEntryAt(15), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<TextBlock Grid.RowSpan="2"
|
||||
Grid.Column="8"
|
||||
MaxWidth="192"
|
||||
Margin="4,0,4,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
FontFamily="Cascadia Code"
|
||||
Foreground="{x:Bind mtu:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
|
||||
Text="{x:Bind Name, Mode=OneWay}"
|
||||
TextTrimming="WordEllipsis" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<StackPanel>
|
||||
|
||||
<!-- Foreground Color -->
|
||||
<local:SettingContainer x:Name="Foreground"
|
||||
x:Uid="Profile_Foreground"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearForeground}"
|
||||
CurrentValue="{x:Bind Appearance.ForegroundPreview, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasForeground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.ForegroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:NullableColorPicker x:Uid="Profile_Foreground_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.Foreground, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Appearance.CurrentColorScheme.ForegroundColor.Color, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Background Color -->
|
||||
<local:SettingContainer x:Name="Background"
|
||||
x:Uid="Profile_Background"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearBackground}"
|
||||
CurrentValue="{x:Bind Appearance.BackgroundPreview, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasBackground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.BackgroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:NullableColorPicker x:Uid="Profile_Background_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.Background, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Appearance.CurrentColorScheme.BackgroundColor.Color, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Selection Background Color -->
|
||||
<local:SettingContainer x:Name="SelectionBackground"
|
||||
x:Uid="Profile_SelectionBackground"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearSelectionBackground}"
|
||||
CurrentValue="{x:Bind Appearance.SelectionBackgroundPreview, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasSelectionBackground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.SelectionBackgroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:NullableColorPicker x:Uid="Profile_SelectionBackground_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.SelectionBackground, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Appearance.CurrentColorScheme.SelectionBackgroundColor.Color, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
<!-- Font Face -->
|
||||
<local:SettingContainer x:Name="FontFaceContainer"
|
||||
x:Uid="Profile_FontFace"
|
||||
@ -452,6 +502,21 @@
|
||||
Text="{Binding ElementName=CursorHeightSlider, Path=Value, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Cursor Color -->
|
||||
<local:SettingContainer x:Name="CursorColor"
|
||||
x:Uid="Profile_CursorColor"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearCursorColor}"
|
||||
CurrentValue="{x:Bind Appearance.CursorColorPreview, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasCursorColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.CursorColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:NullableColorPicker x:Uid="Profile_CursorColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.CursorColor, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Appearance.CurrentColorScheme.CursorColor.Color, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Background -->
|
||||
|
||||
@ -69,6 +69,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return hstring{ fmt::format(FMT_COMPILE(L"{} RGB({}, {}, {})"), _Name, _Color.R, _Color.G, _Color.B) };
|
||||
}
|
||||
|
||||
hstring NameWithHexCode() const
|
||||
{
|
||||
return hstring{ fmt::format(FMT_COMPILE(L"{} #{:02X}{:02X}{:02X}"), _Name, _Color.R, _Color.G, _Color.B) };
|
||||
}
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::UI::Color, Color, PropertyChanged.raise);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, Name, PropertyChanged.raise);
|
||||
|
||||
@ -36,5 +36,6 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
IInspectable Tag;
|
||||
Windows.UI.Color Color;
|
||||
String AccessibleName { get; };
|
||||
String NameWithHexCode { get; };
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
-->
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
|
||||
|
||||
<!-- Merge SettingContainerStyle here to give every page access to the SettingContainer -->
|
||||
@ -60,6 +62,9 @@
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<local:ColorToBrushConverter x:Key="ColorToBrushConverter" />
|
||||
<local:ColorToStringConverter x:Key="ColorToStringConverter" />
|
||||
|
||||
<Color x:Key="DeleteButtonColor">Firebrick</Color>
|
||||
|
||||
<x:Double x:Key="StandardIconSize">14.0</x:Double>
|
||||
@ -69,6 +74,32 @@
|
||||
<x:Double x:Key="StandardControlMaxWidth">1000</x:Double>
|
||||
<Thickness x:Key="SettingStackMargin">13,0,13,48</Thickness>
|
||||
|
||||
<!-- We're purposefully not providing a DataType here.
|
||||
This is expected to be used with an IReference<Microsoft::Terminal::Core::Color>.
|
||||
We're doing all the data type handling in the used converters.-->
|
||||
<DataTemplate x:Key="ColorPreviewTemplate">
|
||||
<Grid ColumnSpacing="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle Grid.Column="0"
|
||||
Width="13"
|
||||
Height="13"
|
||||
VerticalAlignment="Center"
|
||||
Fill="{Binding Converter={StaticResource ColorToBrushConverter}}"
|
||||
RadiusX="2"
|
||||
RadiusY="2" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{Binding Converter={StaticResource ColorToStringConverter}}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<!--
|
||||
This is for styling the entire items control used on the
|
||||
color schemes page
|
||||
@ -399,6 +430,91 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ColorToggleButtonStyle"
|
||||
TargetType="ToggleButton">
|
||||
<Setter Property="BackgroundSizing" Value="OuterBorderEdge" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ToggleButtonBorderThemeBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ToggleButtonBorderThemeThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="FocusVisualMargin" Value="-3" />
|
||||
<Setter Property="Width" Value="32" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<Grid>
|
||||
<Border x:Name="ColorButtonBorder"
|
||||
BorderBrush="{TemplateBinding Background}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid>
|
||||
<Border x:Name="ColorButtonBackground"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderThickness="0" />
|
||||
<!-- We have to use Binding here! We're trying to do a template binding with a converter, so we have to use the verbose syntax. -->
|
||||
<FontIcon Margin="0,0,-1,-1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
FontFamily="Segoe Fluent Icons"
|
||||
FontSize="12"
|
||||
Foreground="{TemplateBinding BorderBrush}"
|
||||
Glyph=""
|
||||
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled" />
|
||||
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
|
||||
Storyboard.TargetProperty="Opacity">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="0.7" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBorder"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBackground"
|
||||
Storyboard.TargetProperty="Opacity">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="0.5" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBorder"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Checked">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ColorButtonBorder"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Slider-Related Styling -->
|
||||
<Style x:Key="SliderValueLabelStyle"
|
||||
TargetType="TextBlock">
|
||||
|
||||
@ -752,9 +752,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (auto menuItem{ weakMenuItem.get() })
|
||||
{
|
||||
const auto& tag{ menuItem.Tag().as<Editor::ProfileViewModel>() };
|
||||
if (args.PropertyName() == L"Icon")
|
||||
if (args.PropertyName() == L"Icon" || args.PropertyName() == L"EvaluatedIcon")
|
||||
{
|
||||
menuItem.Icon(UI::IconPathConverter::IconWUX(tag.Icon()));
|
||||
menuItem.Icon(UI::IconPathConverter::IconWUX(tag.EvaluatedIcon()));
|
||||
}
|
||||
else if (args.PropertyName() == L"Name")
|
||||
{
|
||||
|
||||
@ -57,6 +57,10 @@
|
||||
<DependentUpon>ColorSchemes.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NullableColorPicker.h">
|
||||
<DependentUpon>NullableColorPicker.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EditColorScheme.h">
|
||||
<DependentUpon>EditColorScheme.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@ -88,6 +92,11 @@
|
||||
<DependentUpon>ActionsViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SegoeFluentIconList.h" />
|
||||
<ClInclude Include="TerminalColorConverters.h">
|
||||
<DependentUpon>TerminalColorConverters.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ColorSchemeViewModel.h">
|
||||
<DependentUpon>ColorSchemeViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@ -166,6 +175,9 @@
|
||||
<Page Include="ColorSchemes.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="NullableColorPicker.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="EditColorScheme.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@ -227,6 +239,10 @@
|
||||
<DependentUpon>ColorSchemes.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NullableColorPicker.cpp">
|
||||
<DependentUpon>NullableColorPicker.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EditColorScheme.cpp">
|
||||
<DependentUpon>EditColorScheme.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@ -261,6 +277,10 @@
|
||||
<DependentUpon>ActionsViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalColorConverters.cpp">
|
||||
<DependentUpon>TerminalColorConverters.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ColorSchemeViewModel.cpp">
|
||||
<DependentUpon>ColorSchemeViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@ -343,6 +363,10 @@
|
||||
<DependentUpon>ColorSchemes.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="NullableColorPicker.idl">
|
||||
<DependentUpon>NullableColorPicker.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="EditColorScheme.idl">
|
||||
<DependentUpon>EditColorScheme.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@ -376,6 +400,7 @@
|
||||
</Midl>
|
||||
<Midl Include="ProfileViewModel.idl" />
|
||||
<Midl Include="ActionsViewModel.idl" />
|
||||
<Midl Include="TerminalColorConverters.idl" />
|
||||
<Midl Include="ColorSchemeViewModel.idl" />
|
||||
<Midl Include="ColorSchemesPageViewModel.idl" />
|
||||
<Midl Include="RenderingViewModel.idl" />
|
||||
@ -439,7 +464,6 @@
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
|
||||
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\dll\TerminalControl.vcxproj">
|
||||
<!-- Private:false and ReferenceOutputAssembly:false, in combination with
|
||||
the manual reference to TerminalControl.winmd below make sure that this
|
||||
@ -452,7 +476,6 @@
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Manually add a reference to TerminalControl here. We need this so
|
||||
MDMERGE will know where the TermControl types are defined. However, we need
|
||||
@ -471,17 +494,13 @@
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
|
||||
|
||||
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
|
||||
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
@ -2,6 +2,7 @@
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
|
||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PRIResource Include="Resources\en-US\Resources.resw" />
|
||||
@ -15,6 +16,7 @@
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="PreviewConnection.h" />
|
||||
<ClInclude Include="SegoeFluentIconList.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="ProfileViewModel.idl" />
|
||||
@ -27,10 +29,10 @@
|
||||
<Midl Include="LaunchViewModel.idl" />
|
||||
<Midl Include="EnumEntry.idl" />
|
||||
<Midl Include="SettingContainer.idl" />
|
||||
<Midl Include="TerminalColorConverters.idl" />
|
||||
<Midl Include="NewTabMenuViewModel.idl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="$(ProjectName).def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -50,6 +52,7 @@
|
||||
<Page Include="SettingContainerStyle.xaml" />
|
||||
<Page Include="AddProfile.xaml" />
|
||||
<Page Include="KeyChordListener.xaml" />
|
||||
<Page Include="NullableColorPicker.xaml" />
|
||||
<Page Include="NewTabMenu.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@ -335,7 +335,8 @@
|
||||
|
||||
<!-- Add Profile -->
|
||||
<local:SettingContainer x:Uid="NewTabMenu_AddProfile"
|
||||
FontIconGlyph="">
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
@ -383,7 +384,8 @@
|
||||
|
||||
<!-- Add Separator -->
|
||||
<local:SettingContainer x:Uid="NewTabMenu_AddSeparator"
|
||||
FontIconGlyph="">
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddSeparatorButton"
|
||||
x:Uid="NewTabMenu_AddSeparatorButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
@ -398,7 +400,8 @@
|
||||
|
||||
<!-- Add Folder -->
|
||||
<local:SettingContainer x:Uid="NewTabMenu_AddFolder"
|
||||
FontIconGlyph="">
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
<TextBox x:Name="FolderNameTextBox"
|
||||
@ -424,7 +427,7 @@
|
||||
<!-- Add Match Profiles -->
|
||||
<local:SettingContainer x:Uid="NewTabMenu_AddMatchProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
|
||||
<StackPanel Spacing="10">
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherName, Mode=TwoWay}" />
|
||||
@ -448,7 +451,8 @@
|
||||
|
||||
<!-- Add Remaining Profiles -->
|
||||
<local:SettingContainer x:Uid="NewTabMenu_AddRemainingProfiles"
|
||||
FontIconGlyph="">
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddRemainingProfilesButton"
|
||||
x:Uid="NewTabMenu_AddRemainingProfilesButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
|
||||
226
src/cascadia/TerminalSettingsEditor/NullableColorPicker.cpp
Normal file
226
src/cascadia/TerminalSettingsEditor/NullableColorPicker.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "NullableColorPicker.h"
|
||||
#include "NullableColorPicker.g.cpp"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::UI;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Media;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Microsoft::UI::Xaml::Controls;
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
namespace MUX = Microsoft::UI::Xaml;
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
static constexpr bool equalsColor(Windows::UI::Color a, Microsoft::Terminal::Core::Color b)
|
||||
{
|
||||
return a.R == b.R && a.G == b.G && a.B == b.B;
|
||||
}
|
||||
|
||||
DependencyProperty NullableColorPicker::_ColorSchemeVMProperty{ nullptr };
|
||||
DependencyProperty NullableColorPicker::_CurrentColorProperty{ nullptr };
|
||||
DependencyProperty NullableColorPicker::_ShowNullColorButtonProperty{ nullptr };
|
||||
DependencyProperty NullableColorPicker::_NullColorButtonLabelProperty{ nullptr };
|
||||
DependencyProperty NullableColorPicker::_NullColorPreviewProperty{ nullptr };
|
||||
|
||||
NullableColorPicker::NullableColorPicker()
|
||||
{
|
||||
_InitializeProperties();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
void NullableColorPicker::_InitializeProperties()
|
||||
{
|
||||
// Initialize any dependency properties here.
|
||||
// This performs a lazy load on these properties, instead of
|
||||
// initializing them when the DLL loads.
|
||||
if (!_ColorSchemeVMProperty)
|
||||
{
|
||||
_ColorSchemeVMProperty =
|
||||
DependencyProperty::Register(
|
||||
L"ColorSchemeVM",
|
||||
xaml_typename<Editor::ColorSchemeViewModel>(),
|
||||
xaml_typename<Editor::NullableColorPicker>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_CurrentColorProperty)
|
||||
{
|
||||
_CurrentColorProperty =
|
||||
DependencyProperty::Register(
|
||||
L"CurrentColor",
|
||||
xaml_typename<Windows::Foundation::IReference<Microsoft::Terminal::Core::Color>>(),
|
||||
xaml_typename<Editor::NullableColorPicker>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &NullableColorPicker::_OnCurrentColorValueChanged } });
|
||||
}
|
||||
if (!_ShowNullColorButtonProperty)
|
||||
{
|
||||
_ShowNullColorButtonProperty =
|
||||
DependencyProperty::Register(
|
||||
L"ShowNullColorButton",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::NullableColorPicker>(),
|
||||
PropertyMetadata{ box_value(true) });
|
||||
}
|
||||
if (!_NullColorButtonLabelProperty)
|
||||
{
|
||||
_NullColorButtonLabelProperty =
|
||||
DependencyProperty::Register(
|
||||
L"NullColorButtonLabel",
|
||||
xaml_typename<hstring>(),
|
||||
xaml_typename<Editor::NullableColorPicker>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_NullColorPreviewProperty)
|
||||
{
|
||||
_NullColorPreviewProperty =
|
||||
DependencyProperty::Register(
|
||||
L"NullColorPreview",
|
||||
xaml_typename<Windows::UI::Color>(),
|
||||
xaml_typename<Editor::NullableColorPicker>(),
|
||||
PropertyMetadata{ box_value(Windows::UI::Colors::Transparent()) });
|
||||
}
|
||||
}
|
||||
|
||||
void NullableColorPicker::_OnCurrentColorValueChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto& obj{ d.try_as<Editor::NullableColorPicker>() };
|
||||
get_self<NullableColorPicker>(obj)->_UpdateColorChips();
|
||||
}
|
||||
|
||||
void NullableColorPicker::_UpdateColorChips()
|
||||
{
|
||||
const auto& currentColor = CurrentColor();
|
||||
for (const auto& colorChip : _colorChips)
|
||||
{
|
||||
const auto& chipColor = colorChip.DataContext().as<Editor::ColorTableEntry>().Color();
|
||||
colorChip.IsChecked(currentColor ?
|
||||
equalsColor(chipColor, currentColor.Value()) :
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
SolidColorBrush NullableColorPicker::CalculateBorderBrush(const Windows::UI::Color& color)
|
||||
{
|
||||
static constexpr auto isColorLight = [](const winrt::Windows::UI::Color& clr) -> bool {
|
||||
return (((5 * clr.G) + (2 * clr.R) + clr.B) > (8 * 128));
|
||||
};
|
||||
if (isColorLight(color))
|
||||
{
|
||||
return SolidColorBrush(Colors::Black());
|
||||
}
|
||||
else
|
||||
{
|
||||
return SolidColorBrush(Colors::White());
|
||||
}
|
||||
}
|
||||
|
||||
void NullableColorPicker::ColorChip_Clicked(const IInspectable& sender, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
const auto& btn = sender.as<Windows::UI::Xaml::Controls::Primitives::ToggleButton>();
|
||||
const auto& colorEntryColor = btn.DataContext().as<Editor::ColorTableEntry>().Color();
|
||||
const Microsoft::Terminal::Core::Color terminalColor{ colorEntryColor.R, colorEntryColor.G, colorEntryColor.B, colorEntryColor.A };
|
||||
CurrentColor(terminalColor);
|
||||
btn.IsChecked(true);
|
||||
}
|
||||
|
||||
void NullableColorPicker::ColorChip_DataContextChanged(const IInspectable& sender, const DataContextChangedEventArgs& args)
|
||||
{
|
||||
if (const auto& toggleBtn = sender.try_as<Controls::Primitives::ToggleButton>())
|
||||
{
|
||||
if (const auto& currentColor = CurrentColor())
|
||||
{
|
||||
const auto& currentColorVal = currentColor.Value();
|
||||
const auto& newChipColor = args.NewValue().as<Editor::ColorTableEntry>().Color();
|
||||
toggleBtn.IsChecked(equalsColor(newChipColor, currentColorVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NullableColorPicker::IsNull(IReference<Microsoft::Terminal::Core::Color> color)
|
||||
{
|
||||
return color == nullptr;
|
||||
}
|
||||
|
||||
void NullableColorPicker::NullColorButton_Clicked(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
CurrentColor(nullptr);
|
||||
}
|
||||
|
||||
safe_void_coroutine NullableColorPicker::MoreColors_Clicked(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
co_await ColorPickerDialog().ShowAsync();
|
||||
}
|
||||
|
||||
void NullableColorPicker::ColorPickerDialog_Opened(const IInspectable& /*sender*/, const ContentDialogOpenedEventArgs& /*args*/)
|
||||
{
|
||||
// Initialize color picker with current color
|
||||
if (CurrentColor())
|
||||
{
|
||||
const auto& terminalColor = CurrentColor().Value();
|
||||
const Windows::UI::Color winuiColor{
|
||||
.A = terminalColor.A,
|
||||
.R = terminalColor.R,
|
||||
.G = terminalColor.G,
|
||||
.B = terminalColor.B
|
||||
};
|
||||
ColorPickerControl().Color(winuiColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No current color (null), use the deduced value for null
|
||||
ColorPickerControl().Color(NullColorPreview());
|
||||
}
|
||||
}
|
||||
|
||||
void NullableColorPicker::ColorPickerDialog_PrimaryButtonClick(const IInspectable& /*sender*/, const ContentDialogButtonClickEventArgs& /*args*/)
|
||||
{
|
||||
const auto& selectedColor = ColorPickerControl().Color();
|
||||
const Microsoft::Terminal::Core::Color terminalColor{ selectedColor.R, selectedColor.G, selectedColor.B, selectedColor.A };
|
||||
CurrentColor(terminalColor);
|
||||
}
|
||||
|
||||
void NullableColorPicker::ColorChip_Loaded(const IInspectable& sender, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
if (const auto& toggleBtn = sender.try_as<Controls::Primitives::ToggleButton>())
|
||||
{
|
||||
if (const auto& currentColor = CurrentColor())
|
||||
{
|
||||
const auto& currentColorVal = currentColor.Value();
|
||||
const auto& chipColor = toggleBtn.DataContext().as<Editor::ColorTableEntry>().Color();
|
||||
if (equalsColor(chipColor, currentColorVal))
|
||||
{
|
||||
toggleBtn.IsChecked(true);
|
||||
}
|
||||
}
|
||||
_colorChips.push_back(toggleBtn);
|
||||
}
|
||||
}
|
||||
|
||||
void NullableColorPicker::ColorChip_Unloaded(const IInspectable& sender, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
if (const auto& toggleBtn = sender.try_as<Controls::Primitives::ToggleButton>())
|
||||
{
|
||||
for (auto it = _colorChips.begin(); it != _colorChips.end(); ++it)
|
||||
{
|
||||
if (*it == toggleBtn)
|
||||
{
|
||||
_colorChips.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/cascadia/TerminalSettingsEditor/NullableColorPicker.h
Normal file
49
src/cascadia/TerminalSettingsEditor/NullableColorPicker.h
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "NullableColorPicker.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct NullableColorPicker : public HasScrollViewer<NullableColorPicker>, NullableColorPickerT<NullableColorPicker>
|
||||
{
|
||||
public:
|
||||
NullableColorPicker();
|
||||
|
||||
static winrt::Windows::UI::Xaml::Media::SolidColorBrush CalculateBorderBrush(const Windows::UI::Color& color);
|
||||
static bool IsNull(Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> color);
|
||||
|
||||
void ColorChip_Loaded(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void ColorChip_Unloaded(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void ColorChip_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void ColorChip_DataContextChanged(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::DataContextChangedEventArgs& args);
|
||||
|
||||
void NullColorButton_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
safe_void_coroutine MoreColors_Clicked(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
|
||||
void ColorPickerDialog_Opened(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Controls::ContentDialogOpenedEventArgs& args);
|
||||
void ColorPickerDialog_PrimaryButtonClick(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs& args);
|
||||
|
||||
DEPENDENCY_PROPERTY(Editor::ColorSchemeViewModel, ColorSchemeVM);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IReference<Microsoft::Terminal::Core::Color>, CurrentColor);
|
||||
DEPENDENCY_PROPERTY(bool, ShowNullColorButton);
|
||||
DEPENDENCY_PROPERTY(hstring, NullColorButtonLabel);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Color, NullColorPreview);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnCurrentColorValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _UpdateColorChips();
|
||||
|
||||
std::vector<Windows::UI::Xaml::Controls::Primitives::ToggleButton> _colorChips;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(NullableColorPicker);
|
||||
}
|
||||
30
src/cascadia/TerminalSettingsEditor/NullableColorPicker.idl
Normal file
30
src/cascadia/TerminalSettingsEditor/NullableColorPicker.idl
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "ColorSchemeViewModel.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass NullableColorPicker : Windows.UI.Xaml.Controls.UserControl
|
||||
{
|
||||
NullableColorPicker();
|
||||
|
||||
ColorSchemeViewModel ColorSchemeVM;
|
||||
static Windows.UI.Xaml.DependencyProperty ColorSchemeVMProperty { get; };
|
||||
|
||||
Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> CurrentColor;
|
||||
static Windows.UI.Xaml.DependencyProperty CurrentColorProperty { get; };
|
||||
|
||||
Boolean ShowNullColorButton;
|
||||
static Windows.UI.Xaml.DependencyProperty ShowNullColorButtonProperty { get; };
|
||||
|
||||
String NullColorButtonLabel;
|
||||
static Windows.UI.Xaml.DependencyProperty NullColorButtonLabelProperty { get; };
|
||||
|
||||
Windows.UI.Color NullColorPreview;
|
||||
static Windows.UI.Xaml.DependencyProperty NullColorPreviewProperty { get; };
|
||||
|
||||
static Windows.UI.Xaml.Media.SolidColorBrush CalculateBorderBrush(Windows.UI.Color color);
|
||||
static Boolean IsNull(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color> color);
|
||||
}
|
||||
}
|
||||
155
src/cascadia/TerminalSettingsEditor/NullableColorPicker.xaml
Normal file
155
src/cascadia/TerminalSettingsEditor/NullableColorPicker.xaml
Normal file
@ -0,0 +1,155 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
-->
|
||||
<UserControl x:Class="Microsoft.Terminal.Settings.Editor.NullableColorPicker"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:model="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<DataTemplate x:Key="ColorPreviewChipTemplate"
|
||||
x:DataType="local:ColorTableEntry">
|
||||
<ToggleButton Margin="0,0,4,4"
|
||||
AutomationProperties.Name="{x:Bind NameWithHexCode}"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(Color)}"
|
||||
BorderBrush="{x:Bind local:NullableColorPicker.CalculateBorderBrush(Color), Mode=OneWay}"
|
||||
BorderThickness="2"
|
||||
Click="ColorChip_Clicked"
|
||||
DataContextChanged="ColorChip_DataContextChanged"
|
||||
Loaded="ColorChip_Loaded"
|
||||
Style="{StaticResource ColorToggleButtonStyle}"
|
||||
ToolTipService.ToolTip="{x:Bind NameWithHexCode}"
|
||||
Unloaded="ColorChip_Unloaded" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ColorSchemeTemplate"
|
||||
x:DataType="local:ColorSchemeViewModel">
|
||||
<VariableSizedWrapGrid Name="ColorSchemeGrid"
|
||||
HorizontalAlignment="Left"
|
||||
MaximumRowsOrColumns="4"
|
||||
Orientation="Horizontal"
|
||||
XYFocusKeyboardNavigation="Enabled">
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(0), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(1), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(2), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(3), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(4), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(5), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(6), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(7), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(8), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(9), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(10), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(11), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(12), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(13), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(14), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
<ContentControl Content="{x:Bind ColorEntryAt(15), Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorPreviewChipTemplate}"
|
||||
IsTabStop="False" />
|
||||
</VariableSizedWrapGrid>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid ColumnSpacing="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentDialog x:Name="ColorPickerDialog"
|
||||
x:Uid="NullableColorPicker_ColorPickerContentDialog"
|
||||
DefaultButton="Primary"
|
||||
Opened="ColorPickerDialog_Opened"
|
||||
PrimaryButtonClick="ColorPickerDialog_PrimaryButtonClick"
|
||||
TabFocusNavigation="Cycle">
|
||||
<muxc:ColorPicker x:Name="ColorPickerControl"
|
||||
Margin="0,0,0,-40"
|
||||
ColorSpectrumShape="Box"
|
||||
IsAlphaEnabled="False"
|
||||
IsAlphaSliderVisible="True"
|
||||
IsAlphaTextInputVisible="True"
|
||||
IsColorChannelTextInputVisible="False"
|
||||
IsColorSliderVisible="False"
|
||||
IsHexInputVisible="False"
|
||||
IsMoreButtonVisible="False"
|
||||
Orientation="Horizontal" />
|
||||
</ContentDialog>
|
||||
|
||||
<ContentPresenter Grid.Column="0"
|
||||
Content="{x:Bind ColorSchemeVM, Mode=OneWay}"
|
||||
ContentTemplate="{StaticResource ColorSchemeTemplate}" />
|
||||
|
||||
<StackPanel Grid.Column="1"
|
||||
Spacing="5">
|
||||
<ToggleButton AutomationProperties.Name="{x:Bind NullColorButtonLabel}"
|
||||
Click="NullColorButton_Clicked"
|
||||
IsChecked="{x:Bind IsNull(CurrentColor), Mode=OneWay}">
|
||||
<Grid ColumnSpacing="5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border Grid.Column="0"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Background="{x:Bind mtu:Converters.ColorToBrush(NullColorPreview), Mode=OneWay}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind NullColorButtonLabel}" />
|
||||
</Grid>
|
||||
</ToggleButton>
|
||||
|
||||
<Button x:Uid="NullableColorPicker_MoreColorsButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
Click="MoreColors_Clicked" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
@ -10,6 +10,7 @@
|
||||
#include <LibraryResources.h>
|
||||
#include "../WinRTUtils/inc/Utils.h"
|
||||
#include "../../renderer/base/FontCache.h"
|
||||
#include "SegoeFluentIconList.h"
|
||||
|
||||
using namespace winrt::Windows::UI::Text;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
@ -26,6 +27,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
Windows::Foundation::Collections::IObservableVector<Editor::Font> ProfileViewModel::_MonospaceFontList{ nullptr };
|
||||
Windows::Foundation::Collections::IObservableVector<Editor::Font> ProfileViewModel::_FontList{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<IInspectable> ProfileViewModel::_BuiltInIcons{ nullptr };
|
||||
|
||||
static constexpr std::wstring_view HideIconValue{ L"none" };
|
||||
|
||||
@ -41,6 +43,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(ScrollState, ScrollbarState, winrt::Microsoft::Terminal::Control::ScrollbarState, L"Profile_ScrollbarVisibility", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(PathTranslationStyle, PathTranslationStyle, winrt::Microsoft::Terminal::Control::PathTranslationStyle, L"Profile_PathTranslationStyle", L"Content");
|
||||
|
||||
// set up IconTypes
|
||||
std::vector<IInspectable> iconTypes;
|
||||
iconTypes.reserve(4);
|
||||
iconTypes.emplace_back(make<EnumEntry>(RS_(L"Profile_IconTypeNone"), box_value(IconType::None)));
|
||||
iconTypes.emplace_back(make<EnumEntry>(RS_(L"Profile_IconTypeFontIcon"), box_value(IconType::FontIcon)));
|
||||
iconTypes.emplace_back(make<EnumEntry>(RS_(L"Profile_IconTypeEmoji"), box_value(IconType::Emoji)));
|
||||
iconTypes.emplace_back(make<EnumEntry>(RS_(L"Profile_IconTypeImage"), box_value(IconType::Image)));
|
||||
_IconTypes = winrt::single_threaded_vector<IInspectable>(std::move(iconTypes));
|
||||
_DeduceCurrentIconType();
|
||||
_DeduceCurrentBuiltInIcon();
|
||||
|
||||
// Add a property changed handler to our own property changed event.
|
||||
// This propagates changes from the settings model to anybody listening to our
|
||||
// unique view model members.
|
||||
@ -75,7 +88,29 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else if (viewModelProperty == L"Icon")
|
||||
{
|
||||
_NotifyChanges(L"HideIcon");
|
||||
// _DeduceCurrentIconType() ends with a "CurrentIconType" notification
|
||||
// so we don't need to call _UpdateIconPreview() here
|
||||
_DeduceCurrentIconType();
|
||||
}
|
||||
else if (viewModelProperty == L"CurrentIconType")
|
||||
{
|
||||
// "Using*" handles the visibility of the IconType-related UI.
|
||||
// The others propagate the rendered icon into a preview (i.e. nav view, container item)
|
||||
_NotifyChanges(L"UsingNoIcon",
|
||||
L"UsingBuiltInIcon",
|
||||
L"UsingEmojiIcon",
|
||||
L"UsingImageIcon",
|
||||
L"LocalizedIcon",
|
||||
L"IconPreview",
|
||||
L"EvaluatedIcon");
|
||||
}
|
||||
else if (viewModelProperty == L"CurrentBuiltInIcon")
|
||||
{
|
||||
Icon(unbox_value<hstring>(_CurrentBuiltInIcon.as<Editor::EnumEntry>().EnumValue()));
|
||||
}
|
||||
else if (viewModelProperty == L"CurrentEmojiIcon")
|
||||
{
|
||||
Icon(CurrentEmojiIcon());
|
||||
}
|
||||
else if (viewModelProperty == L"PathTranslationStyle")
|
||||
{
|
||||
@ -107,6 +142,61 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_defaultAppearanceViewModel.IsDefault(true);
|
||||
}
|
||||
|
||||
void ProfileViewModel::_UpdateBuiltInIcons()
|
||||
{
|
||||
std::vector<IInspectable> builtInIcons;
|
||||
for (auto& [val, name] : s_SegoeFluentIcons)
|
||||
{
|
||||
builtInIcons.emplace_back(make<EnumEntry>(hstring{ name }, box_value(val)));
|
||||
}
|
||||
_BuiltInIcons = single_threaded_vector<IInspectable>(std::move(builtInIcons));
|
||||
}
|
||||
|
||||
void ProfileViewModel::_DeduceCurrentIconType()
|
||||
{
|
||||
const auto& profileIcon = _profile.Icon();
|
||||
if (profileIcon == HideIconValue)
|
||||
{
|
||||
_currentIconType = _IconTypes.GetAt(0);
|
||||
}
|
||||
else if (L"\uE700" <= profileIcon && profileIcon <= L"\uF8B3")
|
||||
{
|
||||
_currentIconType = _IconTypes.GetAt(1);
|
||||
_DeduceCurrentBuiltInIcon();
|
||||
}
|
||||
else if (profileIcon.size() <= 2)
|
||||
{
|
||||
// We already did a range check for MDL2 Assets in the previous one,
|
||||
// so if we're out of that range but still short, assume we're an emoji
|
||||
_currentIconType = _IconTypes.GetAt(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentIconType = _IconTypes.GetAt(3);
|
||||
}
|
||||
_NotifyChanges(L"CurrentIconType");
|
||||
}
|
||||
|
||||
void ProfileViewModel::_DeduceCurrentBuiltInIcon()
|
||||
{
|
||||
if (!_BuiltInIcons)
|
||||
{
|
||||
_UpdateBuiltInIcons();
|
||||
}
|
||||
const auto& profileIcon = Icon();
|
||||
for (uint32_t i = 0; i < _BuiltInIcons.Size(); i++)
|
||||
{
|
||||
const auto& builtIn = _BuiltInIcons.GetAt(i);
|
||||
if (profileIcon == unbox_value<hstring>(builtIn.as<Editor::EnumEntry>().EnumValue()))
|
||||
{
|
||||
_CurrentBuiltInIcon = builtIn;
|
||||
return;
|
||||
}
|
||||
}
|
||||
_CurrentBuiltInIcon = _BuiltInIcons.GetAt(0);
|
||||
_NotifyChanges(L"CurrentBuiltInIcon");
|
||||
}
|
||||
|
||||
void ProfileViewModel::LeftPadding(double value) noexcept
|
||||
{
|
||||
const hstring& padding = _GetNewPadding(PaddingDirection::Left, value);
|
||||
@ -483,26 +573,103 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
}
|
||||
|
||||
bool ProfileViewModel::HideIcon()
|
||||
winrt::hstring ProfileViewModel::LocalizedIcon() const
|
||||
{
|
||||
return Icon() == HideIconValue;
|
||||
if (_currentIconType && unbox_value<IconType>(_currentIconType.as<Editor::EnumEntry>().EnumValue()) == IconType::None)
|
||||
{
|
||||
return RS_(L"Profile_IconTypeNone");
|
||||
}
|
||||
return Icon();
|
||||
}
|
||||
void ProfileViewModel::HideIcon(const bool hide)
|
||||
|
||||
Windows::UI::Xaml::Controls::IconElement ProfileViewModel::IconPreview() const
|
||||
{
|
||||
if (hide)
|
||||
// IconWUX sets the icon width/height to 32 by default
|
||||
auto icon = Microsoft::Terminal::UI::IconPathConverter::IconWUX(EvaluatedIcon());
|
||||
icon.Width(16);
|
||||
icon.Height(16);
|
||||
return icon;
|
||||
}
|
||||
|
||||
void ProfileViewModel::CurrentIconType(const Windows::Foundation::IInspectable& value)
|
||||
{
|
||||
if (_currentIconType != value)
|
||||
{
|
||||
// Stash the current value of Icon. If the user
|
||||
// checks and un-checks the "Hide Icon" checkbox, we want
|
||||
// the path that we display in the text box to remain unchanged.
|
||||
_lastIcon = Icon();
|
||||
Icon(HideIconValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Icon(_lastIcon);
|
||||
// Switching from...
|
||||
if (_currentIconType && unbox_value<IconType>(_currentIconType.as<Editor::EnumEntry>().EnumValue()) == IconType::Image)
|
||||
{
|
||||
// Stash the current value of Icon. If the user
|
||||
// switches out of then back to IconType::Image, we want
|
||||
// the path that we display in the text box to remain unchanged.
|
||||
_lastIconPath = Icon();
|
||||
}
|
||||
|
||||
// Set the member here instead of after setting Icon() below!
|
||||
// We have an Icon property changed handler defined for when we discard changes.
|
||||
// Inadvertently, that means that we call this setter again.
|
||||
// Setting the member here means that we early exit at the beginning of the function
|
||||
// because _currentIconType == value.
|
||||
_currentIconType = value;
|
||||
|
||||
// Switched to...
|
||||
switch (unbox_value<IconType>(value.as<Editor::EnumEntry>().EnumValue()))
|
||||
{
|
||||
case IconType::None:
|
||||
{
|
||||
_profile.Icon(HideIconValue);
|
||||
break;
|
||||
}
|
||||
case IconType::Image:
|
||||
{
|
||||
if (!_lastIconPath.empty())
|
||||
{
|
||||
// Conversely, if we switch to Image,
|
||||
// retrieve that saved value and apply it
|
||||
_profile.Icon(_lastIconPath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IconType::FontIcon:
|
||||
{
|
||||
if (_CurrentBuiltInIcon)
|
||||
{
|
||||
_profile.Icon(unbox_value<hstring>(_CurrentBuiltInIcon.as<Editor::EnumEntry>().EnumValue()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IconType::Emoji:
|
||||
{
|
||||
// Don't set Icon here!
|
||||
// Clear out the text box so we direct the user to use the emoji picker.
|
||||
CurrentEmojiIcon({});
|
||||
}
|
||||
}
|
||||
// We're not using the VM's Icon() setter above,
|
||||
// so notify HasIcon changed manually
|
||||
_NotifyChanges(L"CurrentIconType", L"HasIcon");
|
||||
}
|
||||
}
|
||||
|
||||
bool ProfileViewModel::UsingNoIcon() const
|
||||
{
|
||||
return _currentIconType == _IconTypes.GetAt(0);
|
||||
}
|
||||
|
||||
bool ProfileViewModel::UsingBuiltInIcon() const
|
||||
{
|
||||
return _currentIconType == _IconTypes.GetAt(1);
|
||||
}
|
||||
|
||||
bool ProfileViewModel::UsingEmojiIcon() const
|
||||
{
|
||||
return _currentIconType == _IconTypes.GetAt(2);
|
||||
}
|
||||
|
||||
bool ProfileViewModel::UsingImageIcon() const
|
||||
{
|
||||
return _currentIconType == _IconTypes.GetAt(3);
|
||||
}
|
||||
|
||||
bool ProfileViewModel::IsBellStyleFlagSet(const uint32_t flag)
|
||||
{
|
||||
return (WI_EnumValue(BellStyle()) & flag) == flag;
|
||||
|
||||
@ -33,6 +33,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
static void UpdateFontList() noexcept;
|
||||
static Windows::Foundation::Collections::IObservableVector<Editor::Font> CompleteFontList() noexcept { return _FontList; };
|
||||
static Windows::Foundation::Collections::IObservableVector<Editor::Font> MonospaceFontList() noexcept { return _MonospaceFontList; };
|
||||
static Windows::Foundation::Collections::IVector<IInspectable> BuiltInIcons() noexcept { return _BuiltInIcons; };
|
||||
|
||||
ProfileViewModel(const Model::Profile& profile, const Model::CascadiaSettings& settings);
|
||||
Model::TerminalSettings TermSettings() const;
|
||||
@ -64,16 +65,23 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
return _profile.EvaluatedIcon();
|
||||
}
|
||||
Windows::Foundation::IInspectable CurrentIconType() const noexcept
|
||||
{
|
||||
return _currentIconType;
|
||||
}
|
||||
Windows::UI::Xaml::Controls::IconElement IconPreview() const;
|
||||
winrt::hstring LocalizedIcon() const;
|
||||
void CurrentIconType(const Windows::Foundation::IInspectable& value);
|
||||
bool UsingNoIcon() const;
|
||||
bool UsingBuiltInIcon() const;
|
||||
bool UsingEmojiIcon() const;
|
||||
bool UsingImageIcon() const;
|
||||
|
||||
// starting directory
|
||||
bool UseParentProcessDirectory();
|
||||
void UseParentProcessDirectory(const bool useParent);
|
||||
bool UseCustomStartingDirectory();
|
||||
|
||||
// icon
|
||||
bool HideIcon();
|
||||
void HideIcon(const bool hide);
|
||||
|
||||
// general profile knowledge
|
||||
winrt::guid OriginalProfileGuid() const noexcept;
|
||||
bool CanDeleteProfile() const;
|
||||
@ -94,6 +102,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
til::typed_event<Editor::ProfileViewModel, Editor::DeleteProfileEventArgs> DeleteProfileRequested;
|
||||
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(ProfileSubPage, CurrentPage);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::IInspectable, CurrentBuiltInIcon);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(hstring, CurrentEmojiIcon);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, Guid);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, ConnectionType);
|
||||
@ -110,10 +120,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, Commandline);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, StartingDirectory);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, AntialiasingMode);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Foreground);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Background);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), SelectionBackground);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), CursorColor);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Opacity);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), UseAcrylic);
|
||||
OBSERVABLE_PROJECTED_SETTING(_profile, HistorySize);
|
||||
@ -134,6 +140,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
WINRT_PROPERTY(bool, IsBaseLayer, false);
|
||||
WINRT_PROPERTY(bool, FocusDeleteButton, false);
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable>, IconTypes);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AntiAliasingMode, Microsoft::Terminal::Control::TextAntialiasingMode, AntialiasingMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CloseOnExitMode, Microsoft::Terminal::Settings::Model::CloseOnExitMode, CloseOnExit);
|
||||
GETSET_BINDABLE_ENUM_SETTING(ScrollState, Microsoft::Terminal::Control::ScrollbarState, ScrollState);
|
||||
@ -144,11 +151,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
winrt::guid _originalProfileGuid{};
|
||||
winrt::hstring _lastBgImagePath;
|
||||
winrt::hstring _lastStartingDirectoryPath;
|
||||
winrt::hstring _lastIcon;
|
||||
winrt::hstring _lastIconPath;
|
||||
Windows::Foundation::IInspectable _currentIconType{};
|
||||
Editor::AppearanceViewModel _defaultAppearanceViewModel;
|
||||
|
||||
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _MonospaceFontList;
|
||||
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _FontList;
|
||||
static Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> _BuiltInIcons;
|
||||
|
||||
Model::CascadiaSettings _appSettings;
|
||||
Editor::AppearanceViewModel _unfocusedAppearanceViewModel;
|
||||
@ -163,6 +172,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
winrt::hstring _GetNewPadding(PaddingDirection paddingDirection, double newPaddingValue) const;
|
||||
double _GetPaddingValue(PaddingDirection paddingDirection) const;
|
||||
void _UpdateBuiltInIcons();
|
||||
void _DeduceCurrentIconType();
|
||||
void _DeduceCurrentBuiltInIcon();
|
||||
};
|
||||
|
||||
struct DeleteProfileEventArgs :
|
||||
|
||||
@ -33,6 +33,14 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
Advanced = 3
|
||||
};
|
||||
|
||||
enum IconType
|
||||
{
|
||||
None = 0,
|
||||
FontIcon,
|
||||
Image,
|
||||
Emoji
|
||||
};
|
||||
|
||||
runtimeclass ProfileViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
Microsoft.Terminal.Settings.Model.TerminalSettings TermSettings { get; };
|
||||
@ -71,7 +79,6 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
ProfileSubPage CurrentPage;
|
||||
Boolean UseParentProcessDirectory;
|
||||
Boolean UseCustomStartingDirectory { get; };
|
||||
Boolean HideIcon;
|
||||
AppearanceViewModel DefaultAppearance { get; };
|
||||
Guid OriginalProfileGuid { get; };
|
||||
Boolean HasUnfocusedAppearance { get; };
|
||||
@ -83,7 +90,19 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
Boolean AutoMarkPromptsAvailable { get; };
|
||||
Boolean RepositionCursorWithMouseAvailable { get; };
|
||||
|
||||
Windows.UI.Xaml.Controls.IconElement IconPreview { get; };
|
||||
String EvaluatedIcon { get; };
|
||||
String LocalizedIcon { get; };
|
||||
String CurrentEmojiIcon;
|
||||
IInspectable CurrentIconType;
|
||||
Windows.Foundation.Collections.IVector<IInspectable> IconTypes { get; };
|
||||
Boolean UsingNoIcon { get; };
|
||||
Boolean UsingBuiltInIcon { get; };
|
||||
Boolean UsingEmojiIcon { get; };
|
||||
Boolean UsingImageIcon { get; };
|
||||
|
||||
IInspectable CurrentBuiltInIcon;
|
||||
Windows.Foundation.Collections.IVector<IInspectable> BuiltInIcons { get; };
|
||||
|
||||
void CreateUnfocusedAppearance();
|
||||
void DeleteUnfocusedAppearance();
|
||||
@ -106,10 +125,6 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Commandline);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, StartingDirectory);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.TextAntialiasingMode, AntialiasingMode);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Foreground);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, Background);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, SelectionBackground);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, CursorColor);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Int32, HistorySize);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SnapOnInput);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AltGrAliasing);
|
||||
|
||||
@ -148,4 +148,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_Profile.StartingDirectory(folder);
|
||||
}
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::Controls::IconSource Profiles_Base::BuiltInIconConverter(const IInspectable& iconVal)
|
||||
{
|
||||
return Microsoft::Terminal::UI::IconPathConverter::IconSourceWUX(unbox_value<hstring>(iconVal));
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void Advanced_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
void DeleteConfirmation_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
|
||||
static Windows::UI::Xaml::Controls::IconSource BuiltInIconConverter(const Windows::Foundation::IInspectable& iconVal);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_PROPERTY(Editor::ProfileViewModel, Profile, nullptr);
|
||||
|
||||
|
||||
@ -9,5 +9,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
Profiles_Base();
|
||||
ProfileViewModel Profile { get; };
|
||||
|
||||
static Windows.UI.Xaml.Controls.IconSource BuiltInIconConverter(IInspectable iconVal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,28 +102,98 @@
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Uid="Profile_Icon"
|
||||
ClearSettingValue="{x:Bind Profile.ClearIcon}"
|
||||
CurrentValue="{x:Bind Profile.Icon, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<TextBox x:Uid="Profile_IconBox"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.HideIcon), Mode=OneWay}"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Icon, Mode=TwoWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.HideIcon), Mode=OneWay}" />
|
||||
<Button x:Uid="Profile_IconBrowse"
|
||||
Margin="0,10,0,0"
|
||||
Click="Icon_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.HideIcon), Mode=OneWay}" />
|
||||
<CheckBox x:Name="HideIconCheckbox"
|
||||
x:Uid="Profile_HideIconCheckbox"
|
||||
Margin="0,5,0,0"
|
||||
IsChecked="{x:Bind Profile.HideIcon, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind Profile.IconPreview, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.UsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind Profile.UsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<Grid ColumnSpacing="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Icon Type -->
|
||||
<ComboBox x:Uid="Profile_IconType"
|
||||
Grid.Column="0"
|
||||
ItemsSource="{x:Bind Profile.IconTypes}"
|
||||
SelectedItem="{x:Bind Profile.CurrentIconType, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:EnumEntry">
|
||||
<TextBlock Text="{x:Bind EnumName}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<!-- Built-In Icon -->
|
||||
<ComboBox x:Uid="Profile_BuiltInIcon"
|
||||
Grid.Column="1"
|
||||
ItemsSource="{x:Bind Profile.BuiltInIcons}"
|
||||
SelectedItem="{x:Bind Profile.CurrentBuiltInIcon, Mode=TwoWay}"
|
||||
Visibility="{x:Bind Profile.UsingBuiltInIcon, Mode=OneWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="local:EnumEntry">
|
||||
<Grid ColumnSpacing="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind local:Profiles_Base.BuiltInIconConverter(EnumValue), Mode=OneTime}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind EnumName}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<!-- Image (File) Icon -->
|
||||
<TextBox x:Uid="Profile_IconBox"
|
||||
Grid.Column="1"
|
||||
MaxWidth="Infinity"
|
||||
HorizontalAlignment="Stretch"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Icon, Mode=TwoWay}"
|
||||
Visibility="{x:Bind Profile.UsingImageIcon, Mode=OneWay}" />
|
||||
<Button x:Uid="Profile_IconBrowse"
|
||||
Grid.Column="2"
|
||||
Margin="0"
|
||||
VerticalAlignment="Top"
|
||||
Click="Icon_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}"
|
||||
Visibility="{x:Bind Profile.UsingImageIcon, Mode=OneWay}" />
|
||||
|
||||
<!-- Emoji Icon -->
|
||||
<TextBox x:Uid="Profile_IconEmojiBox"
|
||||
Grid.Column="1"
|
||||
MaxWidth="Infinity"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.CurrentEmojiIcon, Mode=TwoWay}"
|
||||
Visibility="{x:Bind Profile.UsingEmojiIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Title -->
|
||||
|
||||
@ -894,6 +894,10 @@
|
||||
<value>Color scheme</value>
|
||||
<comment>Header for a control to select the scheme (or set) of colors used in the session. This is selected from a list of options managed by the user.</comment>
|
||||
</data>
|
||||
<data name="Profile_ColorScheme.HelpText" xml:space="preserve">
|
||||
<value>Expand to override the foreground, background, and selection background.</value>
|
||||
<comment>Help text for a control to select the scheme (or set) of colors used in the session. Directs the user to expand the control to access overrides for certain values in the color scheme.</comment>
|
||||
</data>
|
||||
<data name="Profile_Commandline.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Command line</value>
|
||||
<comment>Name for a control to determine commandline executable (i.e. a .exe file) to run when a terminal session of this profile is launched.</comment>
|
||||
@ -1121,6 +1125,10 @@
|
||||
<value>Icon</value>
|
||||
<comment>Name for a control to determine what icon can be used to represent this profile. This is not necessarily a file path, but can be one.</comment>
|
||||
</data>
|
||||
<data name="Profile_IconEmojiBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Icon</value>
|
||||
<comment>Name for a control to determine what icon can be used to represent this profile.</comment>
|
||||
</data>
|
||||
<data name="Profile_Icon.HelpText" xml:space="preserve">
|
||||
<value>Emoji or image file location of the icon used in the profile.</value>
|
||||
<comment>A description for what the "icon" setting does. Presented near "Profile_Icon".</comment>
|
||||
@ -1929,6 +1937,102 @@
|
||||
<value>Non-monospace fonts:</value>
|
||||
<comment>This is a label that is followed by a list of proportional fonts.</comment>
|
||||
</data>
|
||||
<data name="Profile_TabColor.Header" xml:space="preserve">
|
||||
<value>Tab color</value>
|
||||
<comment>Header for a control to determine the color of the tab.</comment>
|
||||
</data>
|
||||
<data name="Profile_Foreground.Header" xml:space="preserve">
|
||||
<value>Foreground</value>
|
||||
<comment>Header for a control to determine the foreground color of text.</comment>
|
||||
</data>
|
||||
<data name="Profile_Background.Header" xml:space="preserve">
|
||||
<value>Background</value>
|
||||
<comment>Header for a control to determine the background color of text.</comment>
|
||||
</data>
|
||||
<data name="Profile_SelectionBackground.Header" xml:space="preserve">
|
||||
<value>Selection background</value>
|
||||
<comment>Header for a control to determine the background color of selected text.</comment>
|
||||
</data>
|
||||
<data name="Profile_CursorColor.Header" xml:space="preserve">
|
||||
<value>Cursor color</value>
|
||||
<comment>Header for a control to determine the color of the cursor.</comment>
|
||||
</data>
|
||||
<data name="Profile_Foreground.HelpText" xml:space="preserve">
|
||||
<value>Overrides the foreground color from the color scheme.</value>
|
||||
<comment>A description for what the "foreground" setting does. Presented near "Profile_Foreground".</comment>
|
||||
</data>
|
||||
<data name="Profile_CursorColor.HelpText" xml:space="preserve">
|
||||
<value>Overrides the cursor color from the color scheme.</value>
|
||||
<comment>A description for what the "cursor color" setting does. Presented near "Profile_CursorColor".</comment>
|
||||
</data>
|
||||
<data name="Profile_Background.HelpText" xml:space="preserve">
|
||||
<value>Overrides the background color from the color scheme.</value>
|
||||
<comment>A description for what the "background" setting does. Presented near "Profile_Background".</comment>
|
||||
</data>
|
||||
<data name="Profile_SelectionBackground.HelpText" xml:space="preserve">
|
||||
<value>Overrides the selection background color from the color scheme.</value>
|
||||
<comment>A description for what the "selection background" setting does. Presented near "Profile_SelectionBackground".</comment>
|
||||
</data>
|
||||
<data name="NullableColorPicker_MoreColorsButton.Content" xml:space="preserve">
|
||||
<value>More colors...</value>
|
||||
<comment>Text label for a button that allows the user to select from more colors in a new window. {Locked="..."}</comment>
|
||||
</data>
|
||||
<data name="NullableColorPicker_ColorPickerContentDialog.Title" xml:space="preserve">
|
||||
<value>Pick a color</value>
|
||||
<comment>Title displayed on a content dialog directing the user to pick a color.</comment>
|
||||
</data>
|
||||
<data name="NullableColorPicker_ColorPickerContentDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>OK</value>
|
||||
<comment>Button label for the color picker content dialog. Used as confirmation to apply the selected color.</comment>
|
||||
</data>
|
||||
<data name="NullableColorPicker_ColorPickerContentDialog.SecondaryButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
<comment>Text label for secondary button the color picker content dialog. When clicked, the operation of selecting a color is cancelled by the user.</comment>
|
||||
</data>
|
||||
<data name="Profile_CursorColor_NullableColorPicker.NullColorButtonLabel" xml:space="preserve">
|
||||
<value>Use cursor color from color scheme</value>
|
||||
<comment>Label for a button directing the user to use the cursor color defined in the terminal's current color scheme.</comment>
|
||||
</data>
|
||||
<data name="Profile_Foreground_NullableColorPicker.NullColorButtonLabel" xml:space="preserve">
|
||||
<value>Use foreground color from color scheme</value>
|
||||
<comment>Label for a button directing the user to use the foreground color defined in the terminal's current color scheme.</comment>
|
||||
</data>
|
||||
<data name="Profile_Background_NullableColorPicker.NullColorButtonLabel" xml:space="preserve">
|
||||
<value>Use background color from color scheme</value>
|
||||
<comment>Label for a button directing the user to use the background color defined in the terminal's current color scheme.</comment>
|
||||
</data>
|
||||
<data name="Profile_SelectionBackground_NullableColorPicker.NullColorButtonLabel" xml:space="preserve">
|
||||
<value>Use selection background color from color scheme</value>
|
||||
<comment>Label for a button directing the user to use the selection background color defined in the terminal's current color scheme.</comment>
|
||||
</data>
|
||||
<data name="Profile_IconTypeNone" xml:space="preserve">
|
||||
<value>None</value>
|
||||
<comment>An option to choose from for the "icon style" dropdown. When selected, there will be no icon for the profile.</comment>
|
||||
</data>
|
||||
<data name="Profile_IconTypeImage" xml:space="preserve">
|
||||
<value>File</value>
|
||||
<comment>An option to choose from for the "icon style" dropdown. When selected, a custom image can set for the profile's icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_IconTypeEmoji" xml:space="preserve">
|
||||
<value>Emoji</value>
|
||||
<comment>An option to choose from for the "icon style" dropdown. When selected, an emoji can be set for the profile's icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_IconTypeFontIcon" xml:space="preserve">
|
||||
<value>Built-in Icon</value>
|
||||
<comment>An option to choose from for the "icon style" dropdown. When selected, the user can choose from several preselected options to set the profile's icon.</comment>
|
||||
</data>
|
||||
<data name="Profile_IconEmojiBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Use "Win + period" to open the emoji picker</value>
|
||||
<comment>"Win + period" refers to the OS key binding to open the emoji picker.</comment>
|
||||
</data>
|
||||
<data name="Profile_IconType.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Icon type</value>
|
||||
<comment>Accessible name for a control allowing the user to select the type of icon they would like to use.</comment>
|
||||
</data>
|
||||
<data name="Profile_BuiltInIcon.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Icon</value>
|
||||
<comment>Accessible name for a control allowing the user to select the icon from a list of built in icons.</comment>
|
||||
</data>
|
||||
<data name="Nav_NewTabMenu.Content" xml:space="preserve">
|
||||
<value>New Tab Menu</value>
|
||||
<comment>Header for the "new tab menu" menu item. This navigates to a page that lets you see and modify settings related to the app's new tab menu (i.e. profile ordering, nested folders, dividers, etc.)</comment>
|
||||
|
||||
1413
src/cascadia/TerminalSettingsEditor/SegoeFluentIconList.h
Normal file
1413
src/cascadia/TerminalSettingsEditor/SegoeFluentIconList.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
DependencyProperty SettingContainer::_HelpTextProperty{ nullptr };
|
||||
DependencyProperty SettingContainer::_FontIconGlyphProperty{ nullptr };
|
||||
DependencyProperty SettingContainer::_CurrentValueProperty{ nullptr };
|
||||
DependencyProperty SettingContainer::_CurrentValueTemplateProperty{ nullptr };
|
||||
DependencyProperty SettingContainer::_HasSettingValueProperty{ nullptr };
|
||||
DependencyProperty SettingContainer::_SettingOverrideSourceProperty{ nullptr };
|
||||
DependencyProperty SettingContainer::_StartExpandedProperty{ nullptr };
|
||||
@ -60,9 +61,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_CurrentValueProperty =
|
||||
DependencyProperty::Register(
|
||||
L"CurrentValue",
|
||||
xaml_typename<hstring>(),
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingContainer>(),
|
||||
PropertyMetadata{ box_value(L"") });
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_CurrentValueTemplateProperty)
|
||||
{
|
||||
_CurrentValueTemplateProperty =
|
||||
DependencyProperty::Register(
|
||||
L"CurrentValueTemplate",
|
||||
xaml_typename<Windows::UI::Xaml::DataTemplate>(),
|
||||
xaml_typename<Editor::SettingContainer>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_HasSettingValueProperty)
|
||||
{
|
||||
|
||||
@ -36,7 +36,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Header);
|
||||
DEPENDENCY_PROPERTY(hstring, HelpText);
|
||||
DEPENDENCY_PROPERTY(hstring, FontIconGlyph);
|
||||
DEPENDENCY_PROPERTY(hstring, CurrentValue);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, CurrentValue);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::DataTemplate, CurrentValueTemplate);
|
||||
DEPENDENCY_PROPERTY(bool, HasSettingValue);
|
||||
DEPENDENCY_PROPERTY(bool, StartExpanded);
|
||||
DEPENDENCY_PROPERTY(IInspectable, SettingOverrideSource);
|
||||
|
||||
@ -18,9 +18,12 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String FontIconGlyph;
|
||||
static Windows.UI.Xaml.DependencyProperty FontIconGlyphProperty { get; };
|
||||
|
||||
String CurrentValue;
|
||||
IInspectable CurrentValue;
|
||||
static Windows.UI.Xaml.DependencyProperty CurrentValueProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.DataTemplate CurrentValueTemplate;
|
||||
static Windows.UI.Xaml.DependencyProperty CurrentValueTemplateProperty { get; };
|
||||
|
||||
Boolean HasSettingValue;
|
||||
static Windows.UI.Xaml.DependencyProperty HasSettingValueProperty { get; };
|
||||
|
||||
|
||||
@ -178,11 +178,67 @@
|
||||
<Setter Property="TextWrapping" Value="WrapWholeWords" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="ExpanderSettingContainerStringPreviewTemplate">
|
||||
<TextBlock MaxWidth="250"
|
||||
Margin="0,0,-16,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
|
||||
<!-- A setting container for a setting that has no additional options -->
|
||||
<Style TargetType="local:SettingContainer">
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding Content}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
A setting container for a setting that has no additional options.
|
||||
Includes space for an icon on the left side of the header.
|
||||
XAML applies the margin/padding of the icon regardless of its
|
||||
existence (which caused inconsistent padding). It's easier to just create
|
||||
another style and move on.
|
||||
-->
|
||||
<Style x:Key="SettingContainerWithIcon"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
@ -194,9 +250,9 @@
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
Margin="0,0,10,0"
|
||||
Glyph="{TemplateBinding FontIconGlyph}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
Padding="14,12,0,12"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
@ -238,14 +294,10 @@
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
Margin="0,0,10,0"
|
||||
Glyph="{TemplateBinding FontIconGlyph}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
@ -260,14 +312,114 @@
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="2"
|
||||
MaxWidth="250"
|
||||
Margin="0,0,-16,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding CurrentValue}" />
|
||||
<ContentPresenter Grid.Column="1"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
A setting container which can expand. Includes space for an icon on the left side of the header.
|
||||
XAML applies the margin/padding of the icon regardless of its
|
||||
existence (which caused inconsistent padding). It's easier to just create
|
||||
another style and move on.
|
||||
-->
|
||||
<Style x:Key="ExpanderSettingContainerStyleWithIcon"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph="{TemplateBinding FontIconGlyph}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
Padding="14,12,0,12"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- A setting container which can expand. Supports data template override for preview -->
|
||||
<Style x:Key="ExpanderSettingContainerStyleWithComplexPreview"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
MaxWidth="250"
|
||||
Margin="0,0,-16,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{TemplateBinding CurrentValueTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "TerminalColorConverters.h"
|
||||
#include "ColorToBrushConverter.g.cpp"
|
||||
#include "ColorToStringConverter.g.cpp"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
|
||||
Windows::Foundation::IInspectable ColorToBrushConverter::Convert(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& /*targetType*/, Windows::Foundation::IInspectable const& /*parameter*/, hstring const& /*language*/)
|
||||
{
|
||||
const auto color = value.as<Windows::UI::Color>();
|
||||
return Microsoft::Terminal::UI::Converters::ColorToBrush(color);
|
||||
}
|
||||
|
||||
Windows::Foundation::IInspectable ColorToBrushConverter::ConvertBack(Windows::Foundation::IInspectable const& /*value*/, Windows::UI::Xaml::Interop::TypeName const& /*targetType*/, Windows::Foundation::IInspectable const& /*parameter*/, hstring const& /*language*/)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
|
||||
Windows::Foundation::IInspectable ColorToStringConverter::Convert(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& /*targetType*/, Windows::Foundation::IInspectable const& /*parameter*/, hstring const& /*language*/)
|
||||
{
|
||||
const auto color = value.as<Windows::UI::Color>();
|
||||
return winrt::box_value(fmt::format(FMT_COMPILE(L"#{:02X}{:02X}{:02X}"), color.R, color.G, color.B));
|
||||
}
|
||||
|
||||
Windows::Foundation::IInspectable ColorToStringConverter::ConvertBack(Windows::Foundation::IInspectable const& /*value*/, Windows::UI::Xaml::Interop::TypeName const& /*targetType*/, Windows::Foundation::IInspectable const& /*parameter*/, hstring const& /*language*/)
|
||||
{
|
||||
throw hresult_not_implemented();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ColorToBrushConverter.g.h"
|
||||
#include "ColorToStringConverter.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct ColorToBrushConverter : ColorToBrushConverterT<ColorToBrushConverter>
|
||||
{
|
||||
ColorToBrushConverter() = default;
|
||||
|
||||
Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& targetType, Windows::Foundation::IInspectable const& parameter, hstring const& language);
|
||||
Windows::Foundation::IInspectable ConvertBack(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& targetType, Windows::Foundation::IInspectable const& parameter, hstring const& language);
|
||||
};
|
||||
|
||||
struct ColorToStringConverter : ColorToStringConverterT<ColorToStringConverter>
|
||||
{
|
||||
ColorToStringConverter() = default;
|
||||
|
||||
Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& targetType, Windows::Foundation::IInspectable const& parameter, hstring const& language);
|
||||
Windows::Foundation::IInspectable ConvertBack(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& targetType, Windows::Foundation::IInspectable const& parameter, hstring const& language);
|
||||
};
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(ColorToBrushConverter);
|
||||
BASIC_FACTORY(ColorToStringConverter);
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass ColorToBrushConverter : [default] Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
ColorToBrushConverter();
|
||||
}
|
||||
|
||||
runtimeclass ColorToStringConverter : [default] Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
ColorToStringConverter();
|
||||
}
|
||||
}
|
||||
@ -409,6 +409,61 @@ winrt::hstring Profile::_evaluateIcon() const
|
||||
return winrt::hstring{ cmdline.c_str() };
|
||||
}
|
||||
|
||||
bool Profile::HasIcon() const
|
||||
{
|
||||
return _Icon.has_value();
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile Profile::IconOverrideSource()
|
||||
{
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
if (auto source{ parent->_getIconOverrideSourceImpl() })
|
||||
{
|
||||
return source;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Profile::ClearIcon()
|
||||
{
|
||||
_Icon = std::nullopt;
|
||||
_evaluatedIcon = std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<winrt::hstring> Profile::_getIconImpl() const
|
||||
{
|
||||
if (_Icon)
|
||||
{
|
||||
return _Icon;
|
||||
}
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
if (auto val{ parent->_getIconImpl() })
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile Profile::_getIconOverrideSourceImpl() const
|
||||
{
|
||||
if (_Icon)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
if (auto source{ parent->_getIconOverrideSourceImpl() })
|
||||
{
|
||||
return source;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Given a commandLine like the following:
|
||||
// * "C:\WINDOWS\System32\cmd.exe"
|
||||
// * "pwsh -WorkingDirectory ~"
|
||||
|
||||
@ -102,17 +102,22 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
Model::IAppearanceConfig DefaultAppearance();
|
||||
Model::FontConfig FontInfo();
|
||||
|
||||
winrt::hstring EvaluatedIcon();
|
||||
|
||||
static std::wstring NormalizeCommandLine(LPCWSTR commandLine);
|
||||
|
||||
void _FinalizeInheritance() override;
|
||||
|
||||
void LogSettingChanges(std::set<std::string>& changes, const std::string_view& context) const;
|
||||
|
||||
// Special fields
|
||||
// EvaluatedIcon depends on Icon. It allows us to grab the
|
||||
// icon from an exe path.
|
||||
// As a result, we can't use the INHERITABLE_SETTING macro for Icon,
|
||||
// as we manually have to set/unset _evaluatedIcon when Icon changes.
|
||||
winrt::hstring EvaluatedIcon();
|
||||
hstring Icon() const;
|
||||
void Icon(const hstring& value);
|
||||
bool HasIcon() const;
|
||||
Model::Profile IconOverrideSource();
|
||||
void ClearIcon();
|
||||
|
||||
WINRT_PROPERTY(bool, Deleted, false);
|
||||
WINRT_PROPERTY(bool, Orphaned, false);
|
||||
@ -129,8 +134,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
INHERITABLE_SETTING(Model::Profile, bool, Hidden, false);
|
||||
INHERITABLE_SETTING(Model::Profile, guid, Guid, _GenerateGuidForProfile(Name(), Source()));
|
||||
INHERITABLE_SETTING(Model::Profile, hstring, Padding, DEFAULT_PADDING);
|
||||
// Icon is _very special_ because we want to customize its setter
|
||||
_BASE_INHERITABLE_SETTING(Model::Profile, std::optional<hstring>, Icon, L"\uE756");
|
||||
|
||||
public:
|
||||
#define PROFILE_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
|
||||
@ -142,6 +145,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
Model::IAppearanceConfig _DefaultAppearance{ winrt::make<AppearanceConfig>(weak_ref<Model::Profile>(*this)) };
|
||||
Model::FontConfig _FontInfo{ winrt::make<FontConfig>(weak_ref<Model::Profile>(*this)) };
|
||||
|
||||
std::optional<hstring> _Icon{ std::nullopt };
|
||||
std::optional<winrt::hstring> _evaluatedIcon{ std::nullopt };
|
||||
std::set<std::string> _changeLog;
|
||||
|
||||
@ -150,6 +154,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
static guid _GenerateGuidForProfile(const std::wstring_view& name, const std::wstring_view& source) noexcept;
|
||||
|
||||
winrt::hstring _evaluateIcon() const;
|
||||
std::optional<hstring> _getIconImpl() const;
|
||||
Model::Profile _getIconOverrideSourceImpl() const;
|
||||
void _logSettingSet(const std::string_view& setting);
|
||||
void _logSettingIfSet(const std::string_view& setting, const bool isSet);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user