Compare commits

...

2 Commits

Author SHA1 Message Date
Carlos Zamora
41190214b0 [bugged] add support for string when theme color is null 2025-08-28 17:10:21 -07:00
Carlos Zamora
82c49c8913 Add tab color setting to settings UI 2025-08-28 11:38:00 -07:00
14 changed files with 186 additions and 13 deletions

View File

@@ -4,6 +4,7 @@
#include "pch.h"
#include "NullableColorPicker.h"
#include "NullableColorPicker.g.cpp"
#include "NullableColorTemplateSelector.g.cpp"
#include <LibraryResources.h>
@@ -88,9 +89,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_NullColorPreviewProperty =
DependencyProperty::Register(
L"NullColorPreview",
xaml_typename<Windows::UI::Color>(),
xaml_typename<IReference<Windows::UI::Color>>(),
xaml_typename<Editor::NullableColorPicker>(),
PropertyMetadata{ box_value(Windows::UI::Colors::Transparent()) });
PropertyMetadata{ nullptr });
}
}
@@ -154,6 +155,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return color == nullptr;
}
Visibility NullableColorPicker::IsNullToVisibility(Windows::Foundation::IReference<Windows::UI::Color> color)
{
return color == nullptr ? Visibility::Collapsed : Visibility::Visible;
}
void NullableColorPicker::NullColorButton_Clicked(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
{
CurrentColor(nullptr);
@@ -178,10 +184,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
};
ColorPickerControl().Color(winuiColor);
}
else
else if (const auto nullColor = NullColorPreview())
{
// No current color (null), use the deduced value for null
ColorPickerControl().Color(NullColorPreview());
ColorPickerControl().Color(nullColor.Value());
}
else
{
// NullColorPreview is undefined, use a fallback value
ColorPickerControl().Color(Colors::Transparent());
}
}
@@ -223,4 +234,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
}
Windows::UI::Xaml::DataTemplate NullableColorTemplateSelector::SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item, const winrt::Windows::UI::Xaml::DependencyObject& /*container*/)
{
return SelectTemplateCore(item);
}
Windows::UI::Xaml::DataTemplate NullableColorTemplateSelector::SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item)
{
if (const auto nullableColor = item.try_as<IReference<Windows::UI::Color>>())
{
return ColorTemplate();
}
return NullColorTemplate();
}
}

View File

@@ -4,6 +4,7 @@
#pragma once
#include "NullableColorPicker.g.h"
#include "NullableColorTemplateSelector.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
@@ -15,6 +16,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
static winrt::Windows::UI::Xaml::Media::SolidColorBrush CalculateBorderBrush(const Windows::UI::Color& color);
static bool IsNull(Windows::Foundation::IReference<Microsoft::Terminal::Core::Color> color);
static Windows::UI::Xaml::Visibility IsNullToVisibility(Windows::Foundation::IReference<Windows::UI::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);
@@ -31,7 +33,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
DEPENDENCY_PROPERTY(Windows::Foundation::IReference<Microsoft::Terminal::Core::Color>, CurrentColor);
DEPENDENCY_PROPERTY(bool, ShowNullColorButton);
DEPENDENCY_PROPERTY(hstring, NullColorButtonLabel);
DEPENDENCY_PROPERTY(Windows::UI::Color, NullColorPreview);
DEPENDENCY_PROPERTY(Windows::Foundation::IReference<Windows::UI::Color>, NullColorPreview);
private:
static void _InitializeProperties();
@@ -41,9 +43,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
std::vector<Windows::UI::Xaml::Controls::Primitives::ToggleButton> _colorChips;
};
struct NullableColorTemplateSelector : NullableColorTemplateSelectorT<NullableColorTemplateSelector>
{
NullableColorTemplateSelector() = default;
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable&, const winrt::Windows::UI::Xaml::DependencyObject&);
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable&);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, ColorTemplate);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, NullColorTemplate);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(NullableColorPicker);
BASIC_FACTORY(NullableColorTemplateSelector);
}

View File

@@ -21,10 +21,19 @@ namespace Microsoft.Terminal.Settings.Editor
String NullColorButtonLabel;
static Windows.UI.Xaml.DependencyProperty NullColorButtonLabelProperty { get; };
Windows.UI.Color NullColorPreview;
Windows.Foundation.IReference<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);
static Windows.UI.Xaml.Visibility IsNullToVisibility(Windows.Foundation.IReference<Windows.UI.Color> color);
}
[default_interface] runtimeclass NullableColorTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector
{
NullableColorTemplateSelector();
Windows.UI.Xaml.DataTemplate ColorTemplate;
Windows.UI.Xaml.DataTemplate NullColorTemplate;
}
}

View File

@@ -136,9 +136,10 @@
<Border Grid.Column="0"
Width="20"
Height="20"
Background="{x:Bind mtu:Converters.ColorToBrush(NullColorPreview), Mode=OneWay}"
Background="{x:Bind mtu:Converters.ColorToBrush(NullColorPreview.Value), Mode=OneWay}"
BorderThickness="1"
CornerRadius="{StaticResource ControlCornerRadius}" />
CornerRadius="{StaticResource ControlCornerRadius}"
Visibility="{x:Bind IsNullToVisibility(NullColorPreview), Mode=OneWay}" />
<TextBlock Grid.Column="1"
Text="{x:Bind NullColorButtonLabel}" />

