Merge branch 'dev/migrie/fhl/non-terminal-panes-2023' into dev/migrie/fhl/scratchpad-pane

This commit is contained in:
Mike Griese
2024-03-08 10:33:31 -06:00
134 changed files with 2016 additions and 725 deletions

View File

@@ -17,6 +17,7 @@ CMMI
copyable
Counterintuitively
CtrlDToClose
CVS
CUI
cybersecurity
dalet

View File

@@ -1,3 +1,5 @@
aalt
abvm
ACCEPTFILES
ACCESSDENIED
acl
@@ -36,6 +38,7 @@ delayimp
DERR
dlldata
DNE
dnom
DONTADDTORECENT
DWMSBT
DWMWA
@@ -49,6 +52,7 @@ EXPCMDFLAGS
EXPCMDSTATE
filetime
FILTERSPEC
fina
FORCEFILESYSTEM
FORCEMINIMIZE
frac
@@ -120,6 +124,7 @@ LSHIFT
LTGRAY
MAINWINDOW
MAXIMIZEBOX
medi
memchr
memicmp
MENUCOMMAND
@@ -150,6 +155,7 @@ NOTIFYBYPOS
NOTIFYICON
NOTIFYICONDATA
ntprivapi
numr
oaidl
ocidl
ODR
@@ -175,9 +181,11 @@ REGCLS
RETURNCMD
rfind
RLO
rnrn
ROOTOWNER
roundf
RSHIFT
rvrn
SACL
schandle
SEH

View File

@@ -46,6 +46,7 @@ MSAA
msixbundle
MSVC
MSVCP
mtu
muxc
netcore
Onefuzz

View File

@@ -453,6 +453,7 @@ DECSTBM
DECSTGLT
DECSTR
DECSWL
DECSWT
DECTABSR
DECTCEM
DECXCPR

View File

@@ -270,7 +270,6 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestHostApp", "src\cascadia\LocalTests_TerminalApp\TestHostApp\TestHostApp.vcxproj", "{A021EDFF-45C8-4DC2-BEF7-36E1B3B8CFE8}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-9B68-456A-B13E-C8218070DC42} = {CA5CAD1A-9B68-456A-B13E-C8218070DC42}
{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506} = {CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}
EndProjectSection
EndProject
@@ -350,7 +349,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_SettingsModel", "src\cascadia\LocalTests_SettingsModel\SettingsModel.LocalTests.vcxproj", "{CA5CAD1A-9B68-456A-B13E-C8218070DC42}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTests_SettingsModel", "src\cascadia\UnitTests_SettingsModel\SettingsModel.UnitTests.vcxproj", "{CA5CAD1A-9B68-456A-B13E-C8218070DC42}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
@@ -413,6 +412,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TerminalStress", "src\tools
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenderingTests", "src\tools\RenderingTests\RenderingTests.vcxproj", "{37C995E0-2349-4154-8E77-4A52C0C7F46D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UIHelpers", "src\cascadia\UIHelpers\UIHelpers.vcxproj", "{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "benchcat", "src\tools\benchcat\benchcat.vcxproj", "{2C836962-9543-4CE5-B834-D28E1F124B66}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConsoleMonitor", "src\tools\ConsoleMonitor\ConsoleMonitor.vcxproj", "{328729E9-6723-416E-9C98-951F1473BBE1}"
@@ -2357,6 +2358,29 @@ Global
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|ARM64.ActiveCfg = Release|ARM64
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|x64.ActiveCfg = Release|x64
{37C995E0-2349-4154-8E77-4A52C0C7F46D}.Release|x86.ActiveCfg = Release|Win32
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|Any CPU.ActiveCfg = AuditMode|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|x64.ActiveCfg = AuditMode|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|x64.Build.0 = AuditMode|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|Any CPU.ActiveCfg = Debug|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|ARM64.ActiveCfg = Debug|ARM64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|ARM64.Build.0 = Debug|ARM64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x64.ActiveCfg = Debug|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x64.Build.0 = Debug|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x86.ActiveCfg = Debug|Win32
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Debug|x86.Build.0 = Debug|Win32
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|Any CPU.ActiveCfg = Release|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|ARM64.ActiveCfg = Release|ARM64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|ARM64.Build.0 = Release|ARM64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x64.ActiveCfg = Release|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x64.Build.0 = Release|x64
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x86.ActiveCfg = Release|Win32
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}.Release|x86.Build.0 = Release|Win32
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|ARM64.ActiveCfg = Release|ARM64
{2C836962-9543-4CE5-B834-D28E1F124B66}.AuditMode|x64.ActiveCfg = Release|x64
@@ -2512,6 +2536,7 @@ Global
{3C67784E-1453-49C2-9660-483E2CC7F7AD} = {40BD8415-DD93-4200-8D82-498DDDC08CC8}
{613CCB57-5FA9-48EF-80D0-6B1E319E20C4} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{37C995E0-2349-4154-8E77-4A52C0C7F46D} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
{2C836962-9543-4CE5-B834-D28E1F124B66} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{328729E9-6723-416E-9C98-951F1473BBE1} = {A10C4720-DCA4-4640-9749-67F4314F527C}
{BE92101C-04F8-48DA-99F0-E1F4F1D2DC48} = {A10C4720-DCA4-4640-9749-67F4314F527C}

View File

@@ -56,6 +56,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run PGO Tests'
inputs:
pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: >-

View File

@@ -44,6 +44,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run Unit Tests'
inputs:
pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"
@@ -52,6 +53,7 @@ jobs:
- task: PowerShell@2
displayName: 'Run Feature Tests'
inputs:
pwsh: true
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(OutputBuildPlatform)' -Configuration '$(BuildConfiguration)' -LogPath '${{ parameters.testLogPath }}' -Root "$(Terminal.BinDir)"

View File

@@ -30,6 +30,7 @@
<IntermediateOutputPath>$(SolutionDir)obj\$(Configuration)\GenerateFeatureFlags\</IntermediateOutputPath>
<OpenConsoleCommonOutDir>$(SolutionDir)bin\$(Configuration)\</OpenConsoleCommonOutDir>
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Canary'">Canary</_WTBrandingName>
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Preview'">Preview</_WTBrandingName>
<_WTBrandingName Condition="'$(WindowsTerminalBranding)'=='Release'">Release</_WTBrandingName>
<_WTBrandingName Condition="'$(_WTBrandingName)'==''">Dev</_WTBrandingName>

View File

@@ -16,22 +16,48 @@ Param(
# Find test DLLs based on the provided root, match pattern, and recursion
$testDlls = Get-ChildItem -Path $Root -Recurse -Filter $MatchPattern
$args = @()
$teArgs = @()
# Check if the LogPath parameter is provided and enable WTT logging
if ($LogPath) {
$args += '/enablewttlogging'
$args += '/appendwttlogging'
$args += "/logFile:$LogPath"
$teArgs += '/enablewttlogging'
$teArgs += '/appendwttlogging'
$teArgs += "/logFile:$LogPath"
Write-Host "WTT Logging Enabled"
}
# Invoke the te.exe executable with arguments and test DLLs
& "$Root\te.exe" $args $testDlls.FullName $AdditionalTaefArguments
$rootTe = "$Root\te.exe"
# Check the exit code of the te.exe process and exit accordingly
if ($LASTEXITCODE -ne 0) {
Exit $LASTEXITCODE
# Some of our test fixtures depend on resources.pri in the same folder as the .exe hosting them.
# Unfortunately, that means that we need to run the te.exe *next to* each test DLL we discover.
# This code establishes a mapping from te.exe to test DLL (or DLLs)
$testDllTaefGroups = $testDlls | % {
$localTe = Get-Item (Join-Path (Split-Path $_ -Parent) "te.exe") -EA:Ignore
If ($null -eq $localTe) {
$finalTePath = $rootTe
} Else {
$finalTePath = $localTe.FullName
}
[PSCustomObject]@{
TePath = $finalTePath;
TestDll = $_;
}
}
# Invoke the te.exe executables with arguments and test DLLs
$anyFailed = $false
$testDllTaefGroups | Group-Object TePath | % {
$te = $_.Group[0].TePath
$dlls = $_.Group.TestDll
Write-Verbose "Running $te (for $($dlls.Name))"
& $te $teArgs $dlls.FullName $AdditionalTaefArguments
if ($LASTEXITCODE -ne 0) {
$anyFailed = $true
}
}
if ($anyFailed) {
Exit 1
}
Exit 0

View File

@@ -31,9 +31,12 @@ namespace winrt::SampleApp::implementation
auto connectionSettings{ TerminalConnection::ConptyConnection::CreateSettings(L"cmd.exe /k echo This TermControl is hosted in-proc...",
winrt::hstring{},
L"",
false,
L"",
nullptr,
32,
80,
winrt::guid(),
winrt::guid()) };
// "Microsoft.Terminal.TerminalConnection.ConptyConnection"

View File

@@ -92,47 +92,35 @@ CharToColumnMapper::CharToColumnMapper(const wchar_t* chars, const uint16_t* cha
// If given a position (`offset`) inside the ROW's text, this function will return the corresponding column.
// This function in particular returns the glyph's first column.
til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t offset) noexcept
til::CoordType CharToColumnMapper::GetLeadingColumnAt(ptrdiff_t targetOffset) noexcept
{
offset = clamp(offset, 0, _lastCharOffset);
targetOffset = clamp(targetOffset, 0, _lastCharOffset);
// This code needs to fulfill two conditions on top of the obvious (a forward/backward search):
// A: We never want to stop on a column that is marked with CharOffsetsTrailer (= "GetLeadingColumn").
// B: With these parameters we always want to stop at currentOffset=4:
// _charOffsets={4, 6}
// currentOffset=4 *OR* 6
// targetOffset=5
// This is because we're being asked for a "LeadingColumn", while the caller gave us the offset of a
// trailing surrogate pair or similar. Returning the column of the leading half is the correct choice.
auto col = _currentColumn;
const auto currentOffset = _charOffsets[col] & CharOffsetsMask;
auto currentOffset = _charOffsets[col];
// Goal: Move the _currentColumn cursor to a cell which contains the given target offset.
// Depending on where the target offset is we have to either search forward or backward.
if (offset < currentOffset)
// A plain forward-search until we find our targetOffset.
// This loop may iterate too far and thus violate our example in condition B, however...
while (targetOffset > (currentOffset & CharOffsetsMask))
{
// Backward search.
// Goal: Find the first preceding column where the offset is <= the target offset. This results in the first
// cell that contains our target offset, even if that offset is in the middle of a long grapheme.
//
// We abuse the fact that the trailing half of wide glyphs is marked with CharOffsetsTrailer to our advantage.
// Since they're >0x8000, the `offset < _charOffsets[col]` check will always be true and ensure we iterate over them.
//
// Since _charOffsets cannot contain negative values and because offset has been
// clamped to be positive we naturally exit when reaching the first column.
for (; offset < _charOffsets[col - 1]; --col)
{
}
currentOffset = _charOffsets[++col];
}
else if (offset > currentOffset)
// This backward-search is not just a counter-part to the above, but simultaneously also handles conditions A and B.
// It abuses the fact that columns marked with CharOffsetsTrailer are >0x8000 and targetOffset is always <0x8000.
// This means we skip all "trailer" columns when iterating backwards, and only stop on a non-trailer (= condition A).
// Condition B is fixed simply because we iterate backwards after the forward-search (in that exact order).
while (targetOffset < currentOffset)
{
// Forward search.
// Goal: Find the first subsequent column where the offset is > the target offset.
// We stop 1 column before that however so that the next loop works correctly.
// It's the inverse of the loop above.
//
// Since offset has been clamped to be at most 1 less than the maximum
// _charOffsets value the loop naturally exits before hitting the end.
for (; offset >= (_charOffsets[col + 1] & CharOffsetsMask); ++col)
{
}
// Now that we found the cell that definitely includes this char offset,
// we have to iterate back to the cell's starting column.
for (; WI_IsFlagSet(_charOffsets[col], CharOffsetsTrailer); --col)
{
}
currentOffset = _charOffsets[--col];
}
_currentColumn = col;

View File

@@ -71,7 +71,7 @@ struct CharToColumnMapper
{
CharToColumnMapper(const wchar_t* chars, const uint16_t* charOffsets, ptrdiff_t lastCharOffset, til::CoordType currentColumn) noexcept;
til::CoordType GetLeadingColumnAt(ptrdiff_t offset) noexcept;
til::CoordType GetLeadingColumnAt(ptrdiff_t targetOffset) noexcept;
til::CoordType GetTrailingColumnAt(ptrdiff_t offset) noexcept;
til::CoordType GetLeadingColumnAt(const wchar_t* str) noexcept;
til::CoordType GetTrailingColumnAt(const wchar_t* str) noexcept;

View File

@@ -14,6 +14,7 @@
<ClCompile Include="ReflowTests.cpp" />
<ClCompile Include="TextColorTests.cpp" />
<ClCompile Include="TextAttributeTests.cpp" />
<ClCompile Include="UTextAdapterTests.cpp" />
<ClCompile Include="precomp.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
@@ -41,4 +42,4 @@
<Import Project="$(SolutionDir)src\common.build.post.props" />
<Import Project="$(SolutionDir)src\common.build.tests.props" />
<Import Project="$(SolutionDir)src\common.nugetversions.targets" />
</Project>
</Project>

View File

@@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "WexTestClass.h"
#include "../textBuffer.hpp"
#include "../../renderer/inc/DummyRenderer.hpp"
template<>
class WEX::TestExecution::VerifyOutputTraits<std::vector<til::point_span>>
{
public:
static WEX::Common::NoThrowString ToString(const std::vector<til::point_span>& vec)
{
WEX::Common::NoThrowString str;
str.Append(L"{ ");
for (size_t i = 0; i < vec.size(); ++i)
{
const auto& s = vec[i];
if (i != 0)
{
str.Append(L", ");
}
str.AppendFormat(L"{(%d, %d), (%d, %d)}", s.start.x, s.start.y, s.end.x, s.end.y);
}
str.Append(L" }");
return str;
}
};
class UTextAdapterTests
{
TEST_CLASS(UTextAdapterTests);
TEST_METHOD(Unicode)
{
DummyRenderer renderer;
TextBuffer buffer{ til::size{ 24, 1 }, TextAttribute{}, 0, false, renderer };
RowWriteState state{
.text = L"abc 𝒶𝒷𝒸 abc ネコちゃん",
};
buffer.Write(0, TextAttribute{}, state);
VERIFY_IS_TRUE(state.text.empty());
static constexpr auto s = [](til::CoordType beg, til::CoordType end) -> til::point_span {
return { { beg, 0 }, { end, 0 } };
};
auto expected = std::vector{ s(0, 2), s(8, 10) };
auto actual = buffer.SearchText(L"abc", false);
VERIFY_ARE_EQUAL(expected, actual);
expected = std::vector{ s(5, 5) };
actual = buffer.SearchText(L"𝒷", false);
VERIFY_ARE_EQUAL(expected, actual);
expected = std::vector{ s(12, 15) };
actual = buffer.SearchText(L"ネコ", false);
VERIFY_ARE_EQUAL(expected, actual);
}
};

View File

@@ -17,6 +17,7 @@ SOURCES = \
ReflowTests.cpp \
TextColorTests.cpp \
TextAttributeTests.cpp \
UTextAdapterTests.cpp \
DefaultResource.rc \
TARGETLIBS = \

View File

@@ -4,7 +4,7 @@
#include "pch.h"
#include "../TerminalApp/TerminalPage.h"
#include "../LocalTests_SettingsModel/TestUtils.h"
#include "../UnitTests_SettingsModel/TestUtils.h"
using namespace Microsoft::Console;
using namespace WEX::Logging;

View File

@@ -133,7 +133,6 @@
<ItemGroup>
<TestDll Include="$(OpenConsoleCommonOutDir)\LocalTests_TerminalApp\TerminalApp.LocalTests.dll" />
<TestDll Include="$(OpenConsoleCommonOutDir)\LocalTests_SettingsModel\SettingsModel.LocalTests.dll" />
</ItemGroup>
<Target Name="AfterBuild" Inputs="@(TestDll)" Outputs="@(TestDll->'$(TargetDir)'\%(Filename)%(Extension)')">

View File

@@ -2,13 +2,12 @@
// Licensed under the MIT license.
import "TabBase.idl";
import "IDirectKeyListener.idl";
import "HighlightedTextControl.idl";
import "FilteredCommand.idl";
namespace TerminalApp
{
[default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener
[default_interface] runtimeclass CommandPalette : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
CommandPalette();

View File

@@ -9,7 +9,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:TerminalApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
AllowFocusOnInteraction="True"
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
@@ -23,12 +23,6 @@
<UserControl.Resources>
<ResourceDictionary>
<!-- This creates an instance of our CommandKeyChordVisibilityConverter we can reference below -->
<local:EmptyStringVisibilityConverter x:Key="CommandKeyChordVisibilityConverter" />
<local:EmptyStringVisibilityConverter x:Key="ParsedCommandLineTextVisibilityConverter" />
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter" />
<model:IconPathConverter x:Key="IconSourceConverter" />
<DataTemplate x:Key="ListItemTemplate"
x:DataType="local:FilteredCommand">
<ListViewItem HorizontalContentAlignment="Stretch"
@@ -62,8 +56,7 @@
<!--
The block for the key chord is only visible
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details.
when there's actual text set as the label.
We're setting the accessibility view on the
border and text block to Raw because otherwise,
Narrator will read out the key chord. Problem is,
@@ -77,7 +70,7 @@
AutomationProperties.AccessibilityView="Raw"
Background="{ThemeResource FlyoutPresenterBackground}"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
<TextBlock AutomationProperties.AccessibilityView="Raw"
FontSize="12"
@@ -113,8 +106,7 @@
<!--
The block for the key chord is only visible
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details.
when there's actual text set as the label.
We're setting the accessibility view on the
border and text block to Raw because otherwise,
Narrator will read out the key chord. Problem is,
@@ -127,7 +119,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Item.KeyChordText), Mode=OneWay}">
<TextBlock AutomationProperties.AccessibilityView="Raw"
FontSize="12"
@@ -347,12 +339,12 @@
VerticalAlignment="Center"
FontSize="14"
Text="{x:Bind PrefixCharacter, Mode=OneWay}"
Visibility="{x:Bind PrefixCharacter, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}" />
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(PrefixCharacter), Mode=OneWay}" />
<StackPanel Grid.Row="1"
Margin="8,0,8,8"
Orientation="Horizontal"
Visibility="{x:Bind ParentCommandName, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParentCommandName), Mode=OneWay}">
<Button x:Name="_parentCommandBackButton"
x:Uid="ParentCommandBackButton"
@@ -377,7 +369,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Style="{ThemeResource ParsedCommandLineBorderStyle}"
Visibility="{x:Bind ParsedCommandLineText, Mode=OneWay, Converter={StaticResource ParsedCommandLineTextVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParsedCommandLineText), Mode=OneWay}">
<ScrollViewer MaxHeight="200"
VerticalScrollBarVisibility="Auto">

View File

@@ -1,38 +0,0 @@
#include "pch.h"
#include "EmptyStringVisibilityConverter.h"
#include "EmptyStringVisibilityConverter.g.cpp"
using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::TerminalApp::implementation
{
// Method Description:
// - Attempt to convert something into another type. For the
// EmptyStringVisibilityConverter, we're gonna check if `value` is a
// string, and try and convert it into a Visibility value. If the input
// param wasn't a string, or was the empty string, we'll return
// Visibility::Collapsed. Otherwise, we'll return Visible.
// Arguments:
// - value: the input object to attempt to convert into a Visibility.
// Return Value:
// - Visible if the object was a string and wasn't the empty string.
Foundation::IInspectable EmptyStringVisibilityConverter::Convert(const Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& /* targetType */,
const Foundation::IInspectable& /* parameter */,
const hstring& /* language */)
{
const auto& name = winrt::unbox_value_or<hstring>(value, L"");
return winrt::box_value(name.empty() ? Visibility::Collapsed : Visibility::Visible);
}
// unused for one-way bindings
Foundation::IInspectable EmptyStringVisibilityConverter::ConvertBack(const Foundation::IInspectable& /* value */,
const Windows::UI::Xaml::Interop::TypeName& /* targetType */,
const Foundation::IInspectable& /* parameter */,
const hstring& /* language */)
{
throw hresult_not_implemented();
}
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include "EmptyStringVisibilityConverter.g.h"
namespace winrt::TerminalApp::implementation
{
struct EmptyStringVisibilityConverter : EmptyStringVisibilityConverterT<EmptyStringVisibilityConverter>
{
EmptyStringVisibilityConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& targetType,
const Windows::Foundation::IInspectable& parameter,
const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& targetType,
const Windows::Foundation::IInspectable& parameter,
const hstring& language);
};
}
namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(EmptyStringVisibilityConverter);
}

View File

@@ -1,19 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
// See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart
// We use the default attribute to declare IValueConverter as the default
// interface. In the listing, EmptyStringVisibilityConverter has only a
// constructor, and no methods, so no default interface is generated for it.
// The default attribute is optimal if you won't be adding instance members
// to EmptyStringVisibilityConverter, because no QueryInterface will be
// required to call the IValueConverter methods
runtimeclass EmptyStringVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter
{
EmptyStringVisibilityConverter();
};
}

View File

@@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
// C++/winrt makes it difficult to share this idl between two projects,
// Instead, we just pin the uuid and include it in both TermControl and App
// If you update this one, please update the one in TerminalControl\TermControl.idl
// If you change this interface, please update the guid.
// If you press F7 or Alt and get a runtime error, go make sure both copies are the same.
[uuid("0ddf4edc-3fda-4dee-97ca-a417ee3dd510")] interface IDirectKeyListener {
Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down);
}
}

