Simplify PR for review

This commit is contained in:
Carlos Zamora
2026-06-09 17:14:56 -07:00
parent feb35b7c8d
commit 977b4146cb
27 changed files with 1759 additions and 2072 deletions

View File

@@ -8,14 +8,27 @@
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
<!-- Merge SettingsControls and SettingContainer styles here to give every page access to them -->
<!-- Merge SettingsControls styles here to give every page access to them -->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SettingsControlsStyle.xaml" />
<ResourceDictionary Source="SettingContainerStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<Style x:Key="SecondaryTextBlockStyle"
TargetType="TextBlock">
<Setter Property="Foreground" Value="{ThemeResource TextFillColorSecondary}" />
</Style>
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{StaticResource TextFillColorSecondary}" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityBackgroundBrush"
ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconBackground"
ResourceKey="SystemFillColorCriticalBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemFillColorCautionBrush" />
<SolidColorBrush x:Key="DeleteButtonBackground"
Color="{ThemeResource DeleteButtonColor}" />
<SolidColorBrush x:Key="DeleteButtonBackgroundPointerOver"
@@ -32,6 +45,20 @@
Color="#B3FFFFFF" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<Style x:Key="SecondaryTextBlockStyle"
TargetType="TextBlock">
<Setter Property="Foreground" Value="{ThemeResource TextFillColorSecondary}" />
</Style>
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{StaticResource TextFillColorSecondary}" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityBackgroundBrush"
ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconBackground"
ResourceKey="SystemFillColorCriticalBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemFillColorCautionBrush" />
<SolidColorBrush x:Key="DeleteButtonBackground"
Color="{ThemeResource DeleteButtonColor}" />
<SolidColorBrush x:Key="DeleteButtonBackgroundPointerOver"
@@ -48,6 +75,18 @@
Color="#B3FFFFFF" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<Style x:Key="SecondaryTextBlockStyle"
TargetType="TextBlock" />
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{ThemeResource SystemColorWindowTextColor}" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemColorWindowColorBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityBackgroundBrush"
ResourceKey="SystemColorWindowColorBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconBackground"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemColorHighlightColorBrush" />
<SolidColorBrush x:Key="DeleteButtonBackground"
Color="{ThemeResource SystemColorButtonFaceColor}" />
<SolidColorBrush x:Key="DeleteButtonBackgroundPointerOver"
@@ -63,6 +102,31 @@
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<!-- Glyphs / sizing for the inline error & warning severity badges (e.g. on Appearances). -->
<x:String x:Key="SettingContainerErrorIconGlyph">&#xF13D;</x:String>
<x:String x:Key="SettingContainerWarningIconGlyph">&#xF13C;</x:String>
<x:Double x:Key="SettingContainerIconFontSize">16</x:Double>
<Style x:Key="SettingsPageItemDescriptionStyle"
BasedOn="{StaticResource CaptionTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="Margin" Value="0,0,24,0" />
<Setter Property="LineHeight" Value="16" />
<Setter Property="Foreground" Value="{ThemeResource SubgroupHeaderBrush}" />
<Setter Property="TextWrapping" Value="WrapWholeWords" />
<Setter Property="FontFamily" Value="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets" />
</Style>
<Style x:Key="SettingContainerCurrentValueTextBlockStyle"
BasedOn="{StaticResource SettingsPageItemDescriptionStyle}"
TargetType="TextBlock">
<Setter Property="MaxWidth" Value="248" />
<Setter Property="Margin" Value="0" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets" />
</Style>
<local:ColorToBrushConverter x:Key="ColorToBrushConverter" />
<local:ColorToStringConverter x:Key="ColorToStringConverter" />

View File

@@ -1,139 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ControlSizeTrigger.h"
#include "ControlSizeTrigger.g.cpp"
#include <limits>
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
DependencyProperty ControlSizeTrigger::_CanTriggerProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MinWidthProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MaxWidthProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MinHeightProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MaxHeightProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_TargetElementProperty{ nullptr };
ControlSizeTrigger::ControlSizeTrigger()
{
_InitializeProperties();
}
void ControlSizeTrigger::_InitializeProperties()
{
// Defaults mirror the toolkit: trigger is always evaluatable, bounds
// are wide open, no target element until one is bound.
if (!_CanTriggerProperty)
{
_CanTriggerProperty = DependencyProperty::Register(
L"CanTrigger",
xaml_typename<bool>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(true), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MinWidthProperty)
{
_MinWidthProperty = DependencyProperty::Register(
L"MinWidth",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MaxWidthProperty)
{
_MaxWidthProperty = DependencyProperty::Register(
L"MaxWidth",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MinHeightProperty)
{
_MinHeightProperty = DependencyProperty::Register(
L"MinHeight",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MaxHeightProperty)
{
_MaxHeightProperty = DependencyProperty::Register(
L"MaxHeight",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_TargetElementProperty)
{
_TargetElementProperty = DependencyProperty::Register(
L"TargetElement",
xaml_typename<FrameworkElement>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ nullptr, PropertyChangedCallback{ &ControlSizeTrigger::_OnTargetElementChanged } });
}
}
void ControlSizeTrigger::_OnTriggerInputChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
if (const auto obj{ d.try_as<Editor::ControlSizeTrigger>() })
{
get_self<ControlSizeTrigger>(obj)->_UpdateTrigger();
}
}
void ControlSizeTrigger::_OnTargetElementChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
{
const auto obj{ d.try_as<Editor::ControlSizeTrigger>() };
if (!obj)
{
return;
}
const auto oldElement = e.OldValue().try_as<FrameworkElement>();
const auto newElement = e.NewValue().try_as<FrameworkElement>();
get_self<ControlSizeTrigger>(obj)->_UpdateTargetElement(oldElement, newElement);
}
void ControlSizeTrigger::_UpdateTargetElement(const FrameworkElement& /*oldValue*/, const FrameworkElement& newValue)
{
// Revoking handles both unhooking the previous element and a null `newValue`.
_sizeChangedRevoker.revoke();
if (newValue)
{
_sizeChangedRevoker = newValue.SizeChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_UpdateTrigger();
}
});
}
_UpdateTrigger();
}
void ControlSizeTrigger::_UpdateTrigger()
{
const auto target = TargetElement();
if (!target || !CanTrigger())
{
_isActive = false;
SetActive(false);
return;
}
const auto width = target.ActualWidth();
const auto height = target.ActualHeight();
const bool activate =
MinWidth() <= width &&
width < MaxWidth() &&
MinHeight() <= height &&
height < MaxHeight();
_isActive = activate;
SetActive(activate);
}
}

View File

@@ -1,64 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- ControlSizeTrigger
Abstract:
- A conditional state trigger that activates based on the size (width and/or
height) of a target FrameworkElement. Lets XAML visual states swap based on
the live size of a templated part. Ported from the Windows Community Toolkit
primitive `CommunityToolkit.WinUI.ControlSizeTrigger`.
The trigger is "active" when:
MinWidth <= TargetElement.ActualWidth < MaxWidth AND
MinHeight <= TargetElement.ActualHeight < MaxHeight
Defaults: MinWidth = MinHeight = 0; MaxWidth = MaxHeight = +inf, which makes
the trigger always active unless `CanTrigger` is false or `TargetElement` is
null.
Author(s):
- Carlos Zamora - May 2026 (port from CommunityToolkit.WinUI.ControlSizeTrigger)
--*/
#pragma once
#include "ControlSizeTrigger.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct ControlSizeTrigger : ControlSizeTriggerT<ControlSizeTrigger>
{
public:
ControlSizeTrigger();
bool IsActive() const { return _isActive; }
DEPENDENCY_PROPERTY(bool, CanTrigger);
DEPENDENCY_PROPERTY(double, MinWidth);
DEPENDENCY_PROPERTY(double, MaxWidth);
DEPENDENCY_PROPERTY(double, MinHeight);
DEPENDENCY_PROPERTY(double, MaxHeight);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::FrameworkElement, TargetElement);
private:
static void _InitializeProperties();
static void _OnTriggerInputChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static void _OnTargetElementChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
void _UpdateTargetElement(const Windows::UI::Xaml::FrameworkElement& oldValue, const Windows::UI::Xaml::FrameworkElement& newValue);
void _UpdateTrigger();
Windows::UI::Xaml::FrameworkElement::SizeChanged_revoker _sizeChangedRevoker;
bool _isActive{ false };
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(ControlSizeTrigger);
}

