Introduce the Terminal Settings Editor (#8048)

This commit introduces the terminal settings editor (to wit: the
Settings UI) as a standalone project. This project, and this commit, is
the result of two and a half months of work.

TSE started as a hackathon project in the Microsoft 2020 Hackathon, and
from there it's grown to be a bona-fide graphical settings editor.

There is a lot of xaml data binding in here, a number of views and a
number of view models, and a bunch of paradigms that we've been
reviewing and testing out and designing and refining.

Specified in #6720, #8269
Follow-up work in #6800
Closes #1564
Closes #8048 (PR)

Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
Co-authored-by: Kayla Cinnamon <cinnamon@microsoft.com>
Co-authored-by: Alberto Medina Gutierrez <almedina@microsoft.com>
Co-authored-by: John Grandle <jograndl@microsoft.com>
Co-authored-by: xerootg <xerootg@users.noreply.github.com>
Co-authored-by: Scott <sarmiger1@gmail.com>
Co-authored-by: Vineeth Thomas Alex <vineeththomasalex@gmail.com>
Co-authored-by: Leon Liang <lelian@microsoft.com>
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
Signed-off-by: Dustin L. Howett <duhowett@microsoft.com>
This commit is contained in:
Dustin Howett 2020-12-11 13:34:21 -08:00 committed by Dustin L. Howett
parent b80a4e45cc
commit 3e2b94334d
57 changed files with 4280 additions and 0 deletions

View File

@ -32,6 +32,7 @@ IInheritable
IMap
IObject
IStorage
ITab
ITaskbar
llabs
LCID
@ -63,17 +64,24 @@ semver
serializer
shobjidl
SIZENS
GETDESKWALLPAPER
snprintf
spsc
sregex
STDCPP
strchr
Subheader
Subpage
UPDATEINIFILE
syscall
TBPF
THEMECHANGED
tmp
tolower
tx
UPDATEINIFILE
userenv
wcsstr
wcstoui
wsregex
XDocument

View File

@ -12,6 +12,7 @@ LKG
mfcribbon
microsoft
microsoftonline
muxc
netcore
osgvsowi
pgc

View File

@ -172,6 +172,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsTerminal", "src\cascadia\WindowsTerminal\WindowsTerminal.vcxproj", "{CA5CAD1A-1754-4A9D-93D7-857A9D17CB1B}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12} = {CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}
{CA5CAD1A-ABCD-429C-B551-8562EC954746} = {CA5CAD1A-ABCD-429C-B551-8562EC954746}
{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B} = {9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}
@ -180,6 +181,7 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalApp", "src\cascadia\TerminalApp\dll\TerminalApp.vcxproj", "{CA5CAD1A-44BD-4AC7-AC72-F16E576FDD12}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-9A12-429C-B551-8562EC954746} = {CA5CAD1A-9A12-429C-B551-8562EC954746}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-C46D-4588-B1C0-40F31AE9100B} = {CA5CAD1A-C46D-4588-B1C0-40F31AE9100B}
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
@ -233,6 +235,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAppLib", "src\casca
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LocalTests_TerminalApp", "src\cascadia\LocalTests_TerminalApp\TerminalApp.LocalTests.vcxproj", "{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506}"
@ -315,6 +318,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTerminalTestNetCore", "s
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wt", "src\cascadia\wt\wt.vcxproj", "{506FD703-BAA7-4F6E-9361-64F550EC8FCA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings.Editor", "src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj", "{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings.Model.Lib", "src\cascadia\TerminalSettingsModel\Microsoft.Terminal.Settings.ModelLib.vcxproj", "{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}"
ProjectSection(ProjectDependencies) = postProject
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
@ -2012,6 +2020,45 @@ Global
{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x64.Build.0 = Release|x64
{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.ActiveCfg = Release|Win32
{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.ActiveCfg = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.Build.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.Deploy.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|ARM64.ActiveCfg = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|ARM64.Build.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|ARM64.Deploy.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x64Test.ActiveCfg = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x64Test.Build.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x64Test.Deploy.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x86Test.ActiveCfg = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x86Test.Build.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|DotNet_x86Test.Deploy.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x64.ActiveCfg = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x64.Deploy.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x86.ActiveCfg = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x86.Build.0 = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|x86.Deploy.0 = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|ARM64.Build.0 = Debug|ARM64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x64.ActiveCfg = Debug|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x64.Build.0 = Debug|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x64.Deploy.0 = Debug|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x86.ActiveCfg = Debug|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x86.Build.0 = Debug|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Debug|x86.Deploy.0 = Debug|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|Any CPU.ActiveCfg = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|ARM64.ActiveCfg = Release|ARM64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|ARM64.Build.0 = Release|ARM64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x64.ActiveCfg = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x64.Build.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x64.Deploy.0 = Release|x64
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x86.ActiveCfg = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x86.Build.0 = Release|Win32
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.Release|x86.Deploy.0 = Release|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
@ -2170,6 +2217,7 @@ Global
{6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {81C352DB-1818-45B7-A284-18E259F1CC87}
{1588FD7C-241E-4E7D-9113-43735F3E6BAD} = {59840756-302F-44DF-AA47-441A9D673202}
{506FD703-BAA7-4F6E-9361-64F550EC8FCA} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-082C-4476-9F33-94B339494076} = {59840756-302F-44DF-AA47-441A9D673202}
{CA5CAD1A-9B68-456A-B13E-C8218070DC42} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}

View File

@ -0,0 +1,143 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ColorSchemes.h"
#include "ColorTableEntry.g.cpp"
#include "ColorSchemes.g.cpp"
#include "ColorSchemesPageNavigationState.g.cpp"
#include <LibraryResources.h>
using namespace winrt;
using namespace winrt::Windows::UI;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Windows::UI::Xaml::Media;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
static const std::array<hstring, 16> TableColorNames = {
RS_(L"ColorScheme_Black/Header"),
RS_(L"ColorScheme_Red/Header"),
RS_(L"ColorScheme_Green/Header"),
RS_(L"ColorScheme_Yellow/Header"),
RS_(L"ColorScheme_Blue/Header"),
RS_(L"ColorScheme_Purple/Header"),
RS_(L"ColorScheme_Cyan/Header"),
RS_(L"ColorScheme_White/Header"),
RS_(L"ColorScheme_BrightBlack/Header"),
RS_(L"ColorScheme_BrightRed/Header"),
RS_(L"ColorScheme_BrightGreen/Header"),
RS_(L"ColorScheme_BrightYellow/Header"),
RS_(L"ColorScheme_BrightBlue/Header"),
RS_(L"ColorScheme_BrightPurple/Header"),
RS_(L"ColorScheme_BrightCyan/Header"),
RS_(L"ColorScheme_BrightWhite/Header")
};
ColorSchemes::ColorSchemes() :
_ColorSchemeList{ single_threaded_observable_vector<hstring>() },
_CurrentColorTable{ single_threaded_observable_vector<Editor::ColorTableEntry>() }
{
InitializeComponent();
}
void ColorSchemes::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::ColorSchemesPageNavigationState>();
_UpdateColorSchemeList();
// Initialize our color table view model with 16 dummy colors
// so that on a ColorScheme selection change, we can loop through
// each ColorTableEntry and just change its color. Performing a
// clear and 16 appends doesn't seem to update the color pickers
// very accurately.
for (uint8_t i = 0; i < TableColorNames.size(); ++i)
{
auto entry = winrt::make<ColorTableEntry>(i, Windows::UI::Color{ 0, 0, 0, 0 });
_CurrentColorTable.Append(entry);
}
}
// Function Description:
// - Called when a different color scheme is selected. Updates our current
// color scheme and updates our currently modifiable color table.
// Arguments:
// - args: The selection changed args that tells us what's the new color scheme selected.
// Return Value:
// - <none>
void ColorSchemes::ColorSchemeSelectionChanged(IInspectable const& /*sender*/,
SelectionChangedEventArgs const& args)
{
// Update the color scheme this page is modifying
auto str = winrt::unbox_value<hstring>(args.AddedItems().GetAt(0));
auto colorScheme = _State.Globals().ColorSchemes().Lookup(str);
CurrentColorScheme(colorScheme);
_UpdateColorTable(colorScheme);
}
// Function Description:
// - Updates the list of all color schemes available to choose from.
// Arguments:
// - <none>
// Return Value:
// - <none>
void ColorSchemes::_UpdateColorSchemeList()
{
// Surprisingly, though this is called every time we navigate to the page,
// the list does not keep growing on each navigation.
const auto& colorSchemeMap{ _State.Globals().ColorSchemes() };
for (const auto& pair : colorSchemeMap)
{
_ColorSchemeList.Append(pair.Key());
}
}
// Function Description:
// - Called when a ColorPicker control has selected a new color. This is specifically
// called by color pickers assigned to a color table entry. It takes the index
// that's been stuffed in the Tag property of the color picker and uses it
// to update the color table accordingly.
// Arguments:
// - sender: the color picker that raised this event.
// - args: the args that contains the new color that was picked.
// Return Value:
// - <none>
void ColorSchemes::ColorPickerChanged(IInspectable const& sender,
ColorChangedEventArgs const& args)
{
if (auto picker = sender.try_as<ColorPicker>())
{
if (auto tag = picker.Tag())
{
auto index = winrt::unbox_value<uint8_t>(tag);
CurrentColorScheme().SetColorTableEntry(index, args.NewColor());
_CurrentColorTable.GetAt(index).Color(args.NewColor());
}
}
}
// Function Description:
// - Updates the currently modifiable color table based on the given current color scheme.
// Arguments:
// - colorScheme: the color scheme to retrieve the color table from
// Return Value:
// - <none>
void ColorSchemes::_UpdateColorTable(const Model::ColorScheme& colorScheme)
{
for (uint8_t i = 0; i < TableColorNames.size(); ++i)
{
_CurrentColorTable.GetAt(i).Color(colorScheme.Table()[i]);
}
}
ColorTableEntry::ColorTableEntry(uint8_t index, Windows::UI::Color color)
{
Name(TableColorNames[index]);
Index(winrt::box_value<uint8_t>(index));
Color(color);
}
}

View File

@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "ColorTableEntry.g.h"
#include "ColorSchemes.g.h"
#include "ColorSchemesPageNavigationState.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct ColorSchemesPageNavigationState : ColorSchemesPageNavigationStateT<ColorSchemesPageNavigationState>
{
public:
ColorSchemesPageNavigationState(const Model::GlobalAppSettings& settings) :
_Globals{ settings } {}
GETSET_PROPERTY(Model::GlobalAppSettings, Globals, nullptr);
};
struct ColorSchemes : ColorSchemesT<ColorSchemes>
{
ColorSchemes();
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
void ColorSchemeSelectionChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::SelectionChangedEventArgs const& args);
void ColorPickerChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::Controls::ColorChangedEventArgs const& args);
GETSET_PROPERTY(Editor::ColorSchemesPageNavigationState, State, nullptr);
GETSET_PROPERTY(Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::ColorTableEntry>, CurrentColorTable, nullptr);
GETSET_PROPERTY(Windows::Foundation::Collections::IObservableVector<winrt::hstring>, ColorSchemeList, nullptr);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
OBSERVABLE_GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::Model::ColorScheme, CurrentColorScheme, _PropertyChangedHandlers, nullptr);
private:
void _UpdateColorTable(const winrt::Microsoft::Terminal::Settings::Model::ColorScheme& colorScheme);
void _UpdateColorSchemeList();
};
struct ColorTableEntry : ColorTableEntryT<ColorTableEntry>
{
public:
ColorTableEntry(uint8_t index, Windows::UI::Color color);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, Name, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(IInspectable, Index, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(Windows::UI::Color, Color, _PropertyChangedHandlers);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(ColorSchemes);
}

View File

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass ColorSchemesPageNavigationState
{
Microsoft.Terminal.Settings.Model.GlobalAppSettings Globals;
};
[default_interface] runtimeclass ColorSchemes : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged
{
ColorSchemes();
ColorSchemesPageNavigationState State { get; };
Microsoft.Terminal.Settings.Model.ColorScheme CurrentColorScheme { get; };
Windows.Foundation.Collections.IObservableVector<ColorTableEntry> CurrentColorTable;
Windows.Foundation.Collections.IObservableVector<String> ColorSchemeList { get; };
}
[default_interface] runtimeclass ColorTableEntry : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String Name { get; };
IInspectable Index;
Windows.UI.Color Color;
}
}

View File

@ -0,0 +1,154 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.Terminal.Settings.Editor.ColorSchemes"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Thickness x:Key="ColorSchemesStandardControlMargin">10,0,0,20</Thickness>
<Style x:Key="ColorStackPanelStyle" TargetType="StackPanel">
<Setter Property="Margin" Value="{StaticResource ColorSchemesStandardControlMargin}"/>
<Setter Property="Height" Value="59"/>
</Style>
<Style x:Key="ColorHeaderStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="0,0,0,4"/>
</Style>
<Style TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="BorderBrush" Value="{StaticResource SystemBaseLowColor}"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Width" Value="100"/>
</Style>
<Style TargetType="ColorPicker">
<Setter Property="IsColorSliderVisible" Value="False"/>
<Setter Property="IsColorChannelTextInputVisible" Value="False"/>
<Setter Property="IsHexInputVisible" Value="True"/>
<Setter Property="IsAlphaSliderVisible" Value="True"/>
<Setter Property="IsAlphaTextInputVisible" Value="True"/>
</Style>
<local:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
<local:ColorToHexConverter x:Key="ColorToHexConverter"/>
</ResourceDictionary>
</Page.Resources>
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MaxWidth="480"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<!--Select a color scheme-->
<ComboBox x:Name="ColorSchemeComboBox"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
SelectedIndex="0"
ItemsSource="{x:Bind ColorSchemeList, Mode=OneWay}"
SelectionChanged="ColorSchemeSelectionChanged"
Style="{StaticResource ComboBoxSettingStyle}"
Margin="{StaticResource ColorSchemesStandardControlMargin}"/>
<!-- Color Table -->
<ItemsControl x:Name="ColorTableControl"
ItemsSource="{x:Bind CurrentColorTable, Mode=OneWay}"
Grid.Row="1"
Grid.Column="0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"
MaximumRowsOrColumns="4"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="local:ColorTableEntry">
<StackPanel Style="{StaticResource ColorStackPanelStyle}">
<TextBlock Text="{x:Bind Name, Mode=OneWay}"
Style="{StaticResource ColorHeaderStyle}"/>
<Button Background="{x:Bind Color, Converter={StaticResource ColorToBrushConverter}, Mode=OneWay}">
<Button.Flyout>
<Flyout>
<ColorPicker Tag="{x:Bind Index, Mode=OneWay}"
Color="{x:Bind Color, Mode=OneWay}"
ColorChanged="ColorPickerChanged"/>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Additional Colors -->
<ItemsControl Grid.Row="2"
Grid.Column="1">
<StackPanel Style="{StaticResource ColorStackPanelStyle}">
<TextBlock x:Uid="ColorScheme_Foreground"
Style="{StaticResource ColorHeaderStyle}"/>
<Button Background="{Binding Color, ElementName=ForegroundPicker, Converter={StaticResource ColorToBrushConverter}, Mode=OneWay}">
<Button.Flyout>
<Flyout>
<ColorPicker x:Name="ForegroundPicker" Color="{x:Bind CurrentColorScheme.Foreground, Mode=TwoWay}"/>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
<StackPanel Style="{StaticResource ColorStackPanelStyle}">
<TextBlock x:Uid="ColorScheme_Background"
Style="{StaticResource ColorHeaderStyle}"/>
<Button Background="{Binding Color, ElementName=BackgroundPicker, Converter={StaticResource ColorToBrushConverter}, Mode=OneWay}">
<Button.Flyout>
<Flyout>
<ColorPicker x:Name="BackgroundPicker"
Color="{x:Bind CurrentColorScheme.Background, Mode=TwoWay}"/>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
<StackPanel Style="{StaticResource ColorStackPanelStyle}">
<TextBlock x:Uid="ColorScheme_CursorColor"
Style="{StaticResource ColorHeaderStyle}"/>
<Button Background="{Binding Color, ElementName=CursorColorPicker, Converter={StaticResource ColorToBrushConverter}, Mode=OneWay}">
<Button.Flyout>
<Flyout>
<ColorPicker x:Name="CursorColorPicker"
Color="{x:Bind CurrentColorScheme.CursorColor, Mode=TwoWay}"/>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
<StackPanel Style="{StaticResource ColorStackPanelStyle}">
<TextBlock x:Uid="ColorScheme_SelectionBackground"
Style="{StaticResource ColorHeaderStyle}"/>
<Button Background="{Binding Color, ElementName=SelectionBackgroundPicker, Converter={StaticResource ColorToBrushConverter}, Mode=OneWay}">
<Button.Flyout>
<Flyout>
<ColorPicker x:Name="SelectionBackgroundPicker"
Color="{x:Bind CurrentColorScheme.SelectionBackground, Mode=TwoWay}"/>
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
</ItemsControl>
</Grid>
</ScrollViewer>
</Page>