View File

@@ -151,6 +151,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
_NotifyChanges(L"AnswerbackMessagePreview");
}
else if (viewModelProperty == L"TabColor")
{
_NotifyChanges(L"TabColorPreview");
}
else if (viewModelProperty == L"TabThemeColorPreview")
{
_NotifyChanges(L"TabColorPreview");
}
});
_defaultAppearanceViewModel.PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
const auto viewModelProperty{ args.PropertyName() };
if (viewModelProperty == L"DarkColorSchemeName" || viewModelProperty == L"LightColorSchemeName")
{
_NotifyChanges(L"TabThemeColorPreview");
}
});
// Do the same for the starting directory
@@ -437,7 +453,50 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return RS_(L"Profile_AnswerbackMessageNone");
}
Editor::AppearanceViewModel ProfileViewModel::DefaultAppearance()
Windows::Foundation::IReference<Windows::UI::Color> ProfileViewModel::TabColorPreview() const
{
if (const auto modelVal = _profile.TabColor())
{
// 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 theme
return TabThemeColorPreview();
}
Windows::Foundation::IReference<Windows::UI::Color> ProfileViewModel::TabThemeColorPreview() const
{
if (const auto currentTheme = _appSettings.GlobalSettings().CurrentTheme())
{
if (const auto tabTheme = currentTheme.Tab())
{
if (const auto tabBackground = tabTheme.Background())
{
const auto tabColor = DefaultAppearance().CurrentColorScheme().BackgroundColor().Color();
tabColor;
const auto& tabBrush = tabBackground.Evaluate(Application::Current().Resources(),
Windows::UI::Xaml::Media::SolidColorBrush{ DefaultAppearance().CurrentColorScheme().BackgroundColor().Color() },
false);
if (const auto& tabColorBrush = tabBrush.try_as<Windows::UI::Xaml::Media::SolidColorBrush>())
{
const auto brushColor = tabColorBrush.Color();
return brushColor;
}
}
}
}
// XAML default color for tab
return nullptr;
}
Editor::AppearanceViewModel ProfileViewModel::DefaultAppearance() const
{
return _defaultAppearanceViewModel;
}
@@ -476,7 +535,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_NotifyChanges(L"UnfocusedAppearance", L"HasUnfocusedAppearance", L"ShowUnfocusedAppearance");
}
Editor::AppearanceViewModel ProfileViewModel::UnfocusedAppearance()
Editor::AppearanceViewModel ProfileViewModel::UnfocusedAppearance() const
{
return _unfocusedAppearanceViewModel;
}

View File

@@ -109,8 +109,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// general profile knowledge
winrt::guid OriginalProfileGuid() const noexcept;
bool CanDeleteProfile() const;
Editor::AppearanceViewModel DefaultAppearance();
Editor::AppearanceViewModel UnfocusedAppearance();
Editor::AppearanceViewModel DefaultAppearance() const;
Editor::AppearanceViewModel UnfocusedAppearance() const;
bool HasUnfocusedAppearance();
bool EditableUnfocusedAppearance() const noexcept;
bool ShowUnfocusedAppearance();
@@ -124,6 +124,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
bool Orphaned() const;
hstring TabTitlePreview() const;
hstring AnswerbackMessagePreview() const;
Windows::Foundation::IReference<Windows::UI::Color> TabColorPreview() const;
Windows::Foundation::IReference<Windows::UI::Color> TabThemeColorPreview() const;
til::typed_event<Editor::ProfileViewModel, Editor::DeleteProfileEventArgs> DeleteProfileRequested;

View File

@@ -123,6 +123,8 @@ namespace Microsoft.Terminal.Settings.Editor
String TabTitlePreview { get; };
String AnswerbackMessagePreview { get; };
Windows.Foundation.IReference<Windows.UI.Color> TabColorPreview { get; };
Windows.Foundation.IReference<Windows.UI.Color> TabThemeColorPreview { get; };
void CreateUnfocusedAppearance();
void DeleteUnfocusedAppearance();

View File