View File

@@ -1,30 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
[default_interface] runtimeclass ControlSizeTrigger : Windows.UI.Xaml.StateTriggerBase
{
ControlSizeTrigger();
Boolean CanTrigger;
static Windows.UI.Xaml.DependencyProperty CanTriggerProperty { get; };
Double MinWidth;
static Windows.UI.Xaml.DependencyProperty MinWidthProperty { get; };
Double MaxWidth;
static Windows.UI.Xaml.DependencyProperty MaxWidthProperty { get; };
Double MinHeight;
static Windows.UI.Xaml.DependencyProperty MinHeightProperty { get; };
Double MaxHeight;
static Windows.UI.Xaml.DependencyProperty MaxHeightProperty { get; };
Windows.UI.Xaml.FrameworkElement TargetElement;
static Windows.UI.Xaml.DependencyProperty TargetElementProperty { get; };
Boolean IsActive { get; };
}
}

View File

@@ -1,58 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "CornerRadiusFilterConverters.h"
#include "CornerRadiusConverter.g.cpp"
#include "TopCornerRadiusFilterConverter.g.cpp"
#include "BottomCornerRadiusFilterConverter.g.cpp"
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
winrt::Windows::Foundation::IInspectable CornerRadiusConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ 0, 0, cr.BottomRight, cr.BottomLeft });
}
winrt::Windows::Foundation::IInspectable CornerRadiusConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ cr.TopLeft, cr.TopRight, 0, 0 });
}
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ 0, 0, cr.BottomRight, cr.BottomLeft });
}
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
}

View File