View File

@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ColorToBrushConverter.h"
#include "ColorToBrushConverter.g.cpp"
using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Foundation::IInspectable ColorToBrushConverter::Convert(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
return winrt::box_value(Windows::UI::Xaml::Media::SolidColorBrush(winrt::unbox_value<Windows::UI::Color>(value)));
}
Foundation::IInspectable ColorToBrushConverter::ConvertBack(Foundation::IInspectable const& /*value*/,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /*parameter*/,
hstring const& /* language */)
{
throw hresult_not_implemented();
}
}

View File

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

View File

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

View File

@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ColorToHexConverter.h"
#include "ColorToHexConverter.g.cpp"
using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Foundation::IInspectable ColorToHexConverter::Convert(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
til::color color{ winrt::unbox_value<winrt::Windows::UI::Color>(value) };
auto hex = winrt::to_hstring(color.ToHexString().data());
return winrt::box_value(hex);
}
Foundation::IInspectable ColorToHexConverter::ConvertBack(Foundation::IInspectable const& /*value*/,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /*parameter*/,
hstring const& /* language */)
{
throw hresult_not_implemented();
}
}

View File

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

View File

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

View File

@ -0,0 +1,109 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
<x:Double x:Key="StandardFontSize">15.0</x:Double>
<Thickness x:Key="StandardIndentMargin">20,0,0,0</Thickness>
<x:Double x:Key="StandardBoxMinWidth">300</x:Double>
<!-- This is for easier transition to the SettingsContainer control.
The SettingsContainer will wrap a setting with inheritance UI.-->
<Style x:Key="SettingContainerStyle" TargetType="ContentPresenter">
<Setter Property="Padding" Value="0,0,0,20"/>
</Style>
<!--Used to stack a group of settings-->
<Style x:Key="SettingsStackStyle" TargetType="StackPanel">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="{StaticResource StandardIndentMargin}"/>
</Style>
<!--Radio Button-->
<Style x:Key="RadioButtonsSettingStyle" TargetType="muxc:RadioButtons">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
</Style>
<Style x:Key="RadioButtonSettingStyle" TargetType="RadioButton" BasedOn="{StaticResource DefaultRadioButtonStyle}">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
</Style>
<!--Check Box-->
<Style x:Key="CheckBoxSettingStyle" TargetType="CheckBox" BasedOn="{StaticResource DefaultCheckBoxStyle}">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
</Style>
<!--Combo Box-->
<Style x:Key="ComboBoxSettingStyle" TargetType="ComboBox" BasedOn="{StaticResource DefaultComboBoxStyle}">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
<Setter Property="MinWidth" Value="{StaticResource StandardBoxMinWidth}"/>
</Style>
<!--Text Box-->
<Style x:Key="TextBoxSettingStyle" TargetType="TextBox" BasedOn="{StaticResource DefaultTextBoxStyle}">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
<Setter Property="Width" Value="{StaticResource StandardBoxMinWidth}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
<!--Used to create a header for a control-->
<Style x:Key="CustomSettingHeaderStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="Margin" Value="0,0,0,4"/>
</Style>
<!-- Used to create a header for a group of settings -->
<Style x:Key="GroupingHeader" TargetType="TextBlock" BasedOn="{StaticResource SubtitleTextBlockStyle}">
<Setter Property="Margin" Value="0,20,0,10"/>
</Style>
<!--Number Box-->
<Style x:Key="NumberBoxSettingStyle" TargetType="muxc:NumberBox">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
<Setter Property="SpinButtonPlacementMode" Value="Compact"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<!--Button-Related Styling-->
<Style x:Key="BaseButtonStyle" TargetType="Button" BasedOn="{StaticResource DefaultButtonStyle}">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
</Style>
<Style x:Key="BrowseButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Margin" Value="10,0,0,0"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
</Style>
<!--Slider-Related Styling-->
<Style x:Key="SliderSettingStyle" TargetType="Slider" BasedOn="{StaticResource DefaultSliderStyle}">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
</Style>
<Style x:Key="SliderValueLabelStyle" TargetType="TextBlock">
<Setter Property="Width" Value="35"/>
<Setter Property="Margin" Value="10,0,0,20"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
</Style>
<Style x:Key="SliderHeaderStyle" TargetType="TextBlock" BasedOn="{StaticResource CustomSettingHeaderStyle}">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
</Style>
<Style x:Key="CustomSliderControlGridStyle" TargetType="Grid">
<Setter Property="Width" Value="300"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</ResourceDictionary>

View File

@ -0,0 +1,35 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- EnumEntry.h
Abstract:
- An EnumEntry is intended to be used as a ViewModel for settings
that are an enum value. It holds an enum name and enum value
so that any data binding can easily associate one with the other.
Author(s):
- Leon Liang - October 2020
--*/
#pragma once
#include "EnumEntry.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct EnumEntry : EnumEntryT<EnumEntry>
{
public:
EnumEntry(const winrt::hstring enumName, const winrt::Windows::Foundation::IInspectable& enumValue) :
_EnumName{ enumName },
_EnumValue{ enumValue } {}
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
OBSERVABLE_GETSET_PROPERTY(winrt::hstring, EnumName, _PropertyChangedHandlers);
OBSERVABLE_GETSET_PROPERTY(winrt::Windows::Foundation::IInspectable, EnumValue, _PropertyChangedHandlers);
};
}

View File

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
[default_interface] runtimeclass EnumEntry : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
String EnumName { get; };
IInspectable EnumValue { get; };
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "FontWeightConverter.h"
#include "FontWeightConverter.g.cpp"
using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Text;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Foundation::IInspectable FontWeightConverter::Convert(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
const auto weight{ winrt::unbox_value<FontWeight>(value) };
return winrt::box_value<double>(weight.Weight);
}
Foundation::IInspectable FontWeightConverter::ConvertBack(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /*parameter*/,
hstring const& /* language */)
{
const auto sliderVal{ winrt::unbox_value<double>(value) };
FontWeight weight{ base::ClampedNumeric<uint16_t>(sliderVal) };
return winrt::box_value<FontWeight>(weight);
}
}

View File

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

View File

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

View File

@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "GlobalAppearance.h"
#include "GlobalAppearance.g.cpp"
#include "GlobalAppearancePageNavigationState.g.cpp"
#include "EnumEntry.h"
using namespace winrt;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::UI::Xaml::Controls;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Windows::Foundation::Collections;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
GlobalAppearance::GlobalAppearance()
{
InitializeComponent();
INITIALIZE_BINDABLE_ENUM_SETTING(Theme, ElementTheme, winrt::Windows::UI::Xaml::ElementTheme, L"Globals_Theme", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(TabWidthMode, TabViewWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, L"Globals_TabWidthMode", L"Content");
}
void GlobalAppearance::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::GlobalAppearancePageNavigationState>();
}
}

View File

@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "GlobalAppearance.g.h"
#include "GlobalAppearancePageNavigationState.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct GlobalAppearancePageNavigationState : GlobalAppearancePageNavigationStateT<GlobalAppearancePageNavigationState>
{
public:
GlobalAppearancePageNavigationState(const Model::GlobalAppSettings& settings) :
_Globals{ settings } {}
GETSET_PROPERTY(Model::GlobalAppSettings, Globals, nullptr)
};
struct GlobalAppearance : GlobalAppearanceT<GlobalAppearance>
{
public:
GlobalAppearance();
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
GETSET_PROPERTY(Editor::GlobalAppearancePageNavigationState, State, nullptr);
GETSET_BINDABLE_ENUM_SETTING(Theme, winrt::Windows::UI::Xaml::ElementTheme, State().Globals, Theme);
GETSET_BINDABLE_ENUM_SETTING(TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, State().Globals, TabWidthMode);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(GlobalAppearance);
}

View File

@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "EnumEntry.idl";
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass GlobalAppearancePageNavigationState
{
Microsoft.Terminal.Settings.Model.GlobalAppSettings Globals;
};
[default_interface] runtimeclass GlobalAppearance : Windows.UI.Xaml.Controls.Page
{
GlobalAppearance();
GlobalAppearancePageNavigationState State { get; };
IInspectable CurrentTheme;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> ThemeList { get; };
IInspectable CurrentTabWidthMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> TabWidthModeList { get; };
}
}

View File

@ -0,0 +1,82 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.Terminal.Settings.Editor.GlobalAppearance"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:DataType="local:EnumEntry" x:Key="EnumRadioButtonTemplate">
<RadioButton Content="{x:Bind EnumName, Mode=OneWay}"
Style="{StaticResource RadioButtonSettingStyle}"/>
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
<ScrollViewer>
<StackPanel Style="{StaticResource SettingsStackStyle}">
<!--Theme-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Globals_Theme"
SelectedItem="{x:Bind CurrentTheme, Mode=TwoWay}"
ItemsSource="{x:Bind ThemeList, Mode=OneWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--Show Titlebar-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_ShowTitlebar"
IsChecked="{x:Bind State.Globals.ShowTabsInTitlebar, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Show Title in Titlebar-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_ShowTitleInTitlebar"
IsChecked="{x:Bind State.Globals.ShowTitleInTitlebar, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Always show tabs-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_AlwaysShowTabs"
IsChecked="{x:Bind State.Globals.AlwaysShowTabs, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Tab Width Mode-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Globals_TabWidthMode"
SelectedItem="{x:Bind CurrentTabWidthMode, Mode=TwoWay}"
ItemsSource="{x:Bind TabWidthModeList, Mode=OneWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--Confirm Close All Tabs-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_ConfirmCloseAllTabs"
IsChecked="{x:Bind State.Globals.ConfirmCloseAllTabs, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Disable Animations-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_DisableAnimations"
IsChecked="{x:Bind State.Globals.DisableAnimations, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</Page>

View File

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "Interaction.h"
#include "Interaction.g.cpp"
#include "InteractionPageNavigationState.g.cpp"
using namespace winrt::Windows::UI::Xaml::Navigation;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Interaction::Interaction()
{
InitializeComponent();
}
void Interaction::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::InteractionPageNavigationState>();
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Interaction.g.h"
#include "InteractionPageNavigationState.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct InteractionPageNavigationState : InteractionPageNavigationStateT<InteractionPageNavigationState>
{
public:
InteractionPageNavigationState(const Model::GlobalAppSettings& settings) :
_Globals{ settings } {}
GETSET_PROPERTY(Model::GlobalAppSettings, Globals, nullptr)
};
struct Interaction : InteractionT<Interaction>
{
Interaction();
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
GETSET_PROPERTY(Editor::InteractionPageNavigationState, State, nullptr);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(Interaction);
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass InteractionPageNavigationState
{
Microsoft.Terminal.Settings.Model.GlobalAppSettings Globals;
};
[default_interface] runtimeclass Interaction : Windows.UI.Xaml.Controls.Page
{
Interaction();
InteractionPageNavigationState State { get; };
}
}

View File

@ -0,0 +1,43 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.Terminal.Settings.Editor.Interaction"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<ScrollViewer>
<StackPanel Style="{StaticResource SettingsStackStyle}">
<!--Copy On Select-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_CopyOnSelect"
IsChecked="{x:Bind State.Globals.CopyOnSelect, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Word Delimiters-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<TextBox x:Uid="Globals_WordDelimiters"
Text="{x:Bind State.Globals.WordDelimiters, Mode=TwoWay}"
Style="{StaticResource TextBoxSettingStyle}"/>
</ContentPresenter>
<!--Snap On Resize-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_SnapToGridOnResize"
IsChecked="{x:Bind State.Globals.SnapToGridOnResize, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</Page>

View File

@ -0,0 +1,39 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "Launch.h"
#include "Launch.g.cpp"
#include "LaunchPageNavigationState.g.cpp"
#include "EnumEntry.h"
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Terminal::Settings::Model;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Launch::Launch()
{
InitializeComponent();
INITIALIZE_BINDABLE_ENUM_SETTING(LaunchMode, LaunchMode, LaunchMode, L"Globals_LaunchMode", L"Content");
}
void Launch::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::LaunchPageNavigationState>();
}
IInspectable Launch::CurrentDefaultProfile()
{
const auto defaultProfileGuid{ _State.Settings().GlobalSettings().DefaultProfile() };
return winrt::box_value(_State.Settings().FindProfile(defaultProfileGuid));
}
void Launch::CurrentDefaultProfile(const IInspectable& value)
{
const auto profile{ winrt::unbox_value<Model::Profile>(value) };
_State.Settings().GlobalSettings().DefaultProfile(profile.Guid());
}
}

View File

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Launch.g.h"
#include "LaunchPageNavigationState.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct LaunchPageNavigationState : LaunchPageNavigationStateT<LaunchPageNavigationState>
{
public:
LaunchPageNavigationState(const Model::CascadiaSettings& settings) :
_Settings{ settings } {}
GETSET_PROPERTY(Model::CascadiaSettings, Settings, nullptr)
};
struct Launch : LaunchT<Launch>
{
public:
Launch();
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
IInspectable CurrentDefaultProfile();
void CurrentDefaultProfile(const IInspectable& value);
GETSET_PROPERTY(Editor::LaunchPageNavigationState, State, nullptr);
GETSET_BINDABLE_ENUM_SETTING(LaunchMode, Model::LaunchMode, State().Settings().GlobalSettings, LaunchMode);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(Launch);
}

View File

@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "EnumEntry.idl";
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass LaunchPageNavigationState
{
Microsoft.Terminal.Settings.Model.CascadiaSettings Settings;
};
[default_interface] runtimeclass Launch : Windows.UI.Xaml.Controls.Page
{
Launch();
LaunchPageNavigationState State { get; };
IInspectable CurrentDefaultProfile;
IInspectable CurrentLaunchMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> LaunchModeList { get; };
}
}

View File