View File

@@ -17,7 +17,7 @@ namespace winrt::TerminalApp::implementation
{
Controls::IconElement PaletteItem::ResolvedIcon()
{
const auto icon = IconPathConverter::IconWUX(Icon());
const auto icon = Microsoft::Terminal::UI::IconPathConverter::IconWUX(Icon());
icon.Width(16);
icon.Height(16);
return icon;

View File

@@ -114,7 +114,7 @@ namespace winrt::TerminalApp::implementation
// The TabViewItem Icon needs MUX while the IconSourceElement in the CommandPalette needs WUX...
Icon(winrt::hstring{ glyph });
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(glyph, false));
TabViewItem().IconSource(Microsoft::Terminal::UI::IconPathConverter::IconSourceMUX(glyph, false));
}
winrt::Windows::UI::Xaml::Media::Brush SettingsTab::_BackgroundBrush()

View File

@@ -2,7 +2,6 @@
// Licensed under the MIT license.
import "TabBase.idl";
import "IDirectKeyListener.idl";
import "HighlightedTextControl.idl";
import "FilteredCommand.idl";
@@ -21,7 +20,7 @@ namespace TerminalApp
BottomUp
};
[default_interface] runtimeclass SuggestionsControl : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener
[default_interface] runtimeclass SuggestionsControl : Windows.UI.Xaml.Controls.UserControl, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
SuggestionsControl();

View File

@@ -10,6 +10,7 @@
xmlns:local="using:TerminalApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
AllowFocusOnInteraction="True"
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}"
@@ -23,9 +24,6 @@
<UserControl.Resources>
<ResourceDictionary>
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter" />
<model:IconPathConverter x:Key="IconSourceConverter" />
<DataTemplate x:Key="ListItemTemplate"
x:DataType="local:FilteredCommand">
<ListViewItem Height="32"
@@ -161,7 +159,7 @@
<StackPanel Grid.Row="1"
Margin="8,0,8,8"
Orientation="Horizontal"
Visibility="{x:Bind ParentCommandName, Mode=OneWay, Converter={StaticResource ParentCommandVisibilityConverter}}">
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(ParentCommandName), Mode=OneWay}">
<Button x:Name="_parentCommandBackButton"
x:Uid="ParentCommandBackButton"

View File

@@ -130,9 +130,6 @@
<DependentUpon>CommandPalette.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="FilteredCommand.h" />
<ClInclude Include="EmptyStringVisibilityConverter.h">
<DependentUpon>EmptyStringVisibilityConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="Pane.h" />
<ClInclude Include="PaneArgs.h">
<DependentUpon>IPaneContent.idl</DependentUpon>
@@ -241,9 +238,6 @@
<DependentUpon>CommandPalette.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="FilteredCommand.cpp" />
<ClCompile Include="EmptyStringVisibilityConverter.cpp">
<DependentUpon>EmptyStringVisibilityConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="Pane.cpp" />
<ClCompile Include="PaneArgs.cpp">
<DependentUpon>IPaneContent.idl</DependentUpon>
@@ -298,7 +292,6 @@
header in TerminalApp.vcxproj (as well as in this file) -->
<Midl Include="ActionPaletteItem.idl" />
<Midl Include="CommandLinePaletteItem.idl" />
<Midl Include="IDirectKeyListener.idl" />
<Midl Include="AboutDialog.idl">
<DependentUpon>AboutDialog.xaml</DependentUpon>
</Midl>
@@ -359,7 +352,6 @@
<SubType>Code</SubType>
</Midl>
<Midl Include="FilteredCommand.idl" />
<Midl Include="EmptyStringVisibilityConverter.idl" />
<Midl Include="IPaneContent.idl" />
<Midl Include="TerminalPaneContent.idl" />
</ItemGroup>
@@ -405,6 +397,9 @@
<Private>true</Private>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup>

View File

@@ -98,7 +98,6 @@
<Midl Include="ShortcutActionDispatch.idl">
<Filter>settings</Filter>
</Midl>
<Midl Include="IDirectKeyListener.idl" />
<Midl Include="SettingsTab.idl">
<Filter>tab</Filter>
</Midl>
@@ -116,7 +115,6 @@
</Midl>
<Midl Include="PaletteItemTemplateSelector.idl" />
<Midl Include="TabBase.idl" />
<Midl Include="EmptyStringVisibilityConverter.idl" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -187,4 +185,4 @@
<Filter>app</Filter>
</ApplicationDefinition>
</ItemGroup>
</Project>
</Project>

View File

@@ -1101,7 +1101,7 @@ namespace winrt::TerminalApp::implementation
return nullptr;
}
auto icon = IconPathConverter::IconWUX(iconSource);
auto icon = UI::IconPathConverter::IconWUX(iconSource);
Automation::AutomationProperties::SetAccessibilityView(icon, Automation::Peers::AccessibilityView::Raw);
return icon;
@@ -4940,7 +4940,7 @@ namespace winrt::TerminalApp::implementation
if (!icon.empty())
{
auto iconElement = IconPathConverter::IconWUX(icon);
auto iconElement = UI::IconPathConverter::IconWUX(icon);
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
button.Icon(iconElement);
}

View File

@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "TaskbarState.idl";
import "IDirectKeyListener.idl";
namespace TerminalApp
{
@@ -57,7 +56,7 @@ namespace TerminalApp
Boolean IsQuakeWindow();
};
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged, IDirectKeyListener
[default_interface] runtimeclass TerminalPage : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged, Microsoft.Terminal.UI.IDirectKeyListener
{
TerminalPage(WindowProperties properties, ContentManager manager);

View File

@@ -309,7 +309,7 @@ namespace winrt::TerminalApp::implementation
{
Icon(_lastIconPath);
bool isMonochrome = iconStyle == IconStyle::Monochrome;
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath, isMonochrome));
TabViewItem().IconSource(Microsoft::Terminal::UI::IconPathConverter::IconSourceMUX(_lastIconPath, isMonochrome));
}
}
@@ -332,7 +332,7 @@ namespace winrt::TerminalApp::implementation
else
{
Icon(_lastIconPath);
TabViewItem().IconSource(IconPathConverter::IconSourceMUX(_lastIconPath, _lastIconStyle == IconStyle::Monochrome));
TabViewItem().IconSource(Microsoft::Terminal::UI::IconPathConverter::IconSourceMUX(_lastIconPath, _lastIconStyle == IconStyle::Monochrome));
}
_iconHidden = hide;
}

View File