@@ -1,42 +0,0 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license.
#pragma once
#include "CornerRadiusConverter.g.h"
#include "TopCornerRadiusFilterConverter.g.h"
#include "BottomCornerRadiusFilterConverter.g.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct CornerRadiusConverter : CornerRadiusConverterT<CornerRadiusConverter>
{
CornerRadiusConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
struct TopCornerRadiusFilterConverter : TopCornerRadiusFilterConverterT<TopCornerRadiusFilterConverter>
{
TopCornerRadiusFilterConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
struct BottomCornerRadiusFilterConverter : BottomCornerRadiusFilterConverterT<BottomCornerRadiusFilterConverter>
{
BottomCornerRadiusFilterConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(CornerRadiusConverter);
BASIC_FACTORY(TopCornerRadiusFilterConverter);
BASIC_FACTORY(BottomCornerRadiusFilterConverter);
}

View File

@@ -1,20 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
[default_interface] runtimeclass CornerRadiusConverter : Windows.UI.Xaml.Data.IValueConverter
{
CornerRadiusConverter();
}
[default_interface] runtimeclass TopCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
{
TopCornerRadiusFilterConverter();
}
[default_interface] runtimeclass BottomCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
{
BottomCornerRadiusFilterConverter();
}
}

View File

@@ -201,7 +201,7 @@
</local:SettingsCard>
</DataTemplate>
<!-- This styling matches that of ExpanderSettingContainerStyle for consistency -->
<!-- This styling matches that of the SettingsExpander for consistency -->
<Style x:Key="ExpanderStyle"
TargetType="muxc:Expander">
<Setter Property="MinHeight" Value="64" />

View File

@@ -176,17 +176,8 @@
<ClInclude Include="SettingsExpander.h">
<DependentUpon>SettingsExpander.idl</DependentUpon>
</ClInclude>
<ClInclude Include="StyleExtensions.h">
<DependentUpon>StyleExtensions.idl</DependentUpon>
</ClInclude>
<ClInclude Include="ControlSizeTrigger.h">
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
</ClInclude>
<ClInclude Include="CornerRadiusFilterConverters.h">
<DependentUpon>CornerRadiusFilterConverters.idl</DependentUpon>
</ClInclude>
<ClInclude Include="StringDefaultTemplateSelector.h">
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
<ClInclude Include="SettingsControlsHelpers.h">
<DependentUpon>SettingsControlsHelpers.idl</DependentUpon>
</ClInclude>
<ClInclude Include="Utils.h" />
<ClInclude Include="PreviewConnection.h" />
@@ -264,9 +255,6 @@
<Page Include="Rendering.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="SettingContainerStyle.xaml">
<Type>DefaultStyle</Type>
</Page>
<Page Include="SettingsControlsStyle.xaml">
<Type>DefaultStyle</Type>
</Page>
@@ -409,17 +397,8 @@
<ClCompile Include="SettingsExpander.cpp">
<DependentUpon>SettingsExpander.idl</DependentUpon>
</ClCompile>
<ClCompile Include="StyleExtensions.cpp">
<DependentUpon>StyleExtensions.idl</DependentUpon>
</ClCompile>
<ClCompile Include="ControlSizeTrigger.cpp">
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
</ClCompile>
<ClCompile Include="CornerRadiusFilterConverters.cpp">
<DependentUpon>CornerRadiusFilterConverters.idl</DependentUpon>
</ClCompile>
<ClCompile Include="StringDefaultTemplateSelector.cpp">
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
<ClCompile Include="SettingsControlsHelpers.cpp">
<DependentUpon>SettingsControlsHelpers.idl</DependentUpon>
</ClCompile>
<ClCompile Include="Utils.cpp" />
<ClCompile Include="PreviewConnection.cpp">
@@ -531,16 +510,7 @@
<Midl Include="SettingsExpander.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="StyleExtensions.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="ControlSizeTrigger.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="CornerRadiusFilterConverters.idl">
<SubType>Code</SubType>
</Midl>
<Midl Include="StringDefaultTemplateSelector.idl">
<Midl Include="SettingsControlsHelpers.idl">
<SubType>Code</SubType>
</Midl>
</ItemGroup>

View File

@@ -31,10 +31,7 @@
<Midl Include="EnumEntry.idl" />
<Midl Include="SettingsCard.idl" />
<Midl Include="SettingsExpander.idl" />
<Midl Include="StyleExtensions.idl" />
<Midl Include="ControlSizeTrigger.idl" />
<Midl Include="CornerRadiusFilterConverters.idl" />
<Midl Include="StringDefaultTemplateSelector.idl" />
<Midl Include="SettingsControlsHelpers.idl" />
<Midl Include="TerminalColorConverters.idl" />
<Midl Include="NewTabMenuViewModel.idl" />
</ItemGroup>
@@ -56,7 +53,6 @@
<Page Include="Rendering.xaml" />
<Page Include="Actions.xaml" />
<Page Include="EditAction.xaml" />
<Page Include="SettingContainerStyle.xaml" />
<Page Include="SettingsControlsStyle.xaml" />
<Page Include="SettingsControlsImplicitStyles.xaml" />
<Page Include="AddProfile.xaml" />

File diff suppressed because it is too large Load Diff

View File

@@ -1,193 +1,193 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "DeleteProfileEventArgs.g.h"
#include "BellSoundViewModel.g.h"
#include "ProfileViewModel.g.h"
#include "Utils.h"
#include "ViewModelHelpers.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct BellSoundViewModel : BellSoundViewModelT<BellSoundViewModel>, ViewModelHelper<BellSoundViewModel>
{
public:
BellSoundViewModel(const Model::IMediaResource& resource);
hstring Path() const { return _resource.Path(); }
bool FileExists() const { return _resource.Ok(); }
hstring DisplayPath() const;
hstring SubText() const;
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, ShowDirectory);
private:
Model::IMediaResource _resource;
};
struct ProfileViewModel : ProfileViewModelT<ProfileViewModel>, ViewModelHelper<ProfileViewModel>
{
public:
// font face
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; };
ProfileViewModel(const Model::Profile& profile, const Model::CascadiaSettings& settings, const Windows::UI::Core::CoreDispatcher& dispatcher);
Control::IControlSettings TermSettings() const;
void DeleteProfile();
void SetupAppearances(Windows::Foundation::Collections::IObservableVector<Editor::ColorSchemeViewModel> schemesList);
void ResetSettings();
// bell style bits
hstring BellStylePreview() const;
bool IsBellStyleFlagSet(const uint32_t flag);
void SetBellStyleAudible(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleWindow(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleTaskbar(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleNotification(winrt::Windows::Foundation::IReference<bool> on);
hstring BellSoundPreview();
void RequestAddBellSound(hstring path);
void RequestDeleteBellSound(const Editor::BellSoundViewModel& vm);
void SetAcrylicOpacityPercentageValue(double value)
{
Opacity(static_cast<float>(value) / 100.0f);
};
void LeftPadding(double value) noexcept;
double LeftPadding() const noexcept;
void TopPadding(double value) noexcept;
double TopPadding() const noexcept;
void RightPadding(double value) noexcept;
double RightPadding() const noexcept;
void BottomPadding(double value) noexcept;
double BottomPadding() const noexcept;
winrt::hstring EvaluatedIcon() const
{
return _profile.Icon().Resolved();
}
Windows::UI::Xaml::Controls::IconElement IconPreview() const;
winrt::hstring LocalizedIcon() const;
winrt::hstring IconPath() const { return _profile.Icon().Path(); }
void IconPath(const winrt::hstring& path)
{
Icon(Model::MediaResourceHelper::FromString(path));
_NotifyChanges(L"Icon", L"IconPath");
}
bool UsingNoIcon() const noexcept;
// starting directory
hstring CurrentStartingDirectoryPreview() const;
bool UseParentProcessDirectory() const;
void UseParentProcessDirectory(const bool useParent);
// general profile knowledge
winrt::guid OriginalProfileGuid() const noexcept;
bool CanDeleteProfile() const;
Editor::AppearanceViewModel DefaultAppearance() const;
Editor::AppearanceViewModel UnfocusedAppearance() const;
bool HasUnfocusedAppearance();
bool EditableUnfocusedAppearance() const noexcept;
bool ShowUnfocusedAppearance();
void CreateUnfocusedAppearance();
void DeleteUnfocusedAppearance();
bool ShowMarksAvailable() const noexcept;
bool AutoMarkPromptsAvailable() const noexcept;
bool RepositionCursorWithMouseAvailable() const noexcept;
bool Orphaned() const;
hstring TabTitlePreview() const;
hstring AnswerbackMessagePreview() const;
Windows::UI::Color TabColorPreview() const;
Windows::UI::Color TabThemeColorPreview() const;
til::typed_event<Editor::ProfileViewModel, Editor::DeleteProfileEventArgs> DeleteProfileRequested;
VIEW_MODEL_OBSERVABLE_PROPERTY(ProfileSubPage, CurrentPage);
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::BellSoundViewModel>, CurrentBellSounds);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, Guid);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, ConnectionType);
OBSERVABLE_PROJECTED_SETTING(_profile, Name);
OBSERVABLE_PROJECTED_SETTING(_profile, Source);
OBSERVABLE_PROJECTED_SETTING(_profile, Hidden);
OBSERVABLE_PROJECTED_SETTING(_profile, Icon);
OBSERVABLE_PROJECTED_SETTING(_profile, CloseOnExit);
OBSERVABLE_PROJECTED_SETTING(_profile, TabTitle);
OBSERVABLE_PROJECTED_SETTING(_profile, TabColor);
OBSERVABLE_PROJECTED_SETTING(_profile, SuppressApplicationTitle);
OBSERVABLE_PROJECTED_SETTING(_profile, ScrollState);
OBSERVABLE_PROJECTED_SETTING(_profile, Padding);
OBSERVABLE_PROJECTED_SETTING(_profile, Commandline);
OBSERVABLE_PROJECTED_SETTING(_profile, StartingDirectory);
OBSERVABLE_PROJECTED_SETTING(_profile, AntialiasingMode);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Opacity);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), UseAcrylic);
OBSERVABLE_PROJECTED_SETTING(_profile, HistorySize);
OBSERVABLE_PROJECTED_SETTING(_profile, SnapOnInput);
OBSERVABLE_PROJECTED_SETTING(_profile, AltGrAliasing);
OBSERVABLE_PROJECTED_SETTING(_profile, BellStyle);
OBSERVABLE_PROJECTED_SETTING(_profile, BellSound);
OBSERVABLE_PROJECTED_SETTING(_profile, Elevate);
OBSERVABLE_PROJECTED_SETTING(_profile, ReloadEnvironmentVariables);
OBSERVABLE_PROJECTED_SETTING(_profile, RightClickContextMenu);
OBSERVABLE_PROJECTED_SETTING(_profile, ShowMarks);
OBSERVABLE_PROJECTED_SETTING(_profile, AutoMarkPrompts);
OBSERVABLE_PROJECTED_SETTING(_profile, RepositionCursorWithMouse);
OBSERVABLE_PROJECTED_SETTING(_profile, ForceVTInput);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowKittyKeyboardMode);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtChecksumReport);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtClipboardWrite);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowOscNotifications);
OBSERVABLE_PROJECTED_SETTING(_profile, AnswerbackMessage);
OBSERVABLE_PROJECTED_SETTING(_profile, RainbowSuggestions);
OBSERVABLE_PROJECTED_SETTING(_profile, PathTranslationStyle);
OBSERVABLE_PROJECTED_SETTING(_profile, DragDropDelimiter);
WINRT_PROPERTY(bool, IsBaseLayer, false);
WINRT_PROPERTY(bool, FocusDeleteButton, false);
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);
GETSET_BINDABLE_ENUM_SETTING(PathTranslationStyle, Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle);
private:
Model::Profile _profile;
winrt::guid _originalProfileGuid{};
winrt::hstring _lastBgImagePath;
winrt::hstring _lastStartingDirectoryPath;
Editor::AppearanceViewModel _defaultAppearanceViewModel;
Windows::UI::Core::CoreDispatcher _dispatcher;
winrt::Windows::UI::Xaml::Thickness _parsedPadding;
void _InitializeCurrentBellSounds();
void _PrepareModelForBellSoundModification();
void _MarkDuplicateBellSoundDirectories();
void _RefreshDefaultAppearanceViewModel();
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _MonospaceFontList;
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _FontList;
Model::CascadiaSettings _appSettings;
Editor::AppearanceViewModel _unfocusedAppearanceViewModel;
};
struct DeleteProfileEventArgs :
public DeleteProfileEventArgsT<DeleteProfileEventArgs>
{
public:
DeleteProfileEventArgs(guid profileGuid) :
_ProfileGuid(profileGuid) {}
guid ProfileGuid() const noexcept { return _ProfileGuid; }
private:
guid _ProfileGuid{};
};
};
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "DeleteProfileEventArgs.g.h"
#include "BellSoundViewModel.g.h"
#include "ProfileViewModel.g.h"
#include "Utils.h"
#include "ViewModelHelpers.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct BellSoundViewModel : BellSoundViewModelT<BellSoundViewModel>, ViewModelHelper<BellSoundViewModel>
{
public:
BellSoundViewModel(const Model::IMediaResource& resource);
hstring Path() const { return _resource.Path(); }
bool FileExists() const { return _resource.Ok(); }
hstring DisplayPath() const;
hstring SubText() const;
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, ShowDirectory);
private:
Model::IMediaResource _resource;
};
struct ProfileViewModel : ProfileViewModelT<ProfileViewModel>, ViewModelHelper<ProfileViewModel>
{
public:
// font face
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; };
ProfileViewModel(const Model::Profile& profile, const Model::CascadiaSettings& settings, const Windows::UI::Core::CoreDispatcher& dispatcher);
Control::IControlSettings TermSettings() const;
void DeleteProfile();
void SetupAppearances(Windows::Foundation::Collections::IObservableVector<Editor::ColorSchemeViewModel> schemesList);
void ResetSettings();
// bell style bits
hstring BellStylePreview() const;
bool IsBellStyleFlagSet(const uint32_t flag);
void SetBellStyleAudible(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleWindow(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleTaskbar(winrt::Windows::Foundation::IReference<bool> on);
void SetBellStyleNotification(winrt::Windows::Foundation::IReference<bool> on);
hstring BellSoundPreview();
void RequestAddBellSound(hstring path);
void RequestDeleteBellSound(const Editor::BellSoundViewModel& vm);
void SetAcrylicOpacityPercentageValue(double value)
{
Opacity(static_cast<float>(value) / 100.0f);
};
void LeftPadding(double value) noexcept;
double LeftPadding() const noexcept;
void TopPadding(double value) noexcept;
double TopPadding() const noexcept;
void RightPadding(double value) noexcept;
double RightPadding() const noexcept;
void BottomPadding(double value) noexcept;
double BottomPadding() const noexcept;
winrt::hstring EvaluatedIcon() const
{
return _profile.Icon().Resolved();
}
Windows::UI::Xaml::Controls::IconElement IconPreview() const;
winrt::hstring LocalizedIcon() const;
winrt::hstring IconPath() const { return _profile.Icon().Path(); }
void IconPath(const winrt::hstring& path)
{
Icon(Model::MediaResourceHelper::FromString(path));
_NotifyChanges(L"Icon", L"IconPath");
}
bool UsingNoIcon() const noexcept;
// starting directory
hstring CurrentStartingDirectoryPreview() const;
bool UseParentProcessDirectory() const;
void UseParentProcessDirectory(const bool useParent);
// general profile knowledge
winrt::guid OriginalProfileGuid() const noexcept;
bool CanDeleteProfile() const;
Editor::AppearanceViewModel DefaultAppearance() const;
Editor::AppearanceViewModel UnfocusedAppearance() const;
bool HasUnfocusedAppearance();
bool EditableUnfocusedAppearance() const noexcept;
bool ShowUnfocusedAppearance();
void CreateUnfocusedAppearance();
void DeleteUnfocusedAppearance();
bool ShowMarksAvailable() const noexcept;
bool AutoMarkPromptsAvailable() const noexcept;
bool RepositionCursorWithMouseAvailable() const noexcept;
bool Orphaned() const;
hstring TabTitlePreview() const;
hstring AnswerbackMessagePreview() const;
Windows::UI::Color TabColorPreview() const;
Windows::UI::Color TabThemeColorPreview() const;
til::typed_event<Editor::ProfileViewModel, Editor::DeleteProfileEventArgs> DeleteProfileRequested;
VIEW_MODEL_OBSERVABLE_PROPERTY(ProfileSubPage, CurrentPage);
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::BellSoundViewModel>, CurrentBellSounds);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, Guid);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, ConnectionType);
OBSERVABLE_PROJECTED_SETTING(_profile, Name);
OBSERVABLE_PROJECTED_SETTING(_profile, Source);
OBSERVABLE_PROJECTED_SETTING(_profile, Hidden);
OBSERVABLE_PROJECTED_SETTING(_profile, Icon);
OBSERVABLE_PROJECTED_SETTING(_profile, CloseOnExit);
OBSERVABLE_PROJECTED_SETTING(_profile, TabTitle);
OBSERVABLE_PROJECTED_SETTING(_profile, TabColor);
OBSERVABLE_PROJECTED_SETTING(_profile, SuppressApplicationTitle);
OBSERVABLE_PROJECTED_SETTING(_profile, ScrollState);
OBSERVABLE_PROJECTED_SETTING(_profile, Padding);
OBSERVABLE_PROJECTED_SETTING(_profile, Commandline);
OBSERVABLE_PROJECTED_SETTING(_profile, StartingDirectory);
OBSERVABLE_PROJECTED_SETTING(_profile, AntialiasingMode);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), Opacity);
OBSERVABLE_PROJECTED_SETTING(_profile.DefaultAppearance(), UseAcrylic);
OBSERVABLE_PROJECTED_SETTING(_profile, HistorySize);
OBSERVABLE_PROJECTED_SETTING(_profile, SnapOnInput);
OBSERVABLE_PROJECTED_SETTING(_profile, AltGrAliasing);
OBSERVABLE_PROJECTED_SETTING(_profile, BellStyle);
OBSERVABLE_PROJECTED_SETTING(_profile, BellSound);
OBSERVABLE_PROJECTED_SETTING(_profile, Elevate);
OBSERVABLE_PROJECTED_SETTING(_profile, ReloadEnvironmentVariables);
OBSERVABLE_PROJECTED_SETTING(_profile, RightClickContextMenu);
OBSERVABLE_PROJECTED_SETTING(_profile, ShowMarks);
OBSERVABLE_PROJECTED_SETTING(_profile, AutoMarkPrompts);
OBSERVABLE_PROJECTED_SETTING(_profile, RepositionCursorWithMouse);
OBSERVABLE_PROJECTED_SETTING(_profile, ForceVTInput);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowKittyKeyboardMode);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtChecksumReport);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowVtClipboardWrite);
OBSERVABLE_PROJECTED_SETTING(_profile, AllowOscNotifications);
OBSERVABLE_PROJECTED_SETTING(_profile, AnswerbackMessage);
OBSERVABLE_PROJECTED_SETTING(_profile, RainbowSuggestions);
OBSERVABLE_PROJECTED_SETTING(_profile, PathTranslationStyle);
OBSERVABLE_PROJECTED_SETTING(_profile, DragDropDelimiter);
WINRT_PROPERTY(bool, IsBaseLayer, false);
WINRT_PROPERTY(bool, FocusDeleteButton, false);
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);
GETSET_BINDABLE_ENUM_SETTING(PathTranslationStyle, Microsoft::Terminal::Control::PathTranslationStyle, PathTranslationStyle);
private:
Model::Profile _profile;
winrt::guid _originalProfileGuid{};
winrt::hstring _lastBgImagePath;
winrt::hstring _lastStartingDirectoryPath;
Editor::AppearanceViewModel _defaultAppearanceViewModel;
Windows::UI::Core::CoreDispatcher _dispatcher;
winrt::Windows::UI::Xaml::Thickness _parsedPadding;
void _InitializeCurrentBellSounds();
void _PrepareModelForBellSoundModification();
void _MarkDuplicateBellSoundDirectories();
void _RefreshDefaultAppearanceViewModel();
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _MonospaceFontList;
static Windows::Foundation::Collections::IObservableVector<Editor::Font> _FontList;
Model::CascadiaSettings _appSettings;
Editor::AppearanceViewModel _unfocusedAppearanceViewModel;
};
struct DeleteProfileEventArgs :
public DeleteProfileEventArgsT<DeleteProfileEventArgs>
{
public:
DeleteProfileEventArgs(guid profileGuid) :
_ProfileGuid(profileGuid) {}
guid ProfileGuid() const noexcept { return _ProfileGuid; }
private:
guid _ProfileGuid{};
};
};