@ -0,0 +1,131 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.Terminal.Settings.Editor.Launch"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:SettingsModel="using:Microsoft.Terminal.Settings.Model"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:DataType="local:EnumEntry" x:Key="EnumRadioButtonTemplate">
<RadioButton Content="{x:Bind EnumName, Mode=OneWay}"
Style="{StaticResource RadioButtonSettingStyle}"/>
</DataTemplate>
<SettingsModel:IconPathConverter x:Key="IconSourceConverter"/>
</ResourceDictionary>
</Page.Resources>
<ScrollViewer>
<StackPanel Style="{StaticResource SettingsStackStyle}">
<!--Default Profile-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<ComboBox x:Uid="Globals_DefaultProfile"
x:Name="DefaultProfile"
ItemsSource="{x:Bind State.Settings.AllProfiles, Mode=OneWay}"
SelectedItem="{x:Bind CurrentDefaultProfile, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="SettingsModel:Profile">
<Grid HorizontalAlignment="Stretch" ColumnSpacing="8">
<Grid.ColumnDefinitions>
<!-- icon -->
<ColumnDefinition Width="16"/>
<!-- profile name -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<IconSourceElement
Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind Icon,
Mode=OneWay,
Converter={StaticResource IconSourceConverter}}"/>
<TextBlock Grid.Column="1"
Text="{x:Bind Name}"
FontSize="{StaticResource StandardFontSize}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ContentPresenter>
<!--Start on User Login-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_StartOnUserLogin"
IsChecked="{x:Bind State.Settings.GlobalSettings.StartOnUserLogin, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Launch Mode-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Globals_LaunchMode"
SelectedItem="{x:Bind CurrentLaunchMode}"
ItemsSource="{x:Bind LaunchModeList}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--Launch Size-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<Grid>
<Grid.Resources>
<Style x:Key="LaunchSizeSubHeaderStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="{StaticResource StandardFontSize}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,0,5,0"/>
</Style>
<Style x:Key="LaunchSizeNumberBoxStyle" TargetType="muxc:NumberBox" BasedOn="{StaticResource NumberBoxSettingStyle}">
<Setter Property="SmallChange" Value="1"/>
<Setter Property="LargeChange" Value="10"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<!--Header-->
<TextBlock x:Uid="Globals_LaunchSize"
Grid.Row="0" Grid.Column="0"
Grid.ColumnSpan="2"
Style="{StaticResource CustomSettingHeaderStyle}"/>
<!--Columns-->
<StackPanel Orientation="Horizontal"
Grid.Row="1" Grid.Column="0"
Margin="0,0,10,0">
<TextBlock x:Uid="Globals_InitialCols" Style="{StaticResource LaunchSizeSubHeaderStyle}"/>
<muxc:NumberBox Value="{x:Bind State.Settings.GlobalSettings.InitialCols, Mode=TwoWay}"
Style="{StaticResource LaunchSizeNumberBoxStyle}"/>
</StackPanel>
<!--Rows-->
<StackPanel Orientation="Horizontal"
Grid.Row="1" Grid.Column="1">
<TextBlock x:Uid="Globals_InitialRows" Style="{StaticResource LaunchSizeSubHeaderStyle}"/>
<muxc:NumberBox Value="{x:Bind State.Settings.GlobalSettings.InitialRows, Mode=TwoWay}"
Style="{StaticResource LaunchSizeNumberBoxStyle}"/>
</StackPanel>
</Grid>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</Page>

View File

@ -0,0 +1,316 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "MainPage.h"
#include "MainPage.g.cpp"
#include "Launch.h"
#include "Interaction.h"
#include "Rendering.h"
#include "Profiles.h"
#include "GlobalAppearance.h"
#include "ColorSchemes.h"
#include <LibraryResources.h>
namespace winrt
{
namespace MUX = Microsoft::UI::Xaml;
namespace WUX = Windows::UI::Xaml;
}
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Microsoft::Terminal::Settings::Model;
using namespace winrt::Windows::UI::Core;
using namespace winrt::Windows::System;
using namespace winrt::Windows::UI::Xaml::Controls;
static const std::wstring_view launchTag{ L"Launch_Nav" };
static const std::wstring_view interactionTag{ L"Interaction_Nav" };
static const std::wstring_view renderingTag{ L"Rendering_Nav" };
static const std::wstring_view globalProfileTag{ L"GlobalProfile_Nav" };
static const std::wstring_view addProfileTag{ L"AddProfile" };
static const std::wstring_view colorSchemesTag{ L"ColorSchemes_Nav" };
static const std::wstring_view globalAppearanceTag{ L"GlobalAppearance_Nav" };
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
static Editor::ProfileViewModel _viewModelForProfile(const Model::Profile& profile)
{
return winrt::make<implementation::ProfileViewModel>(profile);
}
MainPage::MainPage(const CascadiaSettings& settings) :
_settingsSource{ settings },
_settingsClone{ settings.Copy() }
{
InitializeComponent();
_InitializeProfilesList();
}
// Method Description:
// - Update the Settings UI with a new CascadiaSettings to bind to
// Arguments:
// - settings - the new settings source
// Return value:
// - <none>
fire_and_forget MainPage::UpdateSettings(Model::CascadiaSettings settings)
{
_settingsSource = settings;
_settingsClone = settings.Copy();
co_await winrt::resume_foreground(Dispatcher());
// "remove" all profile-related NavViewItems
// LOAD-BEARING: use Visibility here, instead of menuItems.Remove().
// Remove() works fine on NavViewItems with an hstring tag,
// but causes an out-of-bounds error with Profile tagged items.
// The cause of this error is unknown.
auto menuItems{ SettingsNav().MenuItems() };
for (auto i = menuItems.Size() - 1; i > 0; --i)
{
if (const auto navViewItem{ menuItems.GetAt(i).try_as<MUX::Controls::NavigationViewItem>() })
{
if (const auto tag{ navViewItem.Tag() })
{
if (tag.try_as<Model::Profile>())
{
// hide NavViewItem pointing to a Profile
navViewItem.Visibility(Visibility::Collapsed);
}
else if (const auto stringTag{ tag.try_as<hstring>() })
{
if (stringTag == addProfileTag)
{
// hide NavViewItem pointing to "Add Profile"
navViewItem.Visibility(Visibility::Collapsed);
}
}
}
}
}
_InitializeProfilesList();
_RefreshCurrentPage();
}
void MainPage::_RefreshCurrentPage()
{
auto navigationMenu{ SettingsNav() };
if (const auto selectedItem{ navigationMenu.SelectedItem() })
{
if (const auto tag{ selectedItem.as<MUX::Controls::NavigationViewItem>().Tag() })
{
if (const auto profile{ tag.try_as<Model::Profile>() })
{
// check if the profile still exists
if (_settingsClone.FindProfile(profile.Guid()))
{
// Navigate to the page with the given profile
contentFrame().Navigate(xaml_typename<Editor::Profiles>(), winrt::make<ProfilePageNavigationState>(_viewModelForProfile(profile), _settingsClone.GlobalSettings().ColorSchemes(), *this));
return;
}
}
else if (const auto stringTag{ tag.try_as<hstring>() })
{
// navigate to the page with this tag
_Navigate(*stringTag);
return;
}
}
}
// could not find the page we were on, fallback to first menu item
const auto firstItem{ navigationMenu.MenuItems().GetAt(0) };
navigationMenu.SelectedItem(firstItem);
if (const auto tag{ navigationMenu.SelectedItem().as<NavigationViewItem>().Tag() })
{
_Navigate(unbox_value<hstring>(tag));
}
}
void MainPage::SetHostingWindow(uint64_t hostingWindow) noexcept
{
_hostingHwnd.emplace(reinterpret_cast<HWND>(hostingWindow));
}
bool MainPage::TryPropagateHostingWindow(IInspectable object) noexcept
{
if (_hostingHwnd)
{
if (auto initializeWithWindow{ object.try_as<IInitializeWithWindow>() })
{
return SUCCEEDED(initializeWithWindow->Initialize(*_hostingHwnd));
}
}
return false;
}
// Function Description:
// - Called when the NavigationView is loaded. Navigates to the first item in the NavigationView, if no item is selected
// Arguments:
// - <unused>
// Return Value:
// - <none>
void MainPage::SettingsNav_Loaded(IInspectable const&, RoutedEventArgs const&)
{
if (SettingsNav().SelectedItem() == nullptr)
{
const auto initialItem = SettingsNav().MenuItems().GetAt(0);
SettingsNav().SelectedItem(initialItem);
// Manually navigate because setting the selected item programmatically doesn't trigger ItemInvoked.
if (const auto tag = initialItem.as<MUX::Controls::NavigationViewItem>().Tag())
{
_Navigate(unbox_value<hstring>(tag));
}
}
}
// Function Description:
// - Called when NavigationView items are invoked. Navigates to the corresponding page.
// Arguments:
// - args - additional event info from invoking the NavViewItem
// Return Value:
// - <none>
void MainPage::SettingsNav_ItemInvoked(MUX::Controls::NavigationView const&, MUX::Controls::NavigationViewItemInvokedEventArgs const& args)
{
if (const auto clickedItemContainer = args.InvokedItemContainer())
{
if (const auto navString = clickedItemContainer.Tag().try_as<hstring>())
{
if (navString == addProfileTag)
{
// "AddProfile" needs to create a new profile before we can navigate to it
uint32_t insertIndex;
SettingsNav().MenuItems().IndexOf(clickedItemContainer, insertIndex);
_CreateAndNavigateToNewProfile(insertIndex);
}
else
{
// Otherwise, navigate to the page
_Navigate(*navString);
}
}
else if (const auto profile = clickedItemContainer.Tag().try_as<Editor::ProfileViewModel>())
{
// Navigate to a page with the given profile
contentFrame().Navigate(xaml_typename<Editor::Profiles>(), winrt::make<ProfilePageNavigationState>(profile, _settingsClone.GlobalSettings().ColorSchemes(), *this));
}
}
}
void MainPage::_Navigate(hstring clickedItemTag)
{
if (clickedItemTag == launchTag)
{
contentFrame().Navigate(xaml_typename<Editor::Launch>(), winrt::make<LaunchPageNavigationState>(_settingsClone));
}
else if (clickedItemTag == interactionTag)
{
contentFrame().Navigate(xaml_typename<Editor::Interaction>(), winrt::make<InteractionPageNavigationState>(_settingsClone.GlobalSettings()));
}
else if (clickedItemTag == renderingTag)
{
contentFrame().Navigate(xaml_typename<Editor::Rendering>(), winrt::make<RenderingPageNavigationState>(_settingsClone.GlobalSettings()));
}
else if (clickedItemTag == globalProfileTag)
{
contentFrame().Navigate(xaml_typename<Editor::Profiles>(), winrt::make<ProfilePageNavigationState>(_viewModelForProfile(_settingsClone.ProfileDefaults()), _settingsClone.GlobalSettings().ColorSchemes(), *this));
}
else if (clickedItemTag == colorSchemesTag)
{
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), winrt::make<ColorSchemesPageNavigationState>(_settingsClone.GlobalSettings()));
}
else if (clickedItemTag == globalAppearanceTag)
{
contentFrame().Navigate(xaml_typename<Editor::GlobalAppearance>(), winrt::make<GlobalAppearancePageNavigationState>(_settingsClone.GlobalSettings()));
}
}
void MainPage::OpenJsonTapped(IInspectable const& /*sender*/, Windows::UI::Xaml::Input::TappedRoutedEventArgs const& /*args*/)
{
const CoreWindow window = CoreWindow::GetForCurrentThread();
const auto rAltState = window.GetKeyState(VirtualKey::RightMenu);
const auto lAltState = window.GetKeyState(VirtualKey::LeftMenu);
const bool altPressed = WI_IsFlagSet(lAltState, CoreVirtualKeyStates::Down) ||
WI_IsFlagSet(rAltState, CoreVirtualKeyStates::Down);
const auto target = altPressed ? SettingsTarget::DefaultsFile : SettingsTarget::SettingsFile;
_OpenJsonHandlers(nullptr, target);
}
void MainPage::OpenJsonKeyDown(IInspectable const& /*sender*/, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& args)
{
if (args.Key() == VirtualKey::Enter || args.Key() == VirtualKey::Space)
{
const auto target = args.KeyStatus().IsMenuKeyDown ? SettingsTarget::DefaultsFile : SettingsTarget::SettingsFile;
_OpenJsonHandlers(nullptr, target);
}
}
void MainPage::SaveButton_Click(IInspectable const& /*sender*/, RoutedEventArgs const& /*args*/)
{
_settingsClone.WriteSettingsToDisk();
}
void MainPage::ResetButton_Click(IInspectable const& /*sender*/, RoutedEventArgs const& /*args*/)
{
_settingsClone = _settingsSource.Copy();
_RefreshCurrentPage();
}
void MainPage::_InitializeProfilesList()
{
// Manually create a NavigationViewItem for each profile
// and keep a reference to them in a map so that we
// can easily modify the correct one when the associated
// profile changes.
for (const auto& profile : _settingsClone.AllProfiles())
{
auto navItem = _CreateProfileNavViewItem(_viewModelForProfile(profile));
SettingsNav().MenuItems().Append(navItem);
}
// Top off (the end of the nav view) with the Add Profile item
MUX::Controls::NavigationViewItem addProfileItem;
addProfileItem.Content(box_value(RS_(L"Nav_AddNewProfile/Content")));
addProfileItem.Tag(box_value(addProfileTag));
addProfileItem.SelectsOnInvoked(false);
FontIcon icon;
// This is the "Add" symbol
icon.Glyph(L"\xE710");
addProfileItem.Icon(icon);
SettingsNav().MenuItems().Append(addProfileItem);
}
void MainPage::_CreateAndNavigateToNewProfile(const uint32_t index)
{
const auto newProfile{ _settingsClone.CreateNewProfile() };
const auto profileViewModel{ _viewModelForProfile(newProfile) };
const auto navItem{ _CreateProfileNavViewItem(profileViewModel) };
SettingsNav().MenuItems().InsertAt(index, navItem);
// Select and navigate to the new profile
SettingsNav().SelectedItem(navItem);
contentFrame().Navigate(xaml_typename<Editor::Profiles>(), winrt::make<ProfilePageNavigationState>(profileViewModel, _settingsClone.GlobalSettings().ColorSchemes(), *this));
}
MUX::Controls::NavigationViewItem MainPage::_CreateProfileNavViewItem(const Editor::ProfileViewModel& profile)
{
MUX::Controls::NavigationViewItem profileNavItem;
profileNavItem.Content(box_value(profile.Name()));
profileNavItem.Tag(box_value<Editor::ProfileViewModel>(profile));
const auto iconSource{ IconPathConverter::IconSourceWUX(profile.Icon()) };
WUX::Controls::IconSourceElement icon;
icon.IconSource(iconSource);
profileNavItem.Icon(icon);
return profileNavItem;
}
}

View File