@@ -863,7 +863,7 @@ namespace winrt::TerminalApp::implementation
auto focusedObject{ Windows::UI::Xaml::Input::FocusManager::GetFocusedElement(xamlRoot) };
do
{
if (auto keyListener{ focusedObject.try_as<IDirectKeyListener>() })
if (auto keyListener{ focusedObject.try_as<UI::IDirectKeyListener>() })
{
if (keyListener.OnDirectKeyEvent(vkey, scanCode, down))
{
@@ -891,7 +891,7 @@ namespace winrt::TerminalApp::implementation
// don't want to go around the loop again.
if (!focusedObject)
{
if (auto keyListener{ _root.try_as<IDirectKeyListener>() })
if (auto keyListener{ _root.try_as<UI::IDirectKeyListener>() })
{
return keyListener.OnDirectKeyEvent(vkey, scanCode, down);
}

View File

@@ -3,7 +3,6 @@
import "TerminalPage.idl";
import "ShortcutActionDispatch.idl";
import "IDirectKeyListener.idl";
namespace TerminalApp
{
@@ -40,7 +39,7 @@ namespace TerminalApp
// See IDialogPresenter and TerminalPage's DialogPresenter for more
// information.
[default_interface] runtimeclass TerminalWindow : IDirectKeyListener, IDialogPresenter, Windows.UI.Xaml.Data.INotifyPropertyChanged
[default_interface] runtimeclass TerminalWindow : Microsoft.Terminal.UI.IDirectKeyListener, IDialogPresenter, Windows.UI.Xaml.Data.INotifyPropertyChanged
{
TerminalWindow(SettingsLoadEventArgs result, ContentManager manager);

View File

@@ -70,6 +70,9 @@
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\dll\TerminalControl.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj" />
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
</ProjectReference>
<!-- Reference TerminalAppLib here, so we can use its TerminalApp.winmd as
our TerminalApp.winmd. This didn't work correctly in VS2017, you'd need to
manually reference the lib -->

View File

@@ -60,6 +60,7 @@
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
#include <winrt/Microsoft.Terminal.Settings.Editor.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
#include <winrt/Microsoft.Terminal.UI.h>
#include <winrt/Windows.Services.Store.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Provider.h>

View File

@@ -14,7 +14,6 @@
#include "InteractivityAutomationPeer.h"
#include "ControlInteractivity.g.cpp"
#include "TermControl.h"
using namespace ::Microsoft::Console::Types;
using namespace ::Microsoft::Console::VirtualTerminal;

View File

@@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Control
{
// C++/winrt makes it difficult to share this idl between two projects,
// Instead, we just pin the uuid and include it in both TermControl and App
// If you update this one, please update TerminalApp\IDirectKeyListener.idl.
// If you change this interface, please update the guid.
// If you press F7 or Alt and get a runtime error, go make sure both copies are the same.
[uuid("0ddf4edc-3fda-4dee-97ca-a417ee3dd510")] interface IDirectKeyListener {
Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down);
};
}

View File

@@ -5,6 +5,8 @@
#include "ScrollBarVisualStateManager.h"
#include "ScrollBarVisualStateManager.g.cpp"
#include "TermControl.h"
using namespace winrt::Windows::UI::Xaml::Media;
namespace winrt::Microsoft::Terminal::Control::implementation

View File

@@ -14,12 +14,12 @@
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include "TermControl.h"
#include "ScrollBarVisualStateManager.g.h"
namespace winrt::Microsoft::Terminal::Control::implementation
{
struct TermControl;
struct ScrollBarVisualStateManager : ScrollBarVisualStateManagerT<ScrollBarVisualStateManager>
{
bool GoToStateCore(winrt::Windows::UI::Xaml::Controls::Control const& control, winrt::Windows::UI::Xaml::FrameworkElement const& templateRoot, hstring const& stateName, winrt::Windows::UI::Xaml::VisualStateGroup const& group, winrt::Windows::UI::Xaml::VisualState const& state, bool useTransitions);

View File

@@ -4,13 +4,19 @@
import "IMouseWheelListener.idl";
import "IControlSettings.idl";
import "ControlInteractivity.idl";
import "IDirectKeyListener.idl";
import "EventArgs.idl";
import "ICoreState.idl";
import "ControlCore.idl";
namespace Microsoft.Terminal.Control
{
// This matches the definition in M.T.UI.
// Having it here prevents us from having to refer to M.T.UI in **all consuming projects**.
// WinRT is a trip.
[uuid("0ddf4edc-3fda-4dee-97ca-a417ee3dd510")]
interface IDirectKeyListener {
Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down);
}
enum CursorDisplayState
{

View File

@@ -28,7 +28,6 @@ Modifications:
#pragma once
#include "TermControl.h"
#include "ControlInteractivity.h"
#include "TermControlAutomationPeer.g.h"
#include "../types/TermControlUiaProvider.hpp"
@@ -37,6 +36,8 @@ Modifications:
namespace winrt::Microsoft::Terminal::Control::implementation
{
struct TermControl;
struct TermControlAutomationPeer :
public TermControlAutomationPeerT<TermControlAutomationPeer>,
::Microsoft::Console::Types::IUiaEventDispatcher

View File

@@ -122,7 +122,6 @@
<Midl Include="ControlInteractivity.idl" />
<Midl Include="ScrollBarVisualStateManager.idl" />
<Midl Include="ICoreState.idl" />
<Midl Include="IDirectKeyListener.idl" />
<Midl Include="KeyChord.idl" />
<Midl Include="EventArgs.idl" />
<Midl Include="IKeyBindings.idl" />
@@ -178,6 +177,10 @@
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<!-- ====================== Compiler & Linker Flags ===================== -->
<ItemDefinitionGroup>

View File

@@ -65,6 +65,11 @@
<Private>true</Private>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>

View File

@@ -58,6 +58,8 @@
#include <winrt/Microsoft.Terminal.TerminalConnection.h>
#include <winrt/Microsoft.Terminal.Core.h>
#include <winrt/Microsoft.Terminal.UI.h>
#include <windows.ui.xaml.media.dxinterop.h>
#include <TraceLoggingProvider.h>

View File

@@ -8,7 +8,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
mc:Ignorable="d">
<Page.Resources>
@@ -157,7 +157,6 @@
</Style>
<!-- Converters & Misc. -->
<model:IconPathConverter x:Key="IconSourceConverter" />
<SolidColorBrush x:Key="ActionContainerBackgroundEditing"
Color="{ThemeResource SystemListMediumColor}" />
<SolidColorBrush x:Key="ActionContainerBackground"
@@ -194,7 +193,7 @@
<TextBlock Grid.Column="0"
Style="{StaticResource KeyBindingNameTextBlockStyle}"
Text="{x:Bind Name, Mode=OneWay}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}" />
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}" />
<!-- Edit Mode: Action Combo-box -->
<ComboBox x:Uid="Actions_ActionComboBox"
@@ -210,7 +209,7 @@
HorizontalAlignment="Right"
VerticalAlignment="Center"
Style="{ThemeResource KeyChordBorderStyle}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
<TextBlock FontSize="14"
Style="{ThemeResource KeyChordTextBlockStyle}"
@@ -302,7 +301,7 @@
Margin="8,0,0,0"
AutomationProperties.Name="{x:Bind DeleteButtonName}"
Style="{StaticResource DeleteSmallButtonStyle}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(IsNewlyAdded), Mode=OneWay}">
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsNewlyAdded), Mode=OneWay}">
<Button.Content>
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
Glyph="&#xE74D;" />

View File

@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -17,7 +18,6 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<model:IconPathConverter x:Key="IconSourceConverter" />
</ResourceDictionary>
</Page.Resources>
@@ -59,7 +59,7 @@
<IconSourceElement Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind Icon, Converter={StaticResource IconSourceConverter}}" />
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
<TextBlock Grid.Column="1"
Text="{x:Bind Name}" />

View File

@@ -4,6 +4,8 @@
#include "pch.h"
#include "Appearances.h"
#include "Appearances.g.cpp"
#include "AxisKeyValuePair.g.cpp"
#include "FeatureKeyValuePair.g.cpp"
#include "EnumEntry.h"
#include <LibraryResources.h>
@@ -18,6 +20,20 @@ using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Microsoft::Terminal::Settings::Model;
static constexpr std::array<std::wstring_view, 11> DefaultFeatures{
L"rlig",
L"locl",
L"ccmp",
L"calt",
L"liga",
L"clig",
L"rnrn",
L"kern",
L"mark",
L"mkmk",
L"dist"
};
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
bool Font::HasPowerlineCharacters()
@@ -42,6 +58,285 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return _hasPowerlineCharacters.value_or(false);
}
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> Font::FontAxesTagsAndNames()
{
if (!_fontAxesTagsAndNames)
{
wil::com_ptr<IDWriteFont> font;
THROW_IF_FAILED(_family->GetFont(0, font.put()));
wil::com_ptr<IDWriteFontFace> fontFace;
THROW_IF_FAILED(font->CreateFontFace(fontFace.put()));
wil::com_ptr<IDWriteFontFace5> fontFace5;
if (fontFace5 = fontFace.try_query<IDWriteFontFace5>())
{
wil::com_ptr<IDWriteFontResource> fontResource;
THROW_IF_FAILED(fontFace5->GetFontResource(fontResource.put()));
const auto axesCount = fontFace5->GetFontAxisValueCount();
if (axesCount > 0)
{
std::vector<DWRITE_FONT_AXIS_VALUE> axesVector(axesCount);
fontFace5->GetFontAxisValues(axesVector.data(), axesCount);
uint32_t localeIndex;
BOOL localeExists;
wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
const auto localeToTry = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) ? localeName : L"en-US";
std::unordered_map<winrt::hstring, winrt::hstring> fontAxesTagsAndNames;
for (uint32_t i = 0; i < axesCount; ++i)
{
wil::com_ptr<IDWriteLocalizedStrings> names;
THROW_IF_FAILED(fontResource->GetAxisNames(i, names.put()));
if (!SUCCEEDED(names->FindLocaleName(localeToTry, &localeIndex, &localeExists)) || !localeExists)
{
// default to the first locale in the list
localeIndex = 0;
}
UINT32 length = 0;
if (SUCCEEDED(names->GetStringLength(localeIndex, &length)))
{
winrt::impl::hstring_builder builder{ length };
if (SUCCEEDED(names->GetString(localeIndex, builder.data(), length + 1)))
{
fontAxesTagsAndNames.insert(std::pair<winrt::hstring, winrt::hstring>(_tagToString(axesVector[i].axisTag), builder.to_hstring()));
continue;
}
}
// if there was no name found, it means the font does not actually support this axis
// don't insert anything into the vector in this case
}
_fontAxesTagsAndNames = winrt::single_threaded_map(std::move(fontAxesTagsAndNames));
}
}
}
return _fontAxesTagsAndNames;
}
IMap<hstring, hstring> Font::FontFeaturesTagsAndNames()
{
if (!_fontFeaturesTagsAndNames)
{
wil::com_ptr<IDWriteFont> font;
THROW_IF_FAILED(_family->GetFont(0, font.put()));
wil::com_ptr<IDWriteFontFace> fontFace;
THROW_IF_FAILED(font->CreateFontFace(fontFace.put()));
wil::com_ptr<IDWriteFactory2> factory;
THROW_IF_FAILED(DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(factory), reinterpret_cast<::IUnknown**>(factory.addressof())));
wil::com_ptr<IDWriteTextAnalyzer> textAnalyzer;
factory->CreateTextAnalyzer(textAnalyzer.addressof());
wil::com_ptr<IDWriteTextAnalyzer2> textAnalyzer2 = textAnalyzer.query<IDWriteTextAnalyzer2>();
DWRITE_SCRIPT_ANALYSIS scriptAnalysis{};
UINT32 tagCount;
// we have to call GetTypographicFeatures twice, first to get the actual count then to get the features
std::ignore = textAnalyzer2->GetTypographicFeatures(fontFace.get(), scriptAnalysis, L"en-us", 0, &tagCount, nullptr);
std::vector<DWRITE_FONT_FEATURE_TAG> tags{ tagCount };
textAnalyzer2->GetTypographicFeatures(fontFace.get(), scriptAnalysis, L"en-us", tagCount, &tagCount, tags.data());
std::unordered_map<winrt::hstring, winrt::hstring> fontFeaturesTagsAndNames;
for (auto tag : tags)
{
const auto tagString = _tagToString(tag);
hstring formattedResourceString{ fmt::format(L"Profile_FontFeature_{}", tagString) };
hstring localizedName{ tagString };
// we have resource strings for common font features, see if one for this feature exists
if (HasLibraryResourceWithName(formattedResourceString))
{
localizedName = GetLibraryResourceString(formattedResourceString);
}
fontFeaturesTagsAndNames.insert(std::pair<winrt::hstring, winrt::hstring>(tagString, localizedName));
}
_fontFeaturesTagsAndNames = winrt::single_threaded_map<winrt::hstring, winrt::hstring>(std::move(fontFeaturesTagsAndNames));
}
return _fontFeaturesTagsAndNames;
}
winrt::hstring Font::_tagToString(DWRITE_FONT_AXIS_TAG tag)
{
std::wstring result;
for (int i = 0; i < 4; ++i)
{
result.push_back((tag >> (i * 8)) & 0xFF);
}
return winrt::hstring{ result };
}
hstring Font::_tagToString(DWRITE_FONT_FEATURE_TAG tag)
{
std::wstring result;
for (int i = 0; i < 4; ++i)
{
result.push_back((tag >> (i * 8)) & 0xFF);
}
return hstring{ result };
}
AxisKeyValuePair::AxisKeyValuePair(winrt::hstring axisKey, float axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, float>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap) :
_AxisKey{ axisKey },
_AxisValue{ axisValue },
_baseMap{ baseMap },
_tagToNameMap{ tagToNameMap }
{
if (_tagToNameMap.HasKey(_AxisKey))
{
int32_t i{ 0 };
// IMap guarantees that the iteration order is the same every time
// so this conversion of key to index is safe
for (const auto tagAndName : _tagToNameMap)
{
if (tagAndName.Key() == _AxisKey)
{
_AxisIndex = i;
break;
}
++i;
}
}
}
winrt::hstring AxisKeyValuePair::AxisKey()
{
return _AxisKey;
}
float AxisKeyValuePair::AxisValue()
{
return _AxisValue;
}
int32_t AxisKeyValuePair::AxisIndex()
{
return _AxisIndex;
}
void AxisKeyValuePair::AxisValue(float axisValue)
{
if (axisValue != _AxisValue)
{
_baseMap.Remove(_AxisKey);
_AxisValue = axisValue;
_baseMap.Insert(_AxisKey, _AxisValue);
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"AxisValue" });
}
}
void AxisKeyValuePair::AxisKey(winrt::hstring axisKey)
{
if (axisKey != _AxisKey)
{
_baseMap.Remove(_AxisKey);
_AxisKey = axisKey;
_baseMap.Insert(_AxisKey, _AxisValue);
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"AxisKey" });
}
}
void AxisKeyValuePair::AxisIndex(int32_t axisIndex)
{
if (axisIndex != _AxisIndex)
{
_AxisIndex = axisIndex;
int32_t i{ 0 };
// same as in the constructor, iterating through IMap
// gives us the same order every time
for (const auto tagAndName : _tagToNameMap)
{
if (i == _AxisIndex)
{
AxisKey(tagAndName.Key());
break;
}
++i;
}
}
}
FeatureKeyValuePair::FeatureKeyValuePair(hstring featureKey, uint32_t featureValue, const IMap<hstring, uint32_t>& baseMap, const IMap<hstring, hstring>& tagToNameMap) :
_FeatureKey{ featureKey },
_FeatureValue{ featureValue },
_baseMap{ baseMap },
_tagToNameMap{ tagToNameMap }
{
if (_tagToNameMap.HasKey(_FeatureKey))
{
int32_t i{ 0 };
// this loop assumes that every time we iterate through the map
// we get the same ordering
for (const auto tagAndName : _tagToNameMap)
{
if (tagAndName.Key() == _FeatureKey)
{
_FeatureIndex = i;
break;
}
++i;
}
}
}
hstring FeatureKeyValuePair::FeatureKey()
{
return _FeatureKey;
}
uint32_t FeatureKeyValuePair::FeatureValue()
{
return _FeatureValue;
}
int32_t FeatureKeyValuePair::FeatureIndex()
{
return _FeatureIndex;
}
void FeatureKeyValuePair::FeatureValue(uint32_t featureValue)
{
if (featureValue != _FeatureValue)
{
_baseMap.Remove(_FeatureKey);
_FeatureValue = featureValue;
_baseMap.Insert(_FeatureKey, _FeatureValue);
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"FeatureValue" });
}
}
void FeatureKeyValuePair::FeatureKey(hstring featureKey)
{
if (featureKey != _FeatureKey)
{
_baseMap.Remove(_FeatureKey);
_FeatureKey = featureKey;
_baseMap.Insert(_FeatureKey, _FeatureValue);
_PropertyChangedHandlers(*this, PropertyChangedEventArgs{ L"FeatureKey" });
}
}
void FeatureKeyValuePair::FeatureIndex(int32_t featureIndex)
{
if (featureIndex != _FeatureIndex)
{
_FeatureIndex = featureIndex;
int32_t i{ 0 };
// same as in the constructor, this assumes that iterating through the map
// gives us the same order every time
for (const auto tagAndName : _tagToNameMap)
{
if (i == _FeatureIndex)
{
FeatureKey(tagAndName.Key());
break;
}
++i;
}
}
}
AppearanceViewModel::AppearanceViewModel(const Model::AppearanceConfig& appearance) :
_appearance{ appearance }
{
@@ -60,8 +355,24 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// box, prevent it from ever being changed again.
_NotifyChanges(L"UseDesktopBGImage", L"BackgroundImageSettingsVisible");
}
else if (viewModelProperty == L"FontAxes")
{
// this is a weird one
// we manually make the observable vector based on the map in the settings model
// (this is due to xaml being unable to bind a list view to a map)
// so when the FontAxes change (say from the reset button), reinitialize the observable vector
InitializeFontAxesVector();
}
else if (viewModelProperty == L"FontFeatures")
{
// same as the FontAxes one
InitializeFontFeaturesVector();
}
});
InitializeFontAxesVector();
InitializeFontFeaturesVector();
// Cache the original BG image path. If the user clicks "Use desktop
// wallpaper", then un-checks it, this is the string we'll restore to
// them.
@@ -130,12 +441,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void AppearanceViewModel::SetFontWeightFromDouble(double fontWeight)
{
FontWeight(Converters::DoubleToFontWeight(fontWeight));
FontWeight(winrt::Microsoft::Terminal::UI::Converters::DoubleToFontWeight(fontWeight));
}
void AppearanceViewModel::SetBackgroundImageOpacityFromPercentageValue(double percentageValue)
{
BackgroundImageOpacity(Converters::PercentageValueToPercentage(percentageValue));
BackgroundImageOpacity(winrt::Microsoft::Terminal::UI::Converters::PercentageValueToPercentage(percentageValue));
}
void AppearanceViewModel::SetBackgroundImagePath(winrt::hstring path)
@@ -205,6 +516,263 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
LightColorSchemeName(val.Name());
}
void AppearanceViewModel::AddNewAxisKeyValuePair()
{
if (!_appearance.SourceProfile().FontInfo().FontAxes())
{
_appearance.SourceProfile().FontInfo().FontAxes(winrt::single_threaded_map<winrt::hstring, float>());
}
auto fontAxesMap = _appearance.SourceProfile().FontInfo().FontAxes();
// find one axis that does not already exist, and add that
// if there are no more possible axes to add, the button is disabled so there shouldn't be a way to get here
const auto possibleAxesTagsAndNames = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontAxesTagsAndNames();
for (const auto tagAndName : possibleAxesTagsAndNames)
{
if (!fontAxesMap.HasKey(tagAndName.Key()))
{
fontAxesMap.Insert(tagAndName.Key(), gsl::narrow<float>(0));
FontAxesVector().Append(_CreateAxisKeyValuePairHelper(tagAndName.Key(), gsl::narrow<float>(0), fontAxesMap, possibleAxesTagsAndNames));
break;
}
}
_NotifyChanges(L"CanFontAxesBeAdded");
}
void AppearanceViewModel::DeleteAxisKeyValuePair(winrt::hstring key)
{
for (uint32_t i = 0; i < _FontAxesVector.Size(); i++)
{
if (_FontAxesVector.GetAt(i).AxisKey() == key)
{
FontAxesVector().RemoveAt(i);
_appearance.SourceProfile().FontInfo().FontAxes().Remove(key);
if (_FontAxesVector.Size() == 0)
{
_appearance.SourceProfile().FontInfo().ClearFontAxes();
}
break;
}
}
_NotifyChanges(L"CanFontAxesBeAdded");
}
void AppearanceViewModel::InitializeFontAxesVector()
{
if (!_FontAxesVector)
{
_FontAxesVector = winrt::single_threaded_observable_vector<Editor::AxisKeyValuePair>();
}
_FontAxesVector.Clear();
if (const auto fontAxesMap = _appearance.SourceProfile().FontInfo().FontAxes())
{
const auto fontAxesTagToNameMap = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontAxesTagsAndNames();
for (const auto axis : fontAxesMap)
{
// only show the axes that the font supports
// any axes that the font doesn't support continue to be stored in the json, we just don't show them in the UI
if (fontAxesTagToNameMap.HasKey(axis.Key()))
{
_FontAxesVector.Append(_CreateAxisKeyValuePairHelper(axis.Key(), axis.Value(), fontAxesMap, fontAxesTagToNameMap));
}
}
}
_NotifyChanges(L"AreFontAxesAvailable", L"CanFontAxesBeAdded");
}
// Method Description:
// - Determines whether the currently selected font has any variable font axes
bool AppearanceViewModel::AreFontAxesAvailable()
{
return ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontAxesTagsAndNames().Size() > 0;
}
// Method Description:
// - Determines whether the currently selected font has any variable font axes that have not already been set
bool AppearanceViewModel::CanFontAxesBeAdded()
{
if (const auto fontAxesTagToNameMap = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontAxesTagsAndNames(); fontAxesTagToNameMap.Size() > 0)
{
if (const auto fontAxesMap = _appearance.SourceProfile().FontInfo().FontAxes())
{
for (const auto tagAndName : fontAxesTagToNameMap)
{
if (!fontAxesMap.HasKey(tagAndName.Key()))
{
// we found an axis that has not been set
return true;
}
}
// all possible axes have been set already
return false;
}
// the font supports font axes but the profile has none set
return true;
}
// the font does not support any font axes
return false;
}
// Method Description:
// - Creates an AxisKeyValuePair and sets up an event handler for it
Editor::AxisKeyValuePair AppearanceViewModel::_CreateAxisKeyValuePairHelper(winrt::hstring axisKey, float axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, float>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap)
{
const auto axisKeyValuePair = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::AxisKeyValuePair>(axisKey, axisValue, baseMap, tagToNameMap);
// when either the key or the value changes, send an event for the preview control to catch
axisKeyValuePair.PropertyChanged([weakThis = get_weak()](auto& /*sender*/, auto& /*e*/) {
if (auto appVM{ weakThis.get() })
{
appVM->_NotifyChanges(L"AxisKeyValuePair");
}
});
return axisKeyValuePair;
}
void AppearanceViewModel::AddNewFeatureKeyValuePair()
{
const auto fontInfo = _appearance.SourceProfile().FontInfo();
auto fontFeaturesMap = fontInfo.FontFeatures();
if (!fontFeaturesMap)
{
fontFeaturesMap = winrt::single_threaded_map<hstring, uint32_t>();
fontInfo.FontFeatures(fontFeaturesMap);
}
// find one feature that does not already exist, and add that
// if there are no more possible features to add, the button is disabled so there shouldn't be a way to get here
const auto possibleFeaturesTagsAndNames = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames();
for (const auto tagAndName : possibleFeaturesTagsAndNames)
{
const auto featureKey = tagAndName.Key();
if (!fontFeaturesMap.HasKey(featureKey))
{
const auto featureDefaultValue = _IsDefaultFeature(featureKey) ? 1 : 0;
fontFeaturesMap.Insert(featureKey, featureDefaultValue);
FontFeaturesVector().Append(_CreateFeatureKeyValuePairHelper(featureKey, featureDefaultValue, fontFeaturesMap, possibleFeaturesTagsAndNames));
break;
}
}
_NotifyChanges(L"CanFontFeaturesBeAdded");
}
void AppearanceViewModel::DeleteFeatureKeyValuePair(hstring key)
{
for (uint32_t i = 0; i < _FontFeaturesVector.Size(); i++)
{
if (_FontFeaturesVector.GetAt(i).FeatureKey() == key)
{
FontFeaturesVector().RemoveAt(i);
_appearance.SourceProfile().FontInfo().FontFeatures().Remove(key);
if (_FontFeaturesVector.Size() == 0)
{
_appearance.SourceProfile().FontInfo().ClearFontFeatures();
}
break;
}
}
_NotifyChanges(L"CanFontAxesBeAdded");
}
void AppearanceViewModel::InitializeFontFeaturesVector()
{
if (!_FontFeaturesVector)
{
_FontFeaturesVector = single_threaded_observable_vector<Editor::FeatureKeyValuePair>();
}
_FontFeaturesVector.Clear();
if (const auto fontFeaturesMap = _appearance.SourceProfile().FontInfo().FontFeatures())
{
const auto fontFeaturesTagToNameMap = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames();
for (const auto feature : fontFeaturesMap)
{
const auto featureKey = feature.Key();
// only show the features that the font supports
// any features that the font doesn't support continue to be stored in the json, we just don't show them in the UI
if (fontFeaturesTagToNameMap.HasKey(featureKey))
{
_FontFeaturesVector.Append(_CreateFeatureKeyValuePairHelper(featureKey, feature.Value(), fontFeaturesMap, fontFeaturesTagToNameMap));
}
}
}
_NotifyChanges(L"AreFontFeaturesAvailable", L"CanFontFeaturesBeAdded");
}
// Method Description:
// - Determines whether the currently selected font has any font features
bool AppearanceViewModel::AreFontFeaturesAvailable()
{
return ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames().Size() > 0;
}
// Method Description:
// - Determines whether the currently selected font has any font features that have not already been set
bool AppearanceViewModel::CanFontFeaturesBeAdded()
{
if (const auto fontFeaturesTagToNameMap = ProfileViewModel::FindFontWithLocalizedName(FontFace()).FontFeaturesTagsAndNames(); fontFeaturesTagToNameMap.Size() > 0)
{
if (const auto fontFeaturesMap = _appearance.SourceProfile().FontInfo().FontFeatures())
{
for (const auto tagAndName : fontFeaturesTagToNameMap)
{
if (!fontFeaturesMap.HasKey(tagAndName.Key()))
{
// we found a feature that has not been set
return true;
}
}
// all possible features have been set already
return false;
}
// the font supports font features but the profile has none set
return true;
}
// the font does not support any font features
return false;
}
// Method Description:
// - Creates a FeatureKeyValuePair and sets up an event handler for it
Editor::FeatureKeyValuePair AppearanceViewModel::_CreateFeatureKeyValuePairHelper(hstring featureKey, uint32_t featureValue, const IMap<hstring, uint32_t>& baseMap, const IMap<hstring, hstring>& tagToNameMap)
{
const auto featureKeyValuePair = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::FeatureKeyValuePair>(featureKey, featureValue, baseMap, tagToNameMap);
// when either the key or the value changes, send an event for the preview control to catch
featureKeyValuePair.PropertyChanged([weakThis = get_weak()](auto& sender, const PropertyChangedEventArgs& args) {
if (auto appVM{ weakThis.get() })
{
appVM->_NotifyChanges(L"FeatureKeyValuePair");
const auto settingName{ args.PropertyName() };
if (settingName == L"FeatureKey")
{
const auto senderPair = sender.as<FeatureKeyValuePair>();
const auto senderKey = senderPair->FeatureKey();
if (appVM->_IsDefaultFeature(senderKey))
{
senderPair->FeatureValue(1);
}
else
{
senderPair->FeatureValue(0);
}
}
}
});
return featureKeyValuePair;
}
bool AppearanceViewModel::_IsDefaultFeature(winrt::hstring featureKey)
{
for (const auto defaultFeature : DefaultFeatures)
{
if (defaultFeature == featureKey)
{
return true;
}
}
return false;
}
DependencyProperty Appearances::_AppearanceProperty{ nullptr };
Appearances::Appearances() :
@@ -271,6 +839,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
const auto backgroundImgCheckboxTooltip{ ToolTipService::GetToolTip(UseDesktopImageCheckBox()) };
Automation::AutomationProperties::SetFullDescription(UseDesktopImageCheckBox(), unbox_value<hstring>(backgroundImgCheckboxTooltip));
_FontAxesNames = winrt::single_threaded_observable_vector<winrt::hstring>();
FontAxesNamesCVS().Source(_FontAxesNames);
_FontFeaturesNames = winrt::single_threaded_observable_vector<hstring>();
FontFeaturesNamesCVS().Source(_FontFeaturesNames);
INITIALIZE_BINDABLE_ENUM_SETTING(IntenseTextStyle, IntenseTextStyle, winrt::Microsoft::Terminal::Settings::Model::IntenseStyle, L"Appearance_IntenseTextStyle", L"Content");
}
@@ -330,6 +904,48 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
ShowProportionalFontWarning(false);
}
_FontAxesNames.Clear();
const auto axesTagsAndNames = newFontFace.FontAxesTagsAndNames();
for (const auto tagAndName : axesTagsAndNames)
{
_FontAxesNames.Append(tagAndName.Value());
}
_FontFeaturesNames.Clear();
const auto featuresTagsAndNames = newFontFace.FontFeaturesTagsAndNames();
for (const auto tagAndName : featuresTagsAndNames)
{
_FontFeaturesNames.Append(tagAndName.Value());
}
// when the font face changes, we have to tell the view model to update the font axes/features vectors
// since the new font may not have the same possible axes as the previous one
Appearance().InitializeFontAxesVector();
if (!Appearance().AreFontAxesAvailable())
{
// if the previous font had available font axes and the expander was expanded,
// at this point the expander would be set to disabled so manually collapse it
FontAxesContainer().SetExpanded(false);
FontAxesContainer().HelpText(RS_(L"Profile_FontAxesUnavailable/Text"));
}
else
{
FontAxesContainer().HelpText(RS_(L"Profile_FontAxesAvailable/Text"));
}
Appearance().InitializeFontFeaturesVector();
if (!Appearance().AreFontFeaturesAvailable())
{
// if the previous font had available font features and the expander was expanded,
// at this point the expander would be set to disabled so manually collapse it
FontFeaturesContainer().SetExpanded(false);
FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesUnavailable/Text"));
}
else
{
FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesAvailable/Text"));
}
}
void Appearances::_ViewModelChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*args*/)
@@ -348,6 +964,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
biButton.IsChecked(biButton.Tag().as<int32_t>() == biAlignmentVal);
}
FontAxesCVS().Source(Appearance().FontAxesVector());
Appearance().AreFontAxesAvailable() ? FontAxesContainer().HelpText(RS_(L"Profile_FontAxesAvailable/Text")) : FontAxesContainer().HelpText(RS_(L"Profile_FontAxesUnavailable/Text"));
FontFeaturesCVS().Source(Appearance().FontFeaturesVector());
Appearance().AreFontFeaturesAvailable() ? FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesAvailable/Text")) : FontFeaturesContainer().HelpText(RS_(L"Profile_FontFeaturesUnavailable/Text"));
_ViewModelChangedRevoker = Appearance().PropertyChanged(winrt::auto_revoke, [=](auto&&, const PropertyChangedEventArgs& args) {
const auto settingName{ args.PropertyName() };
if (settingName == L"CursorShape")
@@ -470,6 +1092,38 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
void Appearances::DeleteAxisKeyValuePair_Click(const IInspectable& sender, const RoutedEventArgs& /*e*/)
{
if (const auto& button{ sender.try_as<Controls::Button>() })
{
if (const auto& tag{ button.Tag().try_as<winrt::hstring>() })
{
Appearance().DeleteAxisKeyValuePair(tag.value());
}
}
}
void Appearances::AddNewAxisKeyValuePair_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/)
{
Appearance().AddNewAxisKeyValuePair();
}
void Appearances::DeleteFeatureKeyValuePair_Click(const IInspectable& sender, const RoutedEventArgs& /*e*/)
{
if (const auto& button{ sender.try_as<Controls::Button>() })
{
if (const auto& tag{ button.Tag().try_as<hstring>() })
{
Appearance().DeleteFeatureKeyValuePair(tag.value());
}
}
}
void Appearances::AddNewFeatureKeyValuePair_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*e*/)
{
Appearance().AddNewFeatureKeyValuePair();
}
bool Appearances::IsVintageCursor() const
{
return Appearance().CursorShape() == Core::CursorStyle::Vintage;

View File

@@ -17,26 +17,31 @@ Author(s):
#pragma once
#include "Font.g.h"
#include "AxisKeyValuePair.g.h"
#include "FeatureKeyValuePair.g.h"
#include "Appearances.g.h"
#include "AppearanceViewModel.g.h"
#include "Utils.h"
#include "ViewModelHelpers.h"
#include "SettingContainer.h"
#include <LibraryResources.h>
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct Font : FontT<Font>
{
public:
Font(std::wstring name, std::wstring localizedName, IDWriteFontFamily* family) :
_Name{ name },
_LocalizedName{ localizedName }
Font(winrt::hstring name, winrt::hstring localizedName, IDWriteFontFamily* family) :
_Name{ std::move(name) },
_LocalizedName{ std::move(localizedName) }
{
_family.copy_from(family);
}
hstring ToString() { return _LocalizedName; }
bool HasPowerlineCharacters();
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> FontAxesTagsAndNames();
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> FontFeaturesTagsAndNames();
WINRT_PROPERTY(hstring, Name);
WINRT_PROPERTY(hstring, LocalizedName);
@@ -44,6 +49,58 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
private:
winrt::com_ptr<IDWriteFontFamily> _family;
std::optional<bool> _hasPowerlineCharacters;
winrt::hstring _tagToString(DWRITE_FONT_AXIS_TAG tag);
winrt::hstring _tagToString(DWRITE_FONT_FEATURE_TAG tag);
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _fontAxesTagsAndNames;
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _fontFeaturesTagsAndNames;
};
struct AxisKeyValuePair : AxisKeyValuePairT<AxisKeyValuePair>, ViewModelHelper<AxisKeyValuePair>
{
AxisKeyValuePair(winrt::hstring axisKey, float axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, float>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap);
winrt::hstring AxisKey();
void AxisKey(winrt::hstring axisKey);
float AxisValue();
void AxisValue(float axisValue);
int32_t AxisIndex();
void AxisIndex(int32_t axisIndex);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
private:
winrt::hstring _AxisKey;
float _AxisValue;
int32_t _AxisIndex;
Windows::Foundation::Collections::IMap<winrt::hstring, float> _baseMap{ nullptr };
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _tagToNameMap{ nullptr };
};
struct FeatureKeyValuePair : FeatureKeyValuePairT<FeatureKeyValuePair>, ViewModelHelper<FeatureKeyValuePair>
{
FeatureKeyValuePair(winrt::hstring featureKey, uint32_t featureValue, const Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap);
winrt::hstring FeatureKey();
void FeatureKey(winrt::hstring featureKey);
uint32_t FeatureValue();
void FeatureValue(uint32_t featureValue);
int32_t FeatureIndex();
void FeatureIndex(int32_t featureIndex);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
private:
winrt::hstring _FeatureKey;
uint32_t _FeatureValue;
int32_t _FeatureIndex;
Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t> _baseMap{ nullptr };
Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring> _tagToNameMap{ nullptr };
};
struct AppearanceViewModel : AppearanceViewModelT<AppearanceViewModel>, ViewModelHelper<AppearanceViewModel>
@@ -69,6 +126,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Editor::ColorSchemeViewModel CurrentColorScheme();
void CurrentColorScheme(const Editor::ColorSchemeViewModel& val);
void AddNewAxisKeyValuePair();
void DeleteAxisKeyValuePair(winrt::hstring key);
void InitializeFontAxesVector();
bool AreFontAxesAvailable();
bool CanFontAxesBeAdded();
void AddNewFeatureKeyValuePair();
void DeleteFeatureKeyValuePair(winrt::hstring key);
void InitializeFontFeaturesVector();
bool AreFontFeaturesAvailable();
bool CanFontFeaturesBeAdded();
WINRT_PROPERTY(bool, IsDefault, false);
// These settings are not defined in AppearanceConfig, so we grab them
@@ -79,6 +148,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontFace);
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontSize);
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontWeight);
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontAxes);
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), FontFeatures);
OBSERVABLE_PROJECTED_SETTING(_appearance.SourceProfile().FontInfo(), EnableBuiltinGlyphs);
OBSERVABLE_PROJECTED_SETTING(_appearance, RetroTerminalEffect);
@@ -93,10 +164,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
OBSERVABLE_PROJECTED_SETTING(_appearance, IntenseTextStyle);
OBSERVABLE_PROJECTED_SETTING(_appearance, AdjustIndistinguishableColors);
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::ColorSchemeViewModel>, SchemesList, _propertyChangedHandlers, nullptr);
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::AxisKeyValuePair>, FontAxesVector, _propertyChangedHandlers, nullptr);
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::FeatureKeyValuePair>, FontFeaturesVector, _propertyChangedHandlers, nullptr);
private:
Model::AppearanceConfig _appearance;
winrt::hstring _lastBgImagePath;
Editor::AxisKeyValuePair _CreateAxisKeyValuePairHelper(winrt::hstring axisKey, float axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, float>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap);
Editor::FeatureKeyValuePair _CreateFeatureKeyValuePairHelper(winrt::hstring axisKey, uint32_t axisValue, const Windows::Foundation::Collections::IMap<winrt::hstring, uint32_t>& baseMap, const Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>& tagToNameMap);
bool _IsDefaultFeature(winrt::hstring featureTag);
};
struct Appearances : AppearancesT<Appearances>
@@ -117,6 +195,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
fire_and_forget BackgroundImage_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
void BIAlignment_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
void FontFace_SelectionChanged(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::SelectionChangedEventArgs& e);
void DeleteAxisKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
void AddNewAxisKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
void DeleteFeatureKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
void AddNewFeatureKeyValuePair_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
// manually bind FontWeight
Windows::Foundation::IInspectable CurrentFontWeight() const;
@@ -144,6 +226,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Windows::Foundation::Collections::IMap<uint16_t, Microsoft::Terminal::Settings::Editor::EnumEntry> _FontWeightMap;
Editor::EnumEntry _CustomFontWeight{ nullptr };
Windows::Foundation::Collections::IObservableVector<winrt::hstring> _FontAxesNames;
Windows::Foundation::Collections::IObservableVector<winrt::hstring> _FontFeaturesNames;
Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker _ViewModelChangedRevoker;
static void _ViewModelChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
void _UpdateWithNewViewModel();
@@ -153,4 +238,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(Appearances);
BASIC_FACTORY(AxisKeyValuePair);
BASIC_FACTORY(FeatureKeyValuePair);
}