View File

@@ -1,148 +1,148 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "EnumEntry.idl";
import "MainPage.idl";
import "Appearances.idl";
import "ColorSchemesPageViewModel.idl";
#include "ViewModelHelpers.idl.h"
#define OBSERVABLE_PROJECTED_PROFILE_SETTING(Type, Name) \
OBSERVABLE_PROJECTED_SETTING(Type, Name); \
Object Name##OverrideSource { get; }
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass DeleteProfileEventArgs
{
Guid ProfileGuid { get; };
}
runtimeclass BellSoundViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String Path { get; };
String DisplayPath { get; };
String SubText { get; };
Boolean ShowDirectory { get; };
Boolean FileExists { get; };
}
enum ProfileSubPage
{
Base = 0,
Appearance = 1,
Terminal = 2,
Advanced = 3
};
runtimeclass ProfileViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
event Windows.Foundation.TypedEventHandler<ProfileViewModel, DeleteProfileEventArgs> DeleteProfileRequested;
void SetupAppearances(Windows.Foundation.Collections.IObservableVector<ColorSchemeViewModel> schemesList);
void ResetSettings();
void SetAcrylicOpacityPercentageValue(Double value);
String BellStylePreview { get; };
Boolean IsBellStyleFlagSet(UInt32 flag);
void SetBellStyleAudible(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleWindow(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleTaskbar(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleNotification(Windows.Foundation.IReference<Boolean> on);
String BellSoundPreview { get; };
Windows.Foundation.Collections.IObservableVector<BellSoundViewModel> CurrentBellSounds { get; };
void RequestAddBellSound(String path);
void RequestDeleteBellSound(BellSoundViewModel vm);
IInspectable CurrentAntiAliasingMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> AntiAliasingModeList { get; };
IInspectable CurrentCloseOnExitMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> CloseOnExitModeList { get; };
IInspectable CurrentScrollState;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> ScrollStateList { get; };
Double LeftPadding { get; set; };
Double TopPadding { get; set; };
Double RightPadding { get; set; };
Double BottomPadding { get; set; };
IInspectable CurrentPathTranslationStyle;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> PathTranslationStyleList { get; };
String CurrentStartingDirectoryPreview { get; };
Boolean UseParentProcessDirectory;
Boolean CanDeleteProfile { get; };
Boolean FocusDeleteButton;
Boolean IsBaseLayer;
ProfileSubPage CurrentPage;
AppearanceViewModel DefaultAppearance { get; };
Guid OriginalProfileGuid { get; };
Boolean HasUnfocusedAppearance { get; };
Boolean EditableUnfocusedAppearance { get; };
Boolean ShowUnfocusedAppearance { get; };
AppearanceViewModel UnfocusedAppearance { get; };
Boolean ShowMarksAvailable { get; };
Boolean AutoMarkPromptsAvailable { get; };
Boolean RepositionCursorWithMouseAvailable { get; };
Windows.UI.Xaml.Controls.IconElement IconPreview { get; };
String EvaluatedIcon { get; };
String LocalizedIcon { get; };
String IconPath;
Boolean UsingNoIcon { get; };
String TabTitlePreview { get; };
String AnswerbackMessagePreview { get; };
Windows.UI.Color TabColorPreview { get; };
Windows.UI.Color TabThemeColorPreview { get; };
void CreateUnfocusedAppearance();
void DeleteUnfocusedAppearance();
Boolean Orphaned { get; };
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Name);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Guid, Guid);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Source);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Guid, ConnectionType);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, Hidden);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.IMediaResource, Icon);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.CloseOnExitMode, CloseOnExit);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, TabTitle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, TabColor);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SuppressApplicationTitle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, UseAcrylic);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Single, Opacity);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.ScrollbarState, ScrollState);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Padding);
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(Int32, HistorySize);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SnapOnInput);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AltGrAliasing);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.BellStyle, BellStyle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.Collections.IVector<Microsoft.Terminal.Settings.Model.IMediaResource>, BellSound);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, Elevate);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ReloadEnvironmentVariables);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RightClickContextMenu);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ShowMarks);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AutoMarkPrompts);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RepositionCursorWithMouse);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ForceVTInput);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowKittyKeyboardMode);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtChecksumReport);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, AnswerbackMessage);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RainbowSuggestions);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, DragDropDelimiter);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowOscNotifications);
}
}
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "EnumEntry.idl";
import "MainPage.idl";
import "Appearances.idl";
import "ColorSchemesPageViewModel.idl";
#include "ViewModelHelpers.idl.h"
#define OBSERVABLE_PROJECTED_PROFILE_SETTING(Type, Name) \
OBSERVABLE_PROJECTED_SETTING(Type, Name); \
Object Name##OverrideSource { get; }
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass DeleteProfileEventArgs
{
Guid ProfileGuid { get; };
}
runtimeclass BellSoundViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String Path { get; };
String DisplayPath { get; };
String SubText { get; };
Boolean ShowDirectory { get; };
Boolean FileExists { get; };
}
enum ProfileSubPage
{
Base = 0,
Appearance = 1,
Terminal = 2,
Advanced = 3
};
runtimeclass ProfileViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
event Windows.Foundation.TypedEventHandler<ProfileViewModel, DeleteProfileEventArgs> DeleteProfileRequested;
void SetupAppearances(Windows.Foundation.Collections.IObservableVector<ColorSchemeViewModel> schemesList);
void ResetSettings();
void SetAcrylicOpacityPercentageValue(Double value);
String BellStylePreview { get; };
Boolean IsBellStyleFlagSet(UInt32 flag);
void SetBellStyleAudible(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleWindow(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleTaskbar(Windows.Foundation.IReference<Boolean> on);
void SetBellStyleNotification(Windows.Foundation.IReference<Boolean> on);
String BellSoundPreview { get; };
Windows.Foundation.Collections.IObservableVector<BellSoundViewModel> CurrentBellSounds { get; };
void RequestAddBellSound(String path);
void RequestDeleteBellSound(BellSoundViewModel vm);
IInspectable CurrentAntiAliasingMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> AntiAliasingModeList { get; };
IInspectable CurrentCloseOnExitMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> CloseOnExitModeList { get; };
IInspectable CurrentScrollState;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> ScrollStateList { get; };
Double LeftPadding { get; set; };
Double TopPadding { get; set; };
Double RightPadding { get; set; };
Double BottomPadding { get; set; };
IInspectable CurrentPathTranslationStyle;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> PathTranslationStyleList { get; };
String CurrentStartingDirectoryPreview { get; };
Boolean UseParentProcessDirectory;
Boolean CanDeleteProfile { get; };
Boolean FocusDeleteButton;
Boolean IsBaseLayer;
ProfileSubPage CurrentPage;
AppearanceViewModel DefaultAppearance { get; };
Guid OriginalProfileGuid { get; };
Boolean HasUnfocusedAppearance { get; };
Boolean EditableUnfocusedAppearance { get; };
Boolean ShowUnfocusedAppearance { get; };
AppearanceViewModel UnfocusedAppearance { get; };
Boolean ShowMarksAvailable { get; };
Boolean AutoMarkPromptsAvailable { get; };
Boolean RepositionCursorWithMouseAvailable { get; };
Windows.UI.Xaml.Controls.IconElement IconPreview { get; };
String EvaluatedIcon { get; };
String LocalizedIcon { get; };
String IconPath;
Boolean UsingNoIcon { get; };
String TabTitlePreview { get; };
String AnswerbackMessagePreview { get; };
Windows.UI.Color TabColorPreview { get; };
Windows.UI.Color TabThemeColorPreview { get; };
void CreateUnfocusedAppearance();
void DeleteUnfocusedAppearance();
Boolean Orphaned { get; };
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Name);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Guid, Guid);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Source);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Guid, ConnectionType);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, Hidden);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.IMediaResource, Icon);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.CloseOnExitMode, CloseOnExit);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, TabTitle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.IReference<Microsoft.Terminal.Core.Color>, TabColor);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SuppressApplicationTitle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, UseAcrylic);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Single, Opacity);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.ScrollbarState, ScrollState);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Padding);
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(Int32, HistorySize);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, SnapOnInput);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AltGrAliasing);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Settings.Model.BellStyle, BellStyle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Windows.Foundation.Collections.IVector<Microsoft.Terminal.Settings.Model.IMediaResource>, BellSound);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, Elevate);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ReloadEnvironmentVariables);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RightClickContextMenu);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ShowMarks);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AutoMarkPrompts);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RepositionCursorWithMouse);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, ForceVTInput);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowKittyKeyboardMode);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtChecksumReport);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, AnswerbackMessage);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, RainbowSuggestions);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Microsoft.Terminal.Control.PathTranslationStyle, PathTranslationStyle);
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, DragDropDelimiter);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowVtClipboardWrite);
OBSERVABLE_PROJECTED_PROFILE_SETTING(Boolean, AllowOscNotifications);
}
}