@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "MainPage.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct MainPage : MainPageT<MainPage>
{
MainPage() = delete;
MainPage(const Model::CascadiaSettings& settings);
fire_and_forget UpdateSettings(Model::CascadiaSettings settings);
void OpenJsonKeyDown(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs const& args);
void OpenJsonTapped(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs const& args);
void SettingsNav_Loaded(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void SettingsNav_ItemInvoked(Microsoft::UI::Xaml::Controls::NavigationView const& sender, Microsoft::UI::Xaml::Controls::NavigationViewItemInvokedEventArgs const& args);
void SaveButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void ResetButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
void SetHostingWindow(uint64_t hostingWindow) noexcept;
bool TryPropagateHostingWindow(IInspectable object) noexcept;
TYPED_EVENT(OpenJson, Windows::Foundation::IInspectable, Model::SettingsTarget);
private:
Model::CascadiaSettings _settingsSource;
Model::CascadiaSettings _settingsClone;
std::optional<HWND> _hostingHwnd;
void _InitializeProfilesList();
void _CreateAndNavigateToNewProfile(const uint32_t index);
winrt::Microsoft::UI::Xaml::Controls::NavigationViewItem _CreateProfileNavViewItem(const ProfileViewModel& profile);
void _Navigate(hstring clickedItemTag);
void _RefreshCurrentPage();
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(MainPage);
}

View File

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
// Due to a XAML Compiler bug, it is hard for us to propagate an HWND into a XAML-using runtimeclass.
// To work around that, we'll only propagate the HWND (when we need to) into the settings' toplevel page
// and use IHostedInWindow to hide the implementation detail where we use IInitializeWithWindow (shobjidl_core)
// https://github.com/microsoft/microsoft-ui-xaml/issues/3331
interface IHostedInWindow
{
Boolean TryPropagateHostingWindow(IInspectable i);
}
[default_interface] runtimeclass MainPage : Windows.UI.Xaml.Controls.Page, IHostedInWindow
{
MainPage(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);
void UpdateSettings(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.SettingsTarget> OpenJson;
// Due to the aforementioned bug, we can't use IInitializeWithWindow _here_ either.
// Let's just smuggle the HWND in as a UInt64 :|
void SetHostingWindow(UInt64 window);
}
}

View File

@ -0,0 +1,142 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.Terminal.Settings.Editor.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<AcrylicBrush x:Key="NavigationViewDefaultPaneBackground"
BackgroundSource="Backdrop"
TintColor="{ThemeResource SystemChromeMediumColor}"
TintOpacity="0.5"/>
<AcrylicBrush x:Key="NavigationViewTopPaneBackground"
BackgroundSource="Backdrop"
TintColor="{ThemeResource SystemChromeMediumColor}"
TintOpacity="0.5"/>
<AcrylicBrush x:Key="NavigationViewExpandedPaneBackground"
BackgroundSource="HostBackdrop"
TintColor="{ThemeResource SystemChromeMediumColor}"
TintOpacity="0.7"/>
</ResourceDictionary>
</Page.Resources>
<muxc:NavigationView x:Name="SettingsNav"
IsSettingsVisible="False"
Header="{Binding ElementName=SettingsNav, Path=SelectedItem.Content, Mode=OneWay}"
Loaded="SettingsNav_Loaded"
ItemInvoked="SettingsNav_ItemInvoked"
IsBackButtonVisible="Collapsed">
<muxc:NavigationView.HeaderTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Text="{x:Bind}"
Margin="8,10,0,0"
Style="{StaticResource TitleTextBlockStyle}"/>
</DataTemplate>
</muxc:NavigationView.HeaderTemplate>
<muxc:NavigationView.MenuItems>
<muxc:NavigationViewItem x:Uid="Nav_Launch"
Tag="Launch_Nav">
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE7B5;"/>
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>
<muxc:NavigationViewItem x:Uid="Nav_Interaction"
Tag="Interaction_Nav">
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE7C9;"/>
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>
<muxc:NavigationViewItem x:Uid="Nav_Appearance"
Tag="GlobalAppearance_Nav">
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE771;"/>
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>
<muxc:NavigationViewItem x:Uid="Nav_ColorSchemes"
Tag="ColorSchemes_Nav">
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE790;"/>
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>
<muxc:NavigationViewItem x:Uid="Nav_Rendering"
Tag="Rendering_Nav" >
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE7F8;"/>
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>
<muxc:NavigationViewItemHeader x:Uid="Nav_Profiles"/>
<muxc:NavigationViewItem x:Uid="Nav_ProfileDefaults"
Tag="GlobalProfile_Nav">
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE81E;"/>
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>
</muxc:NavigationView.MenuItems>
<muxc:NavigationView.PaneFooter>
<!--The OpenJson item needs both Tapped and KeyDown handler-->
<muxc:NavigationViewItem x:Uid="Nav_OpenJSON"
Tapped="OpenJsonTapped"
KeyDown="OpenJsonKeyDown">
<muxc:NavigationViewItem.Icon>
<FontIcon Glyph="&#xE713;"/>
</muxc:NavigationViewItem.Icon>
</muxc:NavigationViewItem>
</muxc:NavigationView.PaneFooter>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Frame x:Name="contentFrame"
Grid.Row="0"></Frame>
<Grid Height="100" Grid.Row="1"
BorderBrush="{ThemeResource SystemBaseLowColor}"
BorderThickness="0,1,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock x:Uid="Settings_UnsavedSettingsWarning"
Visibility="Collapsed"
Foreground="Goldenrod"
FontSize="15"
VerticalAlignment="Center"
HorizontalAlignment="Left"
TextAlignment="Left"
Margin="30,0,0,0"/>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal" Margin="0,0,30,0">
<Button x:Uid="Settings_ResetSettingsButton"
FontSize="15"
ToolTipService.Placement="Mouse"
Click="ResetButton_Click"/>
<Button x:Uid="Settings_SaveSettingsButton"
FontSize="15"
Style="{StaticResource AccentButtonStyle}"
Margin="10,0,0,0"
Click="SaveButton_Click"/>
</StackPanel>
</Grid>
</Grid>
</muxc:NavigationView>
</Page>

View File

@ -0,0 +1,3 @@
EXPORTS
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE

View File

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
We're explicitly telling our references to be non-private so that they won't
be copied into our folder. In the case of Microsoft.Ui.Xaml, it seems to copy
literally everything EXCEPT its .winmd file, which allows us to keep building.
-->
<ItemDefinitionGroup>
<Reference>
<Private>false</Private>
</Reference>
</ItemDefinitionGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{CA5CAD1A-0b5e-45c3-96a8-bb496bfe4e32}</ProjectGuid>
<ProjectName>Microsoft.Terminal.Settings.Editor</ProjectName>
<RootNamespace>Microsoft.Terminal.Settings.Editor</RootNamespace>
<!-- cppwinrt.build.pre.props depends on these settings: -->
<!-- build a dll, not exe (Application) -->
<ConfigurationType>DynamicLibrary</ConfigurationType>
<SubSystem>Console</SubSystem>
<!-- sets a bunch of Windows Universal properties -->
<OpenConsoleUniversalApp>true</OpenConsoleUniversalApp>
<!-- C++/WinRT sets the depth to 1 if there is a XAML file in the project
Unfortunately for us, we need it to be 3. When the namespace merging
depth is 1, Microsoft.Terminal.TerminalControl becomes "Microsoft",
and our WinMD file becomes "Microsoft". Because WinRT is very
namespace-driven, this winmd is considered to contain the entire
Microsoft namespace. This is, obviously, not great. None of our other
projects compile properly when they depend on this "Microsoft.winmd."
-->
<CppWinRTNamespaceMergeDepth>4</CppWinRTNamespaceMergeDepth>
<XamlComponentResourceLocation>nested</XamlComponentResourceLocation>
</PropertyGroup>
<Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.pre.props" />
<!-- ========================= Headers ======================== -->
<ItemGroup>
<ClInclude Include="ColorToBrushConverter.h">
<DependentUpon>ColorToBrushConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="ColorToHexConverter.h">
<DependentUpon>ColorToHexConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="FontWeightConverter.h">
<DependentUpon>FontWeightConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="PercentageConverter.h">
<DependentUpon>PercentageConverter.idl</DependentUpon>
</ClInclude>
<ClInclude Include="EnumEntry.h">
<DependentUpon>EnumEntry.idl</DependentUpon>
</ClInclude>
<ClInclude Include="GlobalAppearance.h">
<DependentUpon>GlobalAppearance.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="ColorSchemes.h">
<DependentUpon>ColorSchemes.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="Interaction.h">
<DependentUpon>Interaction.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Launch.h">
<DependentUpon>Launch.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="MainPage.h">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Profiles.h">
<DependentUpon>Profiles.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="Rendering.h">
<DependentUpon>Rendering.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="Utils.h" />
</ItemGroup>
<!-- ========================= XAML files ======================== -->
<ItemGroup>
<Page Include="CommonResources.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="GlobalAppearance.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="ColorSchemes.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="Interaction.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="Launch.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="MainPage.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="Profiles.xaml">
<SubType>Designer</SubType>
</Page>
<Page Include="Rendering.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<!-- ========================= Cpp Files ======================== -->
<ItemGroup>
<ClCompile Include="ColorToBrushConverter.cpp">
<DependentUpon>ColorToBrushConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="ColorToHexConverter.cpp">
<DependentUpon>ColorToHexConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="FontWeightConverter.cpp">
<DependentUpon>FontWeightConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="PercentageConverter.cpp">
<DependentUpon>PercentageConverter.idl</DependentUpon>
</ClCompile>
<ClCompile Include="GlobalAppearance.cpp">
<DependentUpon>GlobalAppearance.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="ColorSchemes.cpp">
<DependentUpon>ColorSchemes.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="Interaction.cpp">
<DependentUpon>Interaction.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Launch.cpp">
<DependentUpon>Launch.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="MainPage.cpp">
<DependentUpon>MainPage.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="Profiles.cpp">
<DependentUpon>Profiles.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
<ClCompile Include="Rendering.cpp">
<DependentUpon>Rendering.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="Utils.cpp" />
</ItemGroup>
<!-- ========================= idl Files ======================== -->
<ItemGroup>
<Midl Include="ColorToBrushConverter.idl" />
<Midl Include="ColorToHexConverter.idl" />
<Midl Include="FontWeightConverter.idl" />
<Midl Include="PercentageConverter.idl" />
<Midl Include="EnumEntry.idl" />
<Midl Include="GlobalAppearance.idl">
<DependentUpon>GlobalAppearance.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="ColorSchemes.idl">
<DependentUpon>ColorSchemes.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="Launch.idl">
<DependentUpon>Launch.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="Interaction.idl">
<DependentUpon>Interaction.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="Rendering.idl">
<DependentUpon>Rendering.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
<Midl Include="MainPage.idl">
<DependentUpon>MainPage.xaml</DependentUpon>
</Midl>
<Midl Include="Profiles.idl">
<DependentUpon>Profiles.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
</ItemGroup>
<!-- ========================= Misc Files ======================== -->
<ItemGroup>
<PRIResource Include="Resources\en-US\Resources.resw">
<SubType>Designer</SubType>
</PRIResource>
<OCResourceDirectory Include="Resources" />
<None Include="TerminalSettingsEditor.def" />
<None Include="packages.config" />
<None Include="PropertySheet.props" />
</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>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalConnection\TerminalConnection.vcxproj">
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\TerminalControl.vcxproj">
<Private>false</Private>
</ProjectReference>
<ProjectReference Include="$(OpenConsoleDir)src\cascadia\TerminalSettingsModel\dll\Microsoft.Terminal.Settings.Model.vcxproj">
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<Import Project="$(OpenConsoleDir)src\cppwinrt.build.post.props" />
<Import Project="..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets" Condition="Exists('..\..\..\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(OpenConsoleDir)\packages\Microsoft.UI.Xaml.2.5.0-prerelease.201202003\build\native\Microsoft.UI.Xaml.targets'))" />
</Target>
<Import Project="$(SolutionDir)build\rules\CollectWildcardResources.targets" />
</Project>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup>
<ItemGroup>
<PRIResource Include="Resources\en-US\Resources.resw" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="Utils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="Utils.h" />
</ItemGroup>
<ItemGroup>
<Midl Include="ColorToBrushConverter.idl">
<Filter>Converters</Filter>
</Midl>
<Midl Include="ColorToHexConverter.idl">
<Filter>Converters</Filter>
</Midl>
<Midl Include="FontWeightConverter.idl">
<Filter>Converters</Filter>
</Midl>
<Midl Include="PercentageConverter.idl">
<Filter>Converters</Filter>
</Midl>
<Midl Include="EnumEntry.idl" />
</ItemGroup>
<ItemGroup>
<None Include="TerminalSettingsEditor.def" />
<None Include="packages.config" />
<None Include="PropertySheet.props" />
</ItemGroup>
<ItemGroup>
<Page Include="CommonResources.xaml" />
<Page Include="GlobalAppearance.xaml" />
<Page Include="ColorSchemes.xaml" />
<Page Include="Interaction.xaml" />
<Page Include="Launch.xaml" />
<Page Include="MainPage.xaml" />
<Page Include="Profiles.xaml" />
<Page Include="Rendering.xaml" />
</ItemGroup>
<ItemGroup>
<Filter Include="Converters">
<UniqueIdentifier>{00f725c8-41b4-40a8-995e-8ee2e49a4a4c}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "PercentageConverter.h"
#include "PercentageConverter.g.cpp"
using namespace winrt::Windows;
using namespace winrt::Windows::UI::Xaml;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Foundation::IInspectable PercentageConverter::Convert(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /* parameter */,
hstring const& /* language */)
{
const auto decimal{ winrt::unbox_value<double>(value) };
const unsigned int number{ base::ClampMul(decimal, 100u) };
return winrt::box_value<double>(number);
}
Foundation::IInspectable PercentageConverter::ConvertBack(Foundation::IInspectable const& value,
Windows::UI::Xaml::Interop::TypeName const& /* targetType */,
Foundation::IInspectable const& /*parameter*/,
hstring const& /* language */)
{
const auto number{ winrt::unbox_value<double>(value) };
const auto decimal{ base::ClampDiv<double, double>(number, 100) };
return winrt::box_value<double>(decimal);
}
}

View File

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

View File

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

View File