View File

@@ -13,6 +13,8 @@ import "ColorSchemesPageViewModel.idl";
OBSERVABLE_PROJECTED_SETTING(Type, Name); \
Object Name##OverrideSource { get; }
#define COMMA ,
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass Font : Windows.Foundation.IStringable
@@ -20,6 +22,26 @@ namespace Microsoft.Terminal.Settings.Editor
String Name { get; };
String LocalizedName { get; };
Boolean HasPowerlineCharacters { get; };
Windows.Foundation.Collections.IMap<String, String> FontAxesTagsAndNames { get; };
Windows.Foundation.Collections.IMap<String, String> FontFeaturesTagsAndNames { get; };
}
// We have to make this because we cannot bind an IObservableMap to a ListView in XAML (in c++)
// So instead we make an IObservableVector of these AxisKeyValuePair objects
runtimeclass AxisKeyValuePair : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
AxisKeyValuePair(String axisKey, Single axisValue, Windows.Foundation.Collections.IMap<String, Single> baseMap, Windows.Foundation.Collections.IMap<String, String> tagToNameMap);
String AxisKey;
Single AxisValue;
Int32 AxisIndex;
}
runtimeclass FeatureKeyValuePair : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
FeatureKeyValuePair(String featureKey, UInt32 featureValue, Windows.Foundation.Collections.IMap<String, UInt32> baseMap, Windows.Foundation.Collections.IMap<String, String> tagToNameMap);
String FeatureKey;
UInt32 FeatureValue;
Int32 FeatureIndex;
}
runtimeclass AppearanceViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
@@ -37,6 +59,22 @@ namespace Microsoft.Terminal.Settings.Editor
ColorSchemeViewModel CurrentColorScheme;
Windows.Foundation.Collections.IObservableVector<ColorSchemeViewModel> SchemesList;
void AddNewAxisKeyValuePair();
void DeleteAxisKeyValuePair(String key);
void InitializeFontAxesVector();
Boolean AreFontAxesAvailable { get; };
Boolean CanFontAxesBeAdded { get; };
Windows.Foundation.Collections.IObservableVector<AxisKeyValuePair> FontAxesVector;
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.Collections.IMap<String COMMA Single>, FontAxes);
void AddNewFeatureKeyValuePair();
void DeleteFeatureKeyValuePair(String key);
void InitializeFontFeaturesVector();
Boolean AreFontFeaturesAvailable { get; };
Boolean CanFontFeaturesBeAdded { get; };
Windows.Foundation.Collections.IObservableVector<FeatureKeyValuePair> FontFeaturesVector;
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Windows.Foundation.Collections.IMap<String COMMA UInt32>, FontFeatures);
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(String, FontFace);
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Single, FontSize);
OBSERVABLE_PROJECTED_APPEARANCE_SETTING(Double, LineHeight);