View File

@@ -1,126 +0,0 @@
<!--
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information.
-->
<ResourceDictionary 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:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<Style x:Key="SecondaryTextBlockStyle"
TargetType="TextBlock">
<Setter Property="Foreground" Value="{ThemeResource TextFillColorSecondary}" />
</Style>
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{StaticResource TextFillColorSecondary}" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityBackgroundBrush"
ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconBackground"
ResourceKey="SystemFillColorCriticalBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemFillColorCautionBrush" />
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
ResourceKey="SystemAccentColorDark2" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<Style x:Key="SecondaryTextBlockStyle"
TargetType="TextBlock" />
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{ThemeResource SystemColorWindowTextColor}" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemColorWindowColorBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityBackgroundBrush"
ResourceKey="SystemColorWindowColorBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconBackground"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemColorHighlightColorBrush" />
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
ResourceKey="SystemAccentColorLight1" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<Style x:Key="SecondaryTextBlockStyle"
TargetType="TextBlock">
<Setter Property="Foreground" Value="{ThemeResource TextFillColorSecondary}" />
</Style>
<SolidColorBrush x:Key="SubgroupHeaderBrush"
Color="{StaticResource TextFillColorSecondary}" />
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityBackgroundBrush"
ResourceKey="SystemFillColorCautionBackgroundBrush" />
<StaticResource x:Key="SettingContainerErrorSeverityIconBackground"
ResourceKey="SystemFillColorCriticalBrush" />
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
ResourceKey="SystemFillColorCautionBrush" />
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
ResourceKey="SystemAccentColorLight2" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<x:String x:Key="SettingContainerErrorIconGlyph">&#xF13D;</x:String>
<x:String x:Key="SettingContainerWarningIconGlyph">&#xF13C;</x:String>
<x:Double x:Key="SettingContainerIconFontSize">16</x:Double>
<Style x:Key="SettingContainerResetButtonStyle"
BasedOn="{StaticResource DefaultButtonStyle}"
TargetType="Button">
<Setter Property="Margin" Value="4,0,0,0" />
<Setter Property="Height" Value="20" />
<Setter Property="Width" Value="20" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
</Style>
<Style x:Key="SettingContainerFontIconStyle"
TargetType="FontIcon">
<Setter Property="Foreground" Value="{ThemeResource SettingContainerResetButtonIconForeground}" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
</Style>
<Style x:Key="SettingsPageItemHeaderStyle"
BasedOn="{StaticResource BodyTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="LineHeight" Value="20" />
<Setter Property="TextWrapping" Value="WrapWholeWords" />
</Style>
<Style x:Key="SettingsPageItemDescriptionStyle"
BasedOn="{StaticResource CaptionTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="Margin" Value="0,0,24,0" />
<Setter Property="LineHeight" Value="16" />
<Setter Property="Foreground" Value="{ThemeResource SubgroupHeaderBrush}" />
<Setter Property="TextWrapping" Value="WrapWholeWords" />
<Setter Property="FontFamily" Value="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets" />
</Style>
<Style x:Key="SettingContainerCurrentValueTextBlockStyle"
BasedOn="{StaticResource SettingsPageItemDescriptionStyle}"
TargetType="TextBlock">
<Setter Property="MaxWidth" Value="248" />
<Setter Property="Margin" Value="0" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets" />
</Style>
</ResourceDictionary>