@ -0,0 +1,224 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "Profiles.h"
#include "Profiles.g.cpp"
#include "EnumEntry.h"
#include <LibraryResources.h>
using namespace winrt::Windows::UI::Text;
using namespace winrt::Windows::UI::Xaml;
using namespace winrt::Windows::UI::Xaml::Navigation;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::Storage;
using namespace winrt::Windows::Storage::AccessCache;
using namespace winrt::Windows::Storage::Pickers;
using namespace winrt::Microsoft::Terminal::Settings::Model;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Profiles::Profiles() :
_ColorSchemeList{ single_threaded_observable_vector<ColorScheme>() }
{
InitializeComponent();
INITIALIZE_BINDABLE_ENUM_SETTING(CursorShape, CursorStyle, winrt::Microsoft::Terminal::TerminalControl::CursorStyle, L"Profile_CursorShape", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(BackgroundImageStretchMode, BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch, L"Profile_BackgroundImageStretchMode", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(AntiAliasingMode, TextAntialiasingMode, winrt::Microsoft::Terminal::TerminalControl::TextAntialiasingMode, L"Profile_AntialiasingMode", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(CloseOnExitMode, CloseOnExitMode, winrt::Microsoft::Terminal::Settings::Model::CloseOnExitMode, L"Profile_CloseOnExit", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(BellStyle, BellStyle, winrt::Microsoft::Terminal::Settings::Model::BellStyle, L"Profile_BellStyle", L"Content");
INITIALIZE_BINDABLE_ENUM_SETTING(ScrollState, ScrollbarState, winrt::Microsoft::Terminal::TerminalControl::ScrollbarState, L"Profile_ScrollbarVisibility", L"Content");
// manually add Custom FontWeight option. Don't add it to the Map
INITIALIZE_BINDABLE_ENUM_SETTING(FontWeight, FontWeight, uint16_t, L"Profile_FontWeight", L"Content");
_CustomFontWeight = winrt::make<EnumEntry>(RS_(L"Profile_FontWeightCustom/Content"), winrt::box_value<uint16_t>(0u));
_FontWeightList.Append(_CustomFontWeight);
// manually keep track of all the Background Image Alignment buttons
_BIAlignmentButtons.at(0) = BIAlign_TopLeft();
_BIAlignmentButtons.at(1) = BIAlign_Top();
_BIAlignmentButtons.at(2) = BIAlign_TopRight();
_BIAlignmentButtons.at(3) = BIAlign_Left();
_BIAlignmentButtons.at(4) = BIAlign_Center();
_BIAlignmentButtons.at(5) = BIAlign_Right();
_BIAlignmentButtons.at(6) = BIAlign_BottomLeft();
_BIAlignmentButtons.at(7) = BIAlign_Bottom();
_BIAlignmentButtons.at(8) = BIAlign_BottomRight();
}
void Profiles::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::ProfilePageNavigationState>();
const auto& colorSchemeMap{ _State.Schemes() };
for (const auto& pair : colorSchemeMap)
{
_ColorSchemeList.Append(pair.Value());
}
const auto& biAlignmentVal{ static_cast<int32_t>(_State.Profile().BackgroundImageAlignment()) };
for (const auto& biButton : _BIAlignmentButtons)
{
biButton.IsChecked(biButton.Tag().as<int32_t>() == biAlignmentVal);
}
}
ColorScheme Profiles::CurrentColorScheme()
{
const auto schemeName{ _State.Profile().ColorSchemeName() };
if (const auto scheme{ _State.Schemes().TryLookup(schemeName) })
{
return scheme;
}
else
{
// This Profile points to a color scheme that was renamed or deleted.
// Fallback to Campbell.
return _State.Schemes().TryLookup(L"Campbell");
}
}
void Profiles::CurrentColorScheme(const ColorScheme& val)
{
_State.Profile().ColorSchemeName(val.Name());
}
fire_and_forget Profiles::BackgroundImage_Click(IInspectable const&, RoutedEventArgs const&)
{
auto lifetime = get_strong();
FileOpenPicker picker;
_State.WindowRoot().TryPropagateHostingWindow(picker); // if we don't do this, there's no HWND for it to attach to
picker.ViewMode(PickerViewMode::Thumbnail);
picker.SuggestedStartLocation(PickerLocationId::PicturesLibrary);
// Converted into a BitmapImage. This list of supported image file formats is from BitmapImage documentation
// https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Media.Imaging.BitmapImage?view=winrt-19041#remarks
picker.FileTypeFilter().ReplaceAll({ L".jpg", L".jpeg", L".png", L".bmp", L".gif", L".tiff", L".ico" });
StorageFile file = co_await picker.PickSingleFileAsync();
if (file != nullptr)
{
_State.Profile().BackgroundImagePath(file.Path());
}
}
fire_and_forget Profiles::Icon_Click(IInspectable const&, RoutedEventArgs const&)
{
auto lifetime = get_strong();
FileOpenPicker picker;
_State.WindowRoot().TryPropagateHostingWindow(picker); // if we don't do this, there's no HWND for it to attach to
picker.ViewMode(PickerViewMode::Thumbnail);
picker.SuggestedStartLocation(PickerLocationId::PicturesLibrary);
// Converted into a BitmapIconSource. This list of supported image file formats is from BitmapImage documentation
// https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Media.Imaging.BitmapImage?view=winrt-19041#remarks
picker.FileTypeFilter().ReplaceAll({ L".jpg", L".jpeg", L".png", L".bmp", L".gif", L".tiff", L".ico" });
StorageFile file = co_await picker.PickSingleFileAsync();
if (file != nullptr)
{
_State.Profile().Icon(file.Path());
}
}
fire_and_forget Profiles::Commandline_Click(IInspectable const&, RoutedEventArgs const&)
{
auto lifetime = get_strong();
FileOpenPicker picker;
_State.WindowRoot().TryPropagateHostingWindow(picker); // if we don't do this, there's no HWND for it to attach to
picker.ViewMode(PickerViewMode::Thumbnail);
picker.SuggestedStartLocation(PickerLocationId::ComputerFolder);
picker.FileTypeFilter().ReplaceAll({ L".bat", L".exe", L".cmd" });
StorageFile file = co_await picker.PickSingleFileAsync();
if (file != nullptr)
{
_State.Profile().Commandline(file.Path());
}
}
fire_and_forget Profiles::StartingDirectory_Click(IInspectable const&, RoutedEventArgs const&)
{
auto lifetime = get_strong();
FolderPicker picker;
_State.WindowRoot().TryPropagateHostingWindow(picker); // if we don't do this, there's no HWND for it to attach to
picker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary);
picker.FileTypeFilter().ReplaceAll({ L"*" });
StorageFolder folder = co_await picker.PickSingleFolderAsync();
if (folder != nullptr)
{
StorageApplicationPermissions::FutureAccessList().AddOrReplace(L"PickedFolderToken", folder);
_State.Profile().StartingDirectory(folder.Path());
}
}
IInspectable Profiles::CurrentFontWeight() const
{
// if no value was found, we have a custom value
const auto maybeEnumEntry{ _FontWeightMap.TryLookup(_State.Profile().FontWeight().Weight) };
return maybeEnumEntry ? maybeEnumEntry : _CustomFontWeight;
}
void Profiles::CurrentFontWeight(const IInspectable& enumEntry)
{
if (auto ee = enumEntry.try_as<Editor::EnumEntry>())
{
if (ee != _CustomFontWeight)
{
const auto weight{ winrt::unbox_value<uint16_t>(ee.EnumValue()) };
const Windows::UI::Text::FontWeight setting{ weight };
_State.Profile().FontWeight(setting);
// Profile does not have observable properties
// So the TwoWay binding doesn't update on the State --> Slider direction
FontWeightSlider().Value(weight);
}
_PropertyChangedHandlers(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"IsCustomFontWeight" });
}
}
bool Profiles::IsCustomFontWeight()
{
// Use SelectedItem instead of CurrentFontWeight.
// CurrentFontWeight converts the Profile's value to the appropriate enum entry,
// whereas SelectedItem identifies which one was selected by the user.
return FontWeightComboBox().SelectedItem() == _CustomFontWeight;
}
void Profiles::BIAlignment_Click(IInspectable const& sender, RoutedEventArgs const& /*e*/)
{
if (const auto& button{ sender.try_as<Windows::UI::Xaml::Controls::Primitives::ToggleButton>() })
{
if (const auto& tag{ button.Tag().try_as<int32_t>() })
{
// Update the Profile's value
_State.Profile().BackgroundImageAlignment(static_cast<ConvergedAlignment>(*tag));
// reset all of the buttons to unchecked, except for the one that was clicked
for (const auto& biButton : _BIAlignmentButtons)
{
biButton.IsChecked(biButton == button);
}
}
}
}
void Profiles::CursorShape_Changed(IInspectable const& /*sender*/, RoutedEventArgs const& /*e*/)
{
_PropertyChangedHandlers(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"IsVintageCursor" });
}
bool Profiles::IsVintageCursor() const
{
return _State.Profile().CursorShape() == TerminalControl::CursorStyle::Vintage;
}
}

View File

@ -0,0 +1,130 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Profiles.g.h"
#include "ProfilePageNavigationState.g.h"
#include "ProfileViewModel.g.h"
#include "Utils.h"
#include "ViewModelHelpers.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct ProfileViewModel : ProfileViewModelT<ProfileViewModel>, ViewModelHelper<ProfileViewModel>
{
public:
ProfileViewModel(const Model::Profile& profile) :
_profile{ profile } {}
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, Guid);
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_profile, ConnectionType);
OBSERVABLE_PROJECTED_SETTING(_profile, Name);
OBSERVABLE_PROJECTED_SETTING(_profile, Source);
OBSERVABLE_PROJECTED_SETTING(_profile, Hidden);
OBSERVABLE_PROJECTED_SETTING(_profile, Icon);
OBSERVABLE_PROJECTED_SETTING(_profile, CloseOnExit);
OBSERVABLE_PROJECTED_SETTING(_profile, TabTitle);
OBSERVABLE_PROJECTED_SETTING(_profile, TabColor);
OBSERVABLE_PROJECTED_SETTING(_profile, SuppressApplicationTitle);
OBSERVABLE_PROJECTED_SETTING(_profile, UseAcrylic);
OBSERVABLE_PROJECTED_SETTING(_profile, AcrylicOpacity);
OBSERVABLE_PROJECTED_SETTING(_profile, ScrollState);
OBSERVABLE_PROJECTED_SETTING(_profile, FontFace);
OBSERVABLE_PROJECTED_SETTING(_profile, FontSize);
OBSERVABLE_PROJECTED_SETTING(_profile, FontWeight);
OBSERVABLE_PROJECTED_SETTING(_profile, Padding);
OBSERVABLE_PROJECTED_SETTING(_profile, Commandline);
OBSERVABLE_PROJECTED_SETTING(_profile, StartingDirectory);
OBSERVABLE_PROJECTED_SETTING(_profile, BackgroundImagePath);
OBSERVABLE_PROJECTED_SETTING(_profile, BackgroundImageOpacity);
OBSERVABLE_PROJECTED_SETTING(_profile, BackgroundImageStretchMode);
OBSERVABLE_PROJECTED_SETTING(_profile, BackgroundImageAlignment);
OBSERVABLE_PROJECTED_SETTING(_profile, AntialiasingMode);
OBSERVABLE_PROJECTED_SETTING(_profile, RetroTerminalEffect);
OBSERVABLE_PROJECTED_SETTING(_profile, ForceFullRepaintRendering);
OBSERVABLE_PROJECTED_SETTING(_profile, SoftwareRendering);
OBSERVABLE_PROJECTED_SETTING(_profile, ColorSchemeName);
OBSERVABLE_PROJECTED_SETTING(_profile, Foreground);
OBSERVABLE_PROJECTED_SETTING(_profile, Background);
OBSERVABLE_PROJECTED_SETTING(_profile, SelectionBackground);
OBSERVABLE_PROJECTED_SETTING(_profile, CursorColor);
OBSERVABLE_PROJECTED_SETTING(_profile, HistorySize);
OBSERVABLE_PROJECTED_SETTING(_profile, SnapOnInput);
OBSERVABLE_PROJECTED_SETTING(_profile, AltGrAliasing);
OBSERVABLE_PROJECTED_SETTING(_profile, CursorShape);
OBSERVABLE_PROJECTED_SETTING(_profile, CursorHeight);
OBSERVABLE_PROJECTED_SETTING(_profile, BellStyle);
private:
Model::Profile _profile;
};
struct ProfilePageNavigationState : ProfilePageNavigationStateT<ProfilePageNavigationState>
{
public:
ProfilePageNavigationState(const Editor::ProfileViewModel& viewModel, const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& schemes, const IHostedInWindow& windowRoot) :
_Profile{ viewModel },
_Schemes{ schemes },
_WindowRoot{ windowRoot }
{
}
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> Schemes() { return _Schemes; }
void Schemes(const Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme>& val) { _Schemes = val; }
GETSET_PROPERTY(IHostedInWindow, WindowRoot, nullptr);
GETSET_PROPERTY(Editor::ProfileViewModel, Profile, nullptr);
private:
Windows::Foundation::Collections::IMapView<hstring, Model::ColorScheme> _Schemes;
};
struct Profiles : ProfilesT<Profiles>
{
public:
Profiles();
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
Model::ColorScheme CurrentColorScheme();
void CurrentColorScheme(const Model::ColorScheme& val);
fire_and_forget BackgroundImage_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
fire_and_forget Commandline_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
fire_and_forget StartingDirectory_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
fire_and_forget Icon_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
void BIAlignment_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::RoutedEventArgs const& e);
// CursorShape visibility logic
void CursorShape_Changed(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e);
bool IsVintageCursor() const;
// manually bind FontWeight
winrt::Windows::Foundation::IInspectable CurrentFontWeight() const;
void CurrentFontWeight(const winrt::Windows::Foundation::IInspectable& enumEntry);
bool IsCustomFontWeight();
GETSET_PROPERTY(winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>, FontWeightList);
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
GETSET_PROPERTY(Editor::ProfilePageNavigationState, State, nullptr);
GETSET_PROPERTY(Windows::Foundation::Collections::IObservableVector<Model::ColorScheme>, ColorSchemeList, nullptr);
GETSET_BINDABLE_ENUM_SETTING(CursorShape, winrt::Microsoft::Terminal::TerminalControl::CursorStyle, State().Profile, CursorShape);
GETSET_BINDABLE_ENUM_SETTING(BackgroundImageStretchMode, winrt::Windows::UI::Xaml::Media::Stretch, State().Profile, BackgroundImageStretchMode);
GETSET_BINDABLE_ENUM_SETTING(AntiAliasingMode, winrt::Microsoft::Terminal::TerminalControl::TextAntialiasingMode, State().Profile, AntialiasingMode);
GETSET_BINDABLE_ENUM_SETTING(CloseOnExitMode, winrt::Microsoft::Terminal::Settings::Model::CloseOnExitMode, State().Profile, CloseOnExit);
GETSET_BINDABLE_ENUM_SETTING(BellStyle, winrt::Microsoft::Terminal::Settings::Model::BellStyle, State().Profile, BellStyle);
GETSET_BINDABLE_ENUM_SETTING(ScrollState, winrt::Microsoft::Terminal::TerminalControl::ScrollbarState, State().Profile, ScrollState);
private:
winrt::Windows::Foundation::Collections::IMap<uint16_t, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _FontWeightMap;
Editor::EnumEntry _CustomFontWeight{ nullptr };
std::array<Windows::UI::Xaml::Controls::Primitives::ToggleButton, 9> _BIAlignmentButtons;
};
};
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(Profiles);
}

View File

@ -0,0 +1,92 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "EnumEntry.idl";
import "MainPage.idl";
#include "ViewModelHelpers.idl.h"
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass ProfileViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
OBSERVABLE_PROJECTED_SETTING(String, Name);
OBSERVABLE_PROJECTED_SETTING(Guid, Guid);
OBSERVABLE_PROJECTED_SETTING(String, Source);
OBSERVABLE_PROJECTED_SETTING(Guid, ConnectionType);
OBSERVABLE_PROJECTED_SETTING(Boolean, Hidden);
OBSERVABLE_PROJECTED_SETTING(String, Icon);
OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.Settings.Model.CloseOnExitMode, CloseOnExit);
OBSERVABLE_PROJECTED_SETTING(String, TabTitle);
OBSERVABLE_PROJECTED_SETTING(Windows.Foundation.IReference<Windows.UI.Color>, TabColor);
OBSERVABLE_PROJECTED_SETTING(Boolean, SuppressApplicationTitle);
OBSERVABLE_PROJECTED_SETTING(Boolean, UseAcrylic);
OBSERVABLE_PROJECTED_SETTING(Double, AcrylicOpacity);
OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.TerminalControl.ScrollbarState, ScrollState);
OBSERVABLE_PROJECTED_SETTING(String, FontFace);
OBSERVABLE_PROJECTED_SETTING(Int32, FontSize);
OBSERVABLE_PROJECTED_SETTING(Windows.UI.Text.FontWeight, FontWeight);
OBSERVABLE_PROJECTED_SETTING(String, Padding);
OBSERVABLE_PROJECTED_SETTING(String, Commandline);
OBSERVABLE_PROJECTED_SETTING(String, StartingDirectory);
OBSERVABLE_PROJECTED_SETTING(String, BackgroundImagePath);
OBSERVABLE_PROJECTED_SETTING(Double, BackgroundImageOpacity);
OBSERVABLE_PROJECTED_SETTING(Windows.UI.Xaml.Media.Stretch, BackgroundImageStretchMode);
OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.Settings.Model.ConvergedAlignment, BackgroundImageAlignment);
OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.TerminalControl.TextAntialiasingMode, AntialiasingMode);
OBSERVABLE_PROJECTED_SETTING(Boolean, RetroTerminalEffect);
OBSERVABLE_PROJECTED_SETTING(Boolean, ForceFullRepaintRendering);
OBSERVABLE_PROJECTED_SETTING(Boolean, SoftwareRendering);
OBSERVABLE_PROJECTED_SETTING(String, ColorSchemeName);
OBSERVABLE_PROJECTED_SETTING(Windows.Foundation.IReference<Windows.UI.Color>, Foreground);
OBSERVABLE_PROJECTED_SETTING(Windows.Foundation.IReference<Windows.UI.Color>, Background);
OBSERVABLE_PROJECTED_SETTING(Windows.Foundation.IReference<Windows.UI.Color>, SelectionBackground);
OBSERVABLE_PROJECTED_SETTING(Windows.Foundation.IReference<Windows.UI.Color>, CursorColor);
OBSERVABLE_PROJECTED_SETTING(Int32, HistorySize);
OBSERVABLE_PROJECTED_SETTING(Boolean, SnapOnInput);
OBSERVABLE_PROJECTED_SETTING(Boolean, AltGrAliasing);
OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.TerminalControl.CursorStyle, CursorShape);
OBSERVABLE_PROJECTED_SETTING(UInt32, CursorHeight);
OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.Settings.Model.BellStyle, BellStyle);
}
runtimeclass ProfilePageNavigationState
{
Windows.Foundation.Collections.IMapView<String, Microsoft.Terminal.Settings.Model.ColorScheme> Schemes;
IHostedInWindow WindowRoot; // necessary to send the right HWND into the file picker dialogs.
ProfileViewModel Profile { get; };
};
[default_interface] runtimeclass Profiles : Windows.UI.Xaml.Controls.Page, Windows.UI.Xaml.Data.INotifyPropertyChanged
{
Profiles();
ProfilePageNavigationState State { get; };
IInspectable CurrentCursorShape;
Boolean IsVintageCursor { get; };
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> CursorShapeList { get; };
IInspectable CurrentBackgroundImageStretchMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> BackgroundImageStretchModeList { get; };
IInspectable CurrentAntiAliasingMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> AntiAliasingModeList { get; };
IInspectable CurrentCloseOnExitMode;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> CloseOnExitModeList { get; };
IInspectable CurrentBellStyle;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> BellStyleList { get; };
IInspectable CurrentScrollState;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> ScrollStateList { get; };
IInspectable CurrentFontWeight;
Boolean IsCustomFontWeight { get; };
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> FontWeightList { get; };
Microsoft.Terminal.Settings.Model.ColorScheme CurrentColorScheme;
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Model.ColorScheme> ColorSchemeList { get; };
}
}