View File

@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
IsTabStop="False"
mc:Ignorable="d">
@@ -34,9 +35,13 @@
x:DataType="local:ColorTableEntry">
<Border Width="8"
Height="8"
Background="{x:Bind local:Converters.ColorToBrush(Color)}"
Background="{x:Bind mtu:Converters.ColorToBrush(Color)}"
CornerRadius="1" />
</DataTemplate>
<CollectionViewSource x:Key="FontAxesCVS"
x:Name="FontAxesCVS" />
<CollectionViewSource x:Key="FontFeaturesCVS"
x:Name="FontFeaturesCVS" />
</ResourceDictionary>
</UserControl.Resources>
@@ -61,7 +66,7 @@
<Grid Grid.Column="0"
Padding="8"
VerticalAlignment="Center"
Background="{x:Bind local:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
Background="{x:Bind mtu:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
ColumnSpacing="1"
CornerRadius="2"
RowSpacing="1">
@@ -168,7 +173,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontFamily="Cascadia Code"
Foreground="{x:Bind local:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
Foreground="{x:Bind mtu:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
Text="{x:Bind Name, Mode=OneWay}"
TextTrimming="WordEllipsis" />
</Grid>
@@ -197,7 +202,7 @@
SelectedItem="{x:Bind CurrentFontFace, Mode=OneWay}"
SelectionChanged="FontFace_SelectionChanged"
Style="{StaticResource ComboBoxSettingStyle}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(ShowAllFonts), Mode=OneWay}" />
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ShowAllFonts), Mode=OneWay}" />
<ComboBox x:Uid="Profile_FontFaceBox"
ItemTemplate="{StaticResource FontFaceComboBoxItemTemplate}"
ItemsSource="{x:Bind SourceProfile.CompleteFontList, Mode=OneWay}"
@@ -278,7 +283,7 @@
Minimum="0"
TickFrequency="50"
TickPlacement="Outside"
Value="{x:Bind local:Converters.FontWeightToDouble(Appearance.FontWeight), BindBack=Appearance.SetFontWeightFromDouble, Mode=TwoWay}" />
Value="{x:Bind mtu:Converters.FontWeightToDouble(Appearance.FontWeight), BindBack=Appearance.SetFontWeightFromDouble, Mode=TwoWay}" />
<TextBlock Grid.Column="1"
Margin="10,0,0,0"
Style="{StaticResource SliderValueLabelStyle}"
@@ -286,6 +291,128 @@
</Grid>
</StackPanel>
</local:SettingContainer>
<local:SettingContainer x:Name="FontAxesContainer"
x:Uid="Profile_FontAxes"
ClearSettingValue="{x:Bind Appearance.ClearFontAxes}"
HasSettingValue="{x:Bind Appearance.HasFontAxes, Mode=OneWay}"
IsEnabled="{x:Bind Appearance.AreFontAxesAvailable, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.FontAxesOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<StackPanel Spacing="16">
<ListView IsItemClickEnabled="False"
ItemsSource="{Binding Source={StaticResource FontAxesCVS}}"
SelectionMode="None">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<CollectionViewSource x:Key="FontAxesNamesCVS"
x:Name="FontAxesNamesCVS" />
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:AxisKeyValuePair">
<Grid ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0"
IsSynchronizedWithCurrentItem="False"
ItemsSource="{Binding Source={StaticResource FontAxesNamesCVS}}"
SelectedIndex="{x:Bind AxisIndex, Mode=TwoWay}" />
<muxc:NumberBox Grid.Column="1"
Value="{x:Bind AxisValue, Mode=TwoWay}" />
<Button Grid.Column="2"
HorizontalAlignment="Right"
Click="DeleteAxisKeyValuePair_Click"
Style="{StaticResource DeleteButtonStyle}"
Tag="{x:Bind AxisKey, Mode=OneWay}">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE74D;" />
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Click="AddNewAxisKeyValuePair_Click"
IsEnabled="{x:Bind Appearance.CanFontAxesBeAdded, Mode=OneWay}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon VerticalAlignment="Bottom"
FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="Profile_AddNewFontAxis"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
</local:SettingContainer>
<local:SettingContainer x:Name="FontFeaturesContainer"
x:Uid="Profile_FontFeatures"
ClearSettingValue="{x:Bind Appearance.ClearFontFeatures}"
HasSettingValue="{x:Bind Appearance.HasFontFeatures, Mode=OneWay}"
IsEnabled="{x:Bind Appearance.AreFontFeaturesAvailable, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.FontFeaturesOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<StackPanel Spacing="16">
<ListView IsItemClickEnabled="False"
ItemsSource="{Binding Source={StaticResource FontFeaturesCVS}}"
SelectionMode="None">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<CollectionViewSource x:Key="FontFeaturesNamesCVS"
x:Name="FontFeaturesNamesCVS" />
</ListView.Resources>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:FeatureKeyValuePair">
<Grid ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0"
IsSynchronizedWithCurrentItem="False"
ItemsSource="{Binding Source={StaticResource FontFeaturesNamesCVS}}"
SelectedIndex="{x:Bind FeatureIndex, Mode=TwoWay}" />
<muxc:NumberBox Grid.Column="1"
Value="{x:Bind FeatureValue, Mode=TwoWay}" />
<Button Grid.Column="2"
HorizontalAlignment="Right"
Click="DeleteFeatureKeyValuePair_Click"
Style="{StaticResource DeleteButtonStyle}"
Tag="{x:Bind FeatureKey, Mode=OneWay}">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE74D;" />
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Click="AddNewFeatureKeyValuePair_Click"
IsEnabled="{x:Bind Appearance.CanFontFeaturesBeAdded, Mode=OneWay}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon VerticalAlignment="Bottom"
FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="Profile_AddNewFontFeature"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
</Button>
</StackPanel>
</local:SettingContainer>
<!-- Builtin Glyphs -->
<local:SettingContainer x:Uid="Profile_EnableBuiltinGlyphs"
@@ -373,15 +500,15 @@
Style="{StaticResource ExpanderSettingContainerStyle}">
<StackPanel Orientation="Vertical">
<TextBox x:Uid="Profile_BackgroundImageBox"
IsEnabled="{x:Bind local:Converters.StringsAreNotEqual('desktopWallpaper', Appearance.BackgroundImagePath), Mode=OneWay}"
IsEnabled="{x:Bind mtu:Converters.StringsAreNotEqual('desktopWallpaper', Appearance.BackgroundImagePath), Mode=OneWay}"
IsSpellCheckEnabled="False"
Style="{StaticResource TextBoxSettingStyle}"
Text="{x:Bind local:Converters.StringOrEmptyIfPlaceholder('desktopWallpaper', Appearance.BackgroundImagePath), Mode=TwoWay, BindBack=Appearance.SetBackgroundImagePath}" />
Text="{x:Bind mtu:Converters.StringOrEmptyIfPlaceholder('desktopWallpaper', Appearance.BackgroundImagePath), Mode=TwoWay, BindBack=Appearance.SetBackgroundImagePath}" />
<StackPanel Orientation="Horizontal">
<Button x:Uid="Profile_BackgroundImageBrowse"
Margin="0,10,10,0"
Click="BackgroundImage_Click"
IsEnabled="{x:Bind local:Converters.StringsAreNotEqual('desktopWallpaper', Appearance.BackgroundImagePath), Mode=OneWay}"
IsEnabled="{x:Bind mtu:Converters.StringsAreNotEqual('desktopWallpaper', Appearance.BackgroundImagePath), Mode=OneWay}"
Style="{StaticResource BrowseButtonStyle}" />
<CheckBox x:Name="UseDesktopImageCheckBox"
x:Uid="Profile_UseDesktopImage"
@@ -606,10 +733,10 @@
<Slider x:Name="BIOpacitySlider"
x:Uid="Profile_BackgroundImageOpacitySlider"
Grid.Column="0"
Value="{x:Bind local:Converters.PercentageToPercentageValue(Appearance.BackgroundImageOpacity), BindBack=Appearance.SetBackgroundImageOpacityFromPercentageValue, Mode=TwoWay}" />
Value="{x:Bind mtu:Converters.PercentageToPercentageValue(Appearance.BackgroundImageOpacity), BindBack=Appearance.SetBackgroundImageOpacityFromPercentageValue, Mode=TwoWay}" />
<TextBlock Grid.Column="1"
Style="{StaticResource SliderValueLabelStyle}"
Text="{x:Bind local:Converters.AppendPercentageSign(BIOpacitySlider.Value), Mode=OneWay}" />
Text="{x:Bind mtu:Converters.AppendPercentageSign(BIOpacitySlider.Value), Mode=OneWay}" />
</Grid>
</local:SettingContainer>
</StackPanel>

View File

@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -22,7 +23,7 @@
x:DataType="local:ColorTableEntry">
<Border Width="12"
Height="12"
Background="{x:Bind local:Converters.ColorToBrush(Color)}"
Background="{x:Bind mtu:Converters.ColorToBrush(Color)}"
CornerRadius="2" />
</DataTemplate>
@@ -89,7 +90,7 @@
Height="48"
Padding="12,11,8,8"
VerticalAlignment="Center"
Background="{x:Bind local:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
Background="{x:Bind mtu:Converters.ColorToBrush(BackgroundColor.Color), Mode=OneWay}"
ColumnSpacing="2"
CornerRadius="4"
RowSpacing="2">
@@ -195,7 +196,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
FontFamily="Cascadia Code"
Foreground="{x:Bind local:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
Foreground="{x:Bind mtu:Converters.ColorToBrush(ForegroundColor.Color), Mode=OneWay}"
Text="{x:Bind Name, Mode=OneWay}" />
</Grid>
<Border Grid.Column="1"

View File

@@ -1,30 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Converters.g.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct Converters : ConvertersT<Converters>
{
static winrt::hstring AppendPercentageSign(double value);
static winrt::Windows::UI::Text::FontWeight DoubleToFontWeight(double value);
static winrt::Windows::UI::Xaml::Media::SolidColorBrush ColorToBrush(winrt::Windows::UI::Color color);
static double FontWeightToDouble(winrt::Windows::UI::Text::FontWeight fontWeight);
static bool InvertBoolean(bool value);
static winrt::Windows::UI::Xaml::Visibility InvertedBooleanToVisibility(bool value);
static double MaxValueFromPaddingString(winrt::hstring paddingString);
static int PercentageToPercentageValue(double value);
static double PercentageValueToPercentage(double value);
static bool StringsAreNotEqual(winrt::hstring expected, winrt::hstring actual);
static winrt::Windows::UI::Xaml::Visibility StringNotEmptyToVisibility(winrt::hstring value);
static winrt::hstring StringOrEmptyIfPlaceholder(winrt::hstring placeholder, winrt::hstring value);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(Converters);
}

View File

@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -56,7 +57,7 @@
<DataTemplate x:Key="ColorTableEntryTemplate"
x:DataType="local:ColorTableEntry">
<Button AutomationProperties.Name="{x:Bind AccessibleName, Mode=OneWay}"
Background="{x:Bind local:Converters.ColorToBrush(Color), Mode=OneWay}"
Background="{x:Bind mtu:Converters.ColorToBrush(Color), Mode=OneWay}"
Style="{StaticResource ColorSchemesColorButtonStyle}"
ToolTipService.ToolTip="{x:Bind AccessibleName, Mode=OneWay}">
<Button.Flyout>
@@ -74,7 +75,7 @@
<TextBlock AutomationProperties.Name="{x:Bind Name}"
FontFamily="Cascadia Code"
FontSize="14"
Foreground="{x:Bind local:Converters.ColorToBrush(Color), Mode=OneWay}"
Foreground="{x:Bind mtu:Converters.ColorToBrush(Color), Mode=OneWay}"
Text="{x:Bind Name}"
ToolTipService.ToolTip="{x:Bind Name}" />
</DataTemplate>
@@ -90,7 +91,7 @@
MaxWidth="{StaticResource StandardControlMaxWidth}"
Margin="4"
HorizontalAlignment="Left"
Background="{x:Bind local:Converters.ColorToBrush(ViewModel.BackgroundColor.Color), Mode=OneWay}"
Background="{x:Bind mtu:Converters.ColorToBrush(ViewModel.BackgroundColor.Color), Mode=OneWay}"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="1">
<Grid.ColumnDefinitions>
@@ -198,7 +199,7 @@
</Border>
<local:SettingContainer x:Uid="ColorScheme_InboxSchemeDuplicate"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(ViewModel.IsEditable), Mode=OneWay}">
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.IsEditable), Mode=OneWay}">
<Button x:Name="DuplicateSchemeButton"
x:Uid="ColorScheme_DuplicateButton"
Click="{x:Bind ViewModel.Duplicate_Click}"

View File

@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -71,7 +72,7 @@
<!-- Always show tabs -->
<local:SettingContainer x:Uid="Globals_AlwaysShowTabs">
<ToggleSwitch IsEnabled="{x:Bind local:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}"
<ToggleSwitch IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}"
IsOn="{x:Bind ViewModel.AlwaysShowTabs, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>

View File