View File

@@ -5,7 +5,7 @@
#include "SettingsCard.h"
#include "SettingsCard.g.cpp"
#include "SettingsCardAutomationPeer.g.cpp"
#include "StyleExtensions.h"
#include "SettingsControlsHelpers.h"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::System;

View File

@@ -0,0 +1,276 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "SettingsControlsHelpers.h"
#include "ControlSizeTrigger.g.cpp"
#include "TopCornerRadiusFilterConverter.g.cpp"
#include "BottomCornerRadiusFilterConverter.g.cpp"
#include "StringDefaultTemplateSelector.g.cpp"
#include "StyleExtensions.g.cpp"
#include <limits>
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
#pragma region ControlSizeTrigger
DependencyProperty ControlSizeTrigger::_CanTriggerProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MinWidthProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MaxWidthProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MinHeightProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_MaxHeightProperty{ nullptr };
DependencyProperty ControlSizeTrigger::_TargetElementProperty{ nullptr };
ControlSizeTrigger::ControlSizeTrigger()
{
_InitializeProperties();
}
void ControlSizeTrigger::_InitializeProperties()
{
// Defaults mirror the toolkit: trigger is always evaluatable, bounds
// are wide open, no target element until one is bound.
if (!_CanTriggerProperty)
{
_CanTriggerProperty = DependencyProperty::Register(
L"CanTrigger",
xaml_typename<bool>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(true), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MinWidthProperty)
{
_MinWidthProperty = DependencyProperty::Register(
L"MinWidth",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MaxWidthProperty)
{
_MaxWidthProperty = DependencyProperty::Register(
L"MaxWidth",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MinHeightProperty)
{
_MinHeightProperty = DependencyProperty::Register(
L"MinHeight",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_MaxHeightProperty)
{
_MaxHeightProperty = DependencyProperty::Register(
L"MaxHeight",
xaml_typename<double>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
}
if (!_TargetElementProperty)
{
_TargetElementProperty = DependencyProperty::Register(
L"TargetElement",
xaml_typename<FrameworkElement>(),
xaml_typename<Editor::ControlSizeTrigger>(),
PropertyMetadata{ nullptr, PropertyChangedCallback{ &ControlSizeTrigger::_OnTargetElementChanged } });
}
}
void ControlSizeTrigger::_OnTriggerInputChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
{
if (const auto obj{ d.try_as<Editor::ControlSizeTrigger>() })
{
get_self<ControlSizeTrigger>(obj)->_UpdateTrigger();
}
}
void ControlSizeTrigger::_OnTargetElementChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
{
const auto obj{ d.try_as<Editor::ControlSizeTrigger>() };
if (!obj)
{
return;
}
const auto oldElement = e.OldValue().try_as<FrameworkElement>();
const auto newElement = e.NewValue().try_as<FrameworkElement>();
get_self<ControlSizeTrigger>(obj)->_UpdateTargetElement(oldElement, newElement);
}
void ControlSizeTrigger::_UpdateTargetElement(const FrameworkElement& /*oldValue*/, const FrameworkElement& newValue)
{
// Revoking handles both unhooking the previous element and a null `newValue`.
_sizeChangedRevoker.revoke();
if (newValue)
{
_sizeChangedRevoker = newValue.SizeChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
if (const auto strongThis = weakThis.get())
{
strongThis->_UpdateTrigger();
}
});
}
_UpdateTrigger();
}
void ControlSizeTrigger::_UpdateTrigger()
{
const auto target = TargetElement();
if (!target || !CanTrigger())
{
_isActive = false;
SetActive(false);
return;
}
const auto width = target.ActualWidth();
const auto height = target.ActualHeight();
const bool activate =
MinWidth() <= width &&
width < MaxWidth() &&
MinHeight() <= height &&
height < MaxHeight();
_isActive = activate;
SetActive(activate);
}
#pragma endregion
#pragma region TopBottomCornerRadiusFilters
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ cr.TopLeft, cr.TopRight, 0, 0 });
}
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
if (!value)
{
return value;
}
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
return box_value(CornerRadius{ 0, 0, cr.BottomRight, cr.BottomLeft });
}
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
{
return value;
}
#pragma endregion
#pragma region StringDefaultTemplateSelector
DataTemplate StringDefaultTemplateSelector::SelectTemplateCore(const IInspectable& item, const DependencyObject& /*container*/)
{
return SelectTemplateCore(item);
}
DataTemplate StringDefaultTemplateSelector::SelectTemplateCore(const IInspectable& item)
{
if (const auto pv{ item.try_as<IPropertyValue>() }; pv && pv.Type() == PropertyType::String)
{
return _StringTemplate;
}
return nullptr;
}
#pragma endregion
#pragma region StyleExtensions
ResourceDictionary StyleExtensions::_sharedImplicitStylesDictionary{ nullptr };
// Lazy singleton: loads SettingsControlsImplicitStyles.xaml exactly once
// for the process lifetime. We do NOT append this dictionary itself to any
// element's MergedDictionaries — that triggers "Element is already the
// child of another element" once a second element tries to merge it.
// Instead, EnsureImplicitStylesMergedInto copies the dictionary's entries
// (Style references) into the target's own Resources. Style instances are
// reference types but not UIElements, so sharing them across multiple
// elements' Resources collections is safe.
ResourceDictionary StyleExtensions::_SharedImplicitStylesDictionary()
{
if (!_sharedImplicitStylesDictionary)
{
try
{
auto dict{ ResourceDictionary{} };
dict.Source(winrt::Windows::Foundation::Uri{ L"ms-appx:///Microsoft.Terminal.Settings.Editor/SettingsControlsImplicitStyles.xaml" });
_sharedImplicitStylesDictionary = dict;
}
CATCH_LOG();
}
return _sharedImplicitStylesDictionary;
}
void StyleExtensions::EnsureImplicitStylesMergedInto(const FrameworkElement& target)
{
if (!target)
{
return;
}
try
{
const auto resources{ target.Resources() };
if (!resources)
{
return;
}
// Idempotency marker: if we've already populated this element's
// Resources with the implicit styles, skip. Cheap to check
// (one hash lookup), independent of MergedDictionaries.
const auto markerKey{ box_value(hstring{ L"__SettingsControls_ImplicitStyles" }) };
if (resources.HasKey(markerKey))
{
return;
}
const auto sharedDict{ _SharedImplicitStylesDictionary() };
if (!sharedDict)
{
return;
}
// Copy each entry (Style or other resource) from the shared loaded
// dictionary into the target's Resources. Style instances are
// reference types that can safely be shared across multiple
// element Resources collections (unlike UIElements, which have a
// single-parent constraint). We deliberately do NOT
// MergedDictionaries.Append(sharedDict) — that path throws
// "Element is already the child of another element" once a second
// element tries to merge the same shared dict.
for (const auto& kv : sharedDict)
{
if (!resources.HasKey(kv.Key()))
{
resources.Insert(kv.Key(), kv.Value());
}
}
resources.Insert(markerKey, box_value(true));
}
CATCH_LOG();
}
#pragma endregion
}