View File

@ -0,0 +1,517 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.Terminal.Settings.Editor.Profiles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:model="using:Microsoft.Terminal.Settings.Model"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:DataType="local:EnumEntry" x:Key="EnumRadioButtonTemplate">
<RadioButton Content="{x:Bind EnumName, Mode=OneWay}"
Style="{StaticResource RadioButtonSettingStyle}"/>
</DataTemplate>
<DataTemplate x:DataType="local:EnumEntry" x:Key="EnumComboBoxItemTemplate">
<TextBlock Text="{x:Bind EnumName, Mode=OneWay}" FontSize="{StaticResource StandardFontSize}"/>
</DataTemplate>
<local:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
<local:PercentageConverter x:Key="PercentageConverter"/>
<local:FontWeightConverter x:Key="FontWeightConverter"/>
</ResourceDictionary>
</Page.Resources>
<Pivot Margin="{StaticResource StandardIndentMargin}" HorizontalAlignment="Left">
<!-- General Tab -->
<PivotItem x:Uid="Profile_General">
<ScrollViewer>
<StackPanel>
<!--Commandline-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<StackPanel Orientation="Horizontal">
<TextBox x:Uid="Profile_Commandline"
x:Name="Commandline"
Text="{x:Bind State.Profile.Commandline, Mode=TwoWay}"
Style="{StaticResource TextBoxSettingStyle}"/>
<Button x:Uid="Profile_CommandlineBrowse"
Click="Commandline_Click"
Style="{StaticResource BrowseButtonStyle}"/>
</StackPanel>
</ContentPresenter>
<!--Starting Directory-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<StackPanel Orientation="Horizontal">
<TextBox x:Uid="Profile_StartingDirectory"
x:Name="StartingDirectory"
Text="{x:Bind State.Profile.StartingDirectory, Mode=TwoWay}"
Style="{StaticResource TextBoxSettingStyle}"/>
<Button x:Uid="Profile_StartingDirectoryBrowse"
Click="StartingDirectory_Click"
Style="{StaticResource BrowseButtonStyle}"/>
</StackPanel>
</ContentPresenter>
<!--Icon-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<StackPanel Orientation="Horizontal">
<TextBox x:Uid="Profile_Icon"
x:Name="Icon"
Text="{x:Bind State.Profile.Icon, Mode=TwoWay}"
FontFamily="Segoe UI, Segoe MDL2 Assets"
Style="{StaticResource TextBoxSettingStyle}"/>
<Button x:Uid="Profile_IconBrowse"
Click="Icon_Click"
Style="{StaticResource BrowseButtonStyle}"/>
</StackPanel>
</ContentPresenter>
<!--Tab Title-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<TextBox x:Uid="Profile_TabTitle"
Text="{x:Bind State.Profile.TabTitle, Mode=TwoWay}"
Style="{StaticResource TextBoxSettingStyle}"/>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</PivotItem>
<!-- Appearance Tab -->
<PivotItem x:Uid="Profile_Appearance">
<ScrollViewer>
<StackPanel>
<!--Grouping: Text-->
<TextBlock x:Uid="Profile_TextHeader" Style="{StaticResource GroupingHeader}" Margin="0,0,0,10"/>
<!--Color Scheme-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<ComboBox x:Uid="Profile_ColorScheme"
ItemsSource="{x:Bind ColorSchemeList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentColorScheme, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="model:ColorScheme">
<TextBlock Text="{x:Bind Name, Mode=OneWay}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</ContentPresenter>
<!--Font Face-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<TextBox x:Uid="Profile_FontFace"
Text="{x:Bind State.Profile.FontFace, Mode=TwoWay}"
Style="{StaticResource TextBoxSettingStyle}"/>
</ContentPresenter>
<!--Font Size-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:NumberBox x:Uid="Profile_FontSize"
Value="{x:Bind State.Profile.FontSize, Mode=TwoWay}"
Style="{StaticResource NumberBoxSettingStyle}"
SmallChange="1"
LargeChange="10"/>
</ContentPresenter>
<!--Font Weight-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<StackPanel>
<ComboBox x:Uid="Profile_FontWeight"
x:Name="FontWeightComboBox"
ItemsSource="{x:Bind FontWeightList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentFontWeight, Mode=TwoWay}"
ItemTemplate="{StaticResource EnumComboBoxItemTemplate}"
Style="{StaticResource ComboBoxSettingStyle}"/>
<!--Custom Font Weight Control-->
<Grid Margin="0,10,0,0"
Visibility="{x:Bind IsCustomFontWeight, Mode=OneWay}"
Style="{StaticResource CustomSliderControlGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Slider x:Name="FontWeightSlider"
Grid.Column="0"
Minimum="0" Maximum="1000"
TickFrequency="50" TickPlacement="Outside"
Value="{x:Bind State.Profile.FontWeight,
Converter={StaticResource FontWeightConverter},
Mode=TwoWay}"/>
<TextBlock Grid.Column="1"
Text="{Binding ElementName=FontWeightSlider, Path=Value, Mode=OneWay}"
Style="{StaticResource SliderValueLabelStyle}"
Margin="10,0,0,0"/>
</Grid>
</StackPanel>
</ContentPresenter>
<!--Retro Terminal Effect-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Profile_RetroTerminalEffect"
IsChecked="{x:Bind State.Profile.RetroTerminalEffect, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Grouping: Window-->
<TextBlock x:Uid="Profile_WindowHeader" Style="{StaticResource GroupingHeader}"/>
<!--Padding-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<TextBox x:Uid="Profile_Padding"
Text="{x:Bind State.Profile.Padding, Mode=TwoWay}"
Style="{StaticResource TextBoxSettingStyle}"/>
</ContentPresenter>
<!--Scrollbar Visibility-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Profile_ScrollbarVisibility"
ItemsSource="{x:Bind ScrollStateList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentScrollState, Mode=TwoWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--Grouping: Cursor-->
<TextBlock x:Uid="Profile_CursorHeader" Style="{StaticResource GroupingHeader}"/>
<!--Cursor Shape-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Profile_CursorShape"
ItemsSource="{x:Bind CursorShapeList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentCursorShape, Mode=TwoWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
SelectionChanged="CursorShape_Changed"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--Cursor Height-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}"
Visibility="{x:Bind IsVintageCursor, Mode=OneWay}">
<muxc:NumberBox x:Uid="Profile_CursorHeight"
Value="{x:Bind State.Profile.CursorHeight, Mode=TwoWay}"
Style="{StaticResource NumberBoxSettingStyle}"
SmallChange="1"
LargeChange="10"/>
</ContentPresenter>
<!--Grouping: Background-->
<TextBlock x:Uid="Profile_BackgroundHeader" Style="{StaticResource GroupingHeader}"/>
<!--Background Image-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<StackPanel Orientation="Horizontal">
<TextBox x:Uid="Profile_BackgroundImage"
x:Name="BackgroundImage"
Text="{x:Bind State.Profile.BackgroundImagePath, Mode=TwoWay}"
Style="{StaticResource TextBoxSettingStyle}"/>
<Button x:Uid="Profile_BackgroundImageBrowse"
Click="BackgroundImage_Click"
Style="{StaticResource BrowseButtonStyle}"/>
</StackPanel>
</ContentPresenter>
<!--Background Image Stretch Mode-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Profile_BackgroundImageStretchMode"
ItemsSource="{x:Bind BackgroundImageStretchModeList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentBackgroundImageStretchMode, Mode=TwoWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--Background Image Alignment-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<StackPanel HorizontalAlignment="Left">
<TextBlock x:Uid="Profile_BackgroundImageAlignment"
Style="{StaticResource CustomSettingHeaderStyle}"
ToolTipService.Placement="Mouse"/>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="ToggleButton" BasedOn="{StaticResource DefaultToggleButtonStyle}">
<Setter Property="Margin" Value="2"/>
<Setter Property="Width" Value="40"/>
<Setter Property="Height" Value="40"/>
<Setter Property="ToolTipService.Placement" Value="Mouse"/>
</Style>
</Grid.Resources>
<!--Top Row-->
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentTopLeft"
x:Name="BIAlign_TopLeft"
Grid.Row="0" Grid.Column="0"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Left (0x01)-->
<x:Int32>17</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE744;" RenderTransformOrigin="0.5,0.5">
<FontIcon.RenderTransform>
<RotateTransform Angle="90"/>
</FontIcon.RenderTransform>
</FontIcon>
</ToggleButton.Content>
</ToggleButton>
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentTop"
x:Name="BIAlign_Top"
Grid.Row="0" Grid.Column="1"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Center (0x00)-->
<x:Int32>16</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE745;" RenderTransformOrigin="0.5,0.5">
<FontIcon.RenderTransform>
<RotateTransform Angle="180"/>
</FontIcon.RenderTransform>
</FontIcon>
</ToggleButton.Content>
</ToggleButton>
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentTopRight"
x:Name="BIAlign_TopRight"
Grid.Row="0" Grid.Column="2"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Top (0x10) | Horizontal_Right (0x02)-->
<x:Int32>18</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xEA5F;" RenderTransformOrigin="0.5,0.5">
<FontIcon.RenderTransform>
<RotateTransform Angle="270"/>
</FontIcon.RenderTransform>
</FontIcon>
</ToggleButton.Content>
</ToggleButton>
<!--Middle Row-->
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentLeft"
x:Name="BIAlign_Left"
Grid.Row="1" Grid.Column="0"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Left (0x01)-->
<x:Int32>1</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE746;"/>
</ToggleButton.Content>
</ToggleButton>
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentCenter"
x:Name="BIAlign_Center"
Grid.Row="1" Grid.Column="1"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Center (0x00)-->
<x:Int32>0</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xF16E;"/>
</ToggleButton.Content>
</ToggleButton>
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentRight"
x:Name="BIAlign_Right"
Grid.Row="1" Grid.Column="2"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Center (0x00) | Horizontal_Right (0x02)-->
<x:Int32>2</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xEA61;"/>
</ToggleButton.Content>
</ToggleButton>
<!--Bottom Row-->
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentBottomLeft"
x:Name="BIAlign_BottomLeft"
Grid.Row="2" Grid.Column="0"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Bottom (0x20) | Horizontal_Left (0x01)-->
<x:Int32>33</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE744;"/>
</ToggleButton.Content>
</ToggleButton>
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentBottom"
x:Name="BIAlign_Bottom"
Grid.Row="2" Grid.Column="1"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Bottom (0x20) | Horizontal_Center (0x00)-->
<x:Int32>32</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE745;"/>
</ToggleButton.Content>
</ToggleButton>
<ToggleButton x:Uid="Profile_BackgroundImageAlignmentBottomRight"
x:Name="BIAlign_BottomRight"
Grid.Row="2" Grid.Column="2"
Click="BIAlignment_Click">
<ToggleButton.Tag>
<!--ConvergedAlignment: Vertical_Top (0x20) | Horizontal_Right (0x02)-->
<x:Int32>34</x:Int32>
</ToggleButton.Tag>
<ToggleButton.Content>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xEA5F;"/>
</ToggleButton.Content>
</ToggleButton>
</Grid>
</StackPanel>
</ContentPresenter>
<!--Background Image Opacity-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<StackPanel>
<TextBlock x:Uid="Profile_BackgroundImageOpacity"
Style="{StaticResource SliderHeaderStyle}"/>
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Slider x:Name="BIOpacitySlider"
Grid.Column="0"
Value="{x:Bind State.Profile.BackgroundImageOpacity, Converter={StaticResource PercentageConverter}, Mode=TwoWay}"/>
<TextBlock Grid.Column="1"
Text="{Binding ElementName=BIOpacitySlider, Path=Value, Mode=OneWay}"
Style="{StaticResource SliderValueLabelStyle}"/>
</Grid>
</StackPanel>
</ContentPresenter>
<!--Grouping: Acrylic-->
<TextBlock x:Uid="Profile_AcrylicHeader" Style="{StaticResource GroupingHeader}"/>
<!--Use Acrylic-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Profile_UseAcrylic"
x:Name="UseAcrylicCheckBox"
IsChecked="{x:Bind State.Profile.UseAcrylic, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Acrylic Opacity-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}"
Visibility="{Binding ElementName=UseAcrylicCheckBox, Path=IsChecked, Mode=OneWay}">
<StackPanel x:Name="AcrylicOpacityControl">
<TextBlock x:Uid="Profile_AcrylicOpacity"
Style="{StaticResource SliderHeaderStyle}"/>
<Grid Style="{StaticResource CustomSliderControlGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Slider x:Name="AcrylicOpacitySlider"
Grid.Column="0"
Value="{x:Bind State.Profile.AcrylicOpacity, Converter={StaticResource PercentageConverter}, Mode=TwoWay}"/>
<TextBlock Grid.Column="1"
Text="{Binding ElementName=AcrylicOpacitySlider, Path=Value, Mode=OneWay}"
Style="{StaticResource SliderValueLabelStyle}"/>
</Grid>
</StackPanel>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</PivotItem>
<!-- Advanced Tab -->
<PivotItem x:Uid="Profile_Advanced">
<ScrollViewer>
<StackPanel>
<!--Hidden-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Profile_Hidden"
IsChecked="{x:Bind State.Profile.Hidden, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Suppress Application Title-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Profile_SuppressApplicationTitle"
IsChecked="{x:Bind State.Profile.SuppressApplicationTitle, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Antialiasing Mode-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Profile_AntialiasingMode"
ItemsSource="{x:Bind AntiAliasingModeList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentAntiAliasingMode, Mode=TwoWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--AltGr Aliasing-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Profile_AltGrAliasing"
IsChecked="{x:Bind State.Profile.AltGrAliasing, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Snap On Input-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Profile_SnapOnInput"
IsChecked="{x:Bind State.Profile.SnapOnInput, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--History Size-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:NumberBox x:Uid="Profile_HistorySize"
Value="{x:Bind State.Profile.HistorySize, Mode=TwoWay}"
Style="{StaticResource NumberBoxSettingStyle}"
SmallChange="10"
LargeChange="100"/>
</ContentPresenter>
<!--Close On Exit-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Profile_CloseOnExit"
ItemsSource="{x:Bind CloseOnExitModeList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentCloseOnExitMode, Mode=TwoWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
<!--Bell Style-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<muxc:RadioButtons x:Uid="Profile_BellStyle"
ItemsSource="{x:Bind BellStyleList, Mode=OneWay}"
SelectedItem="{x:Bind CurrentBellStyle, Mode=TwoWay}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"
Style="{StaticResource RadioButtonsSettingStyle}"/>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</PivotItem>
</Pivot>
</Page>

View File

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "Rendering.h"
#include "Rendering.g.cpp"
#include "RenderingPageNavigationState.g.cpp"
using namespace winrt::Windows::UI::Xaml::Navigation;
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
Rendering::Rendering()
{
InitializeComponent();
}
void Rendering::OnNavigatedTo(const NavigationEventArgs& e)
{
_State = e.Parameter().as<Editor::RenderingPageNavigationState>();
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "Rendering.g.h"
#include "RenderingPageNavigationState.g.h"
#include "Utils.h"
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
struct RenderingPageNavigationState : RenderingPageNavigationStateT<RenderingPageNavigationState>
{
public:
RenderingPageNavigationState(const Model::GlobalAppSettings& settings) :
_Globals{ settings } {}
GETSET_PROPERTY(Model::GlobalAppSettings, Globals, nullptr)
};
struct Rendering : RenderingT<Rendering>
{
Rendering();
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
GETSET_PROPERTY(Editor::RenderingPageNavigationState, State, nullptr);
};
}
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
{
BASIC_FACTORY(Rendering);
}

View File