@@ -9,6 +9,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -22,7 +23,6 @@
x:DataType="local:EnumEntry">
<TextBlock Text="{x:Bind EnumName, Mode=OneWay}" />
</DataTemplate>
<SettingsModel:IconPathConverter x:Key="IconSourceConverter" />
<Style x:Key="LaunchSizeNumberBoxStyle"
BasedOn="{StaticResource NumberBoxSettingStyle}"
TargetType="muxc:NumberBox">
@@ -64,7 +64,7 @@
<IconSourceElement Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind Icon, Converter={StaticResource IconSourceConverter}}" />
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
<TextBlock Grid.Column="1"
Text="{x:Bind Name}" />
@@ -111,7 +111,7 @@
Width="24"
Height="24"
VerticalAlignment="Center"
IconSource="{x:Bind Icon, Converter={StaticResource IconSourceConverter}}" />
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
<TextBlock Grid.Row="0"
Grid.Column="1"
@@ -124,14 +124,14 @@
AutomationProperties.AccessibilityView="Raw"
Style="{ThemeResource SecondaryTextBlockStyle}"
Text="{x:Bind Author}"
Visibility="{x:Bind local:Converters.StringNotEmptyToVisibility(Author)}" />
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Author)}" />
<TextBlock Grid.Row="1"
Grid.Column="2"
AutomationProperties.AccessibilityView="Raw"
Style="{ThemeResource SecondaryTextBlockStyle}"
Text="{x:Bind Version}"
Visibility="{x:Bind local:Converters.StringNotEmptyToVisibility(Version)}" />
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Version)}" />
</Grid>
</DataTemplate>
@@ -248,7 +248,7 @@
Grid.Row="0"
Grid.Column="0"
Width="118"
IsEnabled="{x:Bind local:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
Style="{StaticResource LaunchPositionNumberBoxStyle}"
Value="{x:Bind ViewModel.InitialPosX, Mode=TwoWay}" />
<muxc:NumberBox x:Name="PosYBox"
@@ -256,7 +256,7 @@
Grid.Row="0"
Grid.Column="1"
Width="118"
IsEnabled="{x:Bind local:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
Style="{StaticResource LaunchPositionNumberBoxStyle}"
Value="{x:Bind ViewModel.InitialPosY, Mode=TwoWay}" />
<CheckBox x:Name="UseDefaultLaunchPositionCheckbox"

View File

@@ -602,7 +602,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
MUX::Controls::NavigationViewItem profileNavItem;
profileNavItem.Content(box_value(profile.Name()));
profileNavItem.Tag(box_value<Editor::ProfileViewModel>(profile));
profileNavItem.Icon(IconPathConverter::IconWUX(profile.EvaluatedIcon()));
profileNavItem.Icon(UI::IconPathConverter::IconWUX(profile.EvaluatedIcon()));
// Update the menu item when the icon/name changes
auto weakMenuItem{ make_weak(profileNavItem) };
@@ -612,7 +612,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
const auto& tag{ menuItem.Tag().as<Editor::ProfileViewModel>() };
if (args.PropertyName() == L"Icon")
{
menuItem.Icon(IconPathConverter::IconWUX(tag.Icon()));
menuItem.Icon(UI::IconPathConverter::IconWUX(tag.Icon()));
}
else if (args.PropertyName() == L"Name")
{

View File

@@ -8,6 +8,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:tsm="using:Microsoft.Terminal.Settings.Model"
mc:Ignorable="d">

View File

@@ -47,10 +47,6 @@
<ClInclude Include="AddProfile.h">
<DependentUpon>AddProfile.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Converters.h">
<DependentUpon>Converters.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="EnumEntry.h">
<DependentUpon>EnumEntry.idl</DependentUpon>
</ClInclude>
@@ -194,10 +190,6 @@
<ClCompile Include="AddProfile.cpp">
<DependentUpon>AddProfile.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Converters.cpp">
<DependentUpon>Converters.idl</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="GlobalAppearance.cpp">
<DependentUpon>GlobalAppearance.xaml</DependentUpon>
</ClCompile>
@@ -294,7 +286,6 @@
<DependentUpon>AddProfile.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="Converters.idl" />
<Midl Include="EnumEntry.idl" />
<Midl Include="GlobalAppearance.idl">
<DependentUpon>GlobalAppearance.xaml</DependentUpon>
@@ -377,6 +368,9 @@
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\UIHelpers\UIHelpers.vcxproj">
<Project>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</Project>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj">
<Private>false</Private>
</ProjectReference>

View File

@@ -26,9 +26,6 @@
<Midl Include="GlobalAppearanceViewModel.idl" />
<Midl Include="LaunchViewModel.idl" />
<Midl Include="EnumEntry.idl" />
<Midl Include="Converters.idl">
<Filter>Converters</Filter>
</Midl>
<Midl Include="SettingContainer.idl" />
</ItemGroup>
<ItemGroup>
@@ -53,4 +50,4 @@
<Page Include="AddProfile.xaml" />
<Page Include="KeyChordListener.xaml" />
</ItemGroup>
</Project>
</Project>

View File

@@ -22,7 +22,7 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
static Editor::Font _FontObjectForDWriteFont(IDWriteFontFamily* family);
static Editor::Font fontObjectForDWriteFont(IDWriteFontFamily* family, const wchar_t* locale);
Windows::Foundation::Collections::IObservableVector<Editor::Font> ProfileViewModel::_MonospaceFontList{ nullptr };
Windows::Foundation::Collections::IObservableVector<Editor::Font> ProfileViewModel::_FontList{ nullptr };
@@ -119,6 +119,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
wil::com_ptr<IDWriteFontCollection> fontCollection;
THROW_IF_FAILED(factory->GetSystemFontCollection(fontCollection.addressof(), TRUE));
wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
if (!GetUserDefaultLocaleName(&localeName[0], LOCALE_NAME_MAX_LENGTH))
{
memcpy(&localeName[0], L"en-US", 12);
}
for (UINT32 i = 0; i < fontCollection->GetFontFamilyCount(); ++i)
{
try
@@ -128,7 +134,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
THROW_IF_FAILED(fontCollection->GetFontFamily(i, fontFamily.put()));
// construct a font entry for tracking
if (const auto fontEntry{ _FontObjectForDWriteFont(fontFamily.get()) })
if (const auto fontEntry{ fontObjectForDWriteFont(fontFamily.get(), &localeName[0]) })
{
// check if the font is monospaced
try
@@ -176,6 +182,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
Editor::Font fallbackFont{ nullptr };
try
{
if (!CompleteFontList())
{
UpdateFontList();
}
const auto& currentFontList{ CompleteFontList() };
for (const auto& font : currentFontList)
{
@@ -195,65 +205,43 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return fallbackFont;
}
static Editor::Font _FontObjectForDWriteFont(IDWriteFontFamily* family)
static winrt::hstring getLocalizedStringByIndex(IDWriteLocalizedStrings* strings, UINT32 index)
{
// used for the font's name as an identifier (i.e. text block's font family property)
std::wstring nameID;
UINT32 nameIDIndex;
UINT32 length = 0;
THROW_IF_FAILED(strings->GetStringLength(index, &length));
// used for the font's localized name
std::wstring localizedName;
UINT32 localizedNameIndex;
winrt::impl::hstring_builder builder{ length };
THROW_IF_FAILED(strings->GetString(index, builder.data(), length + 1));
// get the font's localized names
winrt::com_ptr<IDWriteLocalizedStrings> localizedFamilyNames;
THROW_IF_FAILED(family->GetFamilyNames(localizedFamilyNames.put()));
return builder.to_hstring();
}
// use our current locale to find the localized name
auto exists{ FALSE };
HRESULT hr;
wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
if (GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH))
static UINT32 getLocalizedStringIndex(IDWriteLocalizedStrings* strings, const wchar_t* locale, UINT32 fallback)
{
UINT32 index;
BOOL exists;
if (FAILED(strings->FindLocaleName(locale, &index, &exists)) || !exists)
{
hr = localizedFamilyNames->FindLocaleName(localeName, &localizedNameIndex, &exists);
}
if (SUCCEEDED(hr) && !exists)
{
// if we can't find the font for our locale, fallback to the en-us one
// Source: https://docs.microsoft.com/en-us/windows/win32/api/dwrite/nf-dwrite-idwritelocalizedstrings-findlocalename
hr = localizedFamilyNames->FindLocaleName(L"en-us", &localizedNameIndex, &exists);
}
if (!exists)
{
// failed to find the correct locale, using the first one
localizedNameIndex = 0;
index = fallback;
}
return index;
}
// get the localized name
UINT32 nameLength;
THROW_IF_FAILED(localizedFamilyNames->GetStringLength(localizedNameIndex, &nameLength));
static Editor::Font fontObjectForDWriteFont(IDWriteFontFamily* family, const wchar_t* locale)
{
wil::com_ptr<IDWriteLocalizedStrings> familyNames;
THROW_IF_FAILED(family->GetFamilyNames(familyNames.addressof()));
localizedName.resize(nameLength);
THROW_IF_FAILED(localizedFamilyNames->GetString(localizedNameIndex, localizedName.data(), nameLength + 1));
// If en-us is missing we fall back to whatever is at index 0.
const auto ci = getLocalizedStringIndex(familyNames.get(), L"en-us", 0);
// If our locale is missing we fall back to en-us.
const auto li = getLocalizedStringIndex(familyNames.get(), locale, ci);
// now get the nameID
hr = localizedFamilyNames->FindLocaleName(L"en-us", &nameIDIndex, &exists);
if (FAILED(hr) || !exists)
{
// failed to find it, using the first one
nameIDIndex = 0;
}
auto canonical = getLocalizedStringByIndex(familyNames.get(), ci);
// If the canonical/localized indices are the same, there's no need to get the other string.
auto localized = ci == li ? canonical : getLocalizedStringByIndex(familyNames.get(), li);
// get the nameID
THROW_IF_FAILED(localizedFamilyNames->GetStringLength(nameIDIndex, &nameLength));
nameID.resize(nameLength);
THROW_IF_FAILED(localizedFamilyNames->GetString(nameIDIndex, nameID.data(), nameLength + 1));
if (!nameID.empty() && !localizedName.empty())
{
return make<Font>(nameID, localizedName, family);
}
return nullptr;
return make<Font>(std::move(canonical), std::move(localized), family);
}
winrt::guid ProfileViewModel::OriginalProfileGuid() const noexcept

View File

@@ -49,7 +49,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void SetAcrylicOpacityPercentageValue(double value)
{
Opacity(winrt::Microsoft::Terminal::Settings::Editor::Converters::PercentageValueToPercentage(value));
Opacity(winrt::Microsoft::Terminal::UI::Converters::PercentageValueToPercentage(value));
};
void SetPadding(double value)

View File

@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -78,10 +79,10 @@
<Slider x:Name="OpacitySlider"
x:Uid="Profile_OpacitySlider"
Grid.Column="0"
Value="{x:Bind local:Converters.PercentageToPercentageValue(Profile.Opacity), BindBack=Profile.SetAcrylicOpacityPercentageValue, Mode=TwoWay}" />
Value="{x:Bind mtu:Converters.PercentageToPercentageValue(Profile.Opacity), BindBack=Profile.SetAcrylicOpacityPercentageValue, Mode=TwoWay}" />
<TextBlock Grid.Column="1"
Style="{StaticResource SliderValueLabelStyle}"
Text="{x:Bind local:Converters.AppendPercentageSign(OpacitySlider.Value), Mode=OneWay}" />
Text="{x:Bind mtu:Converters.AppendPercentageSign(OpacitySlider.Value), Mode=OneWay}" />
</Grid>
</StackPanel>
</local:SettingContainer>
@@ -116,7 +117,7 @@
<Slider x:Name="PaddingSlider"
x:Uid="Profile_PaddingSlider"
Grid.Column="0"
Value="{x:Bind local:Converters.MaxValueFromPaddingString(Profile.Padding), BindBack=Profile.SetPadding, Mode=TwoWay}" />
Value="{x:Bind mtu:Converters.MaxValueFromPaddingString(Profile.Padding), BindBack=Profile.SetPadding, Mode=TwoWay}" />
<TextBlock Grid.Column="1"
Style="{StaticResource SliderValueLabelStyle}"
Text="{Binding ElementName=PaddingSlider, Path=Value, Mode=OneWay}" />
@@ -144,7 +145,7 @@
Margin="10,0,0,0"
Click="CreateUnfocusedAppearance_Click"
Style="{StaticResource BaseButtonStyle}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(Profile.HasUnfocusedAppearance), Mode=OneWay}">
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.HasUnfocusedAppearance), Mode=OneWay}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon Margin="0,3,0,0"

View File

@@ -9,6 +9,7 @@
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:mtu="using:Microsoft.Terminal.UI"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
@@ -43,7 +44,7 @@
<local:SettingContainer x:Uid="Profile_Name"
CurrentValue="{x:Bind Profile.Name, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
<TextBox Style="{StaticResource TextBoxSettingStyle}"
Text="{x:Bind Profile.Name, Mode=TwoWay}" />
</local:SettingContainer>
@@ -56,7 +57,7 @@
HasSettingValue="{x:Bind Profile.HasCommandline, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.CommandlineOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
<StackPanel>
<TextBox x:Uid="Profile_CommandlineBox"
IsSpellCheckEnabled="False"
@@ -108,16 +109,16 @@
<StackPanel>
<TextBox x:Uid="Profile_IconBox"
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
IsEnabled="{x:Bind local:Converters.InvertBoolean(Profile.HideIcon), Mode=OneWay}"
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.HideIcon), Mode=OneWay}"
IsSpellCheckEnabled="False"
Style="{StaticResource TextBoxSettingStyle}"
Text="{x:Bind Profile.Icon, Mode=TwoWay}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(Profile.HideIcon), Mode=OneWay}" />
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.HideIcon), Mode=OneWay}" />
<Button x:Uid="Profile_IconBrowse"
Margin="0,10,0,0"
Click="Icon_Click"
Style="{StaticResource BrowseButtonStyle}"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(Profile.HideIcon), Mode=OneWay}" />
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.HideIcon), Mode=OneWay}" />
<CheckBox x:Name="HideIconCheckbox"
x:Uid="Profile_HideIconCheckbox"
Margin="0,5,0,0"
@@ -147,7 +148,7 @@
<!-- Hidden -->
<local:SettingContainer x:Uid="Profile_Hidden"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind Profile.Hidden, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
</local:SettingContainer>

View File

@@ -722,6 +722,14 @@
<value>Browse...</value>
<comment>Button label that opens a file picker in a new window. The "..." is standard to mean it will open a new window.</comment>
</data>
<data name="Profile_AddNewFontAxis.Text" xml:space="preserve">
<value>Add new</value>
<comment>Button label that adds a new font axis for the current font.</comment>
</data>
<data name="Profile_AddNewFontFeature.Text" xml:space="preserve">
<value>Add new</value>
<comment>Button label that adds a new font feature for the current font.</comment>
</data>
<data name="Profile_BackgroundImageOpacitySlider.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
<value>Background image opacity</value>
<comment>Name for a control to choose the opacity of the image presented on the background of the app.</comment>
@@ -922,6 +930,30 @@
<value>Sets the weight (lightness or heaviness of the strokes) for the given font.</value>
<comment>A description for what the "font weight" setting does. Presented near "Profile_FontWeight".</comment>
</data>
<data name="Profile_FontAxes.Header" xml:space="preserve">
<value>Variable font axes</value>
<comment>Header for a control to allow editing the font axes.</comment>
</data>
<data name="Profile_FontAxesAvailable.Text" xml:space="preserve">
<value>Add or remove font axes for the given font.</value>
<comment>A description for what the "font axes" setting does. Presented near "Profile_FontAxes".</comment>
</data>
<data name="Profile_FontAxesUnavailable.Text" xml:space="preserve">
<value>The selected font has no variable font axes.</value>
<comment>A description provided when the font axes setting is disabled. Presented near "Profile_FontAxes".</comment>
</data>
<data name="Profile_FontFeatures.Header" xml:space="preserve">
<value>Font features</value>
<comment>Header for a control to allow editing the font features.</comment>
</data>
<data name="Profile_FontFeaturesAvailable.Text" xml:space="preserve">
<value>Add or remove font features for the given font.</value>
<comment>A description for what the "font features" setting does. Presented near "Profile_FontFeatures".</comment>
</data>
<data name="Profile_FontFeaturesUnavailable.Text" xml:space="preserve">
<value>The selected font has no font features.</value>
<comment>A description provided when the font features setting is disabled. Presented near "Profile_FontFeatures".</comment>
</data>
<data name="Profile_General.Header" xml:space="preserve">
<value>General</value>
<comment>Header for a sub-page of profile settings focused on more general scenarios.</comment>
@@ -1238,6 +1270,110 @@
<value>Thin</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontFeature_rlig" xml:space="preserve">
<value>Required ligatures</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_locl" xml:space="preserve">
<value>Localized forms</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_ccmp" xml:space="preserve">
<value>Composition/decomposition</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_calt" xml:space="preserve">
<value>Contextual alternates</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_liga" xml:space="preserve">
<value>Standard ligatures</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_clig" xml:space="preserve">
<value>Contextual ligatures</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_rvrn" xml:space="preserve">
<value>Required variation alternates</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_kern" xml:space="preserve">
<value>Kerning</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_mark" xml:space="preserve">
<value>Mark positioning</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_mkmk" xml:space="preserve">
<value>Mark to mark positioning</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_dist" xml:space="preserve">
<value>Distance</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_aalt" xml:space="preserve">
<value>Access all alternates</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_case" xml:space="preserve">
<value>Case sensitive forms</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_dnom" xml:space="preserve">
<value>Denominator</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_fina" xml:space="preserve">
<value>Terminal forms</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_frac" xml:space="preserve">
<value>Fractions</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_init" xml:space="preserve">
<value>Initial forms</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_medi" xml:space="preserve">
<value>Medial forms</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_numr" xml:space="preserve">
<value>Numerator</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_ordn" xml:space="preserve">
<value>Ordinals</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_rclt" xml:space="preserve">
<value>Required contextual alternates</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_sinf" xml:space="preserve">
<value>Scientific inferiors</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_subs" xml:space="preserve">
<value>Subscript</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_sups" xml:space="preserve">
<value>Superscript</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_zero" xml:space="preserve">
<value>Slashed zero</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Profile_FontFeature_abvm" xml:space="preserve">
<value>Above-base mark positioning</value>
<comment>This is the formal name for a font feature.</comment>
</data>
<data name="Globals_LaunchSize.Header" xml:space="preserve">
<value>Launch size</value>
<comment>Header for a group of settings that control the size of the app. Presented near "Globals_InitialCols" and "Globals_InitialRows".</comment>