@@ -34,6 +34,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
_Profile = args.Profile();
_windowRoot = args.WindowRoot();
_Profile.PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
const auto viewModelProperty{ args.PropertyName() };
if (viewModelProperty == L"TabColorPreview")
{
// TODO CARLOS: When the CurrentValue changes to null (aka "use theme color" resolves to default XAML colors),
// the CurrentValueTemplateSelector should switch from using the ColorTemplate to the NullColorTemplate.
// Breakpoints in SelectTemplateCore() are not hit in this scenario (they are hit when set to not-null).
// Reloading the app with CurrentValue being null works fine. The issue is purely when swapping from a color to null.
TabColor().UpdateLayout();
}
});
// Check the use parent directory box if the starting directory is empty
if (_Profile.StartingDirectory().empty())
{

View File

@@ -208,6 +208,36 @@
Text="{x:Bind Profile.TabTitle, Mode=TwoWay}" />
</local:SettingContainer>
<!-- Tab Color -->
<!-- CurrentValueAccessibleName="{x:Bind Profile.TabColorPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}" -->
<local:SettingContainer x:Name="TabColor"
x:Uid="Profile_TabColor"
ClearSettingValue="{x:Bind Profile.ClearTabColor}"
CurrentValue="{x:Bind Profile.TabColorPreview, Mode=OneWay}"
HasSettingValue="{x:Bind Profile.HasTabColor, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.TabColorOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
<local:SettingContainer.CurrentValueTemplateSelector>
<local:NullableColorTemplateSelector ColorTemplate="{StaticResource ColorPreviewTemplate}">
<local:NullableColorTemplateSelector.NullColorTemplate>
<DataTemplate>
<!-- TODO CARLOS: ResourceString should let me get the label! It's not working though. Usiung a temporary string in the meantime -->
<TextBlock Margin="0"
Style="{StaticResource SettingContainerCurrentValueTextBlockStyle}"
Text="Use theme color" />
<!-- Text="{mtu:ResourceString Tree=TerminalSettingsEditor, Name=Profile_TabColor_NullableColorPicker.NullColorButtonLabel}" /> -->
</DataTemplate>
</local:NullableColorTemplateSelector.NullColorTemplate>
</local:NullableColorTemplateSelector>
</local:SettingContainer.CurrentValueTemplateSelector>
<local:SettingContainer.Content>
<local:NullableColorPicker x:Uid="Profile_TabColor_NullableColorPicker"
ColorSchemeVM="{x:Bind Profile.DefaultAppearance.CurrentColorScheme, Mode=OneWay}"
CurrentColor="{x:Bind Profile.TabColor, Mode=TwoWay}"
NullColorPreview="{x:Bind Profile.TabThemeColorPreview, Mode=OneWay}" />
</local:SettingContainer.Content>
</local:SettingContainer>
<!-- Elevate -->
<local:SettingContainer x:Uid="Profile_Elevate"
ClearSettingValue="{x:Bind Profile.ClearElevate}"

View File

@@ -2080,6 +2080,10 @@
<value>Use scheme color</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_TabColor_NullableColorPicker.NullColorButtonLabel" xml:space="preserve">
<value>Use theme color</value>
<comment>Label for a button directing the user to use the tab color defined in the terminal's current theme.</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>

View File

@@ -15,6 +15,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
DependencyProperty SettingContainer::_FontIconGlyphProperty{ nullptr };
DependencyProperty SettingContainer::_CurrentValueProperty{ nullptr };
DependencyProperty SettingContainer::_CurrentValueTemplateProperty{ nullptr };
DependencyProperty SettingContainer::_CurrentValueTemplateSelectorProperty{ nullptr };
DependencyProperty SettingContainer::_CurrentValueAccessibleNameProperty{ nullptr };
DependencyProperty SettingContainer::_HasSettingValueProperty{ nullptr };
DependencyProperty SettingContainer::_SettingOverrideSourceProperty{ nullptr };
@@ -75,6 +76,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
xaml_typename<Editor::SettingContainer>(),
PropertyMetadata{ nullptr });
}
if (!_CurrentValueTemplateSelectorProperty)
{
_CurrentValueTemplateSelectorProperty =
DependencyProperty::Register(
L"CurrentValueTemplateSelector",
xaml_typename<Windows::UI::Xaml::Controls::DataTemplateSelector>(),
xaml_typename<Editor::SettingContainer>(),
PropertyMetadata{ nullptr });
}
if (!_CurrentValueAccessibleNameProperty)
{
_CurrentValueAccessibleNameProperty =

View File

@@ -38,6 +38,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
DEPENDENCY_PROPERTY(hstring, FontIconGlyph);
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, CurrentValue);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::DataTemplate, CurrentValueTemplate);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Controls::DataTemplateSelector, CurrentValueTemplateSelector);
DEPENDENCY_PROPERTY(hstring, CurrentValueAccessibleName);
DEPENDENCY_PROPERTY(bool, HasSettingValue);
DEPENDENCY_PROPERTY(bool, StartExpanded);

View File

@@ -24,6 +24,9 @@ namespace Microsoft.Terminal.Settings.Editor
Windows.UI.Xaml.DataTemplate CurrentValueTemplate;
static Windows.UI.Xaml.DependencyProperty CurrentValueTemplateProperty { get; };
Windows.UI.Xaml.Controls.DataTemplateSelector CurrentValueTemplateSelector;
static Windows.UI.Xaml.DependencyProperty CurrentValueTemplateSelectorProperty { get; };
String CurrentValueAccessibleName;
static Windows.UI.Xaml.DependencyProperty CurrentValueAccessibleNameProperty { get; };

View File

@@ -461,7 +461,8 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{TemplateBinding CurrentValue}"
ContentTemplate="{TemplateBinding CurrentValueTemplate}" />
ContentTemplate="{TemplateBinding CurrentValueTemplate}"
ContentTemplateSelector="{TemplateBinding CurrentValueTemplateSelector}" />
</Grid>
</muxc:Expander.Header>
</muxc:Expander>