View File

@@ -0,0 +1,100 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- SettingsControlsHelpers
Abstract:
- Helper types backing the Windows Community Toolkit port of SettingsCard/SettingsExpander.
Grouped into a single file so the port boundary is obvious.
Author(s):
- Carlos Zamora - June 2026
--*/
#pragma once
#include "ControlSizeTrigger.g.h"
#include "TopCornerRadiusFilterConverter.g.h"
#include "BottomCornerRadiusFilterConverter.g.h"
#include "StringDefaultTemplateSelector.g.h"
#include "StyleExtensions.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct ControlSizeTrigger : ControlSizeTriggerT<ControlSizeTrigger>
{
public:
ControlSizeTrigger();
bool IsActive() const { return _isActive; }
DEPENDENCY_PROPERTY(bool, CanTrigger);
DEPENDENCY_PROPERTY(double, MinWidth);
DEPENDENCY_PROPERTY(double, MaxWidth);
DEPENDENCY_PROPERTY(double, MinHeight);
DEPENDENCY_PROPERTY(double, MaxHeight);
DEPENDENCY_PROPERTY(Windows::UI::Xaml::FrameworkElement, TargetElement);
private:
static void _InitializeProperties();
static void _OnTriggerInputChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static void _OnTargetElementChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
void _UpdateTargetElement(const Windows::UI::Xaml::FrameworkElement& oldValue, const Windows::UI::Xaml::FrameworkElement& newValue);
void _UpdateTrigger();
Windows::UI::Xaml::FrameworkElement::SizeChanged_revoker _sizeChangedRevoker;
bool _isActive{ false };
};
struct TopCornerRadiusFilterConverter : TopCornerRadiusFilterConverterT<TopCornerRadiusFilterConverter>
{
TopCornerRadiusFilterConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
struct BottomCornerRadiusFilterConverter : BottomCornerRadiusFilterConverterT<BottomCornerRadiusFilterConverter>
{
BottomCornerRadiusFilterConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
};
struct StringDefaultTemplateSelector : StringDefaultTemplateSelectorT<StringDefaultTemplateSelector>
{
StringDefaultTemplateSelector() = default;
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item, const winrt::Windows::UI::Xaml::DependencyObject& container);
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, StringTemplate, nullptr);
};
struct StyleExtensions
{
StyleExtensions() = default;
static void EnsureImplicitStylesMergedInto(const Windows::UI::Xaml::FrameworkElement& target);
private:
static Windows::UI::Xaml::ResourceDictionary _SharedImplicitStylesDictionary();
static Windows::UI::Xaml::ResourceDictionary _sharedImplicitStylesDictionary;
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(ControlSizeTrigger);
BASIC_FACTORY(TopCornerRadiusFilterConverter);
BASIC_FACTORY(BottomCornerRadiusFilterConverter);
BASIC_FACTORY(StringDefaultTemplateSelector);
BASIC_FACTORY(StyleExtensions);
}

View File

@@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
// Helper types backing the Windows Community Toolkit port of SettingsCard/SettingsExpander.
// These are grouped together so the port boundary is obvious.
namespace Microsoft.Terminal.Settings.Editor
{
// A conditional state trigger that activates based on the size of a target
// FrameworkElement. Ported from CommunityToolkit.WinUI.ControlSizeTrigger.
[default_interface] runtimeclass ControlSizeTrigger : Windows.UI.Xaml.StateTriggerBase
{
ControlSizeTrigger();
Boolean CanTrigger;
static Windows.UI.Xaml.DependencyProperty CanTriggerProperty { get; };
Double MinWidth;
static Windows.UI.Xaml.DependencyProperty MinWidthProperty { get; };
Double MaxWidth;
static Windows.UI.Xaml.DependencyProperty MaxWidthProperty { get; };
Double MinHeight;
static Windows.UI.Xaml.DependencyProperty MinHeightProperty { get; };
Double MaxHeight;
static Windows.UI.Xaml.DependencyProperty MaxHeightProperty { get; };
Windows.UI.Xaml.FrameworkElement TargetElement;
static Windows.UI.Xaml.DependencyProperty TargetElementProperty { get; };
Boolean IsActive { get; };
}
// Filter a CornerRadius down to only its top/bottom corners. Used
// by the SettingsExpander template so the header and items panel visually
// stitch together with rounded outer corners only.
[default_interface] runtimeclass TopCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
{
TopCornerRadiusFilterConverter();
}
[default_interface] runtimeclass BottomCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
{
BottomCornerRadiusFilterConverter();
}
// Selects a template only when the bound item is a string. Used by
// SettingsCard/SettingsExpander to render string Header/Description content.
[default_interface] runtimeclass StringDefaultTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector
{
StringDefaultTemplateSelector();
Windows.UI.Xaml.DataTemplate StringTemplate;
}
// Injects the project's SettingsControlsImplicitStyles.xaml dictionary into a
// SettingsCard/SettingsExpander's Resources so children (e.g. ToggleSwitch)
// pick up card-appropriate defaults. Loaded from C++ rather than the WCT
// attached-property Setter pattern, which crashes WinUI 2 in this codebase.
static runtimeclass StyleExtensions
{
static void EnsureImplicitStylesMergedInto(Windows.UI.Xaml.FrameworkElement target);
}
}

View File

@@ -161,7 +161,6 @@
-->
<x:String x:Key="SettingsExpanderChevronToolTip">Show all settings</x:String>
<local:CornerRadiusConverter x:Key="CornerRadiusConverter" />
<local:TopCornerRadiusFilterConverter x:Key="TopCornerRadiusFilterConverter" />
<local:BottomCornerRadiusFilterConverter x:Key="BottomCornerRadiusFilterConverter" />

View File

@@ -6,7 +6,7 @@
#include "SettingsExpander.g.cpp"
#include "SettingsExpanderAutomationPeer.g.cpp"
#include "SettingsExpanderItemStyleSelector.g.cpp"
#include "StyleExtensions.h"
#include "SettingsControlsHelpers.h"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;

View File

@@ -1,26 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "StringDefaultTemplateSelector.h"
#include "StringDefaultTemplateSelector.g.cpp"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
DataTemplate StringDefaultTemplateSelector::SelectTemplateCore(const IInspectable& item, const DependencyObject& /*container*/)
{
return SelectTemplateCore(item);
}
DataTemplate StringDefaultTemplateSelector::SelectTemplateCore(const IInspectable& item)
{
if (const auto pv{ item.try_as<IPropertyValue>() }; pv && pv.Type() == PropertyType::String)
{
return _StringTemplate;
}
return nullptr;
}
}

View File

@@ -1,24 +0,0 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license.
#pragma once
#include "StringDefaultTemplateSelector.g.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct StringDefaultTemplateSelector : StringDefaultTemplateSelectorT<StringDefaultTemplateSelector>
{
StringDefaultTemplateSelector() = default;
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item, const winrt::Windows::UI::Xaml::DependencyObject& container);
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item);
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, StringTemplate, nullptr);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(StringDefaultTemplateSelector);
}

View File

@@ -1,12 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
[default_interface] runtimeclass StringDefaultTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector
{
StringDefaultTemplateSelector();
Windows.UI.Xaml.DataTemplate StringTemplate;
}
}

View File

