mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-17 15:36:35 +00:00
Compare commits
10 Commits
dev/yeelam
...
dev/cazamo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c64b2433da | ||
|
|
17538eb499 | ||
|
|
edfc599d6d | ||
|
|
acc1a59367 | ||
|
|
12e3455bb2 | ||
|
|
fb71a0462e | ||
|
|
c829d4ca54 | ||
|
|
b991eb048e | ||
|
|
3e3b3ad883 | ||
|
|
d3f76e7acf |
@@ -21,10 +21,6 @@ parameters:
|
||||
displayName: "Build Everything (Overrides all other build options)"
|
||||
type: boolean
|
||||
default: false
|
||||
- name: enableRustBuild
|
||||
displayName: "Build src/tools/wtr (requires RustInstaller extension + microsoft/Dart Azure Artifact feeds)"
|
||||
type: boolean
|
||||
default: true
|
||||
- name: pgoBuildMode
|
||||
type: string
|
||||
default: None
|
||||
@@ -170,80 +166,6 @@ jobs:
|
||||
.\build\scripts\Generate-ThirdPartyNotices.ps1 -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
|
||||
displayName: Generate NOTICE.html from NOTICE.md
|
||||
|
||||
- ${{ if eq(parameters.enableRustBuild, true) }}:
|
||||
# ────────────────────────────────────────────────────────────────────────
|
||||
# Rust toolchain for src/tools/wtr (1ES-compliant pattern).
|
||||
# Placed early — before vcpkg/nuget/VC-tools setup — so that Rust pipeline
|
||||
# validation is independent of any C++ build environment problems.
|
||||
#
|
||||
# Pipeline lives at: https://microsoft.visualstudio.com/Dart/
|
||||
# Reference for this pattern: microsoft/sudo (.pipelines/OneBranch.Common.yml)
|
||||
#
|
||||
# Compliance notes (per 1ES Rust workflow guidance):
|
||||
# 1. Toolchain comes from the org-level `RustTools` Azure Artifact NuGet
|
||||
# feed (already exists on `microsoft` ADO org; same feed used by
|
||||
# microsoft/sudo, microsoft/vscode, microsoft/edit, microsoft/qdk).
|
||||
# 2. Crates resolve through a project-level Azure Artifact Cargo feed
|
||||
# named `Cargo` in microsoft/Dart (with crates.io upstream).
|
||||
# 3. The Rust version uses the `ms-prod-X.YY` channel, pinned in
|
||||
# `src/tools/wtr/rust-toolchain.toml`.
|
||||
# 4. Component Governance scanning of Cargo.lock is auto-injected by
|
||||
# 1ES PT (no extra task needed here).
|
||||
#
|
||||
# Prerequisites — until in place, leave `enableRustBuild` parameter false:
|
||||
# - Azure Artifact Cargo feed `Cargo` exists in microsoft/Dart with
|
||||
# `crates.io` upstream. (Project-scope, terminal team can create it.)
|
||||
# - The CI account ("Project Collection Build Service (microsoft)") has
|
||||
# at least Collaborator permission on the `RustTools` feed.
|
||||
# ────────────────────────────────────────────────────────────────────────
|
||||
- task: RustInstaller@1
|
||||
displayName: Install Rust toolchain (MSRustup)
|
||||
inputs:
|
||||
rustVersion: ms-prod-1.93
|
||||
toolchainFeed: https://pkgs.dev.azure.com/microsoft/_packaging/RustTools/nuget/v3/index.json
|
||||
# NOTE: we deliberately do NOT set `cratesIoFeedOverride` here. That
|
||||
# parameter injects an env-var registry override named `ms_crates_io`
|
||||
# which CargoAuthenticate cannot see (it scans config files, not env
|
||||
# vars), so the override registry ends up unauthenticated and Azure
|
||||
# Artifacts returns 404 on its sparse-index endpoint.
|
||||
# Instead, the registry + source replacement lives in
|
||||
# src/tools/wtr/.cargo/config.toml — CargoAuthenticate@0 (next step)
|
||||
# tokens it, and cargo's normal config-file resolution picks it up.
|
||||
additionalTargets: 'x86_64-pc-windows-msvc i686-pc-windows-msvc aarch64-pc-windows-msvc'
|
||||
|
||||
# CargoAuthenticate issues a Bearer token (using System.AccessToken) for
|
||||
# every Azure Artifacts Cargo feed referenced in the config file.
|
||||
# Required: without it, Azure Artifacts returns 404 on the sparse index
|
||||
# endpoint and cargo reports "config.json not found in registry".
|
||||
# This is the canonical 1ES Rust auth pattern (mirrors microsoft/edit).
|
||||
- task: CargoAuthenticate@0
|
||||
displayName: Authenticate Cargo feeds
|
||||
inputs:
|
||||
configFile: src/tools/wtr/.cargo/config.toml
|
||||
|
||||
# Separate fetch step: some 1ES pools disable network during the build
|
||||
# phase. Fetching upfront keeps `cargo build --frozen` fully offline.
|
||||
- script: cargo fetch --manifest-path src/tools/wtr/Cargo.toml --locked
|
||||
displayName: Fetch crates (offline-friendly)
|
||||
|
||||
- pwsh: |-
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$triple = switch ('$(BuildPlatform)') {
|
||||
'x64' { 'x86_64-pc-windows-msvc' }
|
||||
'x86' { 'i686-pc-windows-msvc' }
|
||||
'arm64' { 'aarch64-pc-windows-msvc' }
|
||||
default { 'x86_64-pc-windows-msvc' }
|
||||
}
|
||||
$config = '$(BuildConfiguration)'
|
||||
Write-Host "Building wtr for $triple ($config)"
|
||||
if ($config -eq 'Release') {
|
||||
cargo build --manifest-path src/tools/wtr/Cargo.toml --target $triple --frozen --release
|
||||
} else {
|
||||
cargo build --manifest-path src/tools/wtr/Cargo.toml --target $triple --frozen
|
||||
}
|
||||
if ($LASTEXITCODE -ne 0) { throw "cargo build failed with exit code $LASTEXITCODE" }
|
||||
displayName: Build src/tools/wtr (Cargo)
|
||||
|
||||
- template: .\steps-install-vcpkg.yml
|
||||
|
||||
- template: .\steps-restore-nuget.yml
|
||||
|
||||
@@ -10,30 +10,13 @@ $VCToolsRoot = Join-Path $VSRoot "VC\Tools\MSVC"
|
||||
# differs from the version on the files themselves. We might as well check
|
||||
# whether the version we just found _actually exists_ before we use it.
|
||||
# We'll use whichever highest version exists.
|
||||
#
|
||||
# Some pool images report a package version (e.g. 14.44.35208) but ship only
|
||||
# package metadata, not the actual toolchain — the version folder either
|
||||
# doesn't exist or is empty. Detect both cases by also requiring a non-empty
|
||||
# `bin` subdirectory (where cl.exe / link.exe live).
|
||||
$PackageVCToolPath = Join-Path $VCToolsRoot $LatestVCToolsVersion
|
||||
$PackageVCBinPath = Join-Path $PackageVCToolPath "bin"
|
||||
$PackageIsValid = ($Null -Ne (Get-Item $PackageVCToolPath -ErrorAction:Ignore)) -And `
|
||||
($Null -Ne (Get-Item $PackageVCBinPath -ErrorAction:Ignore))
|
||||
If (-Not $PackageIsValid) {
|
||||
$VCToolsVersions = Get-ChildItem $VCToolsRoot -Directory -ErrorAction:Ignore | Where-Object {
|
||||
# Only consider directories that actually contain a populated `bin`.
|
||||
$binDir = Join-Path $_.FullName "bin"
|
||||
(Test-Path $binDir) -And ((Get-ChildItem $binDir -Recurse -File -ErrorAction:Ignore | Select-Object -First 1) -Ne $Null)
|
||||
} | ForEach-Object {
|
||||
If ($Null -Eq (Get-Item $PackageVCToolPath -ErrorAction:Ignore)) {
|
||||
$VCToolsVersions = Get-ChildItem $VCToolsRoot | ForEach-Object {
|
||||
[Version]$_.Name
|
||||
} | Sort -Descending
|
||||
$LatestActualVCToolsVersion = $VCToolsVersions | Select -First 1
|
||||
|
||||
If ($Null -Eq $LatestActualVCToolsVersion) {
|
||||
Write-Error "No usable VC Tools installation found under $VCToolsRoot. Package version was $LatestVCToolsVersion. This typically indicates a partial/broken pool image (DD-1541167)."
|
||||
Exit 1
|
||||
}
|
||||
|
||||
If ([Version]$LatestVCToolsVersion -Ne $LatestActualVCToolsVersion) {
|
||||
Write-Output "VC Tools Mismatch: Directory = $LatestActualVCToolsVersion, Package = $LatestVCToolsVersion"
|
||||
$LatestVCToolsVersion = $LatestActualVCToolsVersion.ToString(3)
|
||||
|
||||
@@ -2472,6 +2472,13 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"safeUriSchemes": {
|
||||
"description": "Specifies a list of URI schemes that are considered safe. No confirmation will be required to open URIs with these schemes.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"rendering.graphicsAPI": {
|
||||
"description": "Direct3D 11 provides a more performant and feature-rich experience, whereas Direct2D is more stable. The default option \"Automatic\" will pick the API that best fits your graphics hardware. If you experience significant issues, consider using Direct2D.",
|
||||
"type": "string",
|
||||
|
||||
@@ -24,21 +24,6 @@
|
||||
<EntryPointProjectUniqueName>..\WindowsTerminal\WindowsTerminal.vcxproj</EntryPointProjectUniqueName>
|
||||
<DebuggerType>NativeOnly</DebuggerType>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Map MSBuild Platform to Rust target triple for wtr.exe inclusion. -->
|
||||
<PropertyGroup>
|
||||
<WtrRustTarget Condition="'$(Platform)'=='x64'">x86_64-pc-windows-msvc</WtrRustTarget>
|
||||
<WtrRustTarget Condition="'$(Platform)'=='ARM64'">aarch64-pc-windows-msvc</WtrRustTarget>
|
||||
<WtrRustProfile Condition="'$(Configuration)'=='Debug'">debug</WtrRustProfile>
|
||||
<WtrRustProfile Condition="'$(Configuration)'!='Debug'">release</WtrRustProfile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="$(SolutionDir)src\tools\wtr\target\$(WtrRustTarget)\$(WtrRustProfile)\wtr.exe"
|
||||
Condition="Exists('$(SolutionDir)src\tools\wtr\target\$(WtrRustTarget)\$(WtrRustProfile)\wtr.exe')">
|
||||
<Link>wtr.exe</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="!Exists('CascadiaPackage_TemporaryKey.pfx')">
|
||||
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||
<AppxBundle>Never</AppxBundle>
|
||||
|
||||
@@ -496,12 +496,48 @@
|
||||
<value>第三方通知</value>
|
||||
<comment>A hyperlink name for the Terminal's third-party notices</comment>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
|
||||
<value>是否要关闭所有窗口?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
|
||||
<value>全部关闭</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
|
||||
<value>是否要关闭所有标签页?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
|
||||
<value>全部关闭</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
|
||||
<value>是否要关闭此选项卡?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
|
||||
<value>关闭选项卡</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
|
||||
<value>是否要关闭此窗格?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
|
||||
<value>关闭窗格</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
|
||||
<value>是否要关闭这些选项卡?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
|
||||
<value>关闭选项卡</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
|
||||
<value>是否要关闭这些窗格?</value>
|
||||
</data>
|
||||
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
|
||||
<value>关闭窗格</value>
|
||||
</data>
|
||||
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
|
||||
<value>不再询问</value>
|
||||
</data>
|
||||
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
|
||||
@@ -3307,13 +3307,15 @@ namespace winrt::TerminalApp::implementation
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri)
|
||||
bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const
|
||||
{
|
||||
if (parsedUri.SchemeName() == L"http" || parsedUri.SchemeName() == L"https")
|
||||
const auto& schemeName = parsedUri.SchemeName();
|
||||
|
||||
if (schemeName == L"http" || schemeName == L"https")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (parsedUri.SchemeName() == L"file")
|
||||
if (schemeName == L"file")
|
||||
{
|
||||
static const auto pathext{ wil::TryGetEnvironmentVariableW<std::wstring>(L"PATHEXT") };
|
||||
const auto filename = parsedUri.Path();
|
||||
@@ -3327,6 +3329,16 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
return true;
|
||||
}
|
||||
if (const auto& safeSchemes = _settings.GlobalSettings().SafeUriSchemes())
|
||||
{
|
||||
for (const auto& scheme : safeSchemes)
|
||||
{
|
||||
if (til::equals_insensitive_ascii(schemeName, scheme))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -438,7 +438,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
safe_void_coroutine _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs);
|
||||
static bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
static bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri);
|
||||
bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const;
|
||||
|
||||
void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri);
|
||||
bool _CopyText(bool dismissSelection, bool singleLine, bool withControlSequences, Microsoft::Terminal::Control::CopyFormat formats);
|
||||
|
||||
@@ -98,7 +98,6 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
_answerbackMessage = settings.AnswerbackMessage();
|
||||
_wordDelimiters = settings.WordDelimiters();
|
||||
_suppressApplicationTitle = settings.SuppressApplicationTitle();
|
||||
_startingTitle = settings.StartingTitle();
|
||||
_trimBlockSelection = settings.TrimBlockSelection();
|
||||
_autoMarkPrompts = settings.AutoMarkPrompts();
|
||||
_rainbowSuggestions = settings.RainbowSuggestions();
|
||||
@@ -124,6 +123,11 @@ void Terminal::UpdateSettings(ICoreSettings settings)
|
||||
// Save the changes made above and in UpdateAppearance as the new default render settings.
|
||||
GetRenderSettings().SaveDefaultSettings();
|
||||
|
||||
if (!_startingTitle)
|
||||
{
|
||||
_startingTitle = settings.StartingTitle();
|
||||
}
|
||||
|
||||
if (!_startingTabColor && settings.StartingTabColor())
|
||||
{
|
||||
_startingTabColor = settings.StartingTabColor().Value();
|
||||
|
||||
@@ -349,7 +349,7 @@ private:
|
||||
::Microsoft::Console::VirtualTerminal::TerminalInput _terminalInput;
|
||||
|
||||
std::optional<std::wstring> _title;
|
||||
std::wstring _startingTitle;
|
||||
std::optional<std::wstring> _startingTitle;
|
||||
std::optional<til::color> _startingTabColor;
|
||||
|
||||
std::vector<til::point_span> _searchHighlights;
|
||||
|
||||
@@ -91,8 +91,12 @@ void Terminal::SetWindowTitle(const std::wstring_view title)
|
||||
_assertLocked();
|
||||
if (!_suppressApplicationTitle)
|
||||
{
|
||||
_title.emplace(title.empty() ? _startingTitle : title);
|
||||
_pfnTitleChanged(_title.value());
|
||||
_title.reset();
|
||||
if (!title.empty())
|
||||
{
|
||||
_title.emplace(title);
|
||||
}
|
||||
_pfnTitleChanged(GetConsoleTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +116,13 @@ bool Terminal::ResizeWindow(const til::CoordType width, const til::CoordType hei
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto currentDimensions = _GetMutableViewport().Dimensions();
|
||||
|
||||
if (width == currentDimensions.width && height == currentDimensions.height)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_pfnWindowSizeChanged)
|
||||
{
|
||||
_pfnWindowSizeChanged(width, height);
|
||||
|
||||
@@ -184,11 +184,18 @@ void Terminal::SelectNewRegion(const til::point coordStart, const til::point coo
|
||||
std::wstring_view Terminal::GetConsoleTitle() const noexcept
|
||||
{
|
||||
_assertLocked();
|
||||
if (_title.has_value())
|
||||
|
||||
if (_title)
|
||||
{
|
||||
return *_title;
|
||||
}
|
||||
return _startingTitle;
|
||||
|
||||
if (_startingTitle)
|
||||
{
|
||||
return *_startingTitle;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
CurrentValueAccessibleName="{x:Bind Appearance.CurrentColorScheme.Name, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Appearance.HasDarkColorSchemeName, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.DarkColorSchemeNameOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<ComboBox Padding="4"
|
||||
ItemsSource="{x:Bind Appearance.SchemesList, Mode=OneWay}"
|
||||
@@ -220,7 +220,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasForeground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.ForegroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_Foreground_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.Foreground, Mode=TwoWay}"
|
||||
@@ -236,7 +236,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasBackground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.BackgroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_Background_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.Background, Mode=TwoWay}"
|
||||
@@ -252,7 +252,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasSelectionBackground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.SelectionBackgroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_SelectionBackground_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.SelectionBackground, Mode=TwoWay}"
|
||||
@@ -536,7 +536,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasCursorColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.CursorColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_CursorColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.CursorColor, Mode=TwoWay}"
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
|
||||
|
||||
<!-- Merge SettingContainerStyle here to give every page access to the SettingContainer -->
|
||||
<!-- Merge SettingsControls and SettingContainer styles here to give every page access to them -->
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="SettingsControlsStyle.xaml" />
|
||||
<ResourceDictionary Source="SettingContainerStyle.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
@@ -1200,87 +1201,6 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="NavigatorButtonStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="Background" Value="{ThemeResource ExpanderHeaderBackground}" />
|
||||
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
|
||||
<Setter Property="MinHeight" Value="64" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
<Setter Property="Padding" Value="16,0,8,0" />
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid x:Name="Grid"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentPresenter x:Name="ContentPresenter"
|
||||
Grid.Column="0"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}" />
|
||||
<FontIcon Grid.Column="1"
|
||||
Margin="20,0,8,0"
|
||||
HorizontalAlignment="Right"
|
||||
FontSize="10"
|
||||
FontWeight="Black"
|
||||
Glyph="" />
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ToggleButtonBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ToggleButtonBorderBrushPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ToggleButtonBackgroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Grid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource ToggleButtonBorderBrushPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="NewInfoBadge"
|
||||
TargetType="muxc:InfoBadge">
|
||||
<Setter Property="Padding" Value="5,1,5,2" />
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void Extensions::ExtensionNavigator_Click(const IInspectable& sender, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
const auto extPkgVM = sender.as<Controls::Button>().Tag().as<Editor::ExtensionPackageViewModel>();
|
||||
const auto extPkgVM = sender.as<FrameworkElement>().Tag().as<Editor::ExtensionPackageViewModel>();
|
||||
_ViewModel.CurrentExtensionPackage(extPkgVM);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,78 +127,58 @@
|
||||
|
||||
<DataTemplate x:Key="DefaultExtensionNavigatorTemplate"
|
||||
x:DataType="local:ExtensionPackageViewModel">
|
||||
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}"
|
||||
Tag="{x:Bind}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter Content="{x:Bind}"
|
||||
ContentTemplate="{StaticResource DefaultExtensionIdentifierTemplate}" />
|
||||
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
|
||||
</Grid>
|
||||
</Button>
|
||||
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Header="{x:Bind Package.Source}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind}">
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ComplexExtensionNavigatorTemplate"
|
||||
x:DataType="local:ExtensionPackageViewModel">
|
||||
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}"
|
||||
Tag="{x:Bind}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter Content="{x:Bind}"
|
||||
ContentTemplate="{StaticResource ComplexExtensionIdentifierTemplate}" />
|
||||
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Description="{x:Bind Package.Source}"
|
||||
Header="{x:Bind Package.DisplayName}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind}">
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<IconSourceElement IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Package.Icon)}" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ComplexExtensionNavigatorTemplateWithFontIcon"
|
||||
x:DataType="local:ExtensionPackageViewModel">
|
||||
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}"
|
||||
Tag="{x:Bind}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter Content="{x:Bind}"
|
||||
ContentTemplate="{StaticResource ComplexExtensionIdentifierTemplateWithFontIcon}" />
|
||||
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Description="{x:Bind Package.Source}"
|
||||
Header="{x:Bind Package.DisplayName}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind}">
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="{x:Bind Package.Icon}" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="FragmentProfileViewModelTemplate"
|
||||
@@ -502,9 +482,11 @@
|
||||
<!-- Scope -->
|
||||
<local:SettingContainer x:Name="Scope"
|
||||
x:Uid="Extensions_Scope"
|
||||
Content="{x:Bind ViewModel.CurrentExtensionPackage.Scope, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Style="{StaticResource SettingContainerWithTextContent}" />
|
||||
IsTabStop="False">
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentExtensionPackage.Scope, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
<!-- JSON -->
|
||||
<ItemsControl IsTabStop="False"
|
||||
ItemTemplate="{StaticResource JsonTemplate}"
|
||||
|
||||
@@ -173,6 +173,15 @@
|
||||
<ClInclude Include="SettingContainer.h">
|
||||
<DependentUpon>SettingContainer.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SettingsCard.h">
|
||||
<DependentUpon>SettingsCard.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SettingsExpander.h">
|
||||
<DependentUpon>SettingsExpander.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StringDefaultTemplateSelector.h">
|
||||
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="PreviewConnection.h" />
|
||||
<ClInclude Include="$(GeneratedFilesDir)GeneratedSettingsIndex.g.h" />
|
||||
@@ -252,6 +261,9 @@
|
||||
<Page Include="SettingContainerStyle.xaml">
|
||||
<Type>DefaultStyle</Type>
|
||||
</Page>
|
||||
<Page Include="SettingsControlsStyle.xaml">
|
||||
<Type>DefaultStyle</Type>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
@@ -385,6 +397,15 @@
|
||||
<ClCompile Include="SettingContainer.cpp">
|
||||
<DependentUpon>SettingContainer.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SettingsCard.cpp">
|
||||
<DependentUpon>SettingsCard.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SettingsExpander.cpp">
|
||||
<DependentUpon>SettingsExpander.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StringDefaultTemplateSelector.cpp">
|
||||
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
<ClCompile Include="PreviewConnection.cpp">
|
||||
<DependentUpon>PreviewConnection.h</DependentUpon>
|
||||
@@ -492,6 +513,15 @@
|
||||
<Midl Include="SettingContainer.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="SettingsCard.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="SettingsExpander.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="StringDefaultTemplateSelector.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
<!-- ========================= Misc Files ======================== -->
|
||||
<ItemGroup>
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
<Midl Include="LaunchViewModel.idl" />
|
||||
<Midl Include="EnumEntry.idl" />
|
||||
<Midl Include="SettingContainer.idl" />
|
||||
<Midl Include="SettingsCard.idl" />
|
||||
<Midl Include="SettingsExpander.idl" />
|
||||
<Midl Include="StringDefaultTemplateSelector.idl" />
|
||||
<Midl Include="TerminalColorConverters.idl" />
|
||||
<Midl Include="NewTabMenuViewModel.idl" />
|
||||
</ItemGroup>
|
||||
@@ -52,6 +55,7 @@
|
||||
<Page Include="Actions.xaml" />
|
||||
<Page Include="EditAction.xaml" />
|
||||
<Page Include="SettingContainerStyle.xaml" />
|
||||
<Page Include="SettingsControlsStyle.xaml" />
|
||||
<Page Include="AddProfile.xaml" />
|
||||
<Page Include="KeyChordListener.xaml" />
|
||||
<Page Include="NullableColorPicker.xaml" />
|
||||
|
||||
@@ -332,7 +332,7 @@
|
||||
<local:SettingContainer x:Name="CurrentFolderIcon"
|
||||
x:Uid="NewTabMenu_CurrentFolderIcon"
|
||||
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
@@ -378,8 +378,7 @@
|
||||
<!-- Add Profile -->
|
||||
<local:SettingContainer x:Name="AddProfile"
|
||||
x:Uid="NewTabMenu_AddProfile"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
FontIconGlyph="">
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
@@ -428,8 +427,7 @@
|
||||
<!-- Add Separator -->
|
||||
<local:SettingContainer x:Name="AddSeparator"
|
||||
x:Uid="NewTabMenu_AddSeparator"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
FontIconGlyph="">
|
||||
<Button x:Name="AddSeparatorButton"
|
||||
x:Uid="NewTabMenu_AddSeparatorButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
@@ -445,8 +443,7 @@
|
||||
<!-- Add Folder -->
|
||||
<local:SettingContainer x:Name="AddFolder"
|
||||
x:Uid="NewTabMenu_AddFolder"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
FontIconGlyph="">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
<TextBox x:Name="FolderNameTextBox"
|
||||
@@ -473,7 +470,7 @@
|
||||
<local:SettingContainer x:Name="AddMatchProfiles"
|
||||
x:Uid="NewTabMenu_AddMatchProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel Spacing="8">
|
||||
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
|
||||
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
|
||||
@@ -500,8 +497,7 @@
|
||||
<!-- Add Remaining Profiles -->
|
||||
<local:SettingContainer x:Name="AddRemainingProfiles"
|
||||
x:Uid="NewTabMenu_AddRemainingProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
FontIconGlyph="">
|
||||
<Button x:Name="AddRemainingProfilesButton"
|
||||
x:Uid="NewTabMenu_AddRemainingProfilesButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
Automation::AutomationProperties::SetFullDescription(StartingDirectoryUseParentCheckbox(), unbox_value<hstring>(startingDirCheckboxTooltip));
|
||||
|
||||
Automation::AutomationProperties::SetName(DeleteButton(), RS_(L"Profile_DeleteButton/Text"));
|
||||
AppearanceNavigator().Content(box_value(RS_(L"Profile_Appearance/Header")));
|
||||
TerminalNavigator().Content(box_value(RS_(L"Profile_Terminal/Header")));
|
||||
AdvancedNavigator().Content(box_value(RS_(L"Profile_Advanced/Header")));
|
||||
AppearanceNavigator().Header(box_value(RS_(L"Profile_Appearance/Header")));
|
||||
TerminalNavigator().Header(box_value(RS_(L"Profile_Terminal/Header")));
|
||||
AdvancedNavigator().Header(box_value(RS_(L"Profile_Advanced/Header")));
|
||||
}
|
||||
|
||||
void Profiles_Base::OnNavigatedTo(const NavigationEventArgs& e)
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
CurrentValueAccessibleName="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
@@ -150,7 +150,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_TabColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Profile.DefaultAppearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Profile.TabColor, Mode=TwoWay}"
|
||||
@@ -179,15 +179,15 @@
|
||||
Margin="0,32,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<Button x:Name="AppearanceNavigator"
|
||||
Click="Appearance_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}" />
|
||||
<Button x:Name="TerminalNavigator"
|
||||
Click="Terminal_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}" />
|
||||
<Button x:Name="AdvancedNavigator"
|
||||
Click="Advanced_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}" />
|
||||
<local:SettingsCard x:Name="AppearanceNavigator"
|
||||
Click="Appearance_Click"
|
||||
IsClickEnabled="True" />
|
||||
<local:SettingsCard x:Name="TerminalNavigator"
|
||||
Click="Terminal_Click"
|
||||
IsClickEnabled="True" />
|
||||
<local:SettingsCard x:Name="AdvancedNavigator"
|
||||
Click="Advanced_Click"
|
||||
IsClickEnabled="True" />
|
||||
<!-- Delete Button -->
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<Button x:Name="DeleteButton"
|
||||
|
||||
@@ -2201,10 +2201,26 @@
|
||||
<value>关闭多个选项卡时发出警告</value>
|
||||
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmOnClose.Header" xml:space="preserve">
|
||||
<value>关闭时发出警告</value>
|
||||
<comment>Header for a dropdown controlling when to show a confirmation dialog before closing.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmOnClose.HelpText" xml:space="preserve">
|
||||
<value>控制在关闭选项卡或窗口之前何时显示确认对话框。“始终”在关闭任何窗格时显示对话框。</value>
|
||||
<comment>Help text associated with Globals_ConfirmOnClose. "Always" refers to Globals_ConfirmOnCloseAlways.Content.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmOnCloseNever.Content" xml:space="preserve">
|
||||
<value>从不</value>
|
||||
<comment>Option associated with Globals_ConfirmOnClose. "Never" means that the system will never display a warning when closing.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmOnCloseAlways.Content" xml:space="preserve">
|
||||
<value>始终</value>
|
||||
<comment>Option associated with Globals_ConfirmOnClose. "Always" means that the system will always display a warning when closing.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmOnCloseAutomatic.Content" xml:space="preserve">
|
||||
<value>多个选项卡或窗格</value>
|
||||
<comment>Option associated with Globals_ConfirmOnClose. The system will display a warning when multiple tabs or panes are present.</comment>
|
||||
</data>
|
||||
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
|
||||
<value>禁用“触摸键盘和手写面板服务”时发出警告</value>
|
||||
</data>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "SettingContainer.h"
|
||||
#include "SettingsExpander.h"
|
||||
#include "SettingContainer.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
@@ -54,7 +55,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
L"FontIconGlyph",
|
||||
xaml_typename<hstring>(),
|
||||
xaml_typename<Editor::SettingContainer>(),
|
||||
PropertyMetadata{ box_value(L"") });
|
||||
PropertyMetadata{ box_value(L""), PropertyChangedCallback{ &SettingContainer::_OnFontIconGlyphChanged } });
|
||||
}
|
||||
if (!_CurrentValueProperty)
|
||||
{
|
||||
@@ -139,7 +140,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
base.reserve(2);
|
||||
if (const auto& child{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
|
||||
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
base.push_back(child);
|
||||
}
|
||||
@@ -223,13 +224,47 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
_UpdateOverrideSystem();
|
||||
_UpdateHelpText();
|
||||
_UpdateHeaderIcon();
|
||||
}
|
||||
|
||||
void SettingContainer::_UpdateHeaderIcon()
|
||||
{
|
||||
Controls::IconElement icon{ nullptr };
|
||||
if (const auto glyph{ FontIconGlyph() }; !glyph.empty())
|
||||
{
|
||||
Controls::FontIcon fi;
|
||||
fi.Glyph(glyph);
|
||||
icon = fi;
|
||||
}
|
||||
|
||||
if (const auto& cardChild{ GetTemplateChild(L"Card") })
|
||||
{
|
||||
if (const auto& card{ cardChild.try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
card.HeaderIcon(icon);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (const auto& expanderChild{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ expanderChild.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
expander.HeaderIcon(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingContainer::_OnFontIconGlyphChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*args*/)
|
||||
{
|
||||
const auto& obj{ d.try_as<Editor::SettingContainer>() };
|
||||
get_self<SettingContainer>(obj)->_UpdateHeaderIcon();
|
||||
}
|
||||
|
||||
void SettingContainer::SetExpanded(bool expanded)
|
||||
{
|
||||
if (const auto& child{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
|
||||
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
expander.IsExpanded(expanded);
|
||||
}
|
||||
@@ -271,7 +306,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
if (const auto& child{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
|
||||
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
Automation::AutomationProperties::SetName(expander, _GenerateAccessibleName());
|
||||
}
|
||||
|
||||
@@ -48,11 +48,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
static void _OnCurrentValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnHasSettingValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnHelpTextChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnFontIconGlyphChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static hstring _GenerateOverrideMessage(const IInspectable& settingOrigin);
|
||||
hstring _GenerateAccessibleName();
|
||||
void _UpdateOverrideSystem();
|
||||
void _UpdateHelpText();
|
||||
void _UpdateCurrentValueAutoProp();
|
||||
void _UpdateHeaderIcon();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
</Style>
|
||||
<SolidColorBrush x:Key="SubgroupHeaderBrush"
|
||||
Color="{StaticResource TextFillColorSecondary}" />
|
||||
<StaticResource x:Key="ExpanderHeaderBorderBrush"
|
||||
ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
|
||||
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
|
||||
@@ -43,16 +41,12 @@
|
||||
|
||||
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
|
||||
ResourceKey="SystemAccentColorDark2" />
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Style x:Key="SecondaryTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
<!-- Do not mess with the foreground color for High Contrast. Let it ride as is. -->
|
||||
<SolidColorBrush x:Key="SubgroupHeaderBrush"
|
||||
Color="{ThemeResource SystemColorWindowTextColor}" />
|
||||
<StaticResource x:Key="ExpanderHeaderBorderBrush"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
|
||||
ResourceKey="SystemColorWindowColorBrush" />
|
||||
@@ -84,8 +78,6 @@
|
||||
</Style>
|
||||
<SolidColorBrush x:Key="SubgroupHeaderBrush"
|
||||
Color="{StaticResource TextFillColorSecondary}" />
|
||||
<StaticResource x:Key="ExpanderHeaderBorderBrush"
|
||||
ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
|
||||
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
|
||||
@@ -121,12 +113,6 @@
|
||||
<Thickness x:Key="SettingContainerIconMargin">0,4,8,4</Thickness>
|
||||
<x:Double x:Key="SettingContainerIconFontSize">16</x:Double>
|
||||
|
||||
<Style x:Key="StackPanelInExpanderStyle"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Padding" Value="0,12,0,12" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingContainerResetButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -145,18 +131,6 @@
|
||||
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="NonExpanderGrid"
|
||||
TargetType="Grid">
|
||||
<Setter Property="Background" Value="{ThemeResource ExpanderHeaderBackground}" />
|
||||
<Setter Property="MinWidth" Value="{ThemeResource FlyoutThemeMinWidth}" />
|
||||
<Setter Property="MinHeight" Value="64" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
<Setter Property="Padding" Value="16,0,8,0" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsPageItemHeaderStyle"
|
||||
BasedOn="{StaticResource BodyTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
@@ -178,7 +152,7 @@
|
||||
BasedOn="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MaxWidth" Value="248" />
|
||||
<Setter Property="Margin" Value="0,0,-16,0" />
|
||||
<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" />
|
||||
@@ -189,7 +163,9 @@
|
||||
Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
|
||||
<!-- A setting container for a setting that has no additional options -->
|
||||
<local:StringDefaultTemplateSelector x:Key="ExpanderPreviewTemplateSelector"
|
||||
StringTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
|
||||
<Style TargetType="local:SettingContainer">
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
@@ -197,14 +173,9 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<local:SettingsCard x:Name="Card"
|
||||
Content="{TemplateBinding Content}">
|
||||
<local:SettingsCard.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
@@ -214,257 +185,61 @@
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingsCard.Header>
|
||||
<local:SettingsCard.Description>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding Content}" />
|
||||
</Grid>
|
||||
</local:SettingsCard.Description>
|
||||
</local:SettingsCard>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- A basic setting container displaying immutable text as content -->
|
||||
<Style x:Key="SettingContainerWithTextContent"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="1"
|
||||
Margin="0,0,8,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{TemplateBinding Content}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
A setting container for a setting that has no additional options.
|
||||
Includes space for an icon on the left side of the header.
|
||||
XAML applies the margin/padding of the icon regardless of its
|
||||
existence (which caused inconsistent padding). It's easier to just create
|
||||
another style and move on.
|
||||
-->
|
||||
<Style x:Key="SettingContainerWithIcon"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph="{TemplateBinding FontIconGlyph}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
Padding="14,12,0,12"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding Content}" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- A setting container which can expand -->
|
||||
<Style x:Key="ExpanderSettingContainerStyle"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ContentPresenter Content="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
A setting container which can expand. Includes space for an icon on the left side of the header.
|
||||
XAML applies the margin/padding of the icon regardless of its
|
||||
existence (which caused inconsistent padding). It's easier to just create
|
||||
another style and move on.
|
||||
-->
|
||||
<Style x:Key="ExpanderSettingContainerStyleWithIcon"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph="{TemplateBinding FontIconGlyph}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
Padding="14,12,0,12"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- A setting container which can expand. Supports data template override for preview -->
|
||||
<Style x:Key="ExpanderSettingContainerStyleWithComplexPreview"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
MaxWidth="248"
|
||||
Margin="0,0,-16,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{TemplateBinding CurrentValueTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
<local:SettingsExpander x:Name="Expander"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<local:SettingsExpander.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingsExpander.Header>
|
||||
<local:SettingsExpander.Description>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</local:SettingsExpander.Description>
|
||||
<local:SettingsExpander.Content>
|
||||
<ContentControl MaxWidth="248"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalContentAlignment="Right"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{TemplateBinding CurrentValueTemplate}"
|
||||
ContentTemplateSelector="{StaticResource ExpanderPreviewTemplateSelector}"
|
||||
IsTabStop="False" />
|
||||
</local:SettingsExpander.Content>
|
||||
<local:SettingsExpander.ItemsHeader>
|
||||
<ContentPresenter Padding="16,12,16,16"
|
||||
Content="{TemplateBinding Content}" />
|
||||
</local:SettingsExpander.ItemsHeader>
|
||||
</local:SettingsExpander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@@ -479,14 +254,8 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Background="{ThemeResource SettingContainerWarningSeverityBackgroundBrush}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<local:SettingsCard Background="{ThemeResource SettingContainerWarningSeverityBackgroundBrush}">
|
||||
<local:SettingsCard.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Grid>
|
||||
<TextBlock x:Name="IconBackground"
|
||||
@@ -498,7 +267,6 @@
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerWarningSeverityIconBackground}"
|
||||
Text="{StaticResource SettingContainerIconBackgroundGlyph}" />
|
||||
|
||||
<TextBlock x:Name="StandardIcon"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingContainerIconMargin}"
|
||||
@@ -514,12 +282,14 @@
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
</StackPanel>
|
||||
</local:SettingsCard.Header>
|
||||
<local:SettingsCard.Description>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Foreground="{ThemeResource SettingContainerMessageForeground}"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</local:SettingsCard.Description>
|
||||
</local:SettingsCard>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@@ -534,14 +304,8 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Background="{ThemeResource SettingContainerErrorSeverityBackgroundBrush}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<local:SettingsCard Background="{ThemeResource SettingContainerErrorSeverityBackgroundBrush}">
|
||||
<local:SettingsCard.Header>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Grid>
|
||||
<TextBlock x:Name="IconBackground"
|
||||
@@ -553,7 +317,6 @@
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerErrorSeverityIconBackground}"
|
||||
Text="{StaticResource SettingContainerIconBackgroundGlyph}" />
|
||||
|
||||
<TextBlock x:Name="StandardIcon"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingContainerIconMargin}"
|
||||
@@ -569,12 +332,14 @@
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
</StackPanel>
|
||||
</local:SettingsCard.Header>
|
||||
<local:SettingsCard.Description>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Foreground="{ThemeResource SettingContainerMessageForeground}"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</local:SettingsCard.Description>
|
||||
</local:SettingsCard>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
472
src/cascadia/TerminalSettingsEditor/SettingsCard.cpp
Normal file
472
src/cascadia/TerminalSettingsEditor/SettingsCard.cpp
Normal file
@@ -0,0 +1,472 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "SettingsCard.h"
|
||||
#include "SettingsCard.g.cpp"
|
||||
#include "SettingsCardAutomationPeer.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls::Primitives;
|
||||
using namespace winrt::Windows::UI::Xaml::Input;
|
||||
using namespace winrt::Windows::UI::Xaml::Media;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty SettingsCard::_HeaderProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_DescriptionProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_HeaderIconProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_ActionIconProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_ActionIconToolTipProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_IsClickEnabledProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_IsActionIconVisibleProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_ContentAlignmentProperty{ nullptr };
|
||||
|
||||
static constexpr std::wstring_view NormalState{ L"Normal" };
|
||||
static constexpr std::wstring_view PointerOverState{ L"PointerOver" };
|
||||
static constexpr std::wstring_view PressedState{ L"Pressed" };
|
||||
static constexpr std::wstring_view DisabledState{ L"Disabled" };
|
||||
|
||||
static constexpr std::wstring_view RightState{ L"Right" };
|
||||
static constexpr std::wstring_view LeftState{ L"Left" };
|
||||
static constexpr std::wstring_view VerticalState{ L"Vertical" };
|
||||
|
||||
static constexpr std::wstring_view ActionIconPresenterHolder{ L"PART_ActionIconPresenterHolder" };
|
||||
static constexpr std::wstring_view HeaderPresenter{ L"PART_HeaderPresenter" };
|
||||
static constexpr std::wstring_view DescriptionPresenter{ L"PART_DescriptionPresenter" };
|
||||
static constexpr std::wstring_view HeaderIconPresenterHolder{ L"PART_HeaderIconPresenterHolder" };
|
||||
|
||||
SettingsCard::SettingsCard()
|
||||
{
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
void SettingsCard::_InitializeProperties()
|
||||
{
|
||||
if (!_HeaderProperty)
|
||||
{
|
||||
_HeaderProperty = DependencyProperty::Register(
|
||||
L"Header",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnHeaderChanged } });
|
||||
}
|
||||
if (!_DescriptionProperty)
|
||||
{
|
||||
_DescriptionProperty = DependencyProperty::Register(
|
||||
L"Description",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnDescriptionChanged } });
|
||||
}
|
||||
if (!_HeaderIconProperty)
|
||||
{
|
||||
_HeaderIconProperty = DependencyProperty::Register(
|
||||
L"HeaderIcon",
|
||||
xaml_typename<IconElement>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnHeaderIconChanged } });
|
||||
}
|
||||
if (!_ActionIconProperty)
|
||||
{
|
||||
_ActionIconProperty = DependencyProperty::Register(
|
||||
L"ActionIcon",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ActionIconToolTipProperty)
|
||||
{
|
||||
_ActionIconToolTipProperty = DependencyProperty::Register(
|
||||
L"ActionIconToolTip",
|
||||
xaml_typename<hstring>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(hstring{}) });
|
||||
}
|
||||
if (!_IsClickEnabledProperty)
|
||||
{
|
||||
_IsClickEnabledProperty = DependencyProperty::Register(
|
||||
L"IsClickEnabled",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(false), PropertyChangedCallback{ &SettingsCard::_OnIsClickEnabledChanged } });
|
||||
}
|
||||
if (!_IsActionIconVisibleProperty)
|
||||
{
|
||||
_IsActionIconVisibleProperty = DependencyProperty::Register(
|
||||
L"IsActionIconVisible",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(true), PropertyChangedCallback{ &SettingsCard::_OnIsActionIconVisibleChanged } });
|
||||
}
|
||||
if (!_ContentAlignmentProperty)
|
||||
{
|
||||
_ContentAlignmentProperty = DependencyProperty::Register(
|
||||
L"ContentAlignment",
|
||||
xaml_typename<Editor::SettingsCardContentAlignment>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(Editor::SettingsCardContentAlignment::Right), PropertyChangedCallback{ &SettingsCard::_OnContentAlignmentChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
AutomationPeer SettingsCard::OnCreateAutomationPeer()
|
||||
{
|
||||
return winrt::make<implementation::SettingsCardAutomationPeer>(*this);
|
||||
}
|
||||
|
||||
void SettingsCard::OnApplyTemplate()
|
||||
{
|
||||
// Drop any handlers from a previous template.
|
||||
_isEnabledChangedRevoker.revoke();
|
||||
_DisableButtonInteraction();
|
||||
if (_contentChangedToken != 0)
|
||||
{
|
||||
UnregisterPropertyChangedCallback(ContentControl::ContentProperty(), _contentChangedToken);
|
||||
_contentChangedToken = 0;
|
||||
}
|
||||
|
||||
_UpdateActionIconVisibility();
|
||||
_UpdateHeaderVisibility();
|
||||
_UpdateDescriptionVisibility();
|
||||
_UpdateHeaderIconVisibility();
|
||||
// Initial visual states.
|
||||
_CheckInitialVisualState();
|
||||
_SetAccessibleContentName();
|
||||
|
||||
// Watch for Content changing later (we may need to refresh the AutomationProperties.Name on it).
|
||||
_contentChangedToken = RegisterPropertyChangedCallback(ContentControl::ContentProperty(), [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_SetAccessibleContentName();
|
||||
}
|
||||
});
|
||||
|
||||
// Apply click-interaction state.
|
||||
if (IsClickEnabled())
|
||||
{
|
||||
_EnableButtonInteraction();
|
||||
}
|
||||
|
||||
_isEnabledChangedRevoker = IsEnabledChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(strongThis->IsEnabled() ? NormalState : DisabledState, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SettingsCard::_CheckInitialVisualState()
|
||||
{
|
||||
VisualStateManager::GoToState(*this, IsEnabled() ? hstring{ NormalState } : hstring{ DisabledState }, true);
|
||||
_UpdateContentAlignmentState();
|
||||
}
|
||||
|
||||
void SettingsCard::_SetAccessibleContentName()
|
||||
{
|
||||
// If Header is a string and the inner Content lacks an AutomationProperties.Name, propagate the header
|
||||
// into the content so screen readers can announce something meaningful when focus lands there.
|
||||
const auto headerObj{ Header() };
|
||||
if (!headerObj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto headerString{ unbox_value_or<hstring>(headerObj, hstring{}) };
|
||||
if (headerString.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto contentObj{ Content() };
|
||||
if (const auto element{ contentObj.try_as<UIElement>() })
|
||||
{
|
||||
if (Automation::AutomationProperties::GetName(element).empty())
|
||||
{
|
||||
// Don't override ButtonBase content (would clobber its own name) or plain text blocks.
|
||||
if (!element.try_as<ButtonBase>() && !element.try_as<TextBlock>())
|
||||
{
|
||||
Automation::AutomationProperties::SetName(element, headerString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_EnableButtonInteraction()
|
||||
{
|
||||
if (_interactionEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_interactionEnabled = true;
|
||||
|
||||
IsTabStop(true);
|
||||
_pointerEnteredRevoker = PointerEntered(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(PointerOverState, true);
|
||||
}
|
||||
});
|
||||
_pointerExitedRevoker = PointerExited(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
_pointerCaptureLostRevoker = PointerCaptureLost(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
_pointerCanceledRevoker = PointerCanceled(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
_previewKeyDownRevoker = PreviewKeyDown(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e) {
|
||||
const auto strongThis = weakThis.get();
|
||||
if (!strongThis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto key = e.Key();
|
||||
if (key == Windows::System::VirtualKey::Enter || key == Windows::System::VirtualKey::Space || key == Windows::System::VirtualKey::GamepadA)
|
||||
{
|
||||
const auto focused{ strongThis->_GetFocusedElement() };
|
||||
if (focused && focused.try_as<Editor::SettingsCard>() == strongThis.as<Editor::SettingsCard>())
|
||||
{
|
||||
strongThis->_GoToCommonState(PressedState, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
_previewKeyUpRevoker = PreviewKeyUp(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e) {
|
||||
const auto strongThis = weakThis.get();
|
||||
if (!strongThis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto key = e.Key();
|
||||
if (key == Windows::System::VirtualKey::Enter || key == Windows::System::VirtualKey::Space || key == Windows::System::VirtualKey::GamepadA)
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SettingsCard::_DisableButtonInteraction()
|
||||
{
|
||||
_interactionEnabled = false;
|
||||
IsTabStop(false);
|
||||
_pointerEnteredRevoker.revoke();
|
||||
_pointerExitedRevoker.revoke();
|
||||
_pointerCaptureLostRevoker.revoke();
|
||||
_pointerCanceledRevoker.revoke();
|
||||
_previewKeyDownRevoker.revoke();
|
||||
_previewKeyUpRevoker.revoke();
|
||||
}
|
||||
|
||||
void SettingsCard::_GoToCommonState(const std::wstring_view& state, bool useTransitions)
|
||||
{
|
||||
VisualStateManager::GoToState(*this, hstring{ state }, useTransitions);
|
||||
}
|
||||
|
||||
FrameworkElement SettingsCard::_GetFocusedElement()
|
||||
{
|
||||
if (const auto root{ XamlRoot() })
|
||||
{
|
||||
return FocusManager::GetFocusedElement(root).try_as<FrameworkElement>();
|
||||
}
|
||||
return FocusManager::GetFocusedElement().try_as<FrameworkElement>();
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateActionIconVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ ActionIconPresenterHolder }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility((IsClickEnabled() && IsActionIconVisible()) ? Visibility::Visible : Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if the given object is null, or is a string that is empty.
|
||||
// Non-string non-null objects (e.g. a TextBlock) are considered "non-empty".
|
||||
static bool _isNullOrEmpty(const winrt::Windows::Foundation::IInspectable& obj)
|
||||
{
|
||||
if (!obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (const auto pv{ obj.try_as<IPropertyValue>() }; pv && pv.Type() == PropertyType::String)
|
||||
{
|
||||
return unbox_value_or<hstring>(obj, hstring{}).empty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateHeaderVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ HeaderPresenter }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility(_isNullOrEmpty(Header()) ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateDescriptionVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ DescriptionPresenter }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility(_isNullOrEmpty(Description()) ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateHeaderIconVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ HeaderIconPresenterHolder }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility(HeaderIcon() ? Visibility::Visible : Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateContentAlignmentState()
|
||||
{
|
||||
std::wstring_view state{ RightState };
|
||||
switch (ContentAlignment())
|
||||
{
|
||||
case Editor::SettingsCardContentAlignment::Left:
|
||||
state = LeftState;
|
||||
break;
|
||||
case Editor::SettingsCardContentAlignment::Vertical:
|
||||
state = VerticalState;
|
||||
break;
|
||||
default:
|
||||
state = RightState;
|
||||
break;
|
||||
}
|
||||
VisualStateManager::GoToState(*this, hstring{ state }, true);
|
||||
}
|
||||
|
||||
void SettingsCard::_OnHeaderChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
const auto self = get_self<SettingsCard>(obj);
|
||||
self->_UpdateHeaderVisibility();
|
||||
self->_SetAccessibleContentName();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnDescriptionChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
get_self<SettingsCard>(obj)->_UpdateDescriptionVisibility();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnHeaderIconChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
get_self<SettingsCard>(obj)->_UpdateHeaderIconVisibility();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnIsClickEnabledChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
const auto self = get_self<SettingsCard>(obj);
|
||||
self->_UpdateActionIconVisibility();
|
||||
if (self->IsClickEnabled())
|
||||
{
|
||||
self->_EnableButtonInteraction();
|
||||
}
|
||||
else
|
||||
{
|
||||
self->_DisableButtonInteraction();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_OnIsActionIconVisibleChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
get_self<SettingsCard>(obj)->_UpdateActionIconVisibility();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnContentAlignmentChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
get_self<SettingsCard>(obj)->_UpdateContentAlignmentState();
|
||||
}
|
||||
|
||||
SettingsCardAutomationPeer::SettingsCardAutomationPeer(const Editor::SettingsCard& owner) :
|
||||
SettingsCardAutomationPeerT<SettingsCardAutomationPeer>(owner)
|
||||
{
|
||||
}
|
||||
|
||||
AutomationControlType SettingsCardAutomationPeer::GetAutomationControlTypeCore() const
|
||||
{
|
||||
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
if (card.IsClickEnabled())
|
||||
{
|
||||
return AutomationControlType::Button;
|
||||
}
|
||||
}
|
||||
return AutomationControlType::Group;
|
||||
}
|
||||
|
||||
hstring SettingsCardAutomationPeer::GetClassNameCore() const
|
||||
{
|
||||
return hstring{ L"SettingsCard" };
|
||||
}
|
||||
|
||||
hstring SettingsCardAutomationPeer::GetNameCore() const
|
||||
{
|
||||
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
if (card.IsClickEnabled())
|
||||
{
|
||||
if (const auto manualName{ AutomationProperties::GetName(card) }; !manualName.empty())
|
||||
{
|
||||
return manualName;
|
||||
}
|
||||
if (const auto headerString{ unbox_value_or<hstring>(card.Header(), hstring{}) }; !headerString.empty())
|
||||
{
|
||||
return headerString;
|
||||
}
|
||||
}
|
||||
// Not clickable, or no header text: fall back to AutomationProperties.Name (matching
|
||||
// FrameworkElementAutomationPeer's default behavior).
|
||||
return AutomationProperties::GetName(card);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable SettingsCardAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
|
||||
{
|
||||
if (patternInterface == PatternInterface::Invoke)
|
||||
{
|
||||
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
if (card.IsClickEnabled())
|
||||
{
|
||||
// Only provide Invoke pattern if the card is clickable.
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
// ButtonBaseAutomationPeer only provides Invoke; everything else returns null.
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
95
src/cascadia/TerminalSettingsEditor/SettingsCard.h
Normal file
95
src/cascadia/TerminalSettingsEditor/SettingsCard.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- SettingsCard
|
||||
|
||||
Abstract:
|
||||
- A base control for building consistent settings experiences. Based
|
||||
on the Windows Community Toolkit's SettingsCard.
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora - 2026 May
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SettingsCard.g.h"
|
||||
#include "SettingsCardAutomationPeer.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct SettingsCard : SettingsCardT<SettingsCard>
|
||||
{
|
||||
public:
|
||||
SettingsCard();
|
||||
|
||||
void OnApplyTemplate();
|
||||
|
||||
// Automation peer override.
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Header);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Description);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Controls::IconElement, HeaderIcon);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, ActionIcon);
|
||||
DEPENDENCY_PROPERTY(hstring, ActionIconToolTip);
|
||||
DEPENDENCY_PROPERTY(bool, IsClickEnabled);
|
||||
DEPENDENCY_PROPERTY(bool, IsActionIconVisible);
|
||||
DEPENDENCY_PROPERTY(Editor::SettingsCardContentAlignment, ContentAlignment);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnHeaderChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnDescriptionChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnHeaderIconChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnIsClickEnabledChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnIsActionIconVisibleChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnContentAlignmentChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _EnableButtonInteraction();
|
||||
void _DisableButtonInteraction();
|
||||
void _GoToCommonState(const std::wstring_view& state, bool useTransitions);
|
||||
void _UpdateActionIconVisibility();
|
||||
void _UpdateHeaderVisibility();
|
||||
void _UpdateDescriptionVisibility();
|
||||
void _UpdateHeaderIconVisibility();
|
||||
void _UpdateContentAlignmentState();
|
||||
void _CheckInitialVisualState();
|
||||
void _SetAccessibleContentName();
|
||||
Windows::UI::Xaml::FrameworkElement _GetFocusedElement();
|
||||
|
||||
bool _interactionEnabled{ false };
|
||||
Windows::UI::Xaml::Controls::Control::IsEnabledChanged_revoker _isEnabledChangedRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerEntered_revoker _pointerEnteredRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerExited_revoker _pointerExitedRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerCaptureLost_revoker _pointerCaptureLostRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerCanceled_revoker _pointerCanceledRevoker;
|
||||
Windows::UI::Xaml::UIElement::PreviewKeyDown_revoker _previewKeyDownRevoker;
|
||||
Windows::UI::Xaml::UIElement::PreviewKeyUp_revoker _previewKeyUpRevoker;
|
||||
int64_t _contentChangedToken{ 0 };
|
||||
};
|
||||
|
||||
// AutomationPeer for SettingsCard. Mirrors the Community Toolkit's
|
||||
// SettingsCardAutomationPeer: only exposes Invoke + Button control type when
|
||||
// the card has IsClickEnabled=true; otherwise reports as a Group.
|
||||
struct SettingsCardAutomationPeer : SettingsCardAutomationPeerT<SettingsCardAutomationPeer>
|
||||
{
|
||||
public:
|
||||
SettingsCardAutomationPeer(const Editor::SettingsCard& owner);
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const;
|
||||
hstring GetClassNameCore() const;
|
||||
hstring GetNameCore() const;
|
||||
winrt::Windows::Foundation::IInspectable GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(SettingsCard);
|
||||
BASIC_FACTORY(SettingsCardAutomationPeer);
|
||||
}
|
||||
46
src/cascadia/TerminalSettingsEditor/SettingsCard.idl
Normal file
46
src/cascadia/TerminalSettingsEditor/SettingsCard.idl
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
enum SettingsCardContentAlignment
|
||||
{
|
||||
Right,
|
||||
Left,
|
||||
Vertical
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SettingsCard : Windows.UI.Xaml.Controls.Primitives.ButtonBase
|
||||
{
|
||||
SettingsCard();
|
||||
|
||||
Object Header;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderProperty { get; };
|
||||
|
||||
Object Description;
|
||||
static Windows.UI.Xaml.DependencyProperty DescriptionProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.Controls.IconElement HeaderIcon;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderIconProperty { get; };
|
||||
|
||||
Object ActionIcon;
|
||||
static Windows.UI.Xaml.DependencyProperty ActionIconProperty { get; };
|
||||
|
||||
String ActionIconToolTip;
|
||||
static Windows.UI.Xaml.DependencyProperty ActionIconToolTipProperty { get; };
|
||||
|
||||
Boolean IsClickEnabled;
|
||||
static Windows.UI.Xaml.DependencyProperty IsClickEnabledProperty { get; };
|
||||
|
||||
Boolean IsActionIconVisible;
|
||||
static Windows.UI.Xaml.DependencyProperty IsActionIconVisibleProperty { get; };
|
||||
|
||||
SettingsCardContentAlignment ContentAlignment;
|
||||
static Windows.UI.Xaml.DependencyProperty ContentAlignmentProperty { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SettingsCardAutomationPeer : Windows.UI.Xaml.Automation.Peers.ButtonBaseAutomationPeer
|
||||
{
|
||||
SettingsCardAutomationPeer(SettingsCard owner);
|
||||
};
|
||||
}
|
||||
409
src/cascadia/TerminalSettingsEditor/SettingsControlsStyle.xaml
Normal file
409
src/cascadia/TerminalSettingsEditor/SettingsControlsStyle.xaml
Normal file
@@ -0,0 +1,409 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
Default styles for SettingsCard and SettingsExpander.
|
||||
|
||||
These were ported from the Windows Community Toolkit
|
||||
(components/SettingsControls) and trimmed for use in this project:
|
||||
- The Card's responsive RightWrapped/RightWrappedNoIcon visual states are
|
||||
omitted (they depend on tk:ControlSizeTrigger).
|
||||
- The Expander uses muxc:Expander's built-in template rather than the
|
||||
custom 500+ line template the toolkit ships.
|
||||
-->
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="SettingsCardBackground"
|
||||
ResourceKey="CardBackgroundFillColorDefaultBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundDisabled"
|
||||
ResourceKey="ControlFillColorDisabledBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsCardForeground"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundPointerOver"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundPressed"
|
||||
ResourceKey="TextFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundDisabled"
|
||||
ResourceKey="TextFillColorDisabledBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsCardBorderBrush"
|
||||
ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushPointerOver"
|
||||
ResourceKey="ControlElevationBorderBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushPressed"
|
||||
ResourceKey="ControlStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushDisabled"
|
||||
ResourceKey="ControlStrokeColorDefaultBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<StaticResource x:Key="SettingsCardBackground"
|
||||
ResourceKey="CardBackgroundFillColorDefaultBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundDisabled"
|
||||
ResourceKey="ControlFillColorDisabledBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsCardForeground"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundPointerOver"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundPressed"
|
||||
ResourceKey="TextFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundDisabled"
|
||||
ResourceKey="TextFillColorDisabledBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsCardBorderBrush"
|
||||
ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushPointerOver"
|
||||
ResourceKey="ControlElevationBorderBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushPressed"
|
||||
ResourceKey="ControlStrokeColorDefaultBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushDisabled"
|
||||
ResourceKey="ControlStrokeColorDefaultBrush" />
|
||||
</ResourceDictionary>
|
||||
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="SettingsCardBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundPointerOver"
|
||||
ResourceKey="SystemColorHighlightTextColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundPressed"
|
||||
ResourceKey="SystemColorHighlightTextColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardBackgroundDisabled"
|
||||
ResourceKey="SystemControlBackgroundBaseLowBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsCardForeground"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundPointerOver"
|
||||
ResourceKey="SystemColorHighlightColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundPressed"
|
||||
ResourceKey="SystemColorHighlightColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardForegroundDisabled"
|
||||
ResourceKey="SystemControlDisabledBaseMediumLowBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingsCardBorderBrush"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushPointerOver"
|
||||
ResourceKey="SystemColorHighlightColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushPressed"
|
||||
ResourceKey="SystemColorHighlightTextColorBrush" />
|
||||
<StaticResource x:Key="SettingsCardBorderBrushDisabled"
|
||||
ResourceKey="SystemControlDisabledTransparentBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<Thickness x:Key="SettingsCardBorderThickness">1</Thickness>
|
||||
<Thickness x:Key="SettingsCardPadding">16,16,16,16</Thickness>
|
||||
<x:Double x:Key="SettingsCardMinWidth">148</x:Double>
|
||||
<x:Double x:Key="SettingsCardMinHeight">68</x:Double>
|
||||
<x:Double x:Key="SettingsCardDescriptionFontSize">12</x:Double>
|
||||
<x:Double x:Key="SettingsCardHeaderIconMaxSize">20</x:Double>
|
||||
<x:Double x:Key="SettingsCardContentMinWidth">120</x:Double>
|
||||
<Thickness x:Key="SettingsCardHeaderIconMargin">2,0,20,0</Thickness>
|
||||
<Thickness x:Key="SettingsCardActionIconMargin">14,0,0,0</Thickness>
|
||||
<x:Double x:Key="SettingsCardActionIconMaxSize">13</x:Double>
|
||||
|
||||
<Thickness x:Key="SettingsExpanderItemPadding">58,8,44,8</Thickness>
|
||||
<Thickness x:Key="SettingsExpanderItemBorderThickness">0,1,0,0</Thickness>
|
||||
<x:Double x:Key="SettingsExpanderContentMinHeight">16</x:Double>
|
||||
|
||||
<!-- ============ SettingsCard ============ -->
|
||||
|
||||
<!--
|
||||
Card style for items that live inside a SettingsExpander:
|
||||
no left/right rounded corners, a 1-pixel top border between siblings,
|
||||
deeper left padding to line up with the parent expander's content.
|
||||
-->
|
||||
<Style x:Key="SettingsExpanderItemCardStyle"
|
||||
BasedOn="{StaticResource DefaultSettingsCardStyle}"
|
||||
TargetType="local:SettingsCard">
|
||||
<Setter Property="BorderThickness" Value="{StaticResource SettingsExpanderItemBorderThickness}" />
|
||||
<Setter Property="MinHeight" Value="52" />
|
||||
<Setter Property="Padding" Value="{StaticResource SettingsExpanderItemPadding}" />
|
||||
<Setter Property="CornerRadius" Value="0" />
|
||||
</Style>
|
||||
|
||||
<Style BasedOn="{StaticResource DefaultSettingsCardStyle}"
|
||||
TargetType="local:SettingsCard" />
|
||||
|
||||
<Style x:Key="DefaultSettingsCardStyle"
|
||||
TargetType="local:SettingsCard">
|
||||
<Setter Property="Background" Value="{ThemeResource SettingsCardBackground}" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SettingsCardForeground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SettingsCardBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{StaticResource SettingsCardBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource SettingsCardMinHeight}" />
|
||||
<Setter Property="MinWidth" Value="{StaticResource SettingsCardMinWidth}" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="Padding" Value="{StaticResource SettingsCardPadding}" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
|
||||
<Setter Property="FocusVisualMargin" Value="-3" />
|
||||
<Setter Property="ActionIcon" Value="" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingsCard">
|
||||
<Grid x:Name="PART_RootGrid"
|
||||
MinWidth="{TemplateBinding MinWidth}"
|
||||
MinHeight="{TemplateBinding MinHeight}"
|
||||
MaxWidth="{TemplateBinding MaxWidth}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BackgroundSizing="{TemplateBinding BackgroundSizing}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Viewbox x:Name="PART_HeaderIconPresenterHolder"
|
||||
Grid.RowSpan="1"
|
||||
MaxWidth="{StaticResource SettingsCardHeaderIconMaxSize}"
|
||||
MaxHeight="{StaticResource SettingsCardHeaderIconMaxSize}"
|
||||
Margin="{StaticResource SettingsCardHeaderIconMargin}">
|
||||
<ContentPresenter x:Name="PART_HeaderIconPresenter"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Content="{TemplateBinding HeaderIcon}" />
|
||||
</Viewbox>
|
||||
|
||||
<StackPanel x:Name="HeaderPanel"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,24,0"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Vertical">
|
||||
<ContentPresenter x:Name="PART_HeaderPresenter"
|
||||
HorizontalAlignment="Left"
|
||||
Content="{TemplateBinding Header}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<ContentPresenter x:Name="PART_DescriptionPresenter"
|
||||
Content="{TemplateBinding Description}"
|
||||
FontSize="{StaticResource SettingsCardDescriptionFontSize}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
TextWrapping="Wrap">
|
||||
<ContentPresenter.Resources>
|
||||
<Style BasedOn="{StaticResource CaptionTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
</Style>
|
||||
</ContentPresenter.Resources>
|
||||
</ContentPresenter>
|
||||
</StackPanel>
|
||||
|
||||
<ContentPresenter x:Name="PART_ContentPresenter"
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
Content="{TemplateBinding Content}" />
|
||||
|
||||
<Viewbox x:Name="PART_ActionIconPresenterHolder"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="3"
|
||||
MaxWidth="{StaticResource SettingsCardActionIconMaxSize}"
|
||||
MaxHeight="{StaticResource SettingsCardActionIconMaxSize}"
|
||||
Margin="{StaticResource SettingsCardActionIconMargin}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="Collapsed">
|
||||
<ContentPresenter x:Name="PART_ActionIconPresenter"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Content="{TemplateBinding ActionIcon}"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
ToolTipService.ToolTip="{TemplateBinding ActionIconToolTip}" />
|
||||
</Viewbox>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_RootGrid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBackgroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_RootGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_HeaderPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardForegroundPointerOver}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_RootGrid"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBackgroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_RootGrid"
|
||||
Storyboard.TargetProperty="BorderBrush">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardBorderBrushPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_HeaderPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardForegroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_DescriptionPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardForegroundPressed}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Disabled">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_ActionIconPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_HeaderIconPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_HeaderPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_DescriptionPresenter"
|
||||
Storyboard.TargetProperty="Foreground">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SettingsCardForegroundDisabled}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
|
||||
<VisualStateGroup x:Name="ContentAlignmentStates">
|
||||
<VisualState x:Name="Right" />
|
||||
<VisualState x:Name="Left">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="PART_HeaderIconPresenterHolder.Visibility" Value="Collapsed" />
|
||||
<Setter Target="PART_HeaderPresenter.Visibility" Value="Collapsed" />
|
||||
<Setter Target="PART_DescriptionPresenter.Visibility" Value="Collapsed" />
|
||||
<Setter Target="PART_ContentPresenter.(Grid.Row)" Value="1" />
|
||||
<Setter Target="PART_ContentPresenter.(Grid.Column)" Value="1" />
|
||||
<Setter Target="PART_ContentPresenter.HorizontalAlignment" Value="Left" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Vertical">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="PART_ContentPresenter.(Grid.Row)" Value="1" />
|
||||
<Setter Target="PART_ContentPresenter.(Grid.Column)" Value="1" />
|
||||
<Setter Target="PART_ContentPresenter.HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Target="PART_RootGrid.RowSpacing" Value="8" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- ============ SettingsExpander ============ -->
|
||||
|
||||
<Style BasedOn="{StaticResource DefaultSettingsExpanderStyle}"
|
||||
TargetType="local:SettingsExpander" />
|
||||
|
||||
<Style x:Key="DefaultSettingsExpanderStyle"
|
||||
TargetType="local:SettingsExpander">
|
||||
<Setter Property="Background" Value="{ThemeResource SettingsCardBackground}" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource SettingsCardForeground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SettingsCardBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{StaticResource SettingsCardBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource SettingsCardMinHeight}" />
|
||||
<Setter Property="MinWidth" Value="{StaticResource SettingsCardMinWidth}" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingsExpander">
|
||||
<muxc:Expander x:Name="PART_Expander"
|
||||
MinWidth="{TemplateBinding MinWidth}"
|
||||
MinHeight="{TemplateBinding MinHeight}"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
IsExpanded="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}">
|
||||
<muxc:Expander.Header>
|
||||
<local:SettingsCard MinHeight="52"
|
||||
Padding="0,8,0,8"
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Content="{TemplateBinding Content}"
|
||||
Description="{TemplateBinding Description}"
|
||||
FontFamily="{TemplateBinding FontFamily}"
|
||||
Header="{TemplateBinding Header}"
|
||||
HeaderIcon="{TemplateBinding HeaderIcon}"
|
||||
IsClickEnabled="False" />
|
||||
</muxc:Expander.Header>
|
||||
<muxc:Expander.Content>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ContentPresenter Content="{TemplateBinding ItemsHeader}" />
|
||||
<ContentPresenter Grid.Row="1"
|
||||
Content="{TemplateBinding ItemsFooter}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Content>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
150
src/cascadia/TerminalSettingsEditor/SettingsExpander.cpp
Normal file
150
src/cascadia/TerminalSettingsEditor/SettingsExpander.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "SettingsExpander.h"
|
||||
#include "SettingsExpander.g.cpp"
|
||||
#include "SettingsExpanderAutomationPeer.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty SettingsExpander::_HeaderProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_DescriptionProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_HeaderIconProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ContentProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_IsExpandedProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemsHeaderProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemsFooterProperty{ nullptr };
|
||||
|
||||
SettingsExpander::SettingsExpander()
|
||||
{
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
void SettingsExpander::_InitializeProperties()
|
||||
{
|
||||
if (!_HeaderProperty)
|
||||
{
|
||||
_HeaderProperty = DependencyProperty::Register(
|
||||
L"Header",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_DescriptionProperty)
|
||||
{
|
||||
_DescriptionProperty = DependencyProperty::Register(
|
||||
L"Description",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_HeaderIconProperty)
|
||||
{
|
||||
_HeaderIconProperty = DependencyProperty::Register(
|
||||
L"HeaderIcon",
|
||||
xaml_typename<IconElement>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ContentProperty)
|
||||
{
|
||||
_ContentProperty = DependencyProperty::Register(
|
||||
L"Content",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_IsExpandedProperty)
|
||||
{
|
||||
_IsExpandedProperty = DependencyProperty::Register(
|
||||
L"IsExpanded",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ box_value(false), PropertyChangedCallback{ &SettingsExpander::_OnIsExpandedChanged } });
|
||||
}
|
||||
if (!_ItemsHeaderProperty)
|
||||
{
|
||||
_ItemsHeaderProperty = DependencyProperty::Register(
|
||||
L"ItemsHeader",
|
||||
xaml_typename<UIElement>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ItemsFooterProperty)
|
||||
{
|
||||
_ItemsFooterProperty = DependencyProperty::Register(
|
||||
L"ItemsFooter",
|
||||
xaml_typename<UIElement>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
}
|
||||
|
||||
AutomationPeer SettingsExpander::OnCreateAutomationPeer()
|
||||
{
|
||||
return winrt::make<implementation::SettingsExpanderAutomationPeer>(*this);
|
||||
}
|
||||
|
||||
void SettingsExpander::OnApplyTemplate()
|
||||
{
|
||||
// No template-part lookups required: our template uses regular bindings
|
||||
// through TemplateBinding / x:Bind. The DPs do their own work.
|
||||
}
|
||||
|
||||
void SettingsExpander::_OnIsExpandedChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsExpander>() };
|
||||
if (!obj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto self = get_self<SettingsExpander>(obj);
|
||||
const auto newValue = unbox_value_or<bool>(e.NewValue(), false);
|
||||
if (newValue)
|
||||
{
|
||||
self->Expanded.raise(obj, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->Collapsed.raise(obj, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsExpanderAutomationPeer::SettingsExpanderAutomationPeer(const Editor::SettingsExpander& owner) :
|
||||
SettingsExpanderAutomationPeerT<SettingsExpanderAutomationPeer>(owner)
|
||||
{
|
||||
}
|
||||
|
||||
AutomationControlType SettingsExpanderAutomationPeer::GetAutomationControlTypeCore() const
|
||||
{
|
||||
return AutomationControlType::Group;
|
||||
}
|
||||
|
||||
hstring SettingsExpanderAutomationPeer::GetClassNameCore() const
|
||||
{
|
||||
return hstring{ L"SettingsExpander" };
|
||||
}
|
||||
|
||||
hstring SettingsExpanderAutomationPeer::GetNameCore() const
|
||||
{
|
||||
if (const auto expander{ Owner().try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
if (const auto manualName{ AutomationProperties::GetName(expander) }; !manualName.empty())
|
||||
{
|
||||
return manualName;
|
||||
}
|
||||
if (const auto headerString{ unbox_value_or<hstring>(expander.Header(), hstring{}) }; !headerString.empty())
|
||||
{
|
||||
return headerString;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
67
src/cascadia/TerminalSettingsEditor/SettingsExpander.h
Normal file
67
src/cascadia/TerminalSettingsEditor/SettingsExpander.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- SettingsExpander
|
||||
|
||||
Abstract:
|
||||
- A collapsable container for grouping multiple SettingsCards. Based
|
||||
on the Windows Community Toolkit's SettingsExpander.
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora - 2026 (port from CommunityToolkit.WinUI.Controls.SettingsExpander)
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SettingsExpander.g.h"
|
||||
#include "SettingsExpanderAutomationPeer.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct SettingsExpander : SettingsExpanderT<SettingsExpander>
|
||||
{
|
||||
public:
|
||||
SettingsExpander();
|
||||
|
||||
void OnApplyTemplate();
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
|
||||
til::typed_event<Editor::SettingsExpander, Windows::Foundation::IInspectable> Expanded;
|
||||
til::typed_event<Editor::SettingsExpander, Windows::Foundation::IInspectable> Collapsed;
|
||||
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Header);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Description);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Controls::IconElement, HeaderIcon);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Content);
|
||||
DEPENDENCY_PROPERTY(bool, IsExpanded);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::UIElement, ItemsHeader);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::UIElement, ItemsFooter);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnIsExpandedChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
};
|
||||
|
||||
// AutomationPeer for SettingsExpander. Reports class name and falls back to
|
||||
// Header text for the name when AutomationProperties.Name is unset.
|
||||
struct SettingsExpanderAutomationPeer : SettingsExpanderAutomationPeerT<SettingsExpanderAutomationPeer>
|
||||
{
|
||||
public:
|
||||
SettingsExpanderAutomationPeer(const Editor::SettingsExpander& owner);
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const;
|
||||
hstring GetClassNameCore() const;
|
||||
hstring GetNameCore() const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(SettingsExpander);
|
||||
BASIC_FACTORY(SettingsExpanderAutomationPeer);
|
||||
}
|
||||
39
src/cascadia/TerminalSettingsEditor/SettingsExpander.idl
Normal file
39
src/cascadia/TerminalSettingsEditor/SettingsExpander.idl
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass SettingsExpander : Windows.UI.Xaml.Controls.Control
|
||||
{
|
||||
SettingsExpander();
|
||||
|
||||
Object Header;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderProperty { get; };
|
||||
|
||||
Object Description;
|
||||
static Windows.UI.Xaml.DependencyProperty DescriptionProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.Controls.IconElement HeaderIcon;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderIconProperty { get; };
|
||||
|
||||
Object Content;
|
||||
static Windows.UI.Xaml.DependencyProperty ContentProperty { get; };
|
||||
|
||||
Boolean IsExpanded;
|
||||
static Windows.UI.Xaml.DependencyProperty IsExpandedProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.UIElement ItemsHeader;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemsHeaderProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.UIElement ItemsFooter;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemsFooterProperty { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<SettingsExpander, Object> Expanded;
|
||||
event Windows.Foundation.TypedEventHandler<SettingsExpander, Object> Collapsed;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SettingsExpanderAutomationPeer : Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer
|
||||
{
|
||||
SettingsExpanderAutomationPeer(SettingsExpander owner);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// 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);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -102,6 +102,14 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||
globals->_DisabledProfileSources->Append(src);
|
||||
}
|
||||
}
|
||||
if (_SafeUriSchemes)
|
||||
{
|
||||
globals->_SafeUriSchemes = winrt::single_threaded_vector<hstring>();
|
||||
for (const auto& src : *_SafeUriSchemes)
|
||||
{
|
||||
globals->_SafeUriSchemes->Append(src);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
|
||||
@@ -114,6 +114,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic);
|
||||
INHERITABLE_SETTING(Boolean, AllowHeadless);
|
||||
INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
INHERITABLE_SETTING(IVector<String>, SafeUriSchemes);
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
||||
void AddColorScheme(ColorScheme scheme);
|
||||
|
||||
@@ -63,6 +63,7 @@ Author(s):
|
||||
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
|
||||
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, SafeUriSchemes, "safeUriSchemes", nullptr) \
|
||||
X(bool, ShowAdminShield, "showAdminShield", true) \
|
||||
X(bool, TrimPaste, "trimPaste", true) \
|
||||
X(bool, EnableColorSelection, "experimental.enableColorSelection", false) \
|
||||
|
||||
@@ -467,6 +467,7 @@ namespace SettingsModelUnitTests
|
||||
"$schema" : "https://aka.ms/terminal-profiles-schema",
|
||||
"defaultProfile": "{61c54bbd-1111-5271-96e7-009a87ff44bf}",
|
||||
"disabledProfileSources": [ "Windows.Terminal.Wsl" ],
|
||||
"safeUriSchemes": [ "vscode" ],
|
||||
"newTabMenu":
|
||||
[
|
||||
{
|
||||
|
||||
@@ -123,6 +123,7 @@ class ScreenBufferTests
|
||||
TEST_METHOD(VtResizePreservingAttributes);
|
||||
|
||||
TEST_METHOD(VtSoftResetCursorPosition);
|
||||
TEST_METHOD(VtSoftResetAltBufferCursorState);
|
||||
|
||||
TEST_METHOD(VtScrollMarginsNewlineColor);
|
||||
|
||||
@@ -1510,6 +1511,30 @@ void ScreenBufferTests::VtSoftResetCursorPosition()
|
||||
VERIFY_ARE_EQUAL(til::point(1, 1), cursor.GetPosition());
|
||||
}
|
||||
|
||||
void ScreenBufferTests::VtSoftResetAltBufferCursorState()
|
||||
{
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
gci.LockConsole(); // Lock must be taken to manipulate buffer.
|
||||
auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); });
|
||||
|
||||
auto& si = gci.GetActiveOutputBuffer();
|
||||
auto& stateMachine = si.GetStateMachine();
|
||||
|
||||
Log::Comment(L"Move cursor on the main buffer.");
|
||||
stateMachine.ProcessString(L"\x1b[4;7H");
|
||||
VERIFY_ARE_EQUAL(til::point(6, 3), si.GetTextBuffer().GetCursor().GetPosition());
|
||||
|
||||
Log::Comment(L"Enter alt buffer, soft reset, and return to main buffer.");
|
||||
stateMachine.ProcessString(L"\x1b[?1049h");
|
||||
VERIFY_IS_TRUE(gci.GetActiveOutputBuffer()._IsAltBuffer());
|
||||
stateMachine.ProcessString(L"\x1b[!p");
|
||||
stateMachine.ProcessString(L"\x1b[?1049l");
|
||||
VERIFY_IS_FALSE(gci.GetActiveOutputBuffer()._IsAltBuffer());
|
||||
|
||||
Log::Comment(L"Returning from alt buffer should restore the main cursor position.");
|
||||
VERIFY_ARE_EQUAL(til::point(6, 3), gci.GetActiveOutputBuffer().GetTextBuffer().GetCursor().GetPosition());
|
||||
}
|
||||
|
||||
void ScreenBufferTests::VtScrollMarginsNewlineColor()
|
||||
{
|
||||
auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
|
||||
@@ -90,7 +90,15 @@ std::function<bool(wchar_t)> SixelParser::DefineImage(const VTInt macroParameter
|
||||
_state = States::Normal;
|
||||
_parameters.clear();
|
||||
return [&](const auto ch) {
|
||||
_parseCommandChar(ch);
|
||||
try
|
||||
{
|
||||
_parseCommandChar(ch);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Ignore all further content.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
@@ -234,10 +242,18 @@ void SixelParser::_executeNextLine()
|
||||
_executeCarriageReturn();
|
||||
_imageLineCount++;
|
||||
_maybeFlushImageBuffer();
|
||||
_imageCursor.y += _sixelHeight;
|
||||
_availablePixelHeight -= _sixelHeight;
|
||||
_resizeImageBuffer(_sixelHeight);
|
||||
_fillImageBackgroundWhenScrolled();
|
||||
// If we don't have any available pixel height, that means the image has
|
||||
// extended beyond the bottom of the display and we haven't triggered a
|
||||
// a scroll (because sixel display mode is enabled). In this state, there
|
||||
// is no point in extending the image any further, because the additional
|
||||
// content will never be seen, so we'll just be wasting memory.
|
||||
if (_availablePixelHeight > 0)
|
||||
{
|
||||
_imageCursor.y += _sixelHeight;
|
||||
_availablePixelHeight -= _sixelHeight;
|
||||
_resizeImageBuffer(_sixelHeight);
|
||||
_fillImageBackgroundWhenScrolled();
|
||||
}
|
||||
}
|
||||
|
||||
void SixelParser::_executeMoveToHome()
|
||||
|
||||
@@ -3002,17 +3002,15 @@ void AdaptDispatch::SoftReset()
|
||||
SetGraphicsRendition({}); // Normal rendition.
|
||||
SetCharacterProtectionAttribute({}); // Default (unprotected)
|
||||
|
||||
// Reset the saved cursor state.
|
||||
// Note that XTerm only resets the main buffer state, but that
|
||||
// seems likely to be a bug. Most other terminals reset both.
|
||||
_savedCursorState.at(0) = {}; // Main buffer
|
||||
_savedCursorState.at(1) = {}; // Alt buffer
|
||||
// Reset only the active saved cursor state.
|
||||
// This matches xterm behavior when DECSTR is processed while using
|
||||
// the alternate screen buffer (GH#19918).
|
||||
_savedCursorState.at(_usingAltBuffer ? 1 : 0) = {};
|
||||
|
||||
// The TerminalOutput state in these buffers must be reset to
|
||||
// The TerminalOutput state in this buffer must be reset to
|
||||
// the same state as the _termOutput instance, which is not
|
||||
// necessarily equivalent to a full reset.
|
||||
_savedCursorState.at(0).TermOutput = _termOutput;
|
||||
_savedCursorState.at(1).TermOutput = _termOutput;
|
||||
_savedCursorState.at(_usingAltBuffer ? 1 : 0).TermOutput = _termOutput;
|
||||
|
||||
// Soft reset the Sixel parser if in use.
|
||||
if (_sixelParser)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# Cargo source replacement: route crates-io fetches through an Azure Artifact
|
||||
# Cargo feed (1ES compliance — disallow direct public crates.io access).
|
||||
#
|
||||
# Reusing the sudo team's `sudo_public_cargo` feed in microsoft/Dart for now.
|
||||
# TODO(wtr): replace with our own `microsoft/Dart` Cargo feed once provisioned.
|
||||
|
||||
[registries]
|
||||
WindowsTerminalCargo = { index = "sparse+https://pkgs.dev.azure.com/microsoft/Dart/_packaging/sudo_public_cargo/Cargo/index/" }
|
||||
|
||||
[source.crates-io]
|
||||
replace-with = "WindowsTerminalCargo"
|
||||
|
||||
1
src/tools/wtr/.gitignore
vendored
1
src/tools/wtr/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/target/
|
||||
2208
src/tools/wtr/Cargo.lock
generated
2208
src/tools/wtr/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
||||
[package]
|
||||
name = "wtr"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "wtr"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-util = { version = "0.7", features = ["compat"] }
|
||||
async-trait = "0.1"
|
||||
anyhow = "1"
|
||||
serde_json = "1"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
ratatui = "0.30"
|
||||
crossterm = { version = "0.29", features = ["event-stream"] }
|
||||
futures = "0.3"
|
||||
unicode-width = "0.2"
|
||||
textwrap = "0.16"
|
||||
base64 = "0.22"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
windows-sys = { version = "0.61", features = [
|
||||
"Win32_Foundation",
|
||||
"Win32_System_Environment",
|
||||
"Win32_System_Registry",
|
||||
"Win32_System_Threading",
|
||||
] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
|
||||
tracing-appender = "0.2"
|
||||
@@ -1,4 +0,0 @@
|
||||
# Pin the Rust toolchain channel for both local dev and 1ES CI.
|
||||
# Use the MSRustup `ms-prod-X.YY` channel for compliance.
|
||||
[toolchain]
|
||||
channel = "ms-prod-1.93"
|
||||
@@ -1 +0,0 @@
|
||||
fn main() {}
|
||||
Reference in New Issue
Block a user