@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace Microsoft.Terminal.Settings.Editor
{
runtimeclass RenderingPageNavigationState
{
Microsoft.Terminal.Settings.Model.GlobalAppSettings Globals;
};
[default_interface] runtimeclass Rendering : Windows.UI.Xaml.Controls.Page
{
Rendering();
RenderingPageNavigationState State { get; };
}
}

View File

@ -0,0 +1,41 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<Page
x:Class="Microsoft.Terminal.Settings.Editor.Rendering"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<ScrollViewer>
<StackPanel Style="{StaticResource SettingsStackStyle}">
<TextBlock x:Uid="Globals_RenderingDisclaimer"
FontSize="{StaticResource StandardFontSize}"
FontStyle="Italic"
Margin="0,0,0,20"/>
<!--Force Full Repaint-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_ForceFullRepaint"
IsChecked="{x:Bind State.Globals.ForceFullRepaintRendering, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
<!--Software Rendering-->
<ContentPresenter Style="{StaticResource SettingContainerStyle}">
<CheckBox x:Uid="Globals_SoftwareRendering"
IsChecked="{x:Bind State.Globals.SoftwareRendering, Mode=TwoWay}"
Style="{StaticResource CheckBoxSettingStyle}"/>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</Page>

View File

@ -0,0 +1,744 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ColorScheme_Background.Text" xml:space="preserve">
<value>Background</value>
</data>
<data name="ColorScheme_Black.Header" xml:space="preserve">
<value>Black</value>
</data>
<data name="ColorScheme_Blue.Header" xml:space="preserve">
<value>Blue</value>
</data>
<data name="ColorScheme_BrightBlack.Header" xml:space="preserve">
<value>Bright black</value>
</data>
<data name="ColorScheme_BrightBlue.Header" xml:space="preserve">
<value>Bright blue</value>
</data>
<data name="ColorScheme_BrightCyan.Header" xml:space="preserve">
<value>Bright cyan</value>
</data>
<data name="ColorScheme_BrightGreen.Header" xml:space="preserve">
<value>Bright green</value>
</data>
<data name="ColorScheme_BrightPurple.Header" xml:space="preserve">
<value>Bright purple</value>
</data>
<data name="ColorScheme_BrightRed.Header" xml:space="preserve">
<value>Bright red</value>
</data>
<data name="ColorScheme_BrightWhite.Header" xml:space="preserve">
<value>Bright white</value>
</data>
<data name="ColorScheme_BrightYellow.Header" xml:space="preserve">
<value>Bright yellow</value>
</data>
<data name="ColorScheme_CursorColor.Text" xml:space="preserve">
<value>Cursor color</value>
</data>
<data name="ColorScheme_Cyan.Header" xml:space="preserve">
<value>Cyan</value>
</data>
<data name="ColorScheme_Foreground.Text" xml:space="preserve">
<value>Foreground</value>
</data>
<data name="ColorScheme_Green.Header" xml:space="preserve">
<value>Green</value>
</data>
<data name="ColorScheme_Purple.Header" xml:space="preserve">
<value>Purple</value>
</data>
<data name="ColorScheme_SelectionBackground.Text" xml:space="preserve">
<value>Selection background</value>
</data>
<data name="ColorScheme_Red.Header" xml:space="preserve">
<value>Red</value>
</data>
<data name="ColorScheme_White.Header" xml:space="preserve">
<value>White</value>
</data>
<data name="ColorScheme_Yellow.Header" xml:space="preserve">
<value>Yellow</value>
</data>
<data name="Globals_AlwaysShowTabs.Content" xml:space="preserve">
<value>Always show tabs</value>
</data>
<data name="Globals_AlwaysShowTabs.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, tabs are always displayed. When unchecked and 'show the title bar' is checked, tabs only appear after opening a new tab.</value>
<comment>'show the title bar' must match the value for &lt;Globals_ShowTitlebar.Content&gt;.</comment>
</data>
<data name="Globals_ConfirmCloseAllTabs.Content" xml:space="preserve">
<value>Show close all tabs popup</value>
</data>
<data name="Globals_ConfirmCloseAllTabs.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, closing a window with multiple tabs open will require confirmation. When unchecked, the confirmation dialog will not appear.</value>
</data>
<data name="Globals_CopyFormatting.Content" xml:space="preserve">
<value>Copy formatting</value>
</data>
<data name="Globals_CopyFormatting.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the color and font formatting of selected text is also copied to your clipboard. When unchecked, only plain text is copied to your clipboard.</value>
</data>
<data name="Globals_CopyOnSelect.Content" xml:space="preserve">
<value>Copy after selection is made</value>
</data>
<data name="Globals_CopyOnSelect.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, a selection is immediately copied to your clipboard upon creation. When unchecked, the selection persists and awaits further action.</value>
</data>
<data name="Globals_DefaultProfile.Header" xml:space="preserve">
<value>Default profile</value>
</data>
<data name="Globals_DefaultProfile.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Profile that opens when clicking the '+' icon or by typing the key binding assigned to 'newTab'.</value>
</data>
<data name="Globals_ForceFullRepaint.Content" xml:space="preserve">
<value>Redraw entire screen when display updates</value>
</data>
<data name="Globals_ForceFullRepaint.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the terminal will redraw the entire screen each frame. When unchecked, the terminal will render only the updates to the screen between frames.</value>
</data>
<data name="Globals_InitialCols.Text" xml:space="preserve">
<value>Columns:</value>
</data>
<data name="Globals_InitialCols.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>The number of columns displayed in the window upon first load. Measured in characters.</value>
</data>
<data name="Globals_InitialRows.Text" xml:space="preserve">
<value>Rows:</value>
</data>
<data name="Globals_InitialRows.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>The number of rows displayed in the window upon first load. Measured in characters.</value>
</data>
<data name="Globals_LaunchMode.Header" xml:space="preserve">
<value>Launch mode</value>
</data>
<data name="Globals_LaunchMode.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Defines whether the terminal will launch as maximized, full screen, or in a window. Setting this to "Focus" is equivalent to launching the terminal in the "Default" mode, but with the focus mode enabled. Similarly, setting this to "Maximized Focus" will result in launching the terminal in a maximized window with the focus mode enabled.</value>
<comment>"Focus", "Default", and "Maximized Focus" must match Globals_LaunchModeFocus.Content, Globals_LaunchModeDefault.Content, and Globals_LaunchModeMaximizedFocus.Content values respectively.</comment>
</data>
<data name="Globals_LaunchModeDefault.Content" xml:space="preserve">
<value>Default</value>
</data>
<data name="Globals_LaunchModeFullscreen.Content" xml:space="preserve">
<value>Full screen</value>
</data>
<data name="Globals_LaunchModeMaximized.Content" xml:space="preserve">
<value>Maximized</value>
</data>
<data name="Globals_RenderingDisclaimer.Text" xml:space="preserve">
<value>These settings may be useful for troubleshooting an issue, however they will impact your performance.</value>
</data>
<data name="Globals_ShowTitlebar.Content" xml:space="preserve">
<value>Hide the title bar (requires restart)</value>
</data>
<data name="Globals_ShowTitlebar.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the tabs are moved into the title bar and the title bar disappears. When unchecked, the title bar sits above the tabs.</value>
</data>
<data name="Globals_ShowTitleInTitlebar.Content" xml:space="preserve">
<value>Show terminal title in title bar</value>
</data>
<data name="Globals_ShowTitleInTitlebar.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the title bar displays the title of the selected tab. When unchecked, the title bar displays 'Windows Terminal'.</value>
</data>
<data name="Globals_SnapToGridOnResize.Content" xml:space="preserve">
<value>Snap window resizing to character grid</value>
</data>
<data name="Globals_SnapToGridOnResize.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the window will snap to the nearest character boundary on resize. When unchecked, the window will resize smoothly.</value>
</data>
<data name="Globals_SoftwareRendering.Content" xml:space="preserve">
<value>Use software rendering</value>
</data>
<data name="Globals_SoftwareRendering.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the terminal will use the software renderer (a.k.a. WARP) instead of the hardware one.</value>
</data>
<data name="Globals_StartOnUserLogin.Content" xml:space="preserve">
<value>Launch on machine startup</value>
</data>
<data name="Globals_StartOnUserLogin.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, this enables the launch of Windows Terminal at machine startup.</value>
</data>
<data name="Globals_TabWidthMode.Header" xml:space="preserve">
<value>Tab width mode</value>
</data>
<data name="Globals_TabWidthMode.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the width of the tabs. 'Equal' sizes each tab to the same width. 'Title length' sizes each tab to the length of its title. 'Compact' sizes each tab to the length of its title when focused, and shrinks to the size of only the icon when the tab is unfocused.</value>
<comment>'equal' must match the value for &lt;Globals_TabWidthModeEqual.Content&gt;. 'title length' must match the value for &lt;Globals_TabWidthModeTitleLength.Content&gt;. 'compact' must match the value for &lt;Globals_TabWidthModeCompact.Content&gt;.</comment>
</data>
<data name="Globals_TabWidthModeCompact.Content" xml:space="preserve">
<value>Compact</value>
</data>
<data name="Globals_TabWidthModeEqual.Content" xml:space="preserve">
<value>Equal</value>
</data>
<data name="Globals_TabWidthModeTitleLength.Content" xml:space="preserve">
<value>Title length</value>
</data>
<data name="Globals_Theme.Header" xml:space="preserve">
<value>Theme</value>
</data>
<data name="Globals_Theme.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the theme of the application. The value 'default' refers to the active Windows system theme.</value>
<comment>'default' must match the value for &lt;Globals_ThemeDefault.Content&gt;.</comment>
</data>
<data name="Globals_ThemeDark.Content" xml:space="preserve">
<value>Dark</value>
</data>
<data name="Globals_ThemeSystem.Content" xml:space="preserve">
<value>Default</value>
</data>
<data name="Globals_ThemeLight.Content" xml:space="preserve">
<value>Light</value>
</data>
<data name="Globals_WordDelimiters.Header" xml:space="preserve">
<value>Word delimiters</value>
</data>
<data name="Globals_WordDelimiters.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Determines the delimiters used in a double click selection.</value>
</data>
<data name="Nav_Appearance.Content" xml:space="preserve">
<value>Appearance</value>
</data>
<data name="Nav_ColorSchemes.Content" xml:space="preserve">
<value>Color schemes</value>
</data>
<data name="Nav_Interaction.Content" xml:space="preserve">
<value>Interaction</value>
</data>
<data name="Nav_Launch.Content" xml:space="preserve">
<value>Startup</value>
</data>
<data name="Nav_OpenJSON.Content" xml:space="preserve">
<value>Open JSON file</value>
</data>
<data name="Nav_ProfileDefaults.Content" xml:space="preserve">
<value>Base layer</value>
</data>
<data name="Nav_Rendering.Content" xml:space="preserve">
<value>Rendering</value>
</data>
<data name="Profile_AcrylicOpacity.Text" xml:space="preserve">
<value>Acrylic opacity</value>
</data>
<data name="Profile_AcrylicOpacity.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When acrylic is enabled, it sets the transparency of the window for the profile.</value>
</data>
<data name="Profile_Advanced.Header" xml:space="preserve">
<value>Advanced</value>
</data>
<data name="Profile_AltGrAliasing.Content" xml:space="preserve">
<value>AltGr aliasing</value>
</data>
<data name="Profile_AltGrAliasing.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>By default Windows treats Ctrl+Alt as an alias for AltGr. When unchecked, this behavior will be disabled.</value>
</data>
<data name="Profile_AntialiasingMode.Header" xml:space="preserve">
<value>Antialiasing text</value>
</data>
<data name="Profile_AntialiasingMode.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Controls how text is antialiased in the renderer. Note that changing this setting will require starting a new terminal instance.</value>
</data>
<data name="Profile_AntialiasingModeAliased.Content" xml:space="preserve">
<value>Aliased</value>
</data>
<data name="Profile_AntialiasingModeClearType.Content" xml:space="preserve">
<value>ClearType</value>
</data>
<data name="Profile_AntialiasingModeGrayscale.Content" xml:space="preserve">
<value>Grayscale</value>
</data>
<data name="Profile_Appearance.Header" xml:space="preserve">
<value>Appearance</value>
</data>
<data name="Profile_BackgroundColor.Header" xml:space="preserve">
<value>Background color</value>
</data>
<data name="Profile_BackgroundColorToolTip.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the background color of the text. Overrides the background from the color scheme.</value>
</data>
<data name="Profile_BackgroundImage.Header" xml:space="preserve">
<value>Background image</value>
</data>
<data name="Profile_BackgroundImage.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the file location of the image to draw over the window background.</value>
</data>
<data name="Profile_BackgroundImageAlignment.Text" xml:space="preserve">
<value>Background image alignment</value>
</data>
<data name="Profile_BackgroundImageAlignment.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets how the background image aligns to the boundaries of the window.</value>
</data>
<data name="Profile_BackgroundImageAlignmentBottom.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Bottom</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentBottomLeft.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Bottom left</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentBottomRight.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Bottom right</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentCenter.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Center</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentLeft.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Left</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentRight.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Right</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentTop.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Top</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentTopLeft.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Top left</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageAlignmentTopRight.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Top right</value>
<comment>This is the formal name for a visual alignment.</comment>
</data>
<data name="Profile_BackgroundImageBrowse.Content" xml:space="preserve">
<value>Browse...</value>
</data>
<data name="Profile_BackgroundImageOpacity.Text" xml:space="preserve">
<value>Background image opacity</value>
</data>
<data name="Profile_BackgroundImageOpacity.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the transparency of the background image.</value>
</data>
<data name="Profile_BackgroundImageStretchMode.Header" xml:space="preserve">
<value>Background image stretch mode</value>
</data>
<data name="Profile_BackgroundImageStretchMode.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets how the background image is resized to fill the window.</value>
</data>
<data name="Profile_BackgroundImageStretchModeFill.Content" xml:space="preserve">
<value>Fill</value>
</data>
<data name="Profile_BackgroundImageStretchModeNone.Content" xml:space="preserve">
<value>None</value>
</data>
<data name="Profile_BackgroundImageStretchModeUniform.Content" xml:space="preserve">
<value>Uniform</value>
</data>
<data name="Profile_BackgroundImageStretchModeUniformToFill.Content" xml:space="preserve">
<value>Uniform to fill</value>
</data>
<data name="Profile_CloseOnExit.Header" xml:space="preserve">
<value>How the profile closes</value>
</data>
<data name="Profile_CloseOnExit.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets how the profile reacts to termination or failure to launch. Graceful will close when exit is typed or the process exits normally.</value>
</data>
<data name="Profile_CloseOnExitAlways.Content" xml:space="preserve">
<value>Always</value>
</data>
<data name="Profile_CloseOnExitGraceful.Content" xml:space="preserve">
<value>Graceful</value>
</data>
<data name="Profile_CloseOnExitNever.Content" xml:space="preserve">
<value>Never</value>
</data>
<data name="Profile_ColorScheme.Header" xml:space="preserve">
<value>Color scheme</value>
</data>
<data name="Profile_ColorScheme.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Name of the color scheme to use.</value>
</data>
<data name="Profile_Commandline.Header" xml:space="preserve">
<value>Command line</value>
</data>
<data name="Profile_Commandline.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Executable used in the profile.</value>
</data>
<data name="Profile_CommandlineBrowse.Content" xml:space="preserve">
<value>Browse...</value>
</data>
<data name="Profile_CursorColor.Header" xml:space="preserve">
<value>Cursor color</value>
</data>
<data name="Profile_CursorColorToolTip.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the color of the cursor. Overrides the cursor color from the color scheme.</value>
</data>
<data name="Profile_CursorHeight.Header" xml:space="preserve">
<value>Cursor height</value>
</data>
<data name="Profile_CursorHeight.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the percentage height of the cursor starting from the bottom. Only works with the vintage cursor shape.</value>
</data>
<data name="Profile_CursorShape.Header" xml:space="preserve">
<value>Cursor shape</value>
</data>
<data name="Profile_CursorShape.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the shape of the cursor.</value>
</data>
<data name="Profile_CursorShapeBar.Content" xml:space="preserve">
<value>Bar</value>
</data>
<data name="Profile_CursorShapeEmptyBox.Content" xml:space="preserve">
<value>Empty box</value>
</data>
<data name="Profile_CursorShapeFilledBox.Content" xml:space="preserve">
<value>Filled box</value>
</data>
<data name="Profile_CursorShapeUnderscore.Content" xml:space="preserve">
<value>Underscore</value>
</data>
<data name="Profile_CursorShapeVintage.Content" xml:space="preserve">
<value>Vintage</value>
</data>
<data name="Profile_FontFace.Header" xml:space="preserve">
<value>Font face</value>
</data>
<data name="Profile_FontFace.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Name of the font face used in the profile.</value>
</data>
<data name="Profile_FontSize.Header" xml:space="preserve">
<value>Font size</value>
</data>
<data name="Profile_FontSize.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Size of the font in points.</value>
</data>
<data name="Profile_FontWeight.Header" xml:space="preserve">
<value>Font weight</value>
</data>
<data name="Profile_FontWeight.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the weight (lightness or heaviness of the strokes) for the given font.</value>
</data>
<data name="Profile_ForegroundColor.Header" xml:space="preserve">
<value>Foreground color</value>
</data>
<data name="Profile_ForegroundColorToolTip.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the text color. Overrides the foreground from the color scheme.</value>
</data>
<data name="Profile_General.Header" xml:space="preserve">
<value>General</value>
</data>
<data name="Profile_Hidden.Content" xml:space="preserve">
<value>Hide profile from dropdown</value>
</data>
<data name="Profile_Hidden.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>If checked, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamically generated profiles, while leaving them in your settings file.</value>
</data>
<data name="Profile_HistorySize.Header" xml:space="preserve">
<value>History size</value>
</data>
<data name="Profile_HistorySize.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>The number of lines above the ones displayed in the window you can scroll back to.</value>
</data>
<data name="Profile_Icon.Header" xml:space="preserve">
<value>Icon</value>
</data>
<data name="Profile_Icon.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Image file location of the icon used in the profile. Displays within the tab and the dropdown menu.</value>
</data>
<data name="Profile_IconBrowse.Content" xml:space="preserve">
<value>Browse...</value>
</data>
<data name="Profile_Padding.Header" xml:space="preserve">
<value>Padding</value>
</data>
<data name="Profile_Padding.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the padding around the text within the window. Can have three different formats: '#' sets the same padding for all sides. '#, #' sets the same padding for left-right and top-bottom. '#, #, #, #' sets the padding individually for left, top, right, and bottom.</value>
</data>
<data name="Profile_RetroTerminalEffect.Content" xml:space="preserve">
<value>Retro terminal effects</value>
</data>
<data name="Profile_RetroTerminalEffect.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, enables retro terminal effects such as glowing text and scan lines.</value>
</data>
<data name="Profile_ScrollbarVisibility.Header" xml:space="preserve">
<value>Scrollbar visibility</value>
</data>
<data name="Profile_ScrollbarVisibility.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Defines the visibility of the scrollbar.</value>
</data>
<data name="Profile_ScrollbarVisibilityHidden.Content" xml:space="preserve">
<value>Hidden</value>
</data>
<data name="Profile_ScrollbarVisibilityVisible.Content" xml:space="preserve">
<value>Visible</value>
</data>
<data name="Profile_SelectionBackgroundColor.Header" xml:space="preserve">
<value>Selection background color</value>
</data>
<data name="Profile_SelectionBackgroundColorToolTip.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Sets the background color of selected text. Overrides the selection background set in the color scheme.</value>
</data>
<data name="Profile_SnapOnInput.Content" xml:space="preserve">
<value>Scroll to input when typing</value>
</data>
<data name="Profile_SnapOnInput.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the window will scroll to the command input line when typing. Otherwise, the window will not scroll when you start typing.</value>
</data>
<data name="Profile_StartingDirectory.Header" xml:space="preserve">
<value>Starting directory</value>
</data>
<data name="Profile_StartingDirectory.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>The directory the shell starts in when it is loaded.</value>
</data>
<data name="Profile_StartingDirectoryBrowse.Content" xml:space="preserve">
<value>Browse...</value>
</data>
<data name="Profile_SuppressApplicationTitle.Content" xml:space="preserve">
<value>Suppress title changes</value>
</data>
<data name="Profile_SuppressApplicationTitle.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the tab title overrides the default title of the tab and any title change messages from the application will be suppressed.</value>
</data>
<data name="Profile_TabTitle.Header" xml:space="preserve">
<value>Tab title</value>
</data>
<data name="Profile_TabTitle.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Replaces the name as the title to pass to the shell on startup. Some shells (like bash) may choose to ignore this initial value, while others (CMD, PowerShell) may use this value over the lifetime of the application.</value>
</data>
<data name="Profile_UseAcrylic.Content" xml:space="preserve">
<value>Enable acrylic</value>
</data>
<data name="Profile_UseAcrylic.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, the window will have an acrylic background. When unchecked, the window will have a plain, untextured background.</value>
</data>
<data name="Settings_ResetSettingsButton.Content" xml:space="preserve">
<value>Discard changes</value>
</data>
<data name="Settings_ResetSettingsButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Discard your unsaved settings.</value>
</data>
<data name="Settings_SaveSettingsButton.Content" xml:space="preserve">
<value>Apply</value>
</data>
<data name="Settings_UnsavedSettingsWarning.Text" xml:space="preserve">
<value>⚠ You have unsaved changes.</value>
<comment>{Locked="⚠"}</comment>
</data>
<data name="Nav_AddNewProfile.Content" xml:space="preserve">
<value>Add new</value>
</data>
<data name="Nav_Profiles.Content" xml:space="preserve">
<value>Profiles</value>
</data>
<data name="Globals_LaunchModeFocus.Content" xml:space="preserve">
<value>Focus</value>
</data>
<data name="Globals_LaunchModeMaximizedFocus.Content" xml:space="preserve">
<value>Maximized focus</value>
</data>
<data name="Profile_BellStyle.Header" xml:space="preserve">
<value>Bell notification style</value>
</data>
<data name="Profile_BellStyle.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Controls what happens when the application emits a BEL character.</value>
<comment>"Audible" and "None" must match the values for Profile_BellStyleAudible.Content and Profile_BellStyleNone.Content respectively.</comment>
</data>
<data name="Profile_BellStyleAudible.Content" xml:space="preserve">
<value>Audible</value>
</data>
<data name="Profile_BellStyleNone.Content" xml:space="preserve">
<value>None</value>
</data>
<data name="Globals_DisableAnimations.Content" xml:space="preserve">
<value>Disable visual animations</value>
</data>
<data name="Globals_DisableAnimations.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>When checked, visual animations will be disabled across the application.</value>
</data>
<data name="Profile_FontWeightBlack.Content" xml:space="preserve">
<value>Black</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightBold.Content" xml:space="preserve">
<value>Bold</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightCustom.Content" xml:space="preserve">
<value>Custom</value>
</data>
<data name="Profile_FontWeightExtra-black.Content" xml:space="preserve">
<value>Extra-Black</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightExtra-bold.Content" xml:space="preserve">
<value>Extra-Bold</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightExtra-light.Content" xml:space="preserve">
<value>Extra-Light</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightLight.Content" xml:space="preserve">
<value>Light</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightMedium.Content" xml:space="preserve">
<value>Medium</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightNormal.Content" xml:space="preserve">
<value>Normal</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightSemi-bold.Content" xml:space="preserve">
<value>Semi-Bold</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightSemi-light.Content" xml:space="preserve">
<value>Semi-Light</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Profile_FontWeightThin.Content" xml:space="preserve">
<value>Thin</value>
<comment>This is the formal name for a font weight.</comment>
</data>
<data name="Globals_LaunchSize.Text" xml:space="preserve">
<value>Launch size</value>
</data>
<data name="Profile_BellStyleAll.Content" xml:space="preserve">
<value>All</value>
</data>
<data name="Profile_BellStyleVisual.Content" xml:space="preserve">
<value>Visual (Flash Taskbar)</value>
</data>
<data name="Profile_AcrylicHeader.Text" xml:space="preserve">
<value>Acrylic</value>
</data>
<data name="Profile_BackgroundHeader.Text" xml:space="preserve">
<value>Background image</value>
</data>
<data name="Profile_CursorHeader.Text" xml:space="preserve">
<value>Cursor</value>
</data>
<data name="Profile_TextHeader.Text" xml:space="preserve">
<value>Text</value>
</data>
<data name="Profile_WindowHeader.Text" xml:space="preserve">
<value>Window</value>
</data>
<data name="Nav_OpenJSON.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Open your settings.json file. Alt+Click to open your defaults.json file.</value>
<comment>{Locked="settings.json"}, {Locked="defaults.json"}</comment>
</data>
</root>