@@ -1,179 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "StyleExtensions.h"
#include "StyleExtensions.g.cpp"
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
DependencyProperty StyleExtensions::_resourcesProperty{ nullptr };
ResourceDictionary StyleExtensions::_sharedImplicitStylesDictionary{ nullptr };
DependencyProperty StyleExtensions::ResourcesProperty()
{
_InitializeProperties();
return _resourcesProperty;
}
void StyleExtensions::_InitializeProperties()
{
if (!_resourcesProperty)
{
_resourcesProperty = DependencyProperty::RegisterAttached(
L"Resources",
xaml_typename<ResourceDictionary>(),
xaml_typename<Editor::StyleExtensions>(),
PropertyMetadata{ nullptr, PropertyChangedCallback{ &StyleExtensions::_OnResourcesChanged } });
}
}
ResourceDictionary StyleExtensions::GetResources(const DependencyObject& target)
{
return target.GetValue(ResourcesProperty()).try_as<ResourceDictionary>();
}
void StyleExtensions::SetResources(const DependencyObject& target, const ResourceDictionary& value)
{
target.SetValue(ResourcesProperty(), value);
}
void StyleExtensions::_OnResourcesChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
{
const auto frameworkElement{ d.try_as<FrameworkElement>() };
if (!frameworkElement)
{
return;
}
const auto elementResources{ frameworkElement.Resources() };
if (!elementResources)
{
return;
}
const auto mergedDictionaries{ elementResources.MergedDictionaries() };
if (!mergedDictionaries)
{
return;
}
// Remove the previously-merged dictionary (if any). Resource dictionaries
// are reference types so IndexOf walks by identity, which is exactly what
// we want: the same Setter.Value is shared across every element that uses
// this Style, so the OldValue we see here is the exact instance we
// appended last time the property changed.
if (const auto oldDict{ e.OldValue().try_as<ResourceDictionary>() })
{
uint32_t index{ 0 };
if (mergedDictionaries.IndexOf(oldDict, index))
{
mergedDictionaries.RemoveAt(index);
}
}
// Add the new dictionary directly. We deliberately do NOT clone the way
// the WCT C# port does: ResourceDictionary is sealed (so we can't tag a
// private subclass like the toolkit), and a deep clone would have to
// copy the inline dictionary's Source URI — which XAML may leave as a
// relative string like "CommonResources.xaml" and which the runtime
// then rejects with "is not a valid absolute URI". Sharing the same
// dictionary across elements is fine: each element's MergedDictionaries
// only holds a reference, and implicit styles are designed to be shared.
if (const auto newDict{ e.NewValue().try_as<ResourceDictionary>() })
{
mergedDictionaries.Append(newDict);
if (frameworkElement.IsLoaded())
{
_ForceControlToReloadThemeResources(frameworkElement);
}
}
}
void StyleExtensions::_ForceControlToReloadThemeResources(const FrameworkElement& element)
{
// Toggle RequestedTheme to force the framework to re-resolve all
// {ThemeResource} bindings under this element. Required when the
// style is applied to an already-loaded element. Matches the toolkit.
const auto currentTheme{ element.RequestedTheme() };
element.RequestedTheme(currentTheme == ElementTheme::Dark ? ElementTheme::Light : ElementTheme::Dark);
element.RequestedTheme(currentTheme);
}
// Lazy singleton: loads SettingsControlsImplicitStyles.xaml exactly once
// for the process lifetime. We do NOT append this dictionary itself to any
// element's MergedDictionaries — that triggers "Element is already the
// child of another element" once a second element tries to merge it.
// Instead, EnsureImplicitStylesMergedInto copies the dictionary's entries
// (Style references) into the target's own Resources. Style instances are
// reference types but not UIElements, so sharing them across multiple
// elements' Resources collections is safe.
ResourceDictionary StyleExtensions::_SharedImplicitStylesDictionary()
{
if (!_sharedImplicitStylesDictionary)
{
try
{
auto dict{ ResourceDictionary{} };
dict.Source(winrt::Windows::Foundation::Uri{ L"ms-appx:///Microsoft.Terminal.Settings.Editor/SettingsControlsImplicitStyles.xaml" });
_sharedImplicitStylesDictionary = dict;
}
CATCH_LOG();
}
return _sharedImplicitStylesDictionary;
}
void StyleExtensions::EnsureImplicitStylesMergedInto(const FrameworkElement& target)
{
if (!target)
{
return;
}
try
{
const auto resources{ target.Resources() };
if (!resources)
{
return;
}
// Idempotency marker: if we've already populated this element's
// Resources with the implicit styles, skip. Cheap to check
// (one hash lookup), independent of MergedDictionaries.
const auto markerKey{ box_value(hstring{ L"__SettingsControls_ImplicitStyles" }) };
if (resources.HasKey(markerKey))
{
return;
}
const auto sharedDict{ _SharedImplicitStylesDictionary() };
if (!sharedDict)
{
return;
}
// Copy each entry (Style or other resource) from the shared loaded
// dictionary into the target's Resources. Style instances are
// reference types that can safely be shared across multiple
// element Resources collections (unlike UIElements, which have a
// single-parent constraint). We deliberately do NOT
// MergedDictionaries.Append(sharedDict) — that path throws
// "Element is already the child of another element" once a second
// element tries to merge the same shared dict.
for (const auto& kv : sharedDict)
{
if (!resources.HasKey(kv.Key()))
{
resources.Insert(kv.Key(), kv.Value());
}
}
resources.Insert(markerKey, box_value(true));
}
CATCH_LOG();
}
}

View File

@@ -1,35 +0,0 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license.
#pragma once
#include "StyleExtensions.g.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct StyleExtensions
{
StyleExtensions() = default;
static Windows::UI::Xaml::DependencyProperty ResourcesProperty();
static Windows::UI::Xaml::ResourceDictionary GetResources(const Windows::UI::Xaml::DependencyObject& target);
static void SetResources(const Windows::UI::Xaml::DependencyObject& target, const Windows::UI::Xaml::ResourceDictionary& value);
static void EnsureImplicitStylesMergedInto(const Windows::UI::Xaml::FrameworkElement& target);
private:
static void _InitializeProperties();
static void _OnResourcesChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
static void _ForceControlToReloadThemeResources(const Windows::UI::Xaml::FrameworkElement& element);
static Windows::UI::Xaml::ResourceDictionary _SharedImplicitStylesDictionary();
static Windows::UI::Xaml::DependencyProperty _resourcesProperty;
static Windows::UI::Xaml::ResourceDictionary _sharedImplicitStylesDictionary;
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(StyleExtensions);
}

View File

@@ -1,28 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
// Attached property that lets a Style merge an extra ResourceDictionary into
// the target FrameworkElement's Resources.MergedDictionaries. Used by
// SettingsCard / SettingsExpander to inject right-aligned ToggleSwitch and
// sized Slider / ComboBox / TextBox defaults so children laid out inside a
// card look right out of the box. Mirrors the Windows Community Toolkit's
// CommunityToolkit.WinUI.Controls.StyleExtensions.
static runtimeclass StyleExtensions
{
static Windows.UI.Xaml.DependencyProperty ResourcesProperty { get; };
static Windows.UI.Xaml.ResourceDictionary GetResources(Windows.UI.Xaml.DependencyObject target);
static void SetResources(Windows.UI.Xaml.DependencyObject target, Windows.UI.Xaml.ResourceDictionary value);
// Idempotently merges the project's SettingsControlsImplicitStyles.xaml
// dictionary into the target's Resources.MergedDictionaries. Called from
// SettingsCard / SettingsExpander OnApplyTemplate to give children
// (ToggleSwitch / Slider / ComboBox / TextBox) sensible Windows 11
// defaults without each call site setting Style explicitly. Loaded from
// C++ rather than via the attached DP because the WCT Setter.Value
// pattern crashes WinUI 2 in this codebase.
static void EnsureImplicitStylesMergedInto(Windows.UI.Xaml.FrameworkElement target);
}
}

View File

@@ -210,7 +210,7 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
}
# Extract Name via GetAttribute to avoid PowerShell's XML integration
# returning the element name (e.g. "local:SettingContainer") when x:Name is absent.
# returning the element name (e.g. "local:SettingsCard") when x:Name is absent.
$name = $settingContainer.GetAttribute("x:Name")
if ([string]::IsNullOrEmpty($name))
{