View File

@@ -185,6 +185,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}
void SettingContainer::SetExpanded(bool expanded)
{
if (const auto& child{ GetTemplateChild(L"Expander") })
{
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
{
expander.IsExpanded(expanded);
}
}
}
// Method Description:
// - Updates the override system visibility and text
// Arguments:

View File

@@ -29,6 +29,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
void OnApplyTemplate();
void SetExpanded(bool expanded);
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Header);
DEPENDENCY_PROPERTY(hstring, HelpText);
DEPENDENCY_PROPERTY(hstring, CurrentValue);

View File

@@ -7,6 +7,8 @@ namespace Microsoft.Terminal.Settings.Editor
{
SettingContainer();
void SetExpanded(Boolean expanded);
IInspectable Header;
static Windows.UI.Xaml.DependencyProperty HeaderProperty { get; };

View File

@@ -49,6 +49,7 @@
#include <winrt/Microsoft.Terminal.Core.h>
#include <winrt/Microsoft.Terminal.Control.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
#include <winrt/Microsoft.Terminal.UI.h>
#include <shlobj.h>
#include <shobjidl_core.h>

View File

@@ -20,7 +20,7 @@ Author(s):
#include "Command.h"
// fwdecl unittest classes
namespace SettingsModelLocalTests
namespace SettingsModelUnitTests
{
class KeyBindingsTests;
class DeserializationTests;
@@ -123,8 +123,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// than is necessary to be serialized.
std::unordered_map<InternalActionID, Model::Command> _MaskingActions;
friend class SettingsModelLocalTests::KeyBindingsTests;
friend class SettingsModelLocalTests::DeserializationTests;
friend class SettingsModelLocalTests::TerminalSettingsTests;
friend class SettingsModelUnitTests::KeyBindingsTests;
friend class SettingsModelUnitTests::DeserializationTests;
friend class SettingsModelUnitTests::TerminalSettingsTests;
};
}

View File

@@ -25,7 +25,7 @@ Author(s):
#include "SettingsTypes.h"
// fwdecl unittest classes
namespace SettingsModelLocalTests
namespace SettingsModelUnitTests
{
class DeserializationTests;
class CommandTests;
@@ -87,8 +87,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
static std::vector<Model::Command> _expandCommand(Command* const expandable,
Windows::Foundation::Collections::IVectorView<Model::Profile> profiles,
Windows::Foundation::Collections::IVectorView<Model::ColorScheme> schemes);
friend class SettingsModelLocalTests::DeserializationTests;
friend class SettingsModelLocalTests::CommandTests;
friend class SettingsModelUnitTests::DeserializationTests;
friend class SettingsModelUnitTests::CommandTests;
};
}

View File

@@ -30,6 +30,28 @@ winrt::com_ptr<FontConfig> FontConfig::CopyFontInfo(const FontConfig* source, wi
MTSM_FONT_SETTINGS(FONT_SETTINGS_COPY)
#undef FONT_SETTINGS_COPY
// We cannot simply copy the font axes and features with `fontInfo->_FontAxes = source->_FontAxes;`
// since that'll just create a reference; we have to manually copy the values.
if (source->_FontAxes)
{
std::map<winrt::hstring, float> fontAxes;
for (const auto keyValuePair : source->_FontAxes.value())
{
fontAxes.insert(std::pair<winrt::hstring, float>(keyValuePair.Key(), keyValuePair.Value()));
}
fontInfo->_FontAxes = winrt::single_threaded_map(std::move(fontAxes));
}
if (source->_FontFeatures)
{
std::map<winrt::hstring, uint32_t> fontFeatures;
for (const auto keyValuePair : source->_FontFeatures.value())
{
fontFeatures.insert(std::pair<winrt::hstring, uint32_t>(keyValuePair.Key(), keyValuePair.Value()));
}
fontInfo->_FontFeatures = winrt::single_threaded_map(std::move(fontFeatures));
}
return fontInfo;
}

View File

@@ -27,7 +27,7 @@ Author(s):
#include "RemainingProfilesEntry.h"
// fwdecl unittest classes
namespace SettingsModelLocalTests
namespace SettingsModelUnitTests
{
class DeserializationTests;
class ColorSchemeTests;

View File

@@ -1,29 +0,0 @@
#pragma once
#include "IconPathConverter.g.h"
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
struct IconPathConverter : IconPathConverterT<IconPathConverter>
{
IconPathConverter() = default;
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& targetType,
const Windows::Foundation::IInspectable& parameter,
const hstring& language);
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& targetType,
const Windows::Foundation::IInspectable& parameter,
const hstring& language);
static Windows::UI::Xaml::Controls::IconElement IconWUX(const winrt::hstring& iconPath);
static Microsoft::UI::Xaml::Controls::IconSource IconSourceMUX(const winrt::hstring& iconPath, const bool convertToGrayscale);
};
}
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
{
BASIC_FACTORY(IconPathConverter);
}

View File

@@ -1,22 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Model
{
// See https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-quickstart
// We use the default attribute to declare IValueConverter as the default
// interface. In the listing, IconPathConverter has only a
// constructor, and no methods, so no default interface is generated for it.
// The default attribute is optimal if you won't be adding instance members
// to IconPathConverter, because no QueryInterface will be
// required to call the IValueConverter methods
runtimeclass IconPathConverter : [default] Windows.UI.Xaml.Data.IValueConverter
{
IconPathConverter();
static Windows.UI.Xaml.Controls.IconElement IconWUX(String path);
static Microsoft.UI.Xaml.Controls.IconSource IconSourceMUX(String path, Boolean convertToGrayscale);
};
}

View File

@@ -46,9 +46,6 @@
<ClInclude Include="DefaultTerminal.h">
<DependentUpon>DefaultTerminal.idl</DependentUpon>
</ClInclude>
<ClInclude Include="IconPathConverter.h">
<DependentUpon>IconPathConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="ActionArgs.h">
<DependentUpon>ActionArgs.idl</DependentUpon>
@@ -122,9 +119,6 @@
<ClCompile Include="DefaultTerminal.cpp">
<DependentUpon>DefaultTerminal.idl</DependentUpon>
</ClCompile>
<ClCompile Include="IconPathConverter.cpp">
<DependentUpon>IconPathConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="init.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
@@ -229,7 +223,6 @@
<Midl Include="Command.idl" />
<Midl Include="DefaultTerminal.idl" />
<Midl Include="GlobalAppSettings.idl" />
<Midl Include="IconPathConverter.idl" />
<Midl Include="Profile.idl" />
<Midl Include="EnumMappings.idl" />
<Midl Include="TerminalSettings.idl" />
@@ -316,7 +309,7 @@
<DisableSpecificWarnings>4702;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>WindowsApp.lib;user32.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>%(AdditionalDependencies);user32.lib</AdditionalDependencies>
</Link>
<Reference>
<Private>false</Private>

View File

@@ -34,7 +34,6 @@
<Filter>json</Filter>
</ClCompile>
<ClCompile Include="init.cpp" />
<ClCompile Include="IconPathConverter.cpp" />
<ClCompile Include="DefaultTerminal.cpp" />
<ClCompile Include="FileUtils.cpp" />
<ClCompile Include="VisualStudioGenerator.cpp">
@@ -83,7 +82,6 @@
</ClInclude>
<ClInclude Include="IInheritable.h" />
<ClInclude Include="MTSMSettings.h" />
<ClInclude Include="IconPathConverter.h" />
<ClInclude Include="DefaultTerminal.h" />
<ClInclude Include="FileUtils.h" />
<ClInclude Include="HashUtils.h" />
@@ -113,7 +111,6 @@
<Midl Include="CascadiaSettings.idl" />
<Midl Include="KeyChordSerialization.idl" />
<Midl Include="EnumMappings.idl" />
<Midl Include="IconPathConverter.idl" />
<Midl Include="TerminalSettings.idl" />
<Midl Include="AppearanceConfig.idl" />
<Midl Include="IAppearanceConfig.idl" />

View File

@@ -317,7 +317,11 @@ Json::Value Profile::ToJson() const
JsonUtils::SetValueForKey(json, GuidKey, writeBasicSettings ? Guid() : _Guid);
JsonUtils::SetValueForKey(json, HiddenKey, writeBasicSettings ? Hidden() : _Hidden);
JsonUtils::SetValueForKey(json, SourceKey, writeBasicSettings ? Source() : _Source);
JsonUtils::SetValueForKey(json, IconKey, writeBasicSettings ? Icon() : _Icon);
// Recall: Icon isn't actually a setting in the MTSM_PROFILE_SETTINGS. We
// defined it manually in Profile, so make sure we only serialize the Icon
// if the user actually changed it here.
JsonUtils::SetValueForKey(json, IconKey, (writeBasicSettings && HasIcon()) ? Icon() : _Icon);
// PermissiveStringConverter is unnecessary for serialization
JsonUtils::SetValueForKey(json, PaddingKey, _Padding);

View File

@@ -54,7 +54,7 @@ Author(s):
#include "FontConfig.h"
// fwdecl unittest classes
namespace SettingsModelLocalTests
namespace SettingsModelUnitTests
{
class DeserializationTests;
class ProfileTests;
@@ -147,10 +147,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring _evaluateIcon() const;
friend class SettingsModelLocalTests::DeserializationTests;
friend class SettingsModelLocalTests::ProfileTests;
friend class SettingsModelLocalTests::ColorSchemeTests;
friend class SettingsModelLocalTests::KeyBindingsTests;
friend class SettingsModelUnitTests::DeserializationTests;
friend class SettingsModelUnitTests::ProfileTests;
friend class SettingsModelUnitTests::ColorSchemeTests;
friend class SettingsModelUnitTests::KeyBindingsTests;
friend class TerminalAppUnitTests::DynamicProfileTests;
friend class TerminalAppUnitTests::JsonTests;
};

View File

@@ -25,7 +25,7 @@ using IFontFeatureMap = winrt::Windows::Foundation::Collections::IMap<winrt::hst
using IEnvironmentVariableMap = winrt::Windows::Foundation::Collections::IMap<winrt::hstring, winrt::hstring>;
// fwdecl unittest classes
namespace SettingsModelLocalTests
namespace SettingsModelUnitTests
{
class TerminalSettingsTests;
}
@@ -182,7 +182,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
const Windows::Foundation::Collections::IMapView<hstring, Microsoft::Terminal::Settings::Model::ColorScheme>& schemes,
const winrt::Microsoft::Terminal::Settings::Model::Theme currentTheme);
friend class SettingsModelLocalTests::TerminalSettingsTests;
friend class SettingsModelUnitTests::TerminalSettingsTests;
};
}

View File

@@ -37,7 +37,6 @@
<ClInclude Include="../KeyMapping.h" />
<ClInclude Include="../Profile.h" />
<ClInclude Include="../TerminalWarnings.h" />
<ClInclude Include="../IconPathConverter.h" />
<ClInclude Include="../NewTabMenuEntry.h" />
<ClInclude Include="../SeparatorEntry.h">
<DependentUpon>../NewTabMenuEntry.h</DependentUpon>
@@ -130,7 +129,7 @@
<AdditionalIncludeDirectories>$(OpenConsoleDir)\dep\jsoncpp\json;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>User32.lib;WindowsApp.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>%(AdditionalDependencies);user32.lib</AdditionalDependencies>
<!-- TSM Lib contains a DllMain that we need to force the use of. -->
<AdditionalOptions Condition="'$(Platform)'=='Win32'">/INCLUDE:_DllMain@12 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)'!='Win32'">/INCLUDE:DllMain %(AdditionalOptions)</AdditionalOptions>

View File

@@ -29,8 +29,6 @@
#include <winrt/Windows.ApplicationModel.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.Imaging.h>
#include <Windows.Graphics.Imaging.Interop.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.System.h>
@@ -38,7 +36,6 @@
#include <winrt/Windows.UI.ViewManagement.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Media.h>
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>

View File

@@ -1,18 +1,18 @@
#include "pch.h"
#include "Converters.h"
#if __has_include("Converters.g.cpp")
#include "Converters.g.cpp"
#endif
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
#pragma warning(disable : 26497) // We will make these functions constexpr, as they are part of an ABI boundary.
#pragma warning(disable : 26440) // The function ... can be declared as noexcept.
namespace winrt::Microsoft::Terminal::UI::implementation
{
winrt::hstring Converters::AppendPercentageSign(double value)
{
const auto number{ value };
return to_hstring((int)number) + L"%";
return to_hstring(gsl::narrow_cast<uint32_t>(std::lrint(value))) + L"%";
}
winrt::Windows::UI::Xaml::Media::SolidColorBrush Converters::ColorToBrush(winrt::Windows::UI::Color color)
winrt::Windows::UI::Xaml::Media::SolidColorBrush Converters::ColorToBrush(const winrt::Windows::UI::Color& color)
{
return Windows::UI::Xaml::Media::SolidColorBrush(color);
}
@@ -22,7 +22,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return winrt::Windows::UI::Text::FontWeight{ base::ClampedNumeric<uint16_t>(value) };
}
double Converters::FontWeightToDouble(winrt::Windows::UI::Text::FontWeight fontWeight)
double Converters::FontWeightToDouble(const winrt::Windows::UI::Text::FontWeight& fontWeight)
{
return fontWeight.Weight;
}
@@ -37,7 +37,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return value ? winrt::Windows::UI::Xaml::Visibility::Collapsed : winrt::Windows::UI::Xaml::Visibility::Visible;
}
double Converters::MaxValueFromPaddingString(winrt::hstring paddingString)
double Converters::MaxValueFromPaddingString(const winrt::hstring& paddingString)
{
const auto singleCharDelim = L',';
std::wstringstream tokenStream(paddingString.c_str());
@@ -85,11 +85,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return base::ClampDiv<double, double>(value, 100);
}
bool Converters::StringsAreNotEqual(winrt::hstring expected, winrt::hstring actual)
bool Converters::StringsAreNotEqual(const winrt::hstring& expected, const winrt::hstring& actual)
{
return expected != actual;
}
winrt::Windows::UI::Xaml::Visibility Converters::StringNotEmptyToVisibility(winrt::hstring value)
winrt::Windows::UI::Xaml::Visibility Converters::StringNotEmptyToVisibility(const winrt::hstring& value)
{
return value.empty() ? winrt::Windows::UI::Xaml::Visibility::Collapsed : winrt::Windows::UI::Xaml::Visibility::Visible;
}
@@ -101,7 +101,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// - value - the value string.
// Return Value:
// - The value string, unless it matches the placeholder in which case the empty string.
winrt::hstring Converters::StringOrEmptyIfPlaceholder(winrt::hstring placeholder, winrt::hstring value)
winrt::hstring Converters::StringOrEmptyIfPlaceholder(const winrt::hstring& placeholder, const winrt::hstring& value)
{
return placeholder == value ? L"" : value;
}

View File