View File

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "pch.h"
#include "Utils.h"
#include <LibraryResources.h>
using namespace winrt;
using namespace winrt::Windows::System;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
UTILS_DEFINE_LIBRARY_RESOURCE_SCOPE(L"Microsoft.Terminal.Settings.Editor/Resources");
namespace winrt::Microsoft::Terminal::Settings
{
hstring GetSelectedItemTag(winrt::Windows::Foundation::IInspectable const& comboBoxAsInspectable)
{
Controls::ComboBox comboBox = comboBoxAsInspectable.as<Controls::ComboBox>();
Controls::ComboBoxItem selectedOption = comboBox.SelectedItem().as<Controls::ComboBoxItem>();
return unbox_value<hstring>(selectedOption.Tag());
}
hstring LocalizedNameForEnumName(const std::wstring_view sectionAndEnumType, const std::wstring_view enumValue, const std::wstring_view propertyType)
{
// Uppercase the first letter to conform to our current Resource keys
auto fmtKey = fmt::format(L"{}{}{}/{}", sectionAndEnumType, char(std::towupper(enumValue[0])), enumValue.substr(1), propertyType);
return GetLibraryResourceString(fmtKey);
}
}

View File

@ -0,0 +1,61 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "../inc/cppwinrt_utils.h"
// This macro must be used alongside GETSET_BINDABLE_ENUM_SETTING.
// Use this in your class's constructor after Initialize_Component().
// It initializes the observable list of enum entries with the enum name
// being its localized name, and also initializes the enum to EnumEntry
// map that's required to tell XAML what enum value the currently active
// setting has.
#define INITIALIZE_BINDABLE_ENUM_SETTING(name, enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \
_##name##List = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \
_##name##Map = winrt::single_threaded_map<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \
auto enumMapping##name = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::##enumMappingsName(); \
for (auto [key, value] : enumMapping##name) \
{ \
auto enumName = LocalizedNameForEnumName(resourceSectionAndType, key, resourceProperty); \
auto entry = winrt::make<winrt::Microsoft::Terminal::Settings::Editor::implementation::EnumEntry>(enumName, winrt::box_value<enumType>(value)); \
_##name##List.Append(entry); \
_##name##Map.Insert(value, entry); \
}
// This macro must be used alongside INITIALIZE_BINDABLE_ENUM_SETTING.
// It declares the needed data structures, getters, and setters to make
// the given enum type bindable to XAML. It provides an observable list
// of EnumEntries so that we may display all possible values of the given
// enum type and its localized names. It also provides a getter and setter
// for the setting we wish to bind to.
#define GETSET_BINDABLE_ENUM_SETTING(name, enumType, settingsModelName, settingNameInModel) \
public: \
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>##name##List() \
{ \
return _##name##List; \
} \
\
winrt::Windows::Foundation::IInspectable Current##name() \
{ \
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_##name##Map.Lookup(##settingsModelName().##settingNameInModel())); \
} \
\
void Current##name(const winrt::Windows::Foundation::IInspectable& enumEntry) \
{ \
if (auto ee = enumEntry.try_as<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>()) \
{ \
auto setting = winrt::unbox_value<enumType>(ee.EnumValue()); \
##settingsModelName().##settingNameInModel(setting); \
} \
} \
\
private: \
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _##name##List; \
winrt::Windows::Foundation::Collections::IMap<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> _##name##Map;
namespace winrt::Microsoft::Terminal::Settings
{
winrt::hstring GetSelectedItemTag(winrt::Windows::Foundation::IInspectable const& comboBoxAsInspectable);
winrt::hstring LocalizedNameForEnumName(const std::wstring_view sectionAndType, const std::wstring_view enumValue, const std::wstring_view propertyType);
}

View File

@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "../inc/cppwinrt_utils.h"
template<typename T>
struct ViewModelHelper
{
public:
winrt::event_token PropertyChanged(::winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
return _propertyChangedHandlers.add(handler);
}
void PropertyChanged(winrt::event_token const& token)
{
_propertyChangedHandlers.remove(token);
}
protected:
void _NotifyChangeCore(const std::wstring_view name)
{
_propertyChangedHandlers(*static_cast<T*>(this), ::winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs{ name });
}
// template recursion base case: single dispatch
void _NotifyChanges(const std::wstring_view name) { _NotifyChangeCore(name); }
template<typename... Args>
void _NotifyChanges(const std::wstring_view name, Args&&... more)
{
_NotifyChangeCore(name);
_NotifyChanges(std::forward<Args>(more)...);
}
private:
winrt::event<::winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler> _propertyChangedHandlers;
};
#define _BASE_OBSERVABLE_PROJECTED_SETTING(target, name) \
public: \
auto name() const noexcept { return target.name(); }; \
template<typename T> \
void name(const T& value) \
{ \
if (name() != value) \
{ \
target.name(value); \
_NotifyChanges(L"Has" #name, L#name); \
} \
} \
bool Has##name() { return target.Has##name(); }
// Defines a setting that reflects another object's same-named
// setting.
#define OBSERVABLE_PROJECTED_SETTING(target, name) \
_BASE_OBSERVABLE_PROJECTED_SETTING(target, name) \
void Clear##name() \
{ \
const auto hadValue{ target.Has##Name() }; \
target.Clear##name(); \
if (hadValue) \
{ \
_NotifyChanges(L"Has" #name, L#name); \
} \
}
// Defines a setting that reflects another object's same-named
// setting, but which cannot be erased.
#define PERMANENT_OBSERVABLE_PROJECTED_SETTING(target, name) \
_BASE_OBSERVABLE_PROJECTED_SETTING(target, name) \
void Clear##name() {}

View File

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#define OBSERVABLE_PROJECTED_SETTING(Type, Name) \
Type Name \
{ \
get; \
set; \
}; \
Boolean Has##Name { get; }; \
void Clear##Name()

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.UI.Xaml" version="2.5.0-prerelease.201202003" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.201017.1" targetFramework="native" />
</packages>

View File

@ -0,0 +1 @@
#include "pch.h"

View File

@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// pch.h
// Header for platform projection include files
//
#pragma once
#define WIN32_LEAN_AND_MEAN
// 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 <unknwn.h>
#include <hstring.h>
#include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Storage.AccessCache.h>
#include <winrt/Windows.Storage.Pickers.h>
#include <winrt/Windows.UI.h>
#include <winrt/Windows.UI.Core.h>
#include <winrt/Windows.UI.Text.h>
#include <winrt/Windows.UI.Input.h>
#include <winrt/Windows.UI.Popups.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Controls.Primitives.h>
#include <winrt/Windows.UI.Xaml.Data.h>
#include <winrt/Windows.UI.Xaml.Input.h>
#include <winrt/Windows.UI.Xaml.Interop.h>
#include <winrt/Windows.UI.Xaml.Markup.h>
#include <winrt/Windows.UI.Xaml.Media.h>
#include <winrt/Windows.UI.Xaml.Navigation.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
#include <winrt/Microsoft.UI.Xaml.XamlTypeInfo.h>
#include <winrt/Microsoft.Terminal.TerminalControl.h>
#include <winrt/Microsoft.Terminal.Settings.Model.h>
#include "shobjidl_core.h"
// Manually include til after we include Windows.Foundation to give it winrt superpowers
#include "til.h"