@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Converters.g.h"
namespace winrt::Microsoft::Terminal::UI::implementation
{
struct Converters
{
Converters() = default;
static winrt::hstring AppendPercentageSign(double value);
static winrt::Windows::UI::Text::FontWeight DoubleToFontWeight(double value);
static winrt::Windows::UI::Xaml::Media::SolidColorBrush ColorToBrush(const winrt::Windows::UI::Color& color);
static double FontWeightToDouble(const winrt::Windows::UI::Text::FontWeight& fontWeight);
static bool InvertBoolean(bool value);
static winrt::Windows::UI::Xaml::Visibility InvertedBooleanToVisibility(bool value);
static double MaxValueFromPaddingString(const winrt::hstring& paddingString);
static int PercentageToPercentageValue(double value);
static double PercentageValueToPercentage(double value);
static bool StringsAreNotEqual(const winrt::hstring& expected, const winrt::hstring& actual);
static winrt::Windows::UI::Xaml::Visibility StringNotEmptyToVisibility(const winrt::hstring& value);
static winrt::hstring StringOrEmptyIfPlaceholder(const winrt::hstring& placeholder, const winrt::hstring& value);
};
}
namespace winrt::Microsoft::Terminal::UI::factory_implementation
{
struct Converters : ConvertersT<Converters, implementation::Converters>
{
};
}

View File

@@ -1,24 +1,30 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
namespace Microsoft.Terminal.UI
{
[bindable]
[default_interface] static runtimeclass Converters
static runtimeclass Converters
{
// Booleans
static Boolean InvertBoolean(Boolean value);
static Windows.UI.Xaml.Visibility InvertedBooleanToVisibility(Boolean value);
// Numbers
static Int32 PercentageToPercentageValue(Double value);
static Double PercentageValueToPercentage(Double value);
// Strings
static Boolean StringsAreNotEqual(String expected, String actual);
static Windows.UI.Xaml.Visibility StringNotEmptyToVisibility(String value);
static String StringOrEmptyIfPlaceholder(String placeholder, String value);
// Misc
static String AppendPercentageSign(Double value);
static Windows.UI.Text.FontWeight DoubleToFontWeight(Double value);
static Windows.UI.Xaml.Media.SolidColorBrush ColorToBrush(Windows.UI.Color color);
static Double FontWeightToDouble(Windows.UI.Text.FontWeight fontWeight);
static Boolean InvertBoolean(Boolean value);
static Windows.UI.Xaml.Visibility InvertedBooleanToVisibility(Boolean value);
static Double MaxValueFromPaddingString(String paddingString);
static Int32 PercentageToPercentageValue(Double value);
static Double PercentageValueToPercentage(Double value);
static Boolean StringsAreNotEqual(String expected, String actual);
static Windows.UI.Xaml.Visibility StringNotEmptyToVisibility(String value);
static String StringOrEmptyIfPlaceholder(String placeholder, String value);
}
}

View File

@@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.UI
{
[uuid("0ddf4edc-3fda-4dee-97ca-a417ee3dd510")]
interface IDirectKeyListener {
Boolean OnDirectKeyEvent(UInt32 vkey, UInt8 scanCode, Boolean down);
}
}

View File

@@ -19,7 +19,7 @@ using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::Graphics::Imaging;
using namespace winrt::Windows::Storage::Streams;
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
namespace winrt::Microsoft::Terminal::UI::implementation
{
// These are templates that help us figure out which BitmapIconSource/FontIconSource to use for a given IconSource.
// We have to do this because some of our code still wants to use WUX/MUX IconSources.
@@ -95,7 +95,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return nullptr;
}
_TIL_INLINEPREFIX winrt::hstring _expandIconPath(hstring iconPath)
static winrt::hstring _expandIconPath(const hstring& iconPath)
{
if (iconPath.empty())
{
@@ -140,7 +140,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
try
{
typename FontIconSource<TIconSource>::type icon;
const auto ch = iconPath[0];
const auto ch = til::at(iconPath, 0);
// The range of MDL2 Icons isn't explicitly defined, but
// we're using this based off the table on:
@@ -178,51 +178,25 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return iconSource;
}
// Method Description:
// - Attempt to convert something into another type. For the
// IconPathConverter, we support a variety of icons:
// * If the icon is a path to an image, we'll use that.
// * If it isn't, then we'll try and use the text as a FontIcon. If the
// character is in the range of symbols reserved for the Segoe MDL2
// Asserts, well treat it as such. Otherwise, we'll default to a Sego
// UI icon, so things like emoji will work.
// - MUST BE CALLED ON THE UI THREAD.
// Arguments:
// - value: the input object to attempt to convert into an IconSource.
// Return Value:
// - Visible if the object was a string and wasn't the empty string.
Foundation::IInspectable IconPathConverter::Convert(const Foundation::IInspectable& value,
const Windows::UI::Xaml::Interop::TypeName& /* targetType */,
const Foundation::IInspectable& /* parameter */,
const hstring& /* language */)
{
const auto& iconPath = winrt::unbox_value_or<winrt::hstring>(value, L"");
return _getIconSource<Controls::IconSource>(iconPath, false);
}
// unused for one-way bindings
Foundation::IInspectable IconPathConverter::ConvertBack(const Foundation::IInspectable& /* value */,
const Windows::UI::Xaml::Interop::TypeName& /* targetType */,
const Foundation::IInspectable& /* parameter */,
const hstring& /* language */)
{
throw hresult_not_implemented();
}
Windows::UI::Xaml::Controls::IconSource _IconSourceWUX(hstring path)
Windows::UI::Xaml::Controls::IconSource IconPathConverter::IconSourceWUX(const hstring& path)
{
// * If the icon is a path to an image, we'll use that.
// * If it isn't, then we'll try and use the text as a FontIcon. If the
// character is in the range of symbols reserved for the Segoe MDL2
// Asserts, well treat it as such. Otherwise, we'll default to a Segoe
// UI icon, so things like emoji will work.
return _getIconSource<Windows::UI::Xaml::Controls::IconSource>(path, false);
}
Microsoft::UI::Xaml::Controls::IconSource _IconSourceMUX(hstring path, bool monochrome)
static Microsoft::UI::Xaml::Controls::IconSource _IconSourceMUX(const hstring& path, bool monochrome)
{
return _getIconSource<Microsoft::UI::Xaml::Controls::IconSource>(path, monochrome);
}
SoftwareBitmap _convertToSoftwareBitmap(HICON hicon,
BitmapPixelFormat pixelFormat,
BitmapAlphaMode alphaMode,
IWICImagingFactory* imagingFactory)
static SoftwareBitmap _convertToSoftwareBitmap(HICON hicon,
BitmapPixelFormat pixelFormat,
BitmapAlphaMode alphaMode,
gsl::not_null<IWICImagingFactory*> imagingFactory)
{
// Load the icon into an IWICBitmap
wil::com_ptr<IWICBitmap> iconBitmap;
@@ -245,9 +219,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return softwareBitmap;
}
SoftwareBitmap _getBitmapFromIconFileAsync(const winrt::hstring& iconPath,
int32_t iconIndex,
uint32_t iconSize)
static SoftwareBitmap _getBitmapFromIconFileAsync(const winrt::hstring& iconPath,
int32_t iconIndex,
uint32_t iconSize)
{
wil::unique_hicon hicon;
LOG_IF_FAILED(SHDefExtractIcon(iconPath.c_str(), iconIndex, 0, &hicon, nullptr, iconSize));
@@ -276,7 +250,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// - 0 if the iconPath is an exe/dll/lnk file but does not contain an index (i.e. we default
// to the first icon in the file)
// - the icon index if the iconPath is an exe/dll/lnk file and contains an index
std::optional<int> _getIconIndex(const winrt::hstring& iconPath, std::wstring_view& iconPathWithoutIndex)
static std::optional<int> _getIconIndex(const winrt::hstring& iconPath, std::wstring_view& iconPathWithoutIndex)
{
const auto pathView = std::wstring_view{ iconPath };
// Does iconPath have a comma in it? If so, split the string on the
@@ -309,8 +283,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return 0;
}
winrt::Windows::UI::Xaml::Media::Imaging::SoftwareBitmapSource _getImageIconSourceForBinary(std::wstring_view iconPathWithoutIndex,
int index)
static winrt::Windows::UI::Xaml::Media::Imaging::SoftwareBitmapSource _getImageIconSourceForBinary(std::wstring_view iconPathWithoutIndex,
int index)
{
// Try:
// * c:\Windows\System32\SHELL32.dll, 210
@@ -353,7 +327,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
const auto indexOpt = _getIconIndex(iconPath, iconPathWithoutIndex);
if (!indexOpt.has_value())
{
auto source = _IconSourceWUX(iconPath);
auto source = IconSourceWUX(iconPath);
Controls::IconSourceElement icon;
icon.IconSource(source);
return icon;

View File

@@ -0,0 +1,20 @@
#pragma once
#include "IconPathConverter.g.h"
namespace winrt::Microsoft::Terminal::UI::implementation
{
struct IconPathConverter
{
IconPathConverter() = default;
static Windows::UI::Xaml::Controls::IconElement IconWUX(const winrt::hstring& iconPath);
static Windows::UI::Xaml::Controls::IconSource IconSourceWUX(const winrt::hstring& iconPath);
static Microsoft::UI::Xaml::Controls::IconSource IconSourceMUX(const winrt::hstring& iconPath, bool convertToGrayscale);
};
}
namespace winrt::Microsoft::Terminal::UI::factory_implementation
{
BASIC_FACTORY(IconPathConverter);
}

View File

@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.UI
{
static runtimeclass IconPathConverter
{
static Windows.UI.Xaml.Controls.IconElement IconWUX(String path);
static Windows.UI.Xaml.Controls.IconSource IconSourceWUX(String path);
static Microsoft.UI.Xaml.Controls.IconSource IconSourceMUX(String path, Boolean convertToGrayscale);
};
}

View File

@@ -0,0 +1,17 @@
#include "pch.h"
#include "ResourceString.h"
#include "ResourceString.g.cpp"
namespace winrt::Microsoft::Terminal::UI::implementation
{
winrt::Windows::Foundation::IInspectable ResourceString::ProvideValue()
{
if (tree_.empty())
{
return nullptr;
}
auto loader{ winrt::Windows::ApplicationModel::Resources::ResourceLoader::GetForCurrentView(tree_ + L"/Resources") };
return winrt::box_value(loader.GetString(name_));
}
}

View File

@@ -0,0 +1,43 @@
#pragma once
#include "ResourceString.g.h"
namespace winrt::Microsoft::Terminal::UI::implementation
{
struct ResourceString : ResourceStringT<ResourceString>
{
ResourceString() noexcept = default;
hstring Tree()
{
return tree_;
}
void Tree(hstring const& value)
{
tree_ = value;
}
hstring Name()
{
return name_;
}
void Name(hstring const& value)
{
name_ = value;
}
winrt::Windows::Foundation::IInspectable ProvideValue();
private:
winrt::hstring tree_;
winrt::hstring name_;
};
}
namespace winrt::Microsoft::Terminal::UI::factory_implementation
{
struct ResourceString : ResourceStringT<ResourceString, implementation::ResourceString>
{
};
}

View File

@@ -0,0 +1,9 @@
namespace Microsoft.Terminal.UI {
runtimeclass ResourceString : Windows.UI.Xaml.Markup.MarkupExtension
{
ResourceString();
String Tree { get; set; };
String Name { get; set; };
Object ProvideValue();
};
}

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{6515F03F-E56D-4DB4-B23D-AC4FB80DB36F}</ProjectGuid>
<ProjectName>Microsoft.Terminal.UI</ProjectName>
<RootNamespace>Microsoft.Terminal.UI</RootNamespace>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<SubSystem>Console</SubSystem>
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
</PropertyGroup>
<PropertyGroup Label="NuGet Dependencies">
<TerminalCppWinrt>true</TerminalCppWinrt>
<TerminalMUX>true</TerminalMUX>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\common.nugetversions.props" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="Converters.h">
<DependentUpon>Converters.idl</DependentUpon>
</ClInclude>
<ClInclude Include="IconPathConverter.h">
<DependentUpon>IconPathConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="ResourceString.h">
<DependentUpon>ResourceString.idl</DependentUpon>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="init.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Converters.cpp">
<DependentUpon>Converters.idl</DependentUpon>
</ClCompile>
<ClCompile Include="IconPathConverter.cpp">
<DependentUpon>IconPathConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="ResourceString.cpp">
<DependentUpon>ResourceString.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
<Midl Include="Converters.idl" />
<Midl Include="IconPathConverter.idl" />
<Midl Include="IDirectKeyListener.idl" />
<Midl Include="ResourceString.idl" />
</ItemGroup>
<!-- ========================= Project References ======================== -->
<ItemGroup>
<!--
the packaging project won't recurse through our dependencies, you have to
make sure that if you add a cppwinrt dependency to any of these projects,
you also update all the consumers
-->
<ProjectReference Include="$(OpenConsoleDir)src\types\lib\types.vcxproj">
<Project>{18D09A24-8240-42D6-8CB6-236EEE820263}</Project>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\WinRTUtils\WinRTUtils.vcxproj">
<Project>{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>%(AdditionalDependencies);user32.lib;shell32.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<!-- This -must- go after cppwinrt.build.post.props because that includes many VS-provided props including appcontainer.common.props, which stomps on what cppwinrt.targets did. -->
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
</Project>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resources">
<UniqueIdentifier>accd3aa8-1ba0-4223-9bbe-0c431709210b</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{926ab91d-31b4-48c3-b9a4-e681349f27f0}</UniqueIdentifier>
</Filter>
<Filter Include="Resources\en-US">
<UniqueIdentifier>{ee3ff32f-d013-49cb-8eb9-1ec084585086}</UniqueIdentifier>
</Filter>
<Filter Include="Module">
<UniqueIdentifier>{091e7617-c506-4742-82fc-75e7ca32e2fe}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="init.cpp">
<Filter>Module</Filter>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp">
<Filter>Module</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Module</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="ResourceString.idl" />
</ItemGroup>
<ItemGroup>
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation
// Licensed under the MIT license.
#include "pch.h"
#pragma warning(suppress : 26440) // Not interested in changing the specification of DllMain to make it noexcept given it's an interface to the OS.
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD reason, LPVOID /*reserved*/)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hInstDll);
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return TRUE;
}

View File

@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// pch.h
// Header for platform projection include files
//
#pragma once
#define WIN32_LEAN_AND_MEAN
#define NOMCX
#define NOHELP
#define NOCOMM
// Manually include til after we include Windows.Foundation to give it winrt superpowers
#define BLOCK_TIL
#include <LibraryIncludes.h>
// This is inexplicable, but for whatever reason, cppwinrt conflicts with the
// SDK definition of this function, so the only fix is to undef it.
// from WinBase.h
// Windows::UI::Xaml::Media::Animation::IStoryboard::GetCurrentTime
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
#include <wil/cppwinrt.h>
#include <winrt/Windows.ApplicationModel.Resources.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.Imaging.h>
#include <Windows.Graphics.Imaging.Interop.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Markup.h>
#include <winrt/Windows.UI.Xaml.Media.h>
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
// Manually include til after we include Windows.Foundation to give it winrt superpowers
#include "til.h"
#include <cppwinrt_utils.h>
#include <wil/cppwinrt_helpers.h> // must go after the CoreDispatcher type is defined

View File

@@ -16,24 +16,11 @@ using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
namespace SettingsModelLocalTests
namespace SettingsModelUnitTests
{
// TODO:microsoft/terminal#3838:
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
// an updated TAEF that will let us install framework packages when the test
// package is deployed. Until then, these tests won't deploy in CI.
class ColorSchemeTests : public JsonTestClass
{
// Use a custom AppxManifest to ensure that we can activate winrt types
// from our test. This property will tell taef to manually use this as
// the AppxManifest for this test class.
// This does not yet work for anything XAML-y. See TabTests.cpp for more
// details on that.
BEGIN_TEST_CLASS(ColorSchemeTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_CLASS(ColorSchemeTests);
TEST_METHOD(ParseSimpleColorScheme);
TEST_METHOD(LayerColorSchemesOnArray);

View File

@@ -15,24 +15,11 @@ using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;
namespace SettingsModelLocalTests
namespace SettingsModelUnitTests
{
// TODO:microsoft/terminal#3838:
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
// an updated TAEF that will let us install framework packages when the test
// package is deployed. Until then, these tests won't deploy in CI.
class CommandTests : public JsonTestClass
{
// Use a custom AppxManifest to ensure that we can activate winrt types
// from our test. This property will tell taef to manually use this as
// the AppxManifest for this test class.
// This does not yet work for anything XAML-y. See TabTests.cpp for more
// details on that.
BEGIN_TEST_CLASS(CommandTests)
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
END_TEST_CLASS()
TEST_CLASS(CommandTests);
TEST_METHOD(ManyCommandsSameAction);
TEST_METHOD(LayerCommand);

Some files were not shown because too many files have changed in this diff Show More