mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-21 06:18:34 +00:00
Compare commits
43 Commits
feature/ll
...
dev/cazamo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f35541f41 | ||
|
|
03d2e63b98 | ||
|
|
e67fde5af2 | ||
|
|
60a1590fe4 | ||
|
|
4a3811d684 | ||
|
|
410d10d8cc | ||
|
|
216aff3c66 | ||
|
|
d8a00425fb | ||
|
|
d948f8f279 | ||
|
|
6383fff42b | ||
|
|
58e3407de6 | ||
|
|
7c371065ea | ||
|
|
02e5c17ceb | ||
|
|
a175b6291a | ||
|
|
e60562d99d | ||
|
|
96d0762a77 | ||
|
|
53103f6488 | ||
|
|
695a8db6fd | ||
|
|
26069dad5f | ||
|
|
6e05d9ad5c | ||
|
|
c64b2433da | ||
|
|
17538eb499 | ||
|
|
edfc599d6d | ||
|
|
acc1a59367 | ||
|
|
7fed067f43 | ||
|
|
054afcc59d | ||
|
|
0fe41d7db8 | ||
|
|
03dfed4d54 | ||
|
|
84390c5b27 | ||
|
|
b0c1611673 | ||
|
|
5a45c8d7e4 | ||
|
|
fa0f2a7e16 | ||
|
|
56aa5fc73f | ||
|
|
fa2d052ccd | ||
|
|
3ee13c679f | ||
|
|
76f89bff04 | ||
|
|
a7aefad0ba | ||
|
|
bf2cb051b4 | ||
|
|
fbfc761450 | ||
|
|
2fba2ee281 | ||
|
|
87d9fdb1da | ||
|
|
e8a5c32612 | ||
|
|
7cbfb5784a |
2
.github/actions/spelling/expect/expect.txt
vendored
2
.github/actions/spelling/expect/expect.txt
vendored
@@ -17,6 +17,7 @@ ADDSTRING
|
||||
ADDTOOL
|
||||
adml
|
||||
admx
|
||||
Affordance
|
||||
AFill
|
||||
AFX
|
||||
AHelper
|
||||
@@ -1106,7 +1107,6 @@ NOSIZE
|
||||
NOSNAPSHOT
|
||||
NOTHOUSANDS
|
||||
NOTICKS
|
||||
notif
|
||||
NOTIMEOUTIFNOTHUNG
|
||||
NOTIMPL
|
||||
NOTOPMOST
|
||||
|
||||
@@ -344,7 +344,7 @@
|
||||
<TextBlock x:Name="_parentCommandText"
|
||||
Padding="16,4"
|
||||
VerticalAlignment="Center"
|
||||
FontStyle="Italic"
|
||||
FontWeight="SemiBold"
|
||||
Text="{x:Bind ParentCommandName, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
||||
@@ -358,8 +358,8 @@
|
||||
|
||||
<ScrollViewer MaxHeight="200"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock FontStyle="Italic"
|
||||
Text="{x:Bind ParsedCommandLineText, Mode=OneWay}"
|
||||
<TextBlock Text="{x:Bind ParsedCommandLineText, Mode=OneWay}"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap" />
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
@@ -371,7 +371,6 @@
|
||||
Visibility="Collapsed">
|
||||
<TextBlock Padding="12,0"
|
||||
VerticalAlignment="Center"
|
||||
FontStyle="Italic"
|
||||
Text="{x:Bind NoMatchesText, Mode=OneWay}" />
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -152,8 +152,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default style: bold
|
||||
run.FontWeight(FontWeights::Bold());
|
||||
// Default style: semibold
|
||||
run.FontWeight(FontWeights::SemiBold());
|
||||
}
|
||||
inlinesCollection.Append(run);
|
||||
|
||||
|
||||
@@ -443,13 +443,13 @@
|
||||
<value>Open a new tab</value>
|
||||
</data>
|
||||
<data name="NewPaneRun.Text" xml:space="preserve">
|
||||
<value>Alt+Click to split the current window</value>
|
||||
<value>Alt + Click to split the current window</value>
|
||||
</data>
|
||||
<data name="NewWindowRun.Text" xml:space="preserve">
|
||||
<value>Shift+Click to open a new window</value>
|
||||
<value>Shift + Click to open a new window</value>
|
||||
</data>
|
||||
<data name="ElevatedRun.Text" xml:space="preserve">
|
||||
<value>Ctrl+Click to open as administrator</value>
|
||||
<value>Ctrl + Click to open as administrator</value>
|
||||
</data>
|
||||
<data name="WindowCloseButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Close</value>
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
<TextBlock x:Name="_parentCommandText"
|
||||
Padding="16,4"
|
||||
VerticalAlignment="Center"
|
||||
FontStyle="Italic"
|
||||
FontWeight="SemiBold"
|
||||
Text="{x:Bind ParentCommandName, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
||||
@@ -179,7 +179,6 @@
|
||||
Visibility="Collapsed">
|
||||
<TextBlock Padding="12,0"
|
||||
VerticalAlignment="Center"
|
||||
FontStyle="Italic"
|
||||
Text="{x:Bind NoMatchesText, Mode=OneWay}" />
|
||||
</Border>
|
||||
|
||||
@@ -228,7 +227,7 @@
|
||||
Visibility="Collapsed">
|
||||
<TextBlock x:Name="_descriptionTitle"
|
||||
FontSize="14"
|
||||
FontWeight="Bold"
|
||||
FontWeight="SemiBold"
|
||||
IsTextSelectionEnabled="True"
|
||||
TextWrapping="WrapWholeWords">
|
||||
<TextBlock.ContextFlyout>
|
||||
|
||||
@@ -235,14 +235,14 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
auto textBlock = WUX::Controls::TextBlock{};
|
||||
textBlock.TextWrapping(WUX::TextWrapping::Wrap);
|
||||
textBlock.TextAlignment(WUX::TextAlignment::Center);
|
||||
textBlock.TextAlignment(WUX::TextAlignment::Left);
|
||||
textBlock.Inlines().Append(titleRun);
|
||||
|
||||
if (!_keyChord.empty())
|
||||
{
|
||||
auto keyChordRun = WUX::Documents::Run();
|
||||
keyChordRun.Text(_keyChord);
|
||||
keyChordRun.FontStyle(winrt::Windows::UI::Text::FontStyle::Italic);
|
||||
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||
textBlock.Inlines().Append(keyChordRun);
|
||||
}
|
||||
|
||||
@@ -71,11 +71,9 @@
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip Placement="Mouse">
|
||||
<TextBlock TextWrapping="Wrap">
|
||||
<Run x:Uid="NewTabRun" /> <LineBreak />
|
||||
<Run x:Uid="NewPaneRun"
|
||||
FontStyle="Italic" /> <LineBreak />
|
||||
<Run x:Uid="NewWindowRun"
|
||||
FontStyle="Italic" />
|
||||
<Run x:Uid="NewTabRun" /> <LineBreak /><LineBreak />
|
||||
<Run x:Uid="NewPaneRun" /> <LineBreak />
|
||||
<Run x:Uid="NewWindowRun" />
|
||||
</TextBlock>
|
||||
</ToolTip>
|
||||
</ToolTipService.ToolTip>
|
||||
|
||||
@@ -1295,17 +1295,15 @@ namespace winrt::TerminalApp::implementation
|
||||
newTabRun.Text(RS_(L"NewTabRun/Text"));
|
||||
auto newPaneRun = WUX::Documents::Run();
|
||||
newPaneRun.Text(RS_(L"NewPaneRun/Text"));
|
||||
newPaneRun.FontStyle(FontStyle::Italic);
|
||||
auto newWindowRun = WUX::Documents::Run();
|
||||
newWindowRun.Text(RS_(L"NewWindowRun/Text"));
|
||||
newWindowRun.FontStyle(FontStyle::Italic);
|
||||
auto elevatedRun = WUX::Documents::Run();
|
||||
elevatedRun.Text(RS_(L"ElevatedRun/Text"));
|
||||
elevatedRun.FontStyle(FontStyle::Italic);
|
||||
|
||||
auto textBlock = WUX::Controls::TextBlock{};
|
||||
textBlock.Inlines().Append(newTabRun);
|
||||
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||
textBlock.Inlines().Append(newPaneRun);
|
||||
textBlock.Inlines().Append(WUX::Documents::LineBreak{});
|
||||
textBlock.Inlines().Append(newWindowRun);
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
#include "LibraryResources.h"
|
||||
#include "../TerminalSettingsModel/AllShortcutActions.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
@@ -42,4 +44,65 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
// Builds the "view all" flyout lazily on the first click of a
|
||||
// row's "..." button, then caches it on the button so subsequent clicks
|
||||
// just re-show it.
|
||||
void Actions::ViewAllKeyChordsButton_Click(const IInspectable& sender, const RoutedEventArgs& /*e*/)
|
||||
{
|
||||
const auto button = sender.try_as<Button>();
|
||||
if (!button)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve cached flyout, if possible
|
||||
if (const auto existing = button.Flyout())
|
||||
{
|
||||
existing.ShowAt(button);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto cmdVM = button.DataContext().try_as<Editor::CommandViewModel>();
|
||||
if (!cmdVM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Flyout flyout;
|
||||
flyout.Placement(Primitives::FlyoutPlacementMode::Bottom);
|
||||
flyout.FlyoutPresenterStyle(Resources().Lookup(box_value(L"EdgeToEdgeFlyoutPresenterStyle")).as<winrt::Windows::UI::Xaml::Style>());
|
||||
|
||||
StackPanel content;
|
||||
content.Orientation(Orientation::Vertical);
|
||||
content.MinWidth(120.0);
|
||||
|
||||
if (cmdVM.HasNoKeyChords())
|
||||
{
|
||||
const auto emptyTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutEmptyStateTemplate")).as<DataTemplate>();
|
||||
content.Children().Append(emptyTemplate.LoadContent().as<UIElement>());
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto separatorTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutSeparatorTemplate")).as<DataTemplate>();
|
||||
const auto itemTemplate = Resources().Lookup(box_value(L"ViewAllKeyChordsFlyoutItemTemplate")).as<DataTemplate>();
|
||||
const auto chords = cmdVM.KeyChordList();
|
||||
const auto count = chords.Size();
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
content.Children().Append(separatorTemplate.LoadContent().as<UIElement>());
|
||||
}
|
||||
|
||||
auto chordVisual = itemTemplate.LoadContent().as<Editor::KeyChordVisual>();
|
||||
chordVisual.KeyChord(chords.GetAt(i).CurrentKeys());
|
||||
content.Children().Append(chordVisual);
|
||||
}
|
||||
}
|
||||
|
||||
flyout.Content(content);
|
||||
button.Flyout(flyout);
|
||||
flyout.ShowAt(button);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
void ViewAllKeyChordsButton_Click(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(Editor::ActionsViewModel, ViewModel, PropertyChanged.raise, nullptr);
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
@@ -17,182 +16,116 @@
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<!-- Theme Dictionary -->
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlForeground"
|
||||
Color="#B5B5B5" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#B5B5B5" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundPointerOver"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#333333" />
|
||||
<SolidColorBrush x:Key="TextControlForegroundFocused"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#404040" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<!-- TextBox colors ! -->
|
||||
<SolidColorBrush x:Key="TextControlBackground"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrush"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForeground"
|
||||
Color="#636363" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundPointerOver"
|
||||
Color="#DADADA" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushPointerOver"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPointerOver"
|
||||
Color="#FF4343" />
|
||||
|
||||
<SolidColorBrush x:Key="TextControlBackgroundFocused"
|
||||
Color="#CCCCCC" />
|
||||
<SolidColorBrush x:Key="TextControlBorderBrushFocused"
|
||||
Color="#636363" />
|
||||
<SolidColorBrush x:Key="TextControlButtonForegroundPressed"
|
||||
Color="#FFFFFF" />
|
||||
<SolidColorBrush x:Key="TextControlButtonBackgroundPressed"
|
||||
Color="#FF4343" />
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource ControlCornerRadius}" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<!-- Styles -->
|
||||
<Style x:Key="KeyBindingContainerStyle"
|
||||
<Style x:Key="ActionRowItemContainerStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="12,4,4,4" />
|
||||
<Setter Property="Padding" Value="{StaticResource SettingsCardPadding}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource SettingsCardMinHeight}" />
|
||||
<Setter Property="Margin" Value="{StaticResource SettingsCardItemMargin}" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="XYFocusKeyboardNavigation" Value="Enabled" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyBindingNameTextBlockStyle"
|
||||
|
||||
<Style x:Key="ActionRowNameTextStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="TextWrapping" Value="WrapWholeWords" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
|
||||
<Style x:Key="ActionRowSubtleButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
<Setter Property="MinWidth" Value="32" />
|
||||
<Setter Property="Width" Value="32" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
</Style>
|
||||
|
||||
<!-- Converters & Misc. -->
|
||||
<SolidColorBrush x:Key="ActionContainerBackgroundEditing"
|
||||
Color="{ThemeResource SystemListMediumColor}" />
|
||||
<SolidColorBrush x:Key="ActionContainerBackground"
|
||||
Color="Transparent" />
|
||||
<!--
|
||||
FlyoutPresenter style with no internal padding so a full-width Border
|
||||
separator inside the flyout can reach the flyout's left/right edges.
|
||||
-->
|
||||
<Style x:Key="EdgeToEdgeFlyoutPresenterStyle"
|
||||
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||
TargetType="FlyoutPresenter">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
|
||||
</Style>
|
||||
|
||||
<!-- Templates -->
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutSeparatorTemplate">
|
||||
<Border Height="1"
|
||||
Margin="0,4,0,4"
|
||||
Background="{ThemeResource DividerStrokeColorDefaultBrush}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutEmptyStateTemplate">
|
||||
<TextBlock x:Uid="Actions_NoKeyBindings"
|
||||
Margin="12,8,12,8"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryTextBlockStyle}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ViewAllKeyChordsFlyoutItemTemplate">
|
||||
<local:KeyChordVisual Margin="{ThemeResource MenuFlyoutItemThemePaddingNarrow}"
|
||||
HorizontalAlignment="Right" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="CommandTemplate"
|
||||
x:DataType="local:CommandViewModel">
|
||||
<ListViewItem AutomationProperties.Name="{x:Bind DisplayNameAndKeyChordAutomationPropName, Mode=OneWay}"
|
||||
Style="{StaticResource KeyBindingContainerStyle}">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- command name -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid AutomationProperties.Name="{x:Bind DisplayNameAndKeyChordAutomationPropName, Mode=OneWay}"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- command name -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<!-- key chord -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- edit button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- "..." button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Command Name -->
|
||||
<TextBlock Grid.Column="0"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource KeyBindingNameTextBlockStyle}"
|
||||
Text="{x:Bind DisplayName, Mode=OneWay}" />
|
||||
<!-- Key Chord Text -->
|
||||
<Grid Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Column="0"
|
||||
Padding="8,4,8,4"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(FirstKeyChordText)}">
|
||||
<TextBlock FontSize="14"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind FirstKeyChordText, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Border>
|
||||
<Border Grid.Column="1"
|
||||
Padding="8,4,8,4"
|
||||
Style="{ThemeResource KeyChordBorderStyle}"
|
||||
ToolTipService.ToolTip="{x:Bind AdditionalKeyChordTooltipText, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(AdditionalKeyChordCountText)}">
|
||||
<TextBlock FontSize="14"
|
||||
Style="{ThemeResource KeyChordTextBlockStyle}"
|
||||
Text="{x:Bind AdditionalKeyChordCountText, Mode=OneWay}" />
|
||||
</Border>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
<!-- Command Name -->
|
||||
<TextBlock Grid.Column="0"
|
||||
Style="{StaticResource ActionRowNameTextStyle}"
|
||||
Text="{x:Bind DisplayName, Mode=OneWay}" />
|
||||
|
||||
<!-- Key Chord -->
|
||||
<local:KeyChordVisual Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
KeyChord="{x:Bind FirstKeyChord, Mode=OneWay}" />
|
||||
|
||||
<!-- Edit button -->
|
||||
<Button x:Uid="Actions_EditButton"
|
||||
Grid.Column="2"
|
||||
AutomationProperties.Name="{x:Bind DisplayName, Mode=OneWay}"
|
||||
Click="{x:Bind Edit_Click}"
|
||||
Style="{StaticResource ActionRowSubtleButtonStyle}">
|
||||
<FontIcon FontSize="14"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- "..." button + flyout -->
|
||||
<Button x:Uid="Actions_ViewAllKeyChordsButton"
|
||||
Grid.Column="3"
|
||||
Click="ViewAllKeyChordsButton_Click"
|
||||
Style="{StaticResource ActionRowSubtleButtonStyle}">
|
||||
<FontIcon FontSize="14"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
@@ -208,7 +141,8 @@
|
||||
<!-- Add New Button -->
|
||||
<Button x:Name="AddNewButton"
|
||||
Margin="0,12,0,0"
|
||||
Click="{x:Bind ViewModel.AddNewCommand}">
|
||||
Click="{x:Bind ViewModel.AddNewCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
@@ -221,11 +155,42 @@
|
||||
|
||||
<!-- Commands -->
|
||||
<ListView x:Name="CommandsListView"
|
||||
Margin="-8,0,0,0"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="{x:Bind ViewModel.CmdListItemClicked}"
|
||||
ItemContainerStyle="{StaticResource ActionRowItemContainerStyle}"
|
||||
ItemTemplate="{StaticResource CommandTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.CommandList, Mode=OneWay}" />
|
||||
ItemsSource="{x:Bind ViewModel.CommandList, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<!--
|
||||
The framework ListViewItemPresenter reads its per-state backgrounds
|
||||
from these theme resources (not from ListViewItem.Background), so we
|
||||
override them here to match the card chrome on ActionRowItemContainerStyle.
|
||||
-->
|
||||
<ListView.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="ListViewItemBackground"
|
||||
ResourceKey="ExpanderHeaderBackground" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelected"
|
||||
ResourceKey="ExpanderHeaderBackground" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelectedPointerOver"
|
||||
ResourceKey="ControlFillColorSecondaryBrush" />
|
||||
<StaticResource x:Key="ListViewItemBackgroundSelectedPressed"
|
||||
ResourceKey="ControlFillColorTertiaryBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="ListViewItemBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</ListView.Resources>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Page>
|
||||
|
||||
@@ -57,13 +57,22 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return;
|
||||
}
|
||||
std::vector<Editor::KeyChordViewModel> keyChordVMs;
|
||||
int32_t idx = 1;
|
||||
for (const auto keys : _keyChordList)
|
||||
{
|
||||
auto kcVM{ make<KeyChordViewModel>(keys) };
|
||||
_RegisterKeyChordVMEvents(kcVM);
|
||||
keyChordVMs.push_back(kcVM);
|
||||
auto kcVM{ make_self<KeyChordViewModel>(keys) };
|
||||
kcVM->Index(idx++);
|
||||
_RegisterKeyChordVMEvents(*kcVM);
|
||||
keyChordVMs.push_back(*kcVM);
|
||||
}
|
||||
_KeyChordList = single_threaded_observable_vector(std::move(keyChordVMs));
|
||||
_KeyChordList.VectorChanged([weakThis{ get_weak() }](const auto& /*sender*/, const auto& /*args*/) {
|
||||
if (auto self{ weakThis.get() })
|
||||
{
|
||||
self->_ReindexKeyChordList();
|
||||
self->_NotifyChanges(L"FirstKeyChord", L"FirstKeyChordText", L"AdditionalKeyChordCountText", L"AdditionalKeyChordTooltipText", L"DisplayNameAndKeyChordAutomationPropName");
|
||||
}
|
||||
});
|
||||
|
||||
std::vector<hstring> shortcutActions;
|
||||
for (const auto [action, name] : _availableActionsAndNamesMap)
|
||||
@@ -119,7 +128,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return _cachedDisplayName;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::Name()
|
||||
winrt::hstring CommandViewModel::Name() const noexcept
|
||||
{
|
||||
return _command.HasName() ? _command.Name() : L"";
|
||||
}
|
||||
@@ -145,7 +154,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return result;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::FirstKeyChordText()
|
||||
winrt::hstring CommandViewModel::FirstKeyChordText() const
|
||||
{
|
||||
if (_KeyChordList.Size() != 0)
|
||||
{
|
||||
@@ -154,7 +163,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return L"";
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordCountText()
|
||||
Control::KeyChord CommandViewModel::FirstKeyChord() const noexcept
|
||||
{
|
||||
if (_KeyChordList.Size() != 0)
|
||||
{
|
||||
return _KeyChordList.GetAt(0).CurrentKeys();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CommandViewModel::HasNoKeyChords() const noexcept
|
||||
{
|
||||
return _KeyChordList.Size() == 0;
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordCountText() const
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
if (size > 1)
|
||||
@@ -164,7 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return L"";
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordTooltipText()
|
||||
winrt::hstring CommandViewModel::AdditionalKeyChordTooltipText() const
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
if (size <= 1)
|
||||
@@ -183,12 +206,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return winrt::hstring{ result };
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ID()
|
||||
winrt::hstring CommandViewModel::ID() const noexcept
|
||||
{
|
||||
return _command.ID();
|
||||
}
|
||||
|
||||
bool CommandViewModel::IsUserAction()
|
||||
bool CommandViewModel::IsUserAction() const noexcept
|
||||
{
|
||||
return _command.Origin() == OriginTag::User;
|
||||
}
|
||||
@@ -206,23 +229,40 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CommandViewModel::AddKeybinding_Click()
|
||||
{
|
||||
auto kbdVM{ make_self<KeyChordViewModel>(nullptr) };
|
||||
kbdVM->Index(gsl::narrow_cast<int32_t>(_KeyChordList.Size()) + 1);
|
||||
kbdVM->IsInEditMode(true);
|
||||
_RegisterKeyChordVMEvents(*kbdVM);
|
||||
KeyChordList().Append(*kbdVM);
|
||||
FocusContainer.raise(*this, *kbdVM);
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ActionNameTextBoxAutomationPropName()
|
||||
// Reassigns 1-based Index values for every KeyChordViewModel in the list. Called
|
||||
// whenever the list changes shape so the per-row "Key Binding #N" label stays in sync.
|
||||
void CommandViewModel::_ReindexKeyChordList()
|
||||
{
|
||||
const auto size = _KeyChordList.Size();
|
||||
for (uint32_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto kcVM{ _KeyChordList.GetAt(i) };
|
||||
const auto newIdx = gsl::narrow_cast<int32_t>(i) + 1;
|
||||
if (kcVM.Index() != newIdx)
|
||||
{
|
||||
kcVM.Index(newIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ActionNameTextBoxAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_Name/Text");
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::ShortcutActionComboBoxAutomationPropName()
|
||||
winrt::hstring CommandViewModel::ShortcutActionComboBoxAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_ShortcutAction/Text");
|
||||
}
|
||||
|
||||
winrt::hstring CommandViewModel::AdditionalArgumentsControlAutomationPropName()
|
||||
winrt::hstring CommandViewModel::AdditionalArgumentsControlAutomationPropName() const
|
||||
{
|
||||
return RS_(L"Actions_Arguments/Text");
|
||||
}
|
||||
@@ -273,6 +313,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
self->FocusContainer.raise(*self, senderVM);
|
||||
}
|
||||
}
|
||||
else if (propertyName == L"KeyChordText")
|
||||
{
|
||||
// The first chord of the list is what the row visual on the Actions page binds to,
|
||||
// so propagate the change up so the row updates.
|
||||
if (self->_KeyChordList.Size() > 0 && self->_KeyChordList.GetAt(0) == senderVM)
|
||||
{
|
||||
self->_NotifyChanges(L"FirstKeyChord", L"FirstKeyChordText", L"DisplayNameAndKeyChordAutomationPropName");
|
||||
}
|
||||
else
|
||||
{
|
||||
self->_NotifyChanges(L"AdditionalKeyChordTooltipText");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1065,12 +1118,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
KeyChordViewModel::KeyChordViewModel(Control::KeyChord currentKeys)
|
||||
{
|
||||
CurrentKeys(currentKeys);
|
||||
|
||||
// DisplayLabel is derived from Index, so re-fire the change for it whenever Index changes.
|
||||
PropertyChanged([this](const auto& /*sender*/, const Windows::UI::Xaml::Data::PropertyChangedEventArgs& args) {
|
||||
if (args.PropertyName() == L"Index")
|
||||
{
|
||||
_NotifyChanges(L"DisplayLabel");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void KeyChordViewModel::CurrentKeys(const Control::KeyChord& newKeys)
|
||||
{
|
||||
_currentKeys = newKeys;
|
||||
KeyChordText(Model::KeyChordSerialization::ToString(_currentKeys));
|
||||
_NotifyChanges(L"CurrentKeys");
|
||||
}
|
||||
|
||||
Control::KeyChord KeyChordViewModel::CurrentKeys() const noexcept
|
||||
@@ -1126,6 +1188,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
hstring KeyChordViewModel::CancelButtonName() const noexcept { return RS_(L"Actions_CancelButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::AcceptButtonName() const noexcept { return RS_(L"Actions_AcceptButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::DeleteButtonName() const noexcept { return RS_(L"Actions_DeleteButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
hstring KeyChordViewModel::EditButtonName() const noexcept { return RS_(L"Actions_EditButton/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"); }
|
||||
|
||||
winrt::hstring KeyChordViewModel::DisplayLabel() const
|
||||
{
|
||||
return hstring{ RS_fmt(L"EditAction_KeyBindingNumberFormat", _Index) };
|
||||
}
|
||||
|
||||
ActionsViewModel::ActionsViewModel(Model::CascadiaSettings settings) :
|
||||
_Settings{ settings }
|
||||
@@ -1334,7 +1402,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
const auto conflictingCmdName{ conflictingCmd.Name() };
|
||||
TextBlock conflictingCommandNameTB{};
|
||||
conflictingCommandNameTB.Text(fmt::format(L"\"{}\"", conflictingCmdName.empty() ? RS_(L"Actions_UnnamedCommandName") : conflictingCmdName));
|
||||
conflictingCommandNameTB.FontStyle(Windows::UI::Text::FontStyle::Italic);
|
||||
|
||||
TextBlock confirmationQuestionTB{};
|
||||
confirmationQuestionTB.Text(RS_(L"Actions_RenameConflictConfirmationQuestion"));
|
||||
|
||||
@@ -69,16 +69,18 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void Initialize();
|
||||
|
||||
winrt::hstring DisplayName();
|
||||
winrt::hstring Name();
|
||||
winrt::hstring Name() const noexcept;
|
||||
void Name(const winrt::hstring& newName);
|
||||
winrt::hstring DisplayNameAndKeyChordAutomationPropName();
|
||||
|
||||
winrt::hstring FirstKeyChordText();
|
||||
winrt::hstring AdditionalKeyChordCountText();
|
||||
winrt::hstring AdditionalKeyChordTooltipText();
|
||||
winrt::hstring FirstKeyChordText() const;
|
||||
Control::KeyChord FirstKeyChord() const noexcept;
|
||||
bool HasNoKeyChords() const noexcept;
|
||||
winrt::hstring AdditionalKeyChordCountText() const;
|
||||
winrt::hstring AdditionalKeyChordTooltipText() const;
|
||||
|
||||
winrt::hstring ID();
|
||||
bool IsUserAction();
|
||||
winrt::hstring ID() const noexcept;
|
||||
bool IsUserAction() const noexcept;
|
||||
|
||||
void Edit_Click();
|
||||
til::typed_event<Editor::CommandViewModel, IInspectable> EditRequested;
|
||||
@@ -89,9 +91,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void AddKeybinding_Click();
|
||||
|
||||
// UIA text
|
||||
winrt::hstring ActionNameTextBoxAutomationPropName();
|
||||
winrt::hstring ShortcutActionComboBoxAutomationPropName();
|
||||
winrt::hstring AdditionalArgumentsControlAutomationPropName();
|
||||
winrt::hstring ActionNameTextBoxAutomationPropName() const;
|
||||
winrt::hstring ShortcutActionComboBoxAutomationPropName() const;
|
||||
winrt::hstring AdditionalArgumentsControlAutomationPropName() const;
|
||||
|
||||
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeRequested;
|
||||
til::typed_event<IInspectable, Editor::ArgWrapper> PropagateColorSchemeNamesRequested;
|
||||
@@ -115,6 +117,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void _RegisterActionArgsVMEvents(Editor::ActionArgsViewModel actionArgsVM);
|
||||
void _ReplaceCommandWithUserCopy(bool reinitialize);
|
||||
void _CreateAndInitializeActionArgsVMHelper();
|
||||
void _ReindexKeyChordList();
|
||||
};
|
||||
|
||||
struct ArgWrapper : ArgWrapperT<ArgWrapper>, ViewModelHelper<ArgWrapper>
|
||||
@@ -230,15 +233,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CancelChanges();
|
||||
void DeleteKeyChord();
|
||||
|
||||
winrt::hstring DisplayLabel() const;
|
||||
|
||||
// UIA Text
|
||||
hstring CancelButtonName() const noexcept;
|
||||
hstring AcceptButtonName() const noexcept;
|
||||
hstring DeleteButtonName() const noexcept;
|
||||
hstring EditButtonName() const noexcept;
|
||||
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(bool, IsInEditMode, false);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(Control::KeyChord, ProposedKeys);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(winrt::hstring, KeyChordText);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(Windows::UI::Xaml::Controls::Flyout, AcceptChangesFlyout, nullptr);
|
||||
VIEW_MODEL_OBSERVABLE_PROPERTY(int32_t, Index, 0);
|
||||
|
||||
public:
|
||||
til::typed_event<Editor::KeyChordViewModel, Terminal::Control::KeyChord> AddKeyChordRequested;
|
||||
|
||||
@@ -55,6 +55,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
// View-model specific
|
||||
String DisplayName { get; };
|
||||
String FirstKeyChordText { get; };
|
||||
Microsoft.Terminal.Control.KeyChord FirstKeyChord { get; };
|
||||
Boolean HasNoKeyChords { get; };
|
||||
String AdditionalKeyChordCountText { get; };
|
||||
String AdditionalKeyChordTooltipText { get; };
|
||||
String DisplayNameAndKeyChordAutomationPropName { get; };
|
||||
@@ -138,9 +140,12 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String KeyChordText { get; };
|
||||
|
||||
// UI side
|
||||
Microsoft.Terminal.Control.KeyChord CurrentKeys { get; };
|
||||
Microsoft.Terminal.Control.KeyChord ProposedKeys;
|
||||
Windows.UI.Xaml.Controls.Flyout AcceptChangesFlyout;
|
||||
Boolean IsInEditMode { get; };
|
||||
Int32 Index;
|
||||
String DisplayLabel { get; };
|
||||
void ToggleEditMode();
|
||||
void AcceptChanges();
|
||||
void CancelChanges();
|
||||
@@ -148,6 +153,7 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
String CancelButtonName { get; };
|
||||
String AcceptButtonName { get; };
|
||||
String DeleteButtonName { get; };
|
||||
String EditButtonName { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<KeyChordViewModel, Microsoft.Terminal.Control.KeyChord> AddKeyChordRequested;
|
||||
event Windows.Foundation.TypedEventHandler<KeyChordViewModel, ModifyKeyChordEventArgs> ModifyKeyChordRequested;
|
||||
|
||||
@@ -68,9 +68,9 @@
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<!-- Section: Typography settings -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<!-- Grouping: Text -->
|
||||
<TextBlock x:Uid="Profile_TextHeader"
|
||||
<TextBlock x:Uid="Appearance_Section_Typography"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Color Scheme -->
|
||||
@@ -81,7 +81,7 @@
|
||||
CurrentValueAccessibleName="{x:Bind Appearance.CurrentColorScheme.Name, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Appearance.HasDarkColorSchemeName, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.DarkColorSchemeNameOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<ComboBox Padding="4"
|
||||
ItemsSource="{x:Bind Appearance.SchemesList, Mode=OneWay}"
|
||||
@@ -220,7 +220,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasForeground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.ForegroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_Foreground_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.Foreground, Mode=TwoWay}"
|
||||
@@ -236,7 +236,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasBackground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.BackgroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_Background_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.Background, Mode=TwoWay}"
|
||||
@@ -252,7 +252,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasSelectionBackground, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.SelectionBackgroundOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_SelectionBackground_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.SelectionBackground, Mode=TwoWay}"
|
||||
@@ -484,13 +484,25 @@
|
||||
SelectedItem="{x:Bind CurrentAdjustIndistinguishableColors, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Intense is bold, bright -->
|
||||
<local:SettingContainer x:Name="IntenseTextStyle"
|
||||
x:Uid="Appearance_IntenseTextStyle"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearIntenseTextStyle}"
|
||||
HasSettingValue="{x:Bind Appearance.HasIntenseTextStyle, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.IntenseTextStyleOverrideSource, Mode=OneWay}">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind IntenseTextStyleList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentIntenseTextStyle, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Cursor -->
|
||||
<!-- Section: Cursor settings -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_CursorHeader"
|
||||
<TextBlock x:Uid="Appearance_Section_Cursor"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Cursor Shape -->
|
||||
<local:SettingContainer x:Name="CursorShape"
|
||||
x:Uid="Profile_CursorShape"
|
||||
@@ -536,7 +548,7 @@
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Appearance.HasCursorColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.CursorColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_CursorColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Appearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Appearance.CursorColor, Mode=TwoWay}"
|
||||
@@ -544,11 +556,10 @@
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Background -->
|
||||
<!-- Section: Background image -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_BackgroundHeader"
|
||||
<TextBlock x:Uid="Appearance_Section_BackgroundImage"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Background Image -->
|
||||
<local:SettingContainer x:Name="BackgroundImageContainer"
|
||||
x:Uid="Profile_BackgroundImage"
|
||||
@@ -802,24 +813,5 @@
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Text Formatting -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Appearance_TextFormattingHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Intense is bold, bright -->
|
||||
<local:SettingContainer x:Name="IntenseTextStyle"
|
||||
x:Uid="Appearance_IntenseTextStyle"
|
||||
ClearSettingValue="{x:Bind Appearance.ClearIntenseTextStyle}"
|
||||
HasSettingValue="{x:Bind Appearance.HasIntenseTextStyle, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Appearance.IntenseTextStyleOverrideSource, Mode=OneWay}">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind IntenseTextStyleList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind CurrentIntenseTextStyle, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
|
||||
|
||||
<!-- Merge SettingContainerStyle here to give every page access to the SettingContainer -->
|
||||
<!-- Merge SettingsControls and SettingContainer styles here to give every page access to them -->
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="SettingsControlsStyle.xaml" />
|
||||
<ResourceDictionary Source="SettingContainerStyle.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
@@ -64,6 +65,7 @@
|
||||
|
||||
<local:ColorToBrushConverter x:Key="ColorToBrushConverter" />
|
||||
<local:ColorToStringConverter x:Key="ColorToStringConverter" />
|
||||
<mtu:StringNotEmptyToVisibilityConverter x:Key="StringNotEmptyToVisibilityConverter" />
|
||||
|
||||
<Color x:Key="DeleteButtonColor">Firebrick</Color>
|
||||
|
||||
@@ -1228,13 +1230,19 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentPresenter x:Name="ContentPresenter"
|
||||
Grid.Column="0"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}" />
|
||||
<StackPanel Grid.Column="0"
|
||||
Padding="0,12,0,12"
|
||||
VerticalAlignment="Center">
|
||||
<ContentPresenter x:Name="ContentPresenter"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
ContentTransitions="{TemplateBinding ContentTransitions}" />
|
||||
<TextBlock Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{Binding Tag, RelativeSource={RelativeSource Mode=TemplatedParent}}"
|
||||
Visibility="{Binding Tag, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource StringNotEmptyToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
<FontIcon Grid.Column="1"
|
||||
Margin="20,0,8,0"
|
||||
HorizontalAlignment="Right"
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(TextMeasurement, TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, L"Globals_TextMeasurement_", L"Text");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(AmbiguousWidth, AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, L"Globals_AmbiguousWidth_", L"Text");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(GraphicsAPI, GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, L"Globals_GraphicsAPI_", L"Text");
|
||||
}
|
||||
|
||||
bool CompatibilityViewModel::DebugFeaturesAvailable() const noexcept
|
||||
|
||||
@@ -28,6 +28,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.GlobalSettings().TextMeasurement);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, _settings.GlobalSettings().AmbiguousWidth);
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.GlobalSettings().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), SoftwareRendering);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings;
|
||||
};
|
||||
|
||||
@@ -23,6 +23,11 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
|
||||
IInspectable CurrentAmbiguousWidth;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> AmbiguousWidthList { get; };
|
||||
|
||||
IInspectable CurrentGraphicsAPI;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> GraphicsAPIList { get; };
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, SoftwareRendering);
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass Compatibility : Windows.UI.Xaml.Controls.Page
|
||||
|
||||
@@ -25,83 +25,117 @@
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Allow Headless -->
|
||||
<local:SettingContainer x:Name="AllowHeadless"
|
||||
x:Uid="Globals_AllowHeadless">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AllowHeadless, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Compatibility -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Compatibility_Section_Compatibility"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Allow Headless -->
|
||||
<local:SettingContainer x:Name="AllowHeadless"
|
||||
x:Uid="Globals_AllowHeadless">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AllowHeadless, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Text Measurement -->
|
||||
<local:SettingContainer x:Name="TextMeasurement"
|
||||
x:Uid="Globals_TextMeasurement">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TextMeasurementList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTextMeasurement, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Text Measurement -->
|
||||
<local:SettingContainer x:Name="TextMeasurement"
|
||||
x:Uid="Globals_TextMeasurement">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TextMeasurementList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTextMeasurement, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Ambiguous Width -->
|
||||
<local:SettingContainer x:Name="AmbiguousWidth"
|
||||
x:Uid="Globals_AmbiguousWidth">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.AmbiguousWidthList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentAmbiguousWidth, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Ambiguous Width -->
|
||||
<local:SettingContainer x:Name="AmbiguousWidth"
|
||||
x:Uid="Globals_AmbiguousWidth">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.AmbiguousWidthList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentAmbiguousWidth, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Debug Features -->
|
||||
<local:SettingContainer x:Name="DebugFeaturesEnabled"
|
||||
x:Uid="Globals_DebugFeaturesEnabled"
|
||||
Visibility="{x:Bind ViewModel.DebugFeaturesAvailable}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DebugFeaturesEnabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Debug Features -->
|
||||
<local:SettingContainer x:Name="DebugFeaturesEnabled"
|
||||
x:Uid="Globals_DebugFeaturesEnabled"
|
||||
Visibility="{x:Bind ViewModel.DebugFeaturesAvailable}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DebugFeaturesEnabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Reset Application State -->
|
||||
<local:SettingContainer x:Name="ResetApplicationState"
|
||||
x:Uid="Settings_ResetApplicationState">
|
||||
<Button x:Uid="Settings_ResetApplicationStateButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout x:Name="ResetCacheFlyout"
|
||||
FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetApplicationStateConfirmationButton"
|
||||
Click="ResetApplicationStateButton_Click" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
<!-- Reset Application State -->
|
||||
<local:SettingContainer x:Name="ResetApplicationState"
|
||||
x:Uid="Settings_ResetApplicationState">
|
||||
<Button x:Uid="Settings_ResetApplicationStateButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout x:Name="ResetCacheFlyout"
|
||||
FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetApplicationStateConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetApplicationStateConfirmationButton"
|
||||
Click="ResetApplicationStateButton_Click" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Reset to Default Settings -->
|
||||
<local:SettingContainer x:Name="ResetToDefaultSettings"
|
||||
x:Uid="Settings_ResetToDefaultSettings">
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsConfirmationButton"
|
||||
Click="{x:Bind ViewModel.ResetToDefaultSettings}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
<!-- Reset to Default Settings -->
|
||||
<local:SettingContainer x:Name="ResetToDefaultSettings"
|
||||
x:Uid="Settings_ResetToDefaultSettings">
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsButton"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Flyout>
|
||||
<Flyout FlyoutPresenterStyle="{StaticResource CustomFlyoutPresenterStyle}">
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageHeader"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<TextBlock x:Uid="Settings_ResetToDefaultSettingsConfirmationMessageBody"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Settings_ResetToDefaultSettingsConfirmationButton"
|
||||
Click="{x:Bind ViewModel.ResetToDefaultSettings}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Section: Rendering -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Compatibility_Section_Rendering"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Graphics API -->
|
||||
<local:SettingContainer x:Name="GraphicsAPI"
|
||||
x:Uid="Globals_GraphicsAPI">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.GraphicsAPIList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentGraphicsAPI, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Disable Partial Invalidation -->
|
||||
<local:SettingContainer x:Name="DisablePartialInvalidation"
|
||||
x:Uid="Globals_DisablePartialInvalidation">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DisablePartialInvalidation, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Software Rendering -->
|
||||
<local:SettingContainer x:Name="SoftwareRendering"
|
||||
x:Uid="Globals_SoftwareRendering">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SoftwareRendering, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
|
||||
139
src/cascadia/TerminalSettingsEditor/ControlSizeTrigger.cpp
Normal file
139
src/cascadia/TerminalSettingsEditor/ControlSizeTrigger.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "ControlSizeTrigger.h"
|
||||
#include "ControlSizeTrigger.g.cpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty ControlSizeTrigger::_CanTriggerProperty{ nullptr };
|
||||
DependencyProperty ControlSizeTrigger::_MinWidthProperty{ nullptr };
|
||||
DependencyProperty ControlSizeTrigger::_MaxWidthProperty{ nullptr };
|
||||
DependencyProperty ControlSizeTrigger::_MinHeightProperty{ nullptr };
|
||||
DependencyProperty ControlSizeTrigger::_MaxHeightProperty{ nullptr };
|
||||
DependencyProperty ControlSizeTrigger::_TargetElementProperty{ nullptr };
|
||||
|
||||
ControlSizeTrigger::ControlSizeTrigger()
|
||||
{
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
void ControlSizeTrigger::_InitializeProperties()
|
||||
{
|
||||
// Defaults mirror the toolkit: trigger is always evaluatable, bounds
|
||||
// are wide open, no target element until one is bound.
|
||||
if (!_CanTriggerProperty)
|
||||
{
|
||||
_CanTriggerProperty = DependencyProperty::Register(
|
||||
L"CanTrigger",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::ControlSizeTrigger>(),
|
||||
PropertyMetadata{ box_value(true), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
|
||||
}
|
||||
if (!_MinWidthProperty)
|
||||
{
|
||||
_MinWidthProperty = DependencyProperty::Register(
|
||||
L"MinWidth",
|
||||
xaml_typename<double>(),
|
||||
xaml_typename<Editor::ControlSizeTrigger>(),
|
||||
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
|
||||
}
|
||||
if (!_MaxWidthProperty)
|
||||
{
|
||||
_MaxWidthProperty = DependencyProperty::Register(
|
||||
L"MaxWidth",
|
||||
xaml_typename<double>(),
|
||||
xaml_typename<Editor::ControlSizeTrigger>(),
|
||||
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
|
||||
}
|
||||
if (!_MinHeightProperty)
|
||||
{
|
||||
_MinHeightProperty = DependencyProperty::Register(
|
||||
L"MinHeight",
|
||||
xaml_typename<double>(),
|
||||
xaml_typename<Editor::ControlSizeTrigger>(),
|
||||
PropertyMetadata{ box_value(0.0), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
|
||||
}
|
||||
if (!_MaxHeightProperty)
|
||||
{
|
||||
_MaxHeightProperty = DependencyProperty::Register(
|
||||
L"MaxHeight",
|
||||
xaml_typename<double>(),
|
||||
xaml_typename<Editor::ControlSizeTrigger>(),
|
||||
PropertyMetadata{ box_value(std::numeric_limits<double>::infinity()), PropertyChangedCallback{ &ControlSizeTrigger::_OnTriggerInputChanged } });
|
||||
}
|
||||
if (!_TargetElementProperty)
|
||||
{
|
||||
_TargetElementProperty = DependencyProperty::Register(
|
||||
L"TargetElement",
|
||||
xaml_typename<FrameworkElement>(),
|
||||
xaml_typename<Editor::ControlSizeTrigger>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &ControlSizeTrigger::_OnTargetElementChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
void ControlSizeTrigger::_OnTriggerInputChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
if (const auto obj{ d.try_as<Editor::ControlSizeTrigger>() })
|
||||
{
|
||||
get_self<ControlSizeTrigger>(obj)->_UpdateTrigger();
|
||||
}
|
||||
}
|
||||
|
||||
void ControlSizeTrigger::_OnTargetElementChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::ControlSizeTrigger>() };
|
||||
if (!obj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto oldElement = e.OldValue().try_as<FrameworkElement>();
|
||||
const auto newElement = e.NewValue().try_as<FrameworkElement>();
|
||||
get_self<ControlSizeTrigger>(obj)->_UpdateTargetElement(oldElement, newElement);
|
||||
}
|
||||
|
||||
void ControlSizeTrigger::_UpdateTargetElement(const FrameworkElement& /*oldValue*/, const FrameworkElement& newValue)
|
||||
{
|
||||
// Revoking handles both unhooking the previous element and a null `newValue`.
|
||||
_sizeChangedRevoker.revoke();
|
||||
if (newValue)
|
||||
{
|
||||
_sizeChangedRevoker = newValue.SizeChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_UpdateTrigger();
|
||||
}
|
||||
});
|
||||
}
|
||||
_UpdateTrigger();
|
||||
}
|
||||
|
||||
void ControlSizeTrigger::_UpdateTrigger()
|
||||
{
|
||||
const auto target = TargetElement();
|
||||
if (!target || !CanTrigger())
|
||||
{
|
||||
_isActive = false;
|
||||
SetActive(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto width = target.ActualWidth();
|
||||
const auto height = target.ActualHeight();
|
||||
|
||||
const bool activate =
|
||||
MinWidth() <= width &&
|
||||
width < MaxWidth() &&
|
||||
MinHeight() <= height &&
|
||||
height < MaxHeight();
|
||||
|
||||
_isActive = activate;
|
||||
SetActive(activate);
|
||||
}
|
||||
}
|
||||
64
src/cascadia/TerminalSettingsEditor/ControlSizeTrigger.h
Normal file
64
src/cascadia/TerminalSettingsEditor/ControlSizeTrigger.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- ControlSizeTrigger
|
||||
|
||||
Abstract:
|
||||
- A conditional state trigger that activates based on the size (width and/or
|
||||
height) of a target FrameworkElement. Lets XAML visual states swap based on
|
||||
the live size of a templated part. Ported from the Windows Community Toolkit
|
||||
primitive `CommunityToolkit.WinUI.ControlSizeTrigger`.
|
||||
|
||||
The trigger is "active" when:
|
||||
MinWidth <= TargetElement.ActualWidth < MaxWidth AND
|
||||
MinHeight <= TargetElement.ActualHeight < MaxHeight
|
||||
|
||||
Defaults: MinWidth = MinHeight = 0; MaxWidth = MaxHeight = +inf, which makes
|
||||
the trigger always active unless `CanTrigger` is false or `TargetElement` is
|
||||
null.
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora - May 2026 (port from CommunityToolkit.WinUI.ControlSizeTrigger)
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ControlSizeTrigger.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct ControlSizeTrigger : ControlSizeTriggerT<ControlSizeTrigger>
|
||||
{
|
||||
public:
|
||||
ControlSizeTrigger();
|
||||
|
||||
bool IsActive() const { return _isActive; }
|
||||
|
||||
DEPENDENCY_PROPERTY(bool, CanTrigger);
|
||||
DEPENDENCY_PROPERTY(double, MinWidth);
|
||||
DEPENDENCY_PROPERTY(double, MaxWidth);
|
||||
DEPENDENCY_PROPERTY(double, MinHeight);
|
||||
DEPENDENCY_PROPERTY(double, MaxHeight);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::FrameworkElement, TargetElement);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnTriggerInputChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnTargetElementChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _UpdateTargetElement(const Windows::UI::Xaml::FrameworkElement& oldValue, const Windows::UI::Xaml::FrameworkElement& newValue);
|
||||
void _UpdateTrigger();
|
||||
|
||||
Windows::UI::Xaml::FrameworkElement::SizeChanged_revoker _sizeChangedRevoker;
|
||||
bool _isActive{ false };
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(ControlSizeTrigger);
|
||||
}
|
||||
30
src/cascadia/TerminalSettingsEditor/ControlSizeTrigger.idl
Normal file
30
src/cascadia/TerminalSettingsEditor/ControlSizeTrigger.idl
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass ControlSizeTrigger : Windows.UI.Xaml.StateTriggerBase
|
||||
{
|
||||
ControlSizeTrigger();
|
||||
|
||||
Boolean CanTrigger;
|
||||
static Windows.UI.Xaml.DependencyProperty CanTriggerProperty { get; };
|
||||
|
||||
Double MinWidth;
|
||||
static Windows.UI.Xaml.DependencyProperty MinWidthProperty { get; };
|
||||
|
||||
Double MaxWidth;
|
||||
static Windows.UI.Xaml.DependencyProperty MaxWidthProperty { get; };
|
||||
|
||||
Double MinHeight;
|
||||
static Windows.UI.Xaml.DependencyProperty MinHeightProperty { get; };
|
||||
|
||||
Double MaxHeight;
|
||||
static Windows.UI.Xaml.DependencyProperty MaxHeightProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.FrameworkElement TargetElement;
|
||||
static Windows.UI.Xaml.DependencyProperty TargetElementProperty { get; };
|
||||
|
||||
Boolean IsActive { get; };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "CornerRadiusFilterConverters.h"
|
||||
#include "CornerRadiusConverter.g.cpp"
|
||||
#include "TopCornerRadiusFilterConverter.g.cpp"
|
||||
#include "BottomCornerRadiusFilterConverter.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
winrt::Windows::Foundation::IInspectable CornerRadiusConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
|
||||
{
|
||||
if (!value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
|
||||
return box_value(CornerRadius{ 0, 0, cr.BottomRight, cr.BottomLeft });
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable CornerRadiusConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
|
||||
{
|
||||
if (!value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
|
||||
return box_value(CornerRadius{ cr.TopLeft, cr.TopRight, 0, 0 });
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable TopCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::Convert(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
|
||||
{
|
||||
if (!value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
const auto cr = unbox_value_or<CornerRadius>(value, CornerRadius{ 0, 0, 0, 0 });
|
||||
return box_value(CornerRadius{ 0, 0, cr.BottomRight, cr.BottomLeft });
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable BottomCornerRadiusFilterConverter::ConvertBack(const winrt::Windows::Foundation::IInspectable& value, const Interop::TypeName& /*targetType*/, const winrt::Windows::Foundation::IInspectable& /*parameter*/, const hstring& /*language*/)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CornerRadiusConverter.g.h"
|
||||
#include "TopCornerRadiusFilterConverter.g.h"
|
||||
#include "BottomCornerRadiusFilterConverter.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct CornerRadiusConverter : CornerRadiusConverterT<CornerRadiusConverter>
|
||||
{
|
||||
CornerRadiusConverter() = default;
|
||||
|
||||
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
|
||||
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
|
||||
};
|
||||
|
||||
struct TopCornerRadiusFilterConverter : TopCornerRadiusFilterConverterT<TopCornerRadiusFilterConverter>
|
||||
{
|
||||
TopCornerRadiusFilterConverter() = default;
|
||||
|
||||
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
|
||||
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
|
||||
};
|
||||
|
||||
struct BottomCornerRadiusFilterConverter : BottomCornerRadiusFilterConverterT<BottomCornerRadiusFilterConverter>
|
||||
{
|
||||
BottomCornerRadiusFilterConverter() = default;
|
||||
|
||||
Windows::Foundation::IInspectable Convert(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
|
||||
Windows::Foundation::IInspectable ConvertBack(const Windows::Foundation::IInspectable& value, const Windows::UI::Xaml::Interop::TypeName& targetType, const Windows::Foundation::IInspectable& parameter, const hstring& language);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(CornerRadiusConverter);
|
||||
BASIC_FACTORY(TopCornerRadiusFilterConverter);
|
||||
BASIC_FACTORY(BottomCornerRadiusFilterConverter);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass CornerRadiusConverter : Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
CornerRadiusConverter();
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass TopCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
TopCornerRadiusFilterConverter();
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass BottomCornerRadiusFilterConverter : Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
BottomCornerRadiusFilterConverter();
|
||||
}
|
||||
}
|
||||
@@ -17,130 +17,11 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<!-- Theme Dictionary -->
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
<!-- Override visual states -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid>
|
||||
<!-- Define the appearance of the button -->
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed" />
|
||||
<VisualState x:Name="Disabled" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button">
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="1" />
|
||||
<Setter Property="Background" Value="{ThemeResource SystemAltMediumLowColor}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
<!-- Override visual states -->
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Grid>
|
||||
<!-- Define the appearance of the button -->
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Border>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="border"
|
||||
Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0"
|
||||
Value="{ThemeResource SystemControlHighlightAccentRevealBackgroundBrush}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed" />
|
||||
<VisualState x:Name="Disabled" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Button" />
|
||||
<Style x:Key="KeyChordTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<GridLength x:Key="ArgumentNameWidth">148</GridLength>
|
||||
|
||||
<!-- Styles -->
|
||||
<Style x:Key="KeyBindingContainerStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="4" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="XYFocusKeyboardNavigation" Value="Enabled" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
<x:Int32 x:Key="EditButtonSize">32</x:Int32>
|
||||
<x:Double x:Key="EditButtonIconSize">14</x:Double>
|
||||
|
||||
<Style x:Key="EditButtonStyle"
|
||||
BasedOn="{StaticResource DefaultButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -149,6 +30,7 @@
|
||||
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
|
||||
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="AccentEditButtonStyle"
|
||||
BasedOn="{StaticResource AccentButtonStyle}"
|
||||
TargetType="Button">
|
||||
@@ -157,42 +39,63 @@
|
||||
<Setter Property="Height" Value="{StaticResource EditButtonSize}" />
|
||||
<Setter Property="Width" Value="{StaticResource EditButtonSize}" />
|
||||
</Style>
|
||||
<Style x:Key="TextBlockGroupingStyle"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MaxWidth" Value="{StaticResource StandardControlMaxWidth}" />
|
||||
<Setter Property="Margin" Value="0,0,0,4" />
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
|
||||
<Style x:Key="KeyChordEditorStyle"
|
||||
TargetType="local:KeyChordListener">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="MinWidth" Value="160" />
|
||||
</Style>
|
||||
|
||||
<!-- Templates -->
|
||||
<!--
|
||||
Item container for the per-chord ListView. We're hosting a SettingContainer
|
||||
inside each item, so strip the default ListViewItem visuals (padding, border,
|
||||
hover/selection background) so they don't double up.
|
||||
-->
|
||||
<Style x:Key="KeyChordListViewItemStyle"
|
||||
BasedOn="{StaticResource DefaultListViewItemStyle}"
|
||||
TargetType="ListViewItem">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="MinHeight" Value="0" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
</Style>
|
||||
|
||||
<!-- "Key Binding #N" template -->
|
||||
<DataTemplate x:Key="KeyChordTemplate"
|
||||
x:DataType="local:KeyChordViewModel">
|
||||
<ListViewItem IsTabStop="False"
|
||||
Style="{StaticResource KeyBindingContainerStyle}">
|
||||
<Grid Padding="-4,0,0,0"
|
||||
VerticalAlignment="Center">
|
||||
<local:SettingContainer Header="{x:Bind DisplayLabel, Mode=OneWay}">
|
||||
<Grid VerticalAlignment="Center"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<!-- Key visual / key chord listener -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Cancel button (visible only in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Accept button (visible only in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Edit (pencil) button (visible only NOT in edit mode) -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<!-- Delete button -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Grid.Column="0"
|
||||
Background="{ThemeResource AppBarItemBackgroundThemeBrush}"
|
||||
Click="{x:Bind ToggleEditMode}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
|
||||
<TextBlock FontSize="14"
|
||||
Text="{x:Bind KeyChordText, Mode=OneWay}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Button>
|
||||
|
||||
<!-- Read-only key chord visual -->
|
||||
<local:KeyChordVisual Grid.Column="0"
|
||||
KeyChord="{x:Bind CurrentKeys, Mode=OneWay}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}" />
|
||||
|
||||
<!-- Editable key chord listener -->
|
||||
<local:KeyChordListener Grid.Column="0"
|
||||
Keys="{x:Bind ProposedKeys, Mode=TwoWay}"
|
||||
Style="{StaticResource KeyChordEditorStyle}"
|
||||
Visibility="{x:Bind IsInEditMode, Mode=OneWay}" />
|
||||
|
||||
<!-- Cancel changes (edit mode only) -->
|
||||
<Button x:Uid="Actions_CancelButton"
|
||||
Grid.Column="1"
|
||||
Margin="8,0,0,0"
|
||||
AutomationProperties.Name="{x:Bind CancelButtonName}"
|
||||
Click="{x:Bind CancelChanges}"
|
||||
Style="{StaticResource EditButtonStyle}"
|
||||
@@ -201,9 +104,9 @@
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- Accept changes (edit mode only) -->
|
||||
<Button x:Uid="Actions_AcceptButton"
|
||||
Grid.Column="2"
|
||||
Margin="8,0,8,0"
|
||||
AutomationProperties.Name="{x:Bind AcceptButtonName}"
|
||||
Click="{x:Bind AcceptChanges}"
|
||||
Flyout="{x:Bind AcceptChangesFlyout, Mode=OneWay}"
|
||||
@@ -213,8 +116,19 @@
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<Button Grid.Column="3"
|
||||
HorizontalAlignment="Left"
|
||||
<!-- Edit button -->
|
||||
<Button x:Uid="Actions_EditButton"
|
||||
Grid.Column="3"
|
||||
AutomationProperties.Name="{x:Bind EditButtonName}"
|
||||
Click="{x:Bind ToggleEditMode}"
|
||||
Style="{StaticResource EditButtonStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(IsInEditMode), Mode=OneWay}">
|
||||
<FontIcon FontSize="{StaticResource EditButtonIconSize}"
|
||||
Glyph="" />
|
||||
</Button>
|
||||
|
||||
<!-- Delete button -->
|
||||
<Button Grid.Column="4"
|
||||
AutomationProperties.Name="{x:Bind DeleteButtonName}"
|
||||
Style="{StaticResource DeleteSmallButtonStyle}">
|
||||
<Button.Content>
|
||||
@@ -233,25 +147,23 @@
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!--
|
||||
BODGY: Each ArgWrapper DataTemplate below wraps its editor control
|
||||
in a <local:SettingContainer Header="{x:Bind Name}"> rather than sharing a
|
||||
single outer template. This is because a bug in WinUI 2 prevents a
|
||||
ContentPresenter + ContentTemplateSelector pattern from working correctly,
|
||||
resulting in "Microsoft.Terminal.Settings.Editor.ArgWrapper" being shown.
|
||||
-->
|
||||
|
||||
<!-- Example shortcut action to test this template: Adjust Opacity -->
|
||||
<!-- Currently that is the only Int32 arg, so just clamp the min/max values according to that -->
|
||||
<DataTemplate x:Key="Int32Template"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="100"
|
||||
@@ -259,24 +171,14 @@
|
||||
SmallChange="10"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxInt32(Value), Mode=TwoWay, BindBack=Int32BindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Switch To Tab -->
|
||||
<DataTemplate x:Key="UInt32Template"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -284,24 +186,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxUInt32(Value), Mode=TwoWay, BindBack=UInt32BindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Close Other Tabs -->
|
||||
<DataTemplate x:Key="UInt32OptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -309,24 +201,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxUInt32Optional(Value), Mode=TwoWay, BindBack=UInt32OptionalBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="Int32OptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -334,24 +216,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxInt32Optional(Value), Mode=TwoWay, BindBack=Int32OptionalBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Adjust Font Size -->
|
||||
<DataTemplate x:Key="FloatTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="1"
|
||||
Maximum="999"
|
||||
@@ -359,24 +231,14 @@
|
||||
SmallChange="1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxFloat(Value), Mode=TwoWay, BindBack=FloatBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="SplitSizeTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<muxc:NumberBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<muxc:NumberBox MinWidth="160"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
LargeChange="0.2"
|
||||
Maximum="1"
|
||||
@@ -384,144 +246,95 @@
|
||||
SmallChange="0.1"
|
||||
Style="{StaticResource NumberBoxSettingStyle}"
|
||||
Value="{x:Bind UnboxFloat(Value), Mode=TwoWay, BindBack=FloatBindBack}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Send Input -->
|
||||
<DataTemplate x:Key="StringTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<TextBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Color Scheme -->
|
||||
<DataTemplate x:Key="ColorSchemeTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ComboBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ComboBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind EnumValue, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Export Buffer -->
|
||||
<DataTemplate x:Key="FilePickerTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="2"
|
||||
Click="{x:Bind BrowseForFile_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="1"
|
||||
Click="{x:Bind BrowseForFile_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: New Tab -->
|
||||
<DataTemplate x:Key="FolderPickerTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<TextBox Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="2"
|
||||
Click="{x:Bind BrowseForFolder_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<Grid ColumnSpacing="4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"
|
||||
MinWidth="196" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Column="0"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
Text="{x:Bind UnboxString(Value), Mode=TwoWay, BindBack=StringBindBack}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button x:Uid="Actions_Browse"
|
||||
Grid.Column="1"
|
||||
Click="{x:Bind BrowseForFolder_Click}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Focus Mode -->
|
||||
<DataTemplate x:Key="BoolTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
IsOn="{x:Bind UnboxBool(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}" />
|
||||
</Grid>
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ToggleSwitch AutomationProperties.Name="{x:Bind Name}"
|
||||
IsOn="{x:Bind UnboxBool(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Split Pane -->
|
||||
<DataTemplate x:Key="BoolOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<CheckBox Grid.Column="1"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<CheckBox AutomationProperties.Name="{x:Bind Name}"
|
||||
IsChecked="{x:Bind UnboxBoolOptional(Value), Mode=TwoWay, BindBack=BoolOptionalBindBack}"
|
||||
IsThreeState="True" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Resize Pane -->
|
||||
@@ -532,24 +345,14 @@
|
||||
|
||||
<DataTemplate x:Key="EnumTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ComboBox Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ComboBox MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind EnumList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind EnumValue, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Copy Text -->
|
||||
@@ -572,66 +375,35 @@
|
||||
|
||||
<DataTemplate x:Key="FlagTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<ItemsControl Grid.Column="1"
|
||||
Margin="0"
|
||||
HorizontalAlignment="Left"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<ItemsControl AutomationProperties.Name="{x:Bind Name}"
|
||||
ItemTemplate="{StaticResource FlagItemTemplate}"
|
||||
ItemsSource="{x:Bind FlagList, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Add Mark -->
|
||||
<DataTemplate x:Key="TerminalCoreColorOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<local:NullableColorPicker x:Uid="Actions_NullableColorPicker"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ColorSchemeVM="{x:Bind DefaultColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind UnboxTerminalCoreColorOptional(Value), Mode=TwoWay, BindBack=TerminalCoreColorBindBack}"
|
||||
NullColorPreview="{x:Bind DefaultColorScheme.ForegroundColor.Color, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Example shortcut action to test this template: Set Tab Color -->
|
||||
<DataTemplate x:Key="WindowsUIColorOptionalTemplate"
|
||||
x:DataType="local:ArgWrapper">
|
||||
<Grid Margin="0,4,0,4"
|
||||
ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name}"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
<local:SettingContainer Header="{x:Bind Name}">
|
||||
<local:NullableColorPicker x:Uid="Actions_NullableColorPicker"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.Name="{x:Bind Name}"
|
||||
ColorSchemeVM="{x:Bind DefaultColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind UnboxWindowsUIColorOptional(Value), Mode=TwoWay, BindBack=WindowsUIColorBindBack}"
|
||||
NullColorPreview="{x:Bind DefaultColorScheme.ForegroundColor.Color, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</DataTemplate>
|
||||
|
||||
<local:ArgsTemplateSelectors x:Key="ArgsTemplateSelector"
|
||||
@@ -655,122 +427,106 @@
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="{StaticResource SettingStackMargin}">
|
||||
<Grid Margin="{StaticResource SettingStackMargin}"
|
||||
HorizontalAlignment="Stretch">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="{StaticResource ArgumentNameWidth}" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Actions_CommandDetails"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}" />
|
||||
<TextBlock x:Uid="Actions_Name"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="0,0,0,8"
|
||||
VerticalAlignment="Center" />
|
||||
<TextBox x:Name="CommandNameTextBox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,8"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ActionNameTextBoxAutomationPropName}"
|
||||
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Actions_ShortcutAction"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center" />
|
||||
<AutoSuggestBox x:Name="ShortcutActionBox"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
|
||||
GotFocus="ShortcutActionBox_GotFocus"
|
||||
LostFocus="ShortcutActionBox_LostFocus"
|
||||
QuerySubmitted="ShortcutActionBox_QuerySubmitted"
|
||||
TextChanged="ShortcutActionBox_TextChanged" />
|
||||
<TextBlock x:Uid="Actions_Keybindings"
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}" />
|
||||
<ListView x:Name="KeyChordListView"
|
||||
x:Uid="Actions_KeyBindingsListView"
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
ItemTemplate="{StaticResource KeyChordTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
|
||||
SelectionMode="None">
|
||||
<ListView.Footer>
|
||||
<Button Margin="0,4,0,0"
|
||||
Click="{x:Bind ViewModel.AddKeybinding_Click}">
|
||||
<TextBlock x:Uid="Actions_AddKeyChord" />
|
||||
</Button>
|
||||
</ListView.Footer>
|
||||
</ListView>
|
||||
<TextBlock x:Uid="Actions_Arguments"
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource TextBlockGroupingStyle}"
|
||||
Visibility="{x:Bind ViewModel.ActionArgsVM.HasArgs, Mode=OneWay}" />
|
||||
<ItemsControl Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="0,0,0,12"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.AdditionalArgumentsControlAutomationPropName}"
|
||||
IsTabStop="False"
|
||||
ItemTemplateSelector="{StaticResource ArgsTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}" />
|
||||
<Button Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
IsEnabled="{x:Bind ViewModel.IsUserAction, Mode=OneWay}"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Actions_DeleteButton2"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Actions_CommandDeleteConfirmationMessage"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Actions_CommandDeleteConfirmationButton"
|
||||
Click="{x:Bind ViewModel.Delete_Click}" />
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<StackPanel HorizontalAlignment="Stretch"
|
||||
Style="{StaticResource SettingsStackStyle}">
|
||||
|
||||
<!-- Action type (top-most setting on the page) -->
|
||||
<local:SettingContainer x:Name="ActionType"
|
||||
x:Uid="EditAction_ActionType">
|
||||
<AutoSuggestBox x:Name="ShortcutActionBox"
|
||||
MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ShortcutActionComboBoxAutomationPropName}"
|
||||
GotFocus="ShortcutActionBox_GotFocus"
|
||||
LostFocus="ShortcutActionBox_LostFocus"
|
||||
QuerySubmitted="ShortcutActionBox_QuerySubmitted"
|
||||
TextChanged="ShortcutActionBox_TextChanged" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Key bindings expander -->
|
||||
<local:SettingContainer x:Name="KeyBindingsContainer"
|
||||
x:Uid="EditAction_KeyBindings"
|
||||
StartExpanded="{x:Bind mtu:Converters.InvertBoolean(ViewModel.HasNoKeyChords), Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<!-- "New key binding" button -->
|
||||
<local:SettingContainer x:Name="NewKeyBinding"
|
||||
x:Uid="EditAction_NewKeyBinding">
|
||||
<Button x:Uid="EditAction_AddKeyBinding"
|
||||
Click="{x:Bind ViewModel.AddKeybinding_Click}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Existing key bindings, one container per chord -->
|
||||
<ListView x:Name="KeyChordListView"
|
||||
x:Uid="Actions_KeyBindingsListView"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
IsItemClickEnabled="False"
|
||||
ItemContainerStyle="{StaticResource KeyChordListViewItemStyle}"
|
||||
ItemTemplate="{StaticResource KeyChordTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.KeyChordList, Mode=OneWay}"
|
||||
SelectionMode="None" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Additional customizations expander -->
|
||||
<local:SettingContainer x:Name="AdditionalCustomizations"
|
||||
x:Uid="EditAction_AdditionalCustomizations"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<!-- Action name -->
|
||||
<local:SettingContainer x:Name="ActionName"
|
||||
x:Uid="EditAction_ActionName">
|
||||
<TextBox x:Name="CommandNameTextBox"
|
||||
MinWidth="248"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.ActionNameTextBoxAutomationPropName}"
|
||||
PlaceholderText="{x:Bind ViewModel.DisplayName, Mode=OneWay}"
|
||||
Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Action argument controls -->
|
||||
<ItemsControl HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
AutomationProperties.Name="{x:Bind ViewModel.AdditionalArgumentsControlAutomationPropName}"
|
||||
IsTabStop="False"
|
||||
ItemTemplateSelector="{StaticResource ArgsTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.ActionArgsVM.ArgValues, Mode=OneWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel HorizontalAlignment="Stretch" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Delete command button -->
|
||||
<local:SettingContainer x:Name="DeleteCommand"
|
||||
x:Uid="EditAction_DeleteCommand">
|
||||
<Button IsEnabled="{x:Bind ViewModel.IsUserAction, Mode=OneWay}"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Actions_DeleteButton2"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="Actions_CommandDeleteConfirmationMessage"
|
||||
Style="{StaticResource CustomFlyoutTextStyle}" />
|
||||
<Button x:Uid="Actions_CommandDeleteConfirmationButton"
|
||||
Click="{x:Bind ViewModel.Delete_Click}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Page>
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void Extensions::ExtensionNavigator_Click(const IInspectable& sender, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
const auto extPkgVM = sender.as<Controls::Button>().Tag().as<Editor::ExtensionPackageViewModel>();
|
||||
const auto extPkgVM = sender.as<FrameworkElement>().Tag().as<Editor::ExtensionPackageViewModel>();
|
||||
_ViewModel.CurrentExtensionPackage(extPkgVM);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,6 @@
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<Style x:Key="ItalicDisclaimerStyle"
|
||||
BasedOn="{StaticResource DisclaimerStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontStyle" Value="Italic" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CodeBlockStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="Cascadia Mono, Consolas" />
|
||||
@@ -127,78 +121,58 @@
|
||||
|
||||
<DataTemplate x:Key="DefaultExtensionNavigatorTemplate"
|
||||
x:DataType="local:ExtensionPackageViewModel">
|
||||
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}"
|
||||
Tag="{x:Bind}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter Content="{x:Bind}"
|
||||
ContentTemplate="{StaticResource DefaultExtensionIdentifierTemplate}" />
|
||||
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
|
||||
</Grid>
|
||||
</Button>
|
||||
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Header="{x:Bind Package.Source}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind}">
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ComplexExtensionNavigatorTemplate"
|
||||
x:DataType="local:ExtensionPackageViewModel">
|
||||
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}"
|
||||
Tag="{x:Bind}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter Content="{x:Bind}"
|
||||
ContentTemplate="{StaticResource ComplexExtensionIdentifierTemplate}" />
|
||||
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Description="{x:Bind Package.Source}"
|
||||
Header="{x:Bind Package.DisplayName}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind}">
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<IconSourceElement IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Package.Icon)}" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="ComplexExtensionNavigatorTemplateWithFontIcon"
|
||||
x:DataType="local:ExtensionPackageViewModel">
|
||||
<Button AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}"
|
||||
Tag="{x:Bind}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ContentPresenter Content="{x:Bind}"
|
||||
ContentTemplate="{StaticResource ComplexExtensionIdentifierTemplateWithFontIcon}" />
|
||||
|
||||
<ToggleSwitch Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
</Button>
|
||||
<local:SettingsCard AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
Click="ExtensionNavigator_Click"
|
||||
Description="{x:Bind Package.Source}"
|
||||
Header="{x:Bind Package.DisplayName}"
|
||||
IsClickEnabled="True"
|
||||
Tag="{x:Bind}">
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<FontIcon Glyph="{x:Bind Package.Icon}" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
<ToggleSwitch HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.Name="{x:Bind AccessibleName}"
|
||||
IsOn="{x:Bind Enabled, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingsCard>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="FragmentProfileViewModelTemplate"
|
||||
@@ -502,9 +476,11 @@
|
||||
<!-- Scope -->
|
||||
<local:SettingContainer x:Name="Scope"
|
||||
x:Uid="Extensions_Scope"
|
||||
Content="{x:Bind ViewModel.CurrentExtensionPackage.Scope, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Style="{StaticResource SettingContainerWithTextContent}" />
|
||||
IsTabStop="False">
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentExtensionPackage.Scope, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
<!-- JSON -->
|
||||
<ItemsControl IsTabStop="False"
|
||||
ItemTemplate="{StaticResource JsonTemplate}"
|
||||
|
||||
@@ -27,126 +27,152 @@
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Theme -->
|
||||
<local:SettingContainer x:Name="Theme"
|
||||
x:Uid="Globals_Theme">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemsSource="{x:Bind ViewModel.ThemeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:Theme">
|
||||
<TextBlock Text="{x:Bind local:GlobalAppearanceViewModel.ThemeNameConverter((model:Theme)), Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Visual style -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Globals_Section_VisualStyle"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Theme -->
|
||||
<local:SettingContainer x:Name="Theme"
|
||||
x:Uid="Globals_Theme">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemsSource="{x:Bind ViewModel.ThemeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTheme, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:Theme">
|
||||
<TextBlock Text="{x:Bind local:GlobalAppearanceViewModel.ThemeNameConverter((model:Theme)), Mode=OneWay}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Position of new tab -->
|
||||
<local:SettingContainer x:Name="NewTabPosition"
|
||||
x:Uid="Globals_NewTabPosition">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.NewTabPositionList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentNewTabPosition, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Show Acrylic in Tab Row -->
|
||||
<local:SettingContainer x:Name="AcrylicTabRow"
|
||||
x:Uid="Globals_AcrylicTabRow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.UseAcrylicInTabRow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Titlebar -->
|
||||
<local:SettingContainer x:Name="ShowTitlebar"
|
||||
x:Uid="Globals_ShowTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}"
|
||||
Toggled="{x:Bind ViewModel.ShowTitlebarToggled}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Enable Unfocused Acrylic -->
|
||||
<local:SettingContainer x:Name="EnableUnfocusedAcrylic"
|
||||
x:Uid="Globals_EnableUnfocusedAcrylic">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableUnfocusedAcrylic, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Always show tabs -->
|
||||
<local:SettingContainer x:Name="AlwaysShowTabs"
|
||||
x:Uid="Globals_AlwaysShowTabs">
|
||||
<ToggleSwitch IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.AlwaysShowTabs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Disable Animations -->
|
||||
<!-- NOTE: the UID is "DisablePaneAnimationsReversed" not "DisablePaneAnimations". See GH#9124 for more details. -->
|
||||
<local:SettingContainer x:Name="DisableAnimations"
|
||||
x:Uid="Globals_DisableAnimationsReversed">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InvertedDisableAnimations, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Show tabs in full screen -->
|
||||
<local:SettingContainer x:Name="ShowTabsFullscreen"
|
||||
x:Uid="Globals_ShowTabsFullscreen">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsFullscreen, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Tabs and layout -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Globals_Section_TabsLayout"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Position of new tab -->
|
||||
<local:SettingContainer x:Name="NewTabPosition"
|
||||
x:Uid="Globals_NewTabPosition">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.NewTabPositionList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentNewTabPosition, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Acrylic in Tab Row -->
|
||||
<local:SettingContainer x:Name="AcrylicTabRow"
|
||||
x:Uid="Globals_AcrylicTabRow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.UseAcrylicInTabRow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Always show tabs -->
|
||||
<local:SettingContainer x:Name="AlwaysShowTabs"
|
||||
x:Uid="Globals_AlwaysShowTabs">
|
||||
<ToggleSwitch IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.ShowTabsInTitlebar), Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.AlwaysShowTabs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Show Title in Titlebar -->
|
||||
<local:SettingContainer x:Name="ShowTitleInTitlebar"
|
||||
x:Uid="Globals_ShowTitleInTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTitleInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Show tabs in full screen -->
|
||||
<local:SettingContainer x:Name="ShowTabsFullscreen"
|
||||
x:Uid="Globals_ShowTabsFullscreen">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsFullscreen, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Always on Top -->
|
||||
<local:SettingContainer x:Name="AlwaysOnTop"
|
||||
x:Uid="Globals_AlwaysOnTop">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysOnTop, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Tab Width Mode -->
|
||||
<local:SettingContainer x:Name="TabWidthMode"
|
||||
x:Uid="Globals_TabWidthMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabWidthModeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabWidthMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Width Mode -->
|
||||
<local:SettingContainer x:Name="TabWidthMode"
|
||||
x:Uid="Globals_TabWidthMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabWidthModeList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabWidthMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Show Titlebar -->
|
||||
<local:SettingContainer x:Name="ShowTitlebar"
|
||||
x:Uid="Globals_ShowTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTabsInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}"
|
||||
Toggled="{x:Bind ViewModel.ShowTitlebarToggled}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Disable Animations -->
|
||||
<!-- NOTE: the UID is "DisablePaneAnimationsReversed" not "DisablePaneAnimations". See GH#9124 for more details. -->
|
||||
<local:SettingContainer x:Name="DisableAnimations"
|
||||
x:Uid="Globals_DisableAnimationsReversed">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InvertedDisableAnimations, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Window behavior -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Globals_Section_WindowBehavior"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Always on Top -->
|
||||
<local:SettingContainer x:Name="AlwaysOnTop"
|
||||
x:Uid="Globals_AlwaysOnTop">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysOnTop, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Always Show Notification Icon -->
|
||||
<local:SettingContainer x:Name="AlwaysShowNotificationIcon"
|
||||
x:Uid="Globals_AlwaysShowNotificationIcon">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysShowNotificationIcon, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Automatically hide window -->
|
||||
<local:SettingContainer x:Name="AutoHideWindow"
|
||||
x:Uid="Globals_AutoHideWindow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AutoHideWindow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Minimize To Notification Area -->
|
||||
<local:SettingContainer x:Name="MinimizeToNotificationArea"
|
||||
x:Uid="Globals_MinimizeToNotificationArea">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.MinimizeToNotificationArea, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Title bar & identity -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Globals_Section_TitleBarIdentity"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Show Title in Titlebar (use active terminal title as application title) -->
|
||||
<local:SettingContainer x:Name="ShowTitleInTitlebar"
|
||||
x:Uid="Globals_ShowTitleInTitlebar">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowTitleInTitlebar, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Automatically hide window -->
|
||||
<local:SettingContainer x:Name="AutoHideWindow"
|
||||
x:Uid="Globals_AutoHideWindow">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AutoHideWindow, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Show Admin Shield -->
|
||||
<local:SettingContainer x:Name="ShowAdminShield"
|
||||
x:Uid="Globals_ShowAdminShield">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowAdminShield, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Show Admin Shield -->
|
||||
<local:SettingContainer x:Name="ShowAdminShield"
|
||||
x:Uid="Globals_ShowAdminShield">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ShowAdminShield, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: System integration & notifications -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Globals_Section_SystemIntegration"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Always Show Notification Icon -->
|
||||
<local:SettingContainer x:Name="AlwaysShowNotificationIcon"
|
||||
x:Uid="Globals_AlwaysShowNotificationIcon">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AlwaysShowNotificationIcon, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Unfocused Acrylic -->
|
||||
<local:SettingContainer x:Name="EnableUnfocusedAcrylic"
|
||||
x:Uid="Globals_EnableUnfocusedAcrylic">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableUnfocusedAcrylic, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Minimize To Notification Area -->
|
||||
<local:SettingContainer x:Name="MinimizeToNotificationArea"
|
||||
x:Uid="Globals_MinimizeToNotificationArea">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.MinimizeToNotificationArea, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
|
||||
@@ -26,149 +26,173 @@
|
||||
|
||||
<StackPanel>
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Copy On Select -->
|
||||
<local:SettingContainer x:Name="CopyOnSelect"
|
||||
x:Uid="Globals_CopyOnSelect">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CopyOnSelect, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Clipboard and paste behavior -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Interaction_Section_Clipboard"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Copy On Select -->
|
||||
<local:SettingContainer x:Name="CopyOnSelect"
|
||||
x:Uid="Globals_CopyOnSelect">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CopyOnSelect, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Copy Format -->
|
||||
<local:SettingContainer x:Name="CopyFormat"
|
||||
x:Uid="Globals_CopyFormat">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.CopyFormatList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentCopyFormat, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Trim Paste -->
|
||||
<local:SettingContainer x:Name="TrimPaste"
|
||||
x:Uid="Globals_TrimPaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimPaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Trim Block Selection -->
|
||||
<local:SettingContainer x:Name="TrimBlockSelection"
|
||||
x:Uid="Globals_TrimBlockSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimBlockSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Trim Block Selection -->
|
||||
<local:SettingContainer x:Name="TrimBlockSelection"
|
||||
x:Uid="Globals_TrimBlockSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimBlockSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Trim Paste -->
|
||||
<local:SettingContainer x:Name="TrimPaste"
|
||||
x:Uid="Globals_TrimPaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.TrimPaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Copy Format -->
|
||||
<local:SettingContainer x:Name="CopyFormat"
|
||||
x:Uid="Globals_CopyFormat">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.CopyFormatList, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentCopyFormat, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Word Delimiters -->
|
||||
<local:SettingContainer x:Name="WordDelimiters"
|
||||
x:Uid="Globals_WordDelimiters"
|
||||
CurrentValue="{x:Bind ViewModel.WordDelimiters, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.WordDelimiters, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Text selection & editing -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Interaction_Section_TextSelection"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Word Delimiters -->
|
||||
<local:SettingContainer x:Name="WordDelimiters"
|
||||
x:Uid="Globals_WordDelimiters"
|
||||
CurrentValue="{x:Bind ViewModel.WordDelimiters, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.WordDelimiters, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Snap On Resize -->
|
||||
<local:SettingContainer x:Name="SnapToGridOnResize"
|
||||
x:Uid="Globals_SnapToGridOnResize">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SnapToGridOnResize, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Enable Color Selection -->
|
||||
<local:SettingContainer x:Name="EnableColorSelection"
|
||||
x:Uid="Globals_EnableColorSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableColorSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Tab Switcher Mode -->
|
||||
<local:SettingContainer x:Name="TabSwitcherMode"
|
||||
x:Uid="Globals_TabSwitcherMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabSwitcherModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabSwitcherMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Window and layout behavior -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Interaction_Section_WindowLayout"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Snap On Resize -->
|
||||
<local:SettingContainer x:Name="SnapToGridOnResize"
|
||||
x:Uid="Globals_SnapToGridOnResize">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SnapToGridOnResize, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Focus Follow Mouse Mode -->
|
||||
<local:SettingContainer x:Name="FocusFollowMouse"
|
||||
x:Uid="Globals_FocusFollowMouse">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.FocusFollowMouse, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Focus Follow Mouse Mode -->
|
||||
<local:SettingContainer x:Name="FocusFollowMouse"
|
||||
x:Uid="Globals_FocusFollowMouse">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.FocusFollowMouse, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Font Size Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToZoom"
|
||||
x:Uid="Globals_ScrollToZoom">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToZoom, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Tab Switcher Mode -->
|
||||
<local:SettingContainer x:Name="TabSwitcherMode"
|
||||
x:Uid="Globals_TabSwitcherMode">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.TabSwitcherModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentTabSwitcherMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Enable Window Opacity Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToChangeOpacity"
|
||||
x:Uid="Globals_ScrollToChangeOpacity">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToChangeOpacity, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Mouse & scrolling -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Interaction_Section_MouseScrolling"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Enable Font Size Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToZoom"
|
||||
x:Uid="Globals_ScrollToZoom">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToZoom, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Detect URLs -->
|
||||
<local:SettingContainer x:Name="DetectURLs"
|
||||
x:Uid="Globals_DetectURLs">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DetectURLs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Enable Window Opacity Changes with Scrolling -->
|
||||
<local:SettingContainer x:Name="ScrollToChangeOpacity"
|
||||
x:Uid="Globals_ScrollToChangeOpacity">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ScrollToChangeOpacity, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Search Web Default Query URL -->
|
||||
<local:SettingContainer x:Name="SearchWebDefaultQueryUrl"
|
||||
x:Uid="Globals_SearchWebDefaultQueryUrl"
|
||||
CurrentValue="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: URLs & external actions -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Interaction_Section_UrlsExternal"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Detect URLs -->
|
||||
<local:SettingContainer x:Name="DetectURLs"
|
||||
x:Uid="Globals_DetectURLs">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DetectURLs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Enable Color Selection -->
|
||||
<local:SettingContainer x:Name="EnableColorSelection"
|
||||
x:Uid="Globals_EnableColorSelection">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.EnableColorSelection, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
<!-- Search Web Default Query URL -->
|
||||
<local:SettingContainer x:Name="SearchWebDefaultQueryUrl"
|
||||
x:Uid="Globals_SearchWebDefaultQueryUrl"
|
||||
CurrentValue="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.SearchWebDefaultQueryUrl, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Grouping: Warnings -->
|
||||
<TextBlock x:Uid="Globals_WarningsHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Section: Warnings -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Interaction_Section_Warnings"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Confirm Close On -->
|
||||
<local:SettingContainer x:Name="ConfirmOnClose"
|
||||
x:Uid="Globals_ConfirmOnClose">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.ConfirmOnCloseList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentConfirmOnClose, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Confirm Close On -->
|
||||
<local:SettingContainer x:Name="ConfirmOnClose"
|
||||
x:Uid="Globals_ConfirmOnClose">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.ConfirmOnCloseList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentConfirmOnClose, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Input Service Warning -->
|
||||
<local:SettingContainer x:Name="InputServiceWarning"
|
||||
x:Uid="Globals_InputServiceWarning">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InputServiceWarning, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Input Service Warning -->
|
||||
<local:SettingContainer x:Name="InputServiceWarning"
|
||||
x:Uid="Globals_InputServiceWarning">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.InputServiceWarning, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Large Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutLargePaste"
|
||||
x:Uid="Globals_WarnAboutLargePaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.WarnAboutLargePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Multi Line Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutMultiLinePaste"
|
||||
x:Uid="Globals_WarnAboutMultiLinePaste">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind WarnAboutMultiLinePasteList}"
|
||||
SelectedItem="{x:Bind CurrentWarnAboutMultiLinePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Large Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutLargePaste"
|
||||
x:Uid="Globals_WarnAboutLargePaste">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.WarnAboutLargePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Multi Line Paste Warning -->
|
||||
<local:SettingContainer x:Name="WarnAboutMultiLinePaste"
|
||||
x:Uid="Globals_WarnAboutMultiLinePaste">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind WarnAboutMultiLinePasteList}"
|
||||
SelectedItem="{x:Bind CurrentWarnAboutMultiLinePaste, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
|
||||
131
src/cascadia/TerminalSettingsEditor/KeyChordVisual.cpp
Normal file
131
src/cascadia/TerminalSettingsEditor/KeyChordVisual.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "KeyChordVisual.h"
|
||||
#include "KeyChordVisual.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty KeyChordVisual::_KeyChordProperty{ nullptr };
|
||||
|
||||
KeyChordVisual::KeyChordVisual()
|
||||
{
|
||||
InitializeComponent();
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
void KeyChordVisual::_InitializeProperties()
|
||||
{
|
||||
if (!_KeyChordProperty)
|
||||
{
|
||||
_KeyChordProperty =
|
||||
DependencyProperty::Register(
|
||||
L"KeyChord",
|
||||
xaml_typename<Control::KeyChord>(),
|
||||
xaml_typename<Editor::KeyChordVisual>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &KeyChordVisual::_OnKeyChordChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
void KeyChordVisual::_OnKeyChordChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
if (const auto control{ d.try_as<Editor::KeyChordVisual>() })
|
||||
{
|
||||
const auto controlImpl{ get_self<KeyChordVisual>(control) };
|
||||
controlImpl->_UpdateKeyVisuals();
|
||||
}
|
||||
}
|
||||
|
||||
// Capitalizes the first character of the provided string.
|
||||
// Examples: "enter" -> "Enter", "f1" -> "F1", "v" -> "V"
|
||||
static winrt::hstring _formatMainKeyName(std::wstring_view part)
|
||||
{
|
||||
if (part.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::wstring buffer{ part };
|
||||
buffer[0] = til::toupper_ascii(buffer[0]);
|
||||
return winrt::hstring{ buffer };
|
||||
}
|
||||
|
||||
void KeyChordVisual::_UpdateKeyVisuals()
|
||||
{
|
||||
auto panel{ KeysPanel() };
|
||||
if (!panel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
panel.Children().Clear();
|
||||
|
||||
const auto kc{ KeyChord() };
|
||||
if (!kc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Reuse the canonical serialization so the key naming stays in sync with the
|
||||
// rest of the app. Then split on '+' (no key name in the table contains a literal
|
||||
// '+'; VK_OEM_PLUS serializes as "plus") and render each part as its own visual.
|
||||
const auto serialized{ Model::KeyChordSerialization::ToString(kc) };
|
||||
if (serialized.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::wstring_view full{ serialized };
|
||||
for (const auto part : til::split_iterator{ full, L'+' })
|
||||
{
|
||||
if (til::equals_insensitive_ascii(part, L"win"))
|
||||
{
|
||||
_AddGlyphKey();
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"ctrl"))
|
||||
{
|
||||
_AddTextKey(L"Ctrl");
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"alt"))
|
||||
{
|
||||
_AddTextKey(L"Alt");
|
||||
}
|
||||
else if (til::equals_insensitive_ascii(part, L"shift"))
|
||||
{
|
||||
_AddTextKey(L"Shift");
|
||||
}
|
||||
else
|
||||
{
|
||||
_AddTextKey(_formatMainKeyName(part));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyChordVisual::_AddTextKey(const winrt::hstring& text)
|
||||
{
|
||||
const auto tmpl{ Resources().Lookup(box_value(L"KeyChordVisualTextKeyTemplate")).as<DataTemplate>() };
|
||||
const auto border{ tmpl.LoadContent().as<Border>() };
|
||||
if (const auto tb{ border.Child().try_as<TextBlock>() })
|
||||
{
|
||||
tb.Text(text);
|
||||
}
|
||||
KeysPanel().Children().Append(border);
|
||||
}
|
||||
|
||||
void KeyChordVisual::_AddGlyphKey()
|
||||
{
|
||||
const auto tmpl{ Resources().Lookup(box_value(L"KeyChordVisualWindowsKeyTemplate")).as<DataTemplate>() };
|
||||
const auto border{ tmpl.LoadContent().as<Border>() };
|
||||
|
||||
// Provide an accessible name for the glyph since it has no text fallback.
|
||||
if (const auto path{ border.Child() })
|
||||
{
|
||||
Automation::AutomationProperties::SetName(path, L"Win");
|
||||
}
|
||||
KeysPanel().Children().Append(border);
|
||||
}
|
||||
}
|
||||
31
src/cascadia/TerminalSettingsEditor/KeyChordVisual.h
Normal file
31
src/cascadia/TerminalSettingsEditor/KeyChordVisual.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "KeyChordVisual.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct KeyChordVisual : KeyChordVisualT<KeyChordVisual>
|
||||
{
|
||||
public:
|
||||
KeyChordVisual();
|
||||
|
||||
DEPENDENCY_PROPERTY(Control::KeyChord, KeyChord);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnKeyChordChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _UpdateKeyVisuals();
|
||||
void _AddTextKey(const winrt::hstring& text);
|
||||
void _AddGlyphKey();
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(KeyChordVisual);
|
||||
}
|
||||
13
src/cascadia/TerminalSettingsEditor/KeyChordVisual.idl
Normal file
13
src/cascadia/TerminalSettingsEditor/KeyChordVisual.idl
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass KeyChordVisual : Windows.UI.Xaml.Controls.UserControl
|
||||
{
|
||||
KeyChordVisual();
|
||||
|
||||
Microsoft.Terminal.Control.KeyChord KeyChord;
|
||||
static Windows.UI.Xaml.DependencyProperty KeyChordProperty { get; };
|
||||
}
|
||||
}
|
||||
82
src/cascadia/TerminalSettingsEditor/KeyChordVisual.xaml
Normal file
82
src/cascadia/TerminalSettingsEditor/KeyChordVisual.xaml
Normal 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.
|
||||
-->
|
||||
<UserControl x:Class="Microsoft.Terminal.Settings.Editor.KeyChordVisual"
|
||||
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"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
IsTabStop="False"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<StaticResource x:Key="KeyChordVisualKeyBackground"
|
||||
ResourceKey="AccentFillColorDefaultBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyForeground"
|
||||
ResourceKey="TextOnAccentFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyBorderBrush"
|
||||
ResourceKey="AccentControlElevationBorderBrush" />
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<StaticResource x:Key="KeyChordVisualKeyBackground"
|
||||
ResourceKey="SystemColorButtonFaceColorBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyForeground"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
<StaticResource x:Key="KeyChordVisualKeyBorderBrush"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<Style x:Key="KeyChordVisualKeyBorderStyle"
|
||||
TargetType="Border">
|
||||
<Setter Property="MinWidth" Value="32" />
|
||||
<Setter Property="MinHeight" Value="28" />
|
||||
<Setter Property="Padding" Value="8,2,8,2" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="{ThemeResource KeyChordVisualKeyBackground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource KeyChordVisualKeyBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
<Style x:Key="KeyChordVisualKeyTextStyle"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="13" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="TextAlignment" Value="Center" />
|
||||
<Setter Property="Foreground" Value="{ThemeResource KeyChordVisualKeyForeground}" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="KeyChordVisualTextKeyTemplate">
|
||||
<Border Style="{StaticResource KeyChordVisualKeyBorderStyle}">
|
||||
<TextBlock Style="{StaticResource KeyChordVisualKeyTextStyle}" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="KeyChordVisualWindowsKeyTemplate">
|
||||
<Border Style="{StaticResource KeyChordVisualKeyBorderStyle}">
|
||||
<Path Width="11"
|
||||
Height="11"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Data="M9 20H0V11H9V20ZM20 20H11V11H20V20ZM9 9H0V0H9V9ZM20 9H11V0H20V9Z"
|
||||
Fill="{ThemeResource KeyChordVisualKeyForeground}"
|
||||
Stretch="Uniform" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
<StackPanel x:Name="KeysPanel"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="2" />
|
||||
</UserControl>
|
||||
@@ -43,279 +43,290 @@
|
||||
|
||||
<StackPanel>
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<!-- Default Profile -->
|
||||
<local:SettingContainer x:Name="DefaultProfile"
|
||||
x:Uid="Globals_DefaultProfile">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.DefaultProfiles}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultProfile, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="SettingsModel:Profile">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
<!-- Section: Launch behavior -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Launch_Section_LaunchBehavior"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Default Profile -->
|
||||
<local:SettingContainer x:Name="DefaultProfile"
|
||||
x:Uid="Globals_DefaultProfile">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.DefaultProfiles}"
|
||||
SelectedItem="{x:Bind ViewModel.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>
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- profile name -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Default Terminal -->
|
||||
<local:SettingContainer x:Name="DefaultTerminalDropdown"
|
||||
x:Uid="Globals_DefaultTerminal"
|
||||
x:Load="false">
|
||||
<ComboBox x:Name="DefaultTerminal"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultTerminals}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultTerminal, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="SettingsModel:DefaultTerminal">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- terminal name and author -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- version -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<!-- terminal name -->
|
||||
<RowDefinition Height="auto" />
|
||||
<!-- author and version -->
|
||||
<RowDefinition Height="auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Width="24"
|
||||
Height="24"
|
||||
VerticalAlignment="Center"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Author}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Author)}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Version}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Version)}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Language -->
|
||||
<local:SettingContainer x:Name="Language"
|
||||
x:Uid="Globals_Language">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.LanguageList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLanguage, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="x:String">
|
||||
<TextBlock Text="{x:Bind local:LaunchViewModel.LanguageDisplayConverter((x:String))}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Language -->
|
||||
<local:SettingContainer x:Name="DefaultInputScope"
|
||||
x:Uid="Globals_DefaultInputScope">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultInputScopeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultInputScope, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Start on User Login -->
|
||||
<local:SettingContainer x:Name="StartOnUserLogin"
|
||||
x:Uid="Globals_StartOnUserLogin"
|
||||
HelpText="{x:Bind ViewModel.StartOnUserLoginStatefulHelpText, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.StartOnUserLoginAvailable, Mode=OneTime}">
|
||||
<ToggleSwitch IsEnabled="{x:Bind ViewModel.StartOnUserLoginConfigurable, Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.StartOnUserLogin, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- First Window Behavior -->
|
||||
<local:SettingContainer x:Name="FirstWindowPreference"
|
||||
x:Uid="Globals_FirstWindowPreference">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.FirstWindowPreferenceList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentFirstWindowPreference, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Windowing Behavior -->
|
||||
<local:SettingContainer x:Name="WindowingBehavior"
|
||||
x:Uid="Globals_WindowingBehavior">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.WindowingBehaviorList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentWindowingBehavior, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Launch Size -->
|
||||
<local:SettingContainer x:Name="LaunchSize"
|
||||
x:Uid="Globals_LaunchSize"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchSizeCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid ColumnSpacing="12"
|
||||
RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Globals_InitialCols"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialColsBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialCols, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Globals_InitialRows"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialRowsBox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialRows, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Launch Parameters -->
|
||||
<local:SettingContainer x:Name="LaunchParameters"
|
||||
x:Uid="Globals_LaunchParameters"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchParametersCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Globals_LaunchModeSetting"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ComboBox x:Name="LaunchModeComboBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
MinWidth="240"
|
||||
AutomationProperties.AccessibilityView="Content"
|
||||
<!-- First Window Behavior -->
|
||||
<local:SettingContainer x:Name="FirstWindowPreference"
|
||||
x:Uid="Globals_FirstWindowPreference">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.LaunchModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLaunchMode, Mode=TwoWay}"
|
||||
ItemsSource="{x:Bind ViewModel.FirstWindowPreferenceList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentFirstWindowPreference, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
<TextBlock x:Uid="Globals_LaunchPosition"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
ColumnSpacing="4">
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Windowing Behavior -->
|
||||
<local:SettingContainer x:Name="WindowingBehavior"
|
||||
x:Uid="Globals_WindowingBehavior">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.WindowingBehaviorList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentWindowingBehavior, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Start on User Login -->
|
||||
<local:SettingContainer x:Name="StartOnUserLogin"
|
||||
x:Uid="Globals_StartOnUserLogin"
|
||||
HelpText="{x:Bind ViewModel.StartOnUserLoginStatefulHelpText, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.StartOnUserLoginAvailable, Mode=OneTime}">
|
||||
<ToggleSwitch IsEnabled="{x:Bind ViewModel.StartOnUserLoginConfigurable, Mode=OneWay}"
|
||||
IsOn="{x:Bind ViewModel.StartOnUserLogin, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Launch Parameters -->
|
||||
<local:SettingContainer x:Name="LaunchParameters"
|
||||
x:Uid="Globals_LaunchParameters"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchParametersCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Match the width of these NumberBoxes to the Width of the LaunchModeComboBox above minus the Grid's ColumnSpacing -->
|
||||
<muxc:NumberBox x:Name="PosXBox"
|
||||
x:Uid="Globals_InitialPosXBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosX, Mode=TwoWay}" />
|
||||
<muxc:NumberBox x:Name="PosYBox"
|
||||
x:Uid="Globals_InitialPosYBox"
|
||||
<TextBlock x:Uid="Globals_LaunchModeSetting"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ComboBox x:Name="LaunchModeComboBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
MinWidth="240"
|
||||
AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.LaunchModeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLaunchMode, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
<TextBlock x:Uid="Globals_LaunchPosition"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<Grid Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
ColumnSpacing="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- Match the width of these NumberBoxes to the Width of the LaunchModeComboBox above minus the Grid's ColumnSpacing -->
|
||||
<muxc:NumberBox x:Name="PosXBox"
|
||||
x:Uid="Globals_InitialPosXBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosX, Mode=TwoWay}" />
|
||||
<muxc:NumberBox x:Name="PosYBox"
|
||||
x:Uid="Globals_InitialPosYBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosY, Mode=TwoWay}" />
|
||||
<CheckBox x:Name="UseDefaultLaunchPositionCheckbox"
|
||||
x:Uid="Globals_DefaultLaunchPositionCheckbox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
IsChecked="{x:Bind ViewModel.UseDefaultLaunchPosition, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<TextBlock x:Uid="Globals_CenterOnLaunch"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ToggleSwitch x:Name="CenterOnLaunchToggle"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
IsOn="{x:Bind ViewModel.CenterOnLaunch, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Launch Size -->
|
||||
<local:SettingContainer x:Name="LaunchSize"
|
||||
x:Uid="Globals_LaunchSize"
|
||||
CurrentValue="{x:Bind ViewModel.LaunchSizeCurrentValue, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<Grid ColumnSpacing="12"
|
||||
RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Uid="Globals_InitialCols"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialColsBox"
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Width="118"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(ViewModel.UseDefaultLaunchPosition), Mode=OneWay}"
|
||||
Style="{StaticResource LaunchPositionNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialPosY, Mode=TwoWay}" />
|
||||
<CheckBox x:Name="UseDefaultLaunchPositionCheckbox"
|
||||
x:Uid="Globals_DefaultLaunchPositionCheckbox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
IsChecked="{x:Bind ViewModel.UseDefaultLaunchPosition, Mode=TwoWay}" />
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialCols, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Globals_InitialRows"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}" />
|
||||
<muxc:NumberBox x:Uid="Globals_InitialRowsBox"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialRows, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<TextBlock x:Uid="Globals_CenterOnLaunch"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center" />
|
||||
<ToggleSwitch x:Name="CenterOnLaunchToggle"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
IsOn="{x:Bind ViewModel.CenterOnLaunch, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</Grid>
|
||||
</local:SettingContainer>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Section: System & input defaults -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Launch_Section_SystemInputDefaults"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Default Terminal -->
|
||||
<local:SettingContainer x:Name="DefaultTerminalDropdown"
|
||||
x:Uid="Globals_DefaultTerminal"
|
||||
x:Load="false">
|
||||
<ComboBox x:Name="DefaultTerminal"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultTerminals}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultTerminal, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="SettingsModel:DefaultTerminal">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- terminal name and author -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
<!-- version -->
|
||||
<ColumnDefinition Width="auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<!-- terminal name -->
|
||||
<RowDefinition Height="auto" />
|
||||
<!-- author and version -->
|
||||
<RowDefinition Height="auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Width="24"
|
||||
Height="24"
|
||||
VerticalAlignment="Center"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Text="{x:Bind Name}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Author}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Author)}" />
|
||||
|
||||
<TextBlock Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource SecondaryTextBlockStyle}"
|
||||
Text="{x:Bind Version}"
|
||||
Visibility="{x:Bind mtu:Converters.StringNotEmptyToVisibility(Version)}" />
|
||||
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Language -->
|
||||
<local:SettingContainer x:Name="Language"
|
||||
x:Uid="Globals_Language">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.LanguageList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentLanguage, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="x:String">
|
||||
<TextBlock Text="{x:Bind local:LaunchViewModel.LanguageDisplayConverter((x:String))}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Default IME Input Mode -->
|
||||
<local:SettingContainer x:Name="DefaultInputScope"
|
||||
x:Uid="Globals_DefaultInputScope">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.DefaultInputScopeList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentDefaultInputScope, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "Launch.h"
|
||||
#include "Interaction.h"
|
||||
#include "Compatibility.h"
|
||||
#include "Rendering.h"
|
||||
#include "RenderingViewModel.h"
|
||||
#include "Extensions.h"
|
||||
#include "Actions.h"
|
||||
#include "ProfileViewModel.h"
|
||||
@@ -17,6 +15,7 @@
|
||||
#include "ColorSchemes.h"
|
||||
#include "EditColorScheme.h"
|
||||
#include "AddProfile.h"
|
||||
#include "Profiles.h"
|
||||
#include "InteractionViewModel.h"
|
||||
#include "LaunchViewModel.h"
|
||||
#include "NewTabMenuViewModel.h"
|
||||
@@ -28,6 +27,8 @@
|
||||
#include <dwmapi.h>
|
||||
#include <fmt/compile.h>
|
||||
|
||||
#include <winrt/Windows.UI.Xaml.Media.Animation.h>
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
namespace MUX = Microsoft::UI::Xaml;
|
||||
@@ -40,6 +41,7 @@ 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;
|
||||
using namespace winrt::Windows::UI::Xaml::Media::Animation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
@@ -102,7 +104,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
MainPage::MainPage(const CascadiaSettings& settings) :
|
||||
_settingsSource{ settings },
|
||||
_settingsClone{ settings.Copy() },
|
||||
_profileVMs{ single_threaded_observable_vector<Editor::ProfileViewModel>() }
|
||||
_profilesPageVM{ winrt::make<ProfilesPageViewModel>() }
|
||||
{
|
||||
InitializeComponent();
|
||||
_UpdateBackgroundForMica();
|
||||
@@ -116,14 +118,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(currentFolder), currentFolder.Name(), BreadcrumbSubPage::NewTabMenu_Folder));
|
||||
SettingsMainPage_ScrollViewer().ScrollToVerticalOffset(0);
|
||||
_navDirection = NavDirection::Forward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we don't have a current folder, we're at the root of the NTM
|
||||
_breadcrumbs.Clear();
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(newTabMenuTag), RS_(L"Nav_NewTabMenu/Content"), BreadcrumbSubPage::None));
|
||||
_navDirection = NavDirection::Back;
|
||||
}
|
||||
contentFrame().Navigate(xaml_typename<Editor::NewTabMenu>(), winrt::make<NavigateToPageArgs>(_newTabMenuPageVM, *this));
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
contentFrame().Navigate(xaml_typename<Editor::NewTabMenu>(), winrt::make<NavigateToPageArgs>(_newTabMenuPageVM, *this), _MakeTransitionInfo());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -145,19 +150,24 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(currentExtensionPackage), currentExtensionPackage.DisplayName(), BreadcrumbSubPage::Extensions_Extension));
|
||||
SettingsMainPage_ScrollViewer().ScrollToVerticalOffset(0);
|
||||
_navDirection = NavDirection::Forward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we don't have a current extension package, we're at the root of the Extensions page
|
||||
_breadcrumbs.Clear();
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(extensionsTag), RS_(L"Nav_Extensions/Content"), BreadcrumbSubPage::None));
|
||||
_navDirection = NavDirection::Back;
|
||||
}
|
||||
contentFrame().Navigate(xaml_typename<Editor::Extensions>(), winrt::make<NavigateToPageArgs>(_extensionsVM, *this));
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
contentFrame().Navigate(xaml_typename<Editor::Extensions>(), winrt::make<NavigateToPageArgs>(_extensionsVM, *this), _MakeTransitionInfo());
|
||||
}
|
||||
});
|
||||
|
||||
_SetupProfilesPageEventHandling();
|
||||
|
||||
// Make sure to initialize the profiles _after_ we have initialized the color schemes page VM, because we pass
|
||||
// that VM into the appearance VMs within the profiles
|
||||
// that VM into the appearance VMs within the profiles. The Profiles VM owns the per-profile list itself.
|
||||
_InitializeProfilesList();
|
||||
|
||||
// Apply icons and tooltips (GH#19688, long names may be truncated) to static nav items
|
||||
@@ -205,28 +215,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
_UpdateBackgroundForMica();
|
||||
|
||||
// Deduce information about the currently selected item
|
||||
IInspectable lastBreadcrumb;
|
||||
const auto size = _breadcrumbs.Size();
|
||||
if (size > 0)
|
||||
// Capture data about where we are right now, so we can re-navigate to the same
|
||||
// place after we rebuild all the settings.
|
||||
IInspectable destination{ nullptr };
|
||||
auto subPage = BreadcrumbSubPage::None;
|
||||
if (const auto size = _breadcrumbs.Size(); size > 0)
|
||||
{
|
||||
lastBreadcrumb = _breadcrumbs.GetAt(size - 1);
|
||||
const auto& crumb = _breadcrumbs.GetAt(size - 1).as<Breadcrumb>();
|
||||
destination = crumb->Tag();
|
||||
subPage = crumb->SubPage();
|
||||
}
|
||||
|
||||
// Collect only the first items out of the menu item source, the static
|
||||
// ones that we don't want to regenerate.
|
||||
//
|
||||
// By manipulating a MenuItemsSource this way, rather than manipulating the
|
||||
// MenuItems directly, we avoid a crash in WinUI.
|
||||
//
|
||||
// By making the vector only _originalNumItems big to start, GetMany
|
||||
// will only fill that number of elements out of the current source.
|
||||
std::vector<IInspectable> menuItemsSTL(_originalNumItems, nullptr);
|
||||
_menuItemSource.GetMany(0, menuItemsSTL);
|
||||
// now, just stick them back in.
|
||||
_menuItemSource.ReplaceAll(menuItemsSTL);
|
||||
|
||||
// Repopulate profile-related menu items
|
||||
_InitializeProfilesList();
|
||||
|
||||
// Update the Nav State with the new version of the settings
|
||||
@@ -236,64 +235,41 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_extensionsVM.UpdateSettings(_settingsClone, _colorSchemesPageVM);
|
||||
_profileDefaultsVM = nullptr; // Lazy-loaded upon navigation
|
||||
|
||||
// Now that the menuItems are repopulated,
|
||||
// refresh the current page using the breadcrumb data we collected before the refresh
|
||||
if (const auto& crumb{ lastBreadcrumb.try_as<Breadcrumb>() }; crumb && crumb->Tag())
|
||||
if (const auto& profileTag{ destination.try_as<Editor::ProfileViewModel>() })
|
||||
{
|
||||
bool foundNavigationParams = false;
|
||||
auto destination = crumb->Tag();
|
||||
auto subPage = crumb->SubPage();
|
||||
for (const auto& item : _menuItemSource)
|
||||
// Find the new profile VM by guid
|
||||
if (const auto newProfileVM = _FindProfileViewModelByGuid(profileTag.OriginalProfileGuid()))
|
||||
{
|
||||
const auto menuItem = item.try_as<MUX::Controls::NavigationViewItem>();
|
||||
if (!menuItem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& tag = menuItem.Tag();
|
||||
if (const auto& stringTag{ tag.try_as<hstring>() })
|
||||
{
|
||||
if (const auto& destString{ destination.try_as<hstring>() })
|
||||
{
|
||||
foundNavigationParams = (*stringTag == *destString);
|
||||
}
|
||||
else if (destination.try_as<Editor::FolderEntryViewModel>() && *stringTag == newTabMenuTag)
|
||||
{
|
||||
foundNavigationParams = true;
|
||||
subPage = BreadcrumbSubPage::NewTabMenu_Folder;
|
||||
}
|
||||
else if (destination.try_as<Editor::ExtensionPackageViewModel>() && *stringTag == extensionsTag)
|
||||
{
|
||||
foundNavigationParams = true;
|
||||
subPage = BreadcrumbSubPage::Extensions_Extension;
|
||||
}
|
||||
}
|
||||
else if (const auto& profileTag{ tag.try_as<ProfileViewModel>() })
|
||||
{
|
||||
const auto destProfile = destination.try_as<ProfileViewModel>();
|
||||
if (destProfile && profileTag->OriginalProfileGuid() == destProfile->OriginalProfileGuid())
|
||||
{
|
||||
// Use the new profile VM from the refreshed menu items
|
||||
destination = tag;
|
||||
foundNavigationParams = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundNavigationParams)
|
||||
{
|
||||
// found the one that was selected before the refresh
|
||||
_Navigate(destination, subPage);
|
||||
return;
|
||||
}
|
||||
destination = newProfileVM;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to the Profiles landing page
|
||||
destination = box_value(profilesTag);
|
||||
subPage = BreadcrumbSubPage::None;
|
||||
}
|
||||
}
|
||||
else if (destination.try_as<Editor::FolderEntryViewModel>())
|
||||
{
|
||||
destination = box_value(newTabMenuTag);
|
||||
subPage = BreadcrumbSubPage::NewTabMenu_Folder;
|
||||
}
|
||||
else if (destination.try_as<Editor::ExtensionPackageViewModel>())
|
||||
{
|
||||
destination = box_value(extensionsTag);
|
||||
subPage = BreadcrumbSubPage::Extensions_Extension;
|
||||
}
|
||||
else if (!destination.try_as<hstring>())
|
||||
{
|
||||
// Couldn't find a meaningful previous page. Fall back to the first menu item.
|
||||
if (_menuItemSource && _menuItemSource.Size() > 0)
|
||||
{
|
||||
destination = _menuItemSource.GetAt(0).as<MUX::Controls::NavigationViewItem>().Tag();
|
||||
subPage = BreadcrumbSubPage::None;
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't find the selected item, fall back to first menu item
|
||||
// This happens when the selected item was a profile which doesn't exist in the new configuration
|
||||
// We can use menuItemsSTL here because the only things they miss are profile entries.
|
||||
const auto& firstItem{ _menuItemSource.GetAt(0).as<MUX::Controls::NavigationViewItem>() };
|
||||
_Navigate(firstItem.Tag(), BreadcrumbSubPage::None);
|
||||
_Navigate(destination, subPage);
|
||||
|
||||
_UpdateSearchIndex();
|
||||
}
|
||||
@@ -325,12 +301,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// can be empty to indicate that we should create a fresh profile
|
||||
void MainPage::_AddProfileHandler(winrt::guid profileGuid)
|
||||
{
|
||||
uint32_t insertIndex;
|
||||
auto selectedItem{ SettingsNav().SelectedItem() };
|
||||
if (_menuItemSource)
|
||||
{
|
||||
_menuItemSource.IndexOf(selectedItem, insertIndex);
|
||||
}
|
||||
if (profileGuid != winrt::guid{})
|
||||
{
|
||||
// if we were given a non-empty guid, we want to duplicate the corresponding profile
|
||||
@@ -338,13 +308,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (profile)
|
||||
{
|
||||
const auto duplicated = _settingsClone.DuplicateProfile(profile);
|
||||
_CreateAndNavigateToNewProfile(insertIndex, duplicated);
|
||||
_CreateAndNavigateToNewProfile(duplicated);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we were given an empty guid, create a new profile
|
||||
_CreateAndNavigateToNewProfile(insertIndex, nullptr);
|
||||
_CreateAndNavigateToNewProfile(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,11 +416,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
const auto currentScheme = _colorSchemesPageVM.CurrentScheme();
|
||||
if (_colorSchemesPageVM.CurrentPage() == ColorSchemesSubPage::EditColorScheme && currentScheme)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditColorScheme>(), winrt::make<NavigateToPageArgs>(currentScheme, *this));
|
||||
_navDirection = NavDirection::Forward;
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditColorScheme>(), winrt::make<NavigateToPageArgs>(currentScheme, *this), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(boxedTag, currentScheme.Name(), BreadcrumbSubPage::ColorSchemes_Edit));
|
||||
}
|
||||
else if (_colorSchemesPageVM.CurrentPage() == ColorSchemesSubPage::Base)
|
||||
{
|
||||
_navDirection = NavDirection::Back;
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
_Navigate(boxedTag, BreadcrumbSubPage::None);
|
||||
}
|
||||
}
|
||||
@@ -471,11 +445,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
const auto boxedTag = box_value(actionsTag);
|
||||
if (_actionsVM.CurrentPage() == ActionsSubPage::Edit)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditAction>(), winrt::make<NavigateToPageArgs>(_actionsVM.CurrentCommand(), *this));
|
||||
_navDirection = NavDirection::Forward;
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditAction>(), winrt::make<NavigateToPageArgs>(_actionsVM.CurrentCommand(), *this), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(boxedTag, RS_(L"Nav_EditAction/Content"), BreadcrumbSubPage::Actions_Edit));
|
||||
}
|
||||
else if (_actionsVM.CurrentPage() == ActionsSubPage::Base)
|
||||
{
|
||||
_navDirection = NavDirection::Back;
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
_Navigate(boxedTag, BreadcrumbSubPage::None);
|
||||
}
|
||||
}
|
||||
@@ -486,21 +464,21 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
if (page == ProfileSubPage::Base)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Base>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Base>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus), _MakeTransitionInfo());
|
||||
}
|
||||
else if (page == ProfileSubPage::Appearance)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Appearance>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Appearance>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(breadcrumbTag, RS_(L"Profile_Appearance/Header"), BreadcrumbSubPage::Profile_Appearance));
|
||||
}
|
||||
else if (page == ProfileSubPage::Terminal)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Terminal>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Terminal>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(breadcrumbTag, RS_(L"Profile_Terminal/Header"), BreadcrumbSubPage::Profile_Terminal));
|
||||
}
|
||||
else if (page == ProfileSubPage::Advanced)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Advanced>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Advanced>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(breadcrumbTag, RS_(L"Profile_Advanced/Header"), BreadcrumbSubPage::Profile_Advanced));
|
||||
}
|
||||
SettingsMainPage_ScrollViewer().ScrollToVerticalOffset(0);
|
||||
@@ -521,8 +499,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (currentPage == ProfileSubPage::Base)
|
||||
{
|
||||
_breadcrumbs.Clear();
|
||||
_AppendProfilesRootCrumb();
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(breadcrumbTag, breadcrumbText, BreadcrumbSubPage::None));
|
||||
_navDirection = NavDirection::Back;
|
||||
}
|
||||
else
|
||||
{
|
||||
_navDirection = NavDirection::Forward;
|
||||
}
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
_NavigateToProfileSubPage(profile, currentPage, breadcrumbTag, {});
|
||||
}
|
||||
});
|
||||
@@ -546,22 +531,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
selectedNavTag = *clickedItemTag;
|
||||
if (*clickedItemTag == launchTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Launch>(), winrt::make<NavigateToPageArgs>(winrt::make<LaunchViewModel>(_settingsClone), *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Launch>(), winrt::make<NavigateToPageArgs>(winrt::make<LaunchViewModel>(_settingsClone), *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Launch/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == interactionTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Interaction>(), winrt::make<NavigateToPageArgs>(winrt::make<InteractionViewModel>(_settingsClone.GlobalSettings()), *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Interaction>(), winrt::make<NavigateToPageArgs>(winrt::make<InteractionViewModel>(_settingsClone.GlobalSettings()), *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Interaction/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == renderingTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Rendering>(), winrt::make<NavigateToPageArgs>(winrt::make<RenderingViewModel>(_settingsClone), *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Rendering/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == compatibilityTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Compatibility>(), winrt::make<NavigateToPageArgs>(winrt::make<CompatibilityViewModel>(_settingsClone), *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Compatibility>(), winrt::make<NavigateToPageArgs>(winrt::make<CompatibilityViewModel>(_settingsClone), *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Compatibility/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == actionsTag)
|
||||
@@ -575,7 +555,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// Navigate directly to EditAction instead of relying on PropertyChanged,
|
||||
// which won't fire if CurrentPage is already Edit
|
||||
_actionsVM.CurrentPage(ActionsSubPage::Edit);
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditAction>(), winrt::make<NavigateToPageArgs>(_actionsVM.CurrentCommand(), *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditAction>(), winrt::make<NavigateToPageArgs>(_actionsVM.CurrentCommand(), *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_EditAction/Content"), BreadcrumbSubPage::Actions_Edit));
|
||||
|
||||
// Re-register the handler for future user-driven changes
|
||||
@@ -583,7 +563,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Actions>(), winrt::make<NavigateToPageArgs>(_actionsVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Actions>(), winrt::make<NavigateToPageArgs>(_actionsVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_actionsVM.CurrentPage(ActionsSubPage::Base);
|
||||
}
|
||||
}
|
||||
@@ -598,7 +578,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
else
|
||||
{
|
||||
// Navigate to the NewTabMenu page
|
||||
contentFrame().Navigate(xaml_typename<Editor::NewTabMenu>(), winrt::make<NavigateToPageArgs>(_newTabMenuPageVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::NewTabMenu>(), winrt::make<NavigateToPageArgs>(_newTabMenuPageVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_NewTabMenu/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
}
|
||||
@@ -612,12 +592,19 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Extensions>(), winrt::make<NavigateToPageArgs>(_extensionsVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Extensions>(), winrt::make<NavigateToPageArgs>(_extensionsVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Extensions/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
}
|
||||
else if (*clickedItemTag == profilesTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles>(), winrt::make<NavigateToPageArgs>(_profilesPageVM, *this, elementToFocus));
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Profiles/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == globalProfileTag)
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
|
||||
// lazy load profile defaults VM
|
||||
if (!_profileDefaultsVM)
|
||||
{
|
||||
@@ -636,11 +623,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
// Register handler for future user-driven sub-page changes
|
||||
_SetupProfileEventHandling(_profileDefaultsVM);
|
||||
|
||||
// Keep the Profiles nav item selected.
|
||||
selectedNavTag = profilesTag;
|
||||
}
|
||||
else if (*clickedItemTag == colorSchemesTag)
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
selectedNavTag = profilesTag;
|
||||
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_ColorSchemes/Content"), BreadcrumbSubPage::None));
|
||||
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), winrt::make<NavigateToPageArgs>(_colorSchemesPageVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), winrt::make<NavigateToPageArgs>(_colorSchemesPageVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
|
||||
if (subPage == BreadcrumbSubPage::ColorSchemes_Edit)
|
||||
{
|
||||
@@ -649,57 +642,63 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
else if (*clickedItemTag == globalAppearanceTag)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::GlobalAppearance>(), winrt::make<NavigateToPageArgs>(winrt::make<GlobalAppearanceViewModel>(_settingsClone.GlobalSettings()), *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::GlobalAppearance>(), winrt::make<NavigateToPageArgs>(winrt::make<GlobalAppearanceViewModel>(_settingsClone.GlobalSettings()), *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_Appearance/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
else if (*clickedItemTag == addProfileTag)
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
|
||||
auto addProfileState{ winrt::make<AddProfilePageNavigationState>(_settingsClone) };
|
||||
addProfileState.AddNew({ get_weak(), &MainPage::_AddProfileHandler });
|
||||
contentFrame().Navigate(xaml_typename<Editor::AddProfile>(), winrt::make<NavigateToPageArgs>(addProfileState, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::AddProfile>(), winrt::make<NavigateToPageArgs>(addProfileState, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, RS_(L"Nav_AddNewProfile/Content"), BreadcrumbSubPage::None));
|
||||
|
||||
// Keep the Profiles nav item selected.
|
||||
selectedNavTag = profilesTag;
|
||||
}
|
||||
}
|
||||
else if (const auto& profile = vm.try_as<Editor::ProfileViewModel>())
|
||||
{
|
||||
_AppendProfilesRootCrumb();
|
||||
selectedNavTag = profilesTag;
|
||||
|
||||
if (profile.Orphaned())
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Base_Orphaned>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Profiles_Base_Orphaned>(), winrt::make<NavigateToPageArgs>(profile, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, profile.Name(), BreadcrumbSubPage::None));
|
||||
profile.CurrentPage(ProfileSubPage::Base);
|
||||
_SetupProfileEventHandling(profile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set CurrentPage before registering the handler to avoid double-navigation
|
||||
const ProfileSubPage profileSubPage = ProfileSubPageFromBreadcrumb(subPage);
|
||||
profile.CurrentPage(profileSubPage);
|
||||
|
||||
// Navigate directly to the correct sub-page
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, profile.Name(), BreadcrumbSubPage::None));
|
||||
_NavigateToProfileSubPage(profile, profileSubPage, vm, elementToFocus);
|
||||
|
||||
if (const auto profileNavItem = _FindProfileNavItem(profile.OriginalProfileGuid()))
|
||||
else
|
||||
{
|
||||
SettingsNav().SelectedItem(profileNavItem);
|
||||
}
|
||||
// Set CurrentPage before registering the handler to avoid double-navigation
|
||||
const ProfileSubPage profileSubPage = ProfileSubPageFromBreadcrumb(subPage);
|
||||
profile.CurrentPage(profileSubPage);
|
||||
|
||||
// Register handler for future user-driven sub-page changes
|
||||
_SetupProfileEventHandling(profile);
|
||||
// Navigate directly to the correct sub-page
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(vm, profile.Name(), BreadcrumbSubPage::None));
|
||||
_NavigateToProfileSubPage(profile, profileSubPage, vm, elementToFocus);
|
||||
|
||||
// Register handler for future user-driven sub-page changes
|
||||
_SetupProfileEventHandling(profile);
|
||||
}
|
||||
}
|
||||
else if (const auto& colorSchemeVM = vm.try_as<Editor::ColorSchemeViewModel>())
|
||||
{
|
||||
selectedNavTag = colorSchemesTag;
|
||||
const auto boxedColorSchemesTag = box_value(colorSchemesTag);
|
||||
|
||||
// Suppress the handler to avoid double-navigation
|
||||
_colorSchemesPageViewModelChangedRevoker.revoke();
|
||||
|
||||
_AppendProfilesRootCrumb();
|
||||
selectedNavTag = profilesTag;
|
||||
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(boxedColorSchemesTag, RS_(L"Nav_ColorSchemes/Content"), BreadcrumbSubPage::None));
|
||||
|
||||
if (subPage == BreadcrumbSubPage::None)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), winrt::make<NavigateToPageArgs>(_colorSchemesPageVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::ColorSchemes>(), winrt::make<NavigateToPageArgs>(_colorSchemesPageVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_colorSchemesPageVM.CurrentScheme(nullptr);
|
||||
_colorSchemesPageVM.CurrentPage(ColorSchemesSubPage::Base);
|
||||
}
|
||||
@@ -707,7 +706,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
_colorSchemesPageVM.CurrentScheme(colorSchemeVM);
|
||||
_colorSchemesPageVM.CurrentPage(ColorSchemesSubPage::EditColorScheme);
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditColorScheme>(), winrt::make<NavigateToPageArgs>(colorSchemeVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditColorScheme>(), winrt::make<NavigateToPageArgs>(colorSchemeVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(boxedColorSchemesTag, colorSchemeVM.Name(), BreadcrumbSubPage::ColorSchemes_Edit));
|
||||
}
|
||||
|
||||
@@ -718,7 +717,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
selectedNavTag = newTabMenuTag;
|
||||
|
||||
contentFrame().Navigate(xaml_typename<Editor::NewTabMenu>(), winrt::make<NavigateToPageArgs>(_newTabMenuPageVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::NewTabMenu>(), winrt::make<NavigateToPageArgs>(_newTabMenuPageVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(newTabMenuTag), RS_(L"Nav_NewTabMenu/Content"), BreadcrumbSubPage::None));
|
||||
|
||||
if (subPage == BreadcrumbSubPage::None)
|
||||
@@ -749,7 +748,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
selectedNavTag = extensionsTag;
|
||||
|
||||
contentFrame().Navigate(xaml_typename<Editor::Extensions>(), winrt::make<NavigateToPageArgs>(_extensionsVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Extensions>(), winrt::make<NavigateToPageArgs>(_extensionsVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(extensionsTag), RS_(L"Nav_Extensions/Content"), BreadcrumbSubPage::None));
|
||||
|
||||
if (subPage == BreadcrumbSubPage::None)
|
||||
@@ -794,7 +793,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
if (subPage == BreadcrumbSubPage::None || !commandVM)
|
||||
{
|
||||
contentFrame().Navigate(xaml_typename<Editor::Actions>(), winrt::make<NavigateToPageArgs>(_actionsVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::Actions>(), winrt::make<NavigateToPageArgs>(_actionsVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_actionsVM.CurrentCommand(nullptr);
|
||||
}
|
||||
else
|
||||
@@ -804,7 +803,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
_actionsVM.CurrentCommand(commandVM);
|
||||
_actionsVM.CurrentPage(ActionsSubPage::Edit);
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditAction>(), winrt::make<NavigateToPageArgs>(commandVM, *this, elementToFocus));
|
||||
contentFrame().Navigate(xaml_typename<Editor::EditAction>(), winrt::make<NavigateToPageArgs>(commandVM, *this, elementToFocus), _MakeTransitionInfo());
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(boxedActionsTag, RS_(L"Nav_EditAction/Content"), BreadcrumbSubPage::Actions_Edit));
|
||||
|
||||
// Re-register the handler for future user-driven changes
|
||||
@@ -813,26 +812,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
|
||||
// Select the appropriate nav item
|
||||
// NOTE: profiles are special in that they have their own nav item, so those are handled in the profile branch above
|
||||
if (!selectedNavTag.empty())
|
||||
{
|
||||
for (auto&& menuItem : _menuItemSource)
|
||||
{
|
||||
if (const auto& navViewItem{ menuItem.try_as<MUX::Controls::NavigationViewItem>() })
|
||||
{
|
||||
if (const auto& tag{ navViewItem.Tag() })
|
||||
{
|
||||
if (const auto& stringTag{ tag.try_as<hstring>() })
|
||||
{
|
||||
if (*stringTag == selectedNavTag)
|
||||
{
|
||||
SettingsNav().SelectedItem(navViewItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_SelectNavItemByTag(selectedNavTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -854,11 +836,34 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
if (gsl::narrow_cast<uint32_t>(args.Index()) < (_breadcrumbs.Size() - 1))
|
||||
{
|
||||
_navDirection = NavDirection::Back;
|
||||
const auto resetDir = wil::scope_exit([this]() noexcept { _navDirection = NavDirection::Default; });
|
||||
const auto crumb = args.Item().as<Breadcrumb>();
|
||||
_Navigate(crumb->Tag(), crumb->SubPage());
|
||||
}
|
||||
}
|
||||
|
||||
NavigationTransitionInfo MainPage::_MakeTransitionInfo() const
|
||||
{
|
||||
switch (_navDirection)
|
||||
{
|
||||
case NavDirection::Forward:
|
||||
{
|
||||
SlideNavigationTransitionInfo info;
|
||||
info.Effect(SlideNavigationTransitionEffect::FromRight);
|
||||
return info;
|
||||
}
|
||||
case NavDirection::Back:
|
||||
{
|
||||
SlideNavigationTransitionInfo info;
|
||||
info.Effect(SlideNavigationTransitionEffect::FromLeft);
|
||||
return info;
|
||||
}
|
||||
default:
|
||||
return EntranceNavigationTransitionInfo{};
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::_InitializeProfilesList()
|
||||
{
|
||||
const auto& itemSource{ SettingsNav().MenuItemsSource() };
|
||||
@@ -872,35 +877,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_MoveXamlParsedNavItemsIntoItemSource();
|
||||
}
|
||||
|
||||
// Manually create a NavigationViewItem and view model 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.
|
||||
_profileVMs.Clear();
|
||||
// Populate the per-profile view models on the Profiles VM. The Profiles landing
|
||||
// page (and the search index) read this same list back through the VM.
|
||||
const auto& profileVMs = _profilesPageVM.Profiles();
|
||||
profileVMs.Clear();
|
||||
for (const auto& profile : _settingsClone.AllProfiles())
|
||||
{
|
||||
if (!profile.Deleted())
|
||||
{
|
||||
auto profileVM = _viewModelForProfile(profile, _settingsClone, Dispatcher());
|
||||
profileVM.SetupAppearances(_colorSchemesPageVM.AllColorSchemes());
|
||||
auto navItem = _CreateProfileNavViewItem(profileVM);
|
||||
_menuItemSource.Append(navItem);
|
||||
profileVM.DeleteProfileRequested({ this, &MainPage::_DeleteProfile });
|
||||
profileVMs.Append(profileVM);
|
||||
}
|
||||
}
|
||||
|
||||
// Top off (the end of the nav view) with the Add Profile item
|
||||
MUX::Controls::NavigationViewItem addProfileItem;
|
||||
const auto addProfileText = RS_(L"Nav_AddNewProfile/Content");
|
||||
addProfileItem.Content(box_value(addProfileText));
|
||||
addProfileItem.Tag(box_value(addProfileTag));
|
||||
WUX::Controls::ToolTipService::SetToolTip(addProfileItem, box_value(addProfileText));
|
||||
|
||||
FontIcon icon;
|
||||
// This is the "Add" symbol
|
||||
icon.Glyph(NavTagIconMap[addProfileTag]);
|
||||
addProfileItem.Icon(icon);
|
||||
|
||||
_menuItemSource.Append(addProfileItem);
|
||||
}
|
||||
|
||||
// BODGY
|
||||
@@ -936,79 +926,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
SettingsNav().MenuItemsSource(_menuItemSource);
|
||||
}
|
||||
|
||||
void MainPage::_CreateAndNavigateToNewProfile(const uint32_t index, const Model::Profile& profile)
|
||||
void MainPage::_CreateAndNavigateToNewProfile(const Model::Profile& profile)
|
||||
{
|
||||
const auto newProfile{ profile ? profile : _settingsClone.CreateNewProfile() };
|
||||
const auto profileViewModel{ _viewModelForProfile(newProfile, _settingsClone, Dispatcher()) };
|
||||
profileViewModel.SetupAppearances(_colorSchemesPageVM.AllColorSchemes());
|
||||
const auto navItem{ _CreateProfileNavViewItem(profileViewModel) };
|
||||
profileViewModel.DeleteProfileRequested({ this, &MainPage::_DeleteProfile });
|
||||
|
||||
if (_menuItemSource)
|
||||
{
|
||||
_menuItemSource.InsertAt(index, navItem);
|
||||
}
|
||||
_profilesPageVM.Profiles().Append(profileViewModel);
|
||||
|
||||
// Select and navigate to the new profile
|
||||
_Navigate(profileViewModel, BreadcrumbSubPage::None);
|
||||
}
|
||||
|
||||
static MUX::Controls::InfoBadge _createGlyphIconBadge(wil::zwstring_view glyph)
|
||||
{
|
||||
MUX::Controls::InfoBadge badge;
|
||||
MUX::Controls::FontIconSource icon;
|
||||
icon.FontFamily(winrt::Windows::UI::Xaml::Media::FontFamily{ L"Segoe Fluent Icons, Segoe MDL2 Assets" });
|
||||
icon.FontSize(12);
|
||||
icon.Glyph(glyph);
|
||||
badge.IconSource(icon);
|
||||
return badge;
|
||||
}
|
||||
|
||||
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));
|
||||
profileNavItem.Icon(UI::IconPathConverter::IconWUX(profile.EvaluatedIcon()));
|
||||
WUX::Controls::ToolTipService::SetToolTip(profileNavItem, box_value(profile.Name()));
|
||||
|
||||
if (profile.Orphaned())
|
||||
{
|
||||
profileNavItem.InfoBadge(_createGlyphIconBadge(L"\xE7BA") /* Warning Triangle */);
|
||||
}
|
||||
else if (profile.Hidden())
|
||||
{
|
||||
profileNavItem.InfoBadge(_createGlyphIconBadge(L"\xED1A") /* Hide */);
|
||||
}
|
||||
|
||||
// Update the menu item when the icon/name changes
|
||||
auto weakMenuItem{ make_weak(profileNavItem) };
|
||||
profile.PropertyChanged([weakMenuItem](const auto&, const WUX::Data::PropertyChangedEventArgs& args) {
|
||||
if (auto menuItem{ weakMenuItem.get() })
|
||||
{
|
||||
const auto& tag{ menuItem.Tag().as<Editor::ProfileViewModel>() };
|
||||
if (args.PropertyName() == L"Icon")
|
||||
{
|
||||
menuItem.Icon(UI::IconPathConverter::IconWUX(tag.EvaluatedIcon()));
|
||||
}
|
||||
else if (args.PropertyName() == L"Name")
|
||||
{
|
||||
menuItem.Content(box_value(tag.Name()));
|
||||
WUX::Controls::ToolTipService::SetToolTip(menuItem, box_value(tag.Name()));
|
||||
}
|
||||
else if (args.PropertyName() == L"Hidden")
|
||||
{
|
||||
menuItem.InfoBadge(tag.Hidden() ? _createGlyphIconBadge(L"\xED1A") /* Hide */ : nullptr);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add an event handler for when the user wants to delete a profile.
|
||||
profile.DeleteProfileRequested({ this, &MainPage::_DeleteProfile });
|
||||
|
||||
// Register the VM so that it appears in the search index
|
||||
_profileVMs.Append(profile);
|
||||
|
||||
return profileNavItem;
|
||||
_Navigate(profileViewModel);
|
||||
}
|
||||
|
||||
void MainPage::_DeleteProfile(const IInspectable /*sender*/, const Editor::DeleteProfileEventArgs& args)
|
||||
@@ -1025,33 +953,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// remove selected item
|
||||
uint32_t index;
|
||||
auto selectedItem{ SettingsNav().SelectedItem() };
|
||||
if (_menuItemSource)
|
||||
// Remove the profile VM
|
||||
const auto& profileVMs = _profilesPageVM.Profiles();
|
||||
for (uint32_t i = 0; i < profileVMs.Size(); ++i)
|
||||
{
|
||||
_menuItemSource.IndexOf(selectedItem, index);
|
||||
_menuItemSource.RemoveAt(index);
|
||||
|
||||
// Remove it from the list of VMs
|
||||
auto profileVM = selectedItem.as<MUX::Controls::NavigationViewItem>().Tag().as<Editor::ProfileViewModel>();
|
||||
uint32_t vmIndex;
|
||||
if (_menuItemSource.IndexOf(profileVM, vmIndex))
|
||||
if (profileVMs.GetAt(i).OriginalProfileGuid() == guid)
|
||||
{
|
||||
_profileVMs.RemoveAt(vmIndex);
|
||||
profileVMs.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
|
||||
// navigate to the profile next to this one
|
||||
const auto newSelectedItem{ _menuItemSource.GetAt(index < _menuItemSource.Size() - 1 ? index : index - 1) };
|
||||
const auto newTag = newSelectedItem.as<MUX::Controls::NavigationViewItem>().Tag();
|
||||
if (const auto profileViewModel = newTag.try_as<ProfileViewModel>())
|
||||
{
|
||||
profileViewModel->FocusDeleteButton(true);
|
||||
}
|
||||
_Navigate(newTag, BreadcrumbSubPage::None);
|
||||
// Since we are navigating to a new profile after deletion, scroll up to the top
|
||||
SettingsMainPage_ScrollViewer().ChangeView(nullptr, 0.0, nullptr);
|
||||
}
|
||||
|
||||
// Go back to the Profiles landing page
|
||||
_Navigate(box_value(profilesTag));
|
||||
SettingsMainPage_ScrollViewer().ChangeView(nullptr, 0.0, nullptr);
|
||||
}
|
||||
|
||||
IObservableVector<IInspectable> MainPage::Breadcrumbs() noexcept
|
||||
@@ -1061,29 +976,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void MainPage::_NavigateToProfileHandler(const IInspectable& /*sender*/, winrt::guid profileGuid)
|
||||
{
|
||||
if (const auto profileNavItem = _FindProfileNavItem(profileGuid))
|
||||
if (const auto profileVM = _FindProfileViewModelByGuid(profileGuid))
|
||||
{
|
||||
_Navigate(profileNavItem.Tag(), BreadcrumbSubPage::None);
|
||||
_Navigate(profileVM);
|
||||
}
|
||||
// Silently fail if the profile wasn't found
|
||||
}
|
||||
|
||||
MUX::Controls::NavigationViewItem MainPage::_FindProfileNavItem(winrt::guid profileGuid) const
|
||||
Editor::ProfileViewModel MainPage::_FindProfileViewModelByGuid(winrt::guid profileGuid) const
|
||||
{
|
||||
for (auto&& menuItem : _menuItemSource)
|
||||
for (const auto& profileVM : _profilesPageVM.Profiles())
|
||||
{
|
||||
if (const auto& navViewItem{ menuItem.try_as<MUX::Controls::NavigationViewItem>() })
|
||||
if (profileVM.OriginalProfileGuid() == profileGuid)
|
||||
{
|
||||
if (const auto& tag{ navViewItem.Tag() })
|
||||
{
|
||||
if (const auto& profileTag{ tag.try_as<ProfileViewModel>() })
|
||||
{
|
||||
if (profileTag->OriginalProfileGuid() == profileGuid)
|
||||
{
|
||||
return navViewItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return profileVM;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -1094,6 +1000,52 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
_Navigate(box_value(hstring{ colorSchemesTag }), BreadcrumbSubPage::ColorSchemes_Edit);
|
||||
}
|
||||
|
||||
void MainPage::_AppendProfilesRootCrumb()
|
||||
{
|
||||
_breadcrumbs.Append(winrt::make<Breadcrumb>(box_value(profilesTag), RS_(L"Nav_Profiles/Content"), BreadcrumbSubPage::None));
|
||||
}
|
||||
|
||||
void MainPage::_SelectNavItemByTag(std::wstring_view tag)
|
||||
{
|
||||
if (!_menuItemSource)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (auto&& menuItem : _menuItemSource)
|
||||
{
|
||||
if (const auto& navViewItem{ menuItem.try_as<MUX::Controls::NavigationViewItem>() })
|
||||
{
|
||||
if (const auto& itemTag{ navViewItem.Tag() })
|
||||
{
|
||||
if (const auto& stringTag{ itemTag.try_as<hstring>() })
|
||||
{
|
||||
if (*stringTag == tag)
|
||||
{
|
||||
SettingsNav().SelectedItem(navViewItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainPage::_SetupProfilesPageEventHandling()
|
||||
{
|
||||
_profilesPageVM.OpenDefaultsRequested([this](const auto&, const auto&) {
|
||||
_Navigate(box_value(globalProfileTag));
|
||||
});
|
||||
_profilesPageVM.OpenColorSchemesRequested([this](const auto&, const auto&) {
|
||||
_Navigate(box_value(colorSchemesTag));
|
||||
});
|
||||
_profilesPageVM.AddProfileRequested([this](const auto&, const auto&) {
|
||||
_Navigate(box_value(addProfileTag));
|
||||
});
|
||||
_profilesPageVM.OpenProfileRequested([this](const auto&, const Editor::ProfileViewModel& profile) {
|
||||
_Navigate(profile);
|
||||
});
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Xaml::Media::Brush MainPage::BackgroundBrush()
|
||||
{
|
||||
return SettingsNav().Background();
|
||||
@@ -1196,7 +1148,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
co_return;
|
||||
}
|
||||
_currentSearch = SearchIndex::Instance().SearchAsync(sanitizedQuery,
|
||||
_profileVMs.GetView(),
|
||||
_profilesPageVM.Profiles().GetView(),
|
||||
get_self<implementation::NewTabMenuViewModel>(_newTabMenuPageVM)->FolderTreeFlatList().GetView(),
|
||||
_colorSchemesPageVM.AllColorSchemes().GetView(),
|
||||
_extensionsVM.ExtensionPackages().GetView(),
|
||||
|
||||
@@ -84,21 +84,33 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
std::optional<HWND> _hostingHwnd;
|
||||
|
||||
void _InitializeProfilesList();
|
||||
void _CreateAndNavigateToNewProfile(const uint32_t index, const Model::Profile& profile);
|
||||
winrt::Microsoft::UI::Xaml::Controls::NavigationViewItem _CreateProfileNavViewItem(const Editor::ProfileViewModel& profile);
|
||||
void _CreateAndNavigateToNewProfile(const Model::Profile& profile);
|
||||
void _DeleteProfile(const Windows::Foundation::IInspectable sender, const Editor::DeleteProfileEventArgs& args);
|
||||
void _AddProfileHandler(const winrt::guid profileGuid);
|
||||
|
||||
void _SetupProfileEventHandling(const winrt::Microsoft::Terminal::Settings::Editor::ProfileViewModel profile);
|
||||
void _SetupColorSchemesEventHandling();
|
||||
void _SetupActionsEventHandling();
|
||||
void _SetupProfilesPageEventHandling();
|
||||
void _NavigateToProfileSubPage(const Editor::ProfileViewModel& profile, ProfileSubPage page, const IInspectable& breadcrumbTag, const hstring& elementToFocus);
|
||||
|
||||
void _PreNavigateHelper();
|
||||
void _Navigate(const IInspectable& vm, BreadcrumbSubPage subPage, hstring elementToFocus = {});
|
||||
void _Navigate(const IInspectable& vm, BreadcrumbSubPage subPage = BreadcrumbSubPage::None, hstring elementToFocus = {});
|
||||
Windows::UI::Xaml::Media::Animation::NavigationTransitionInfo _MakeTransitionInfo() const;
|
||||
|
||||
enum class NavDirection
|
||||
{
|
||||
Default,
|
||||
Forward,
|
||||
Back
|
||||
};
|
||||
NavDirection _navDirection{ NavDirection::Default };
|
||||
void _NavigateToProfileHandler(const IInspectable& sender, winrt::guid profileGuid);
|
||||
void _NavigateToColorSchemeHandler(const IInspectable& sender, const IInspectable& args);
|
||||
Microsoft::UI::Xaml::Controls::NavigationViewItem _FindProfileNavItem(winrt::guid profileGuid) const;
|
||||
Editor::ProfileViewModel _FindProfileViewModelByGuid(winrt::guid profileGuid) const;
|
||||
|
||||
void _AppendProfilesRootCrumb();
|
||||
void _SelectNavItemByTag(std::wstring_view tag);
|
||||
|
||||
void _UpdateBackgroundForMica();
|
||||
void _MoveXamlParsedNavItemsIntoItemSource();
|
||||
@@ -106,11 +118,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
safe_void_coroutine _UpdateSearchIndex();
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ProfileViewModel _profileDefaultsVM{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Editor::ProfileViewModel> _profileVMs{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ColorSchemesPageViewModel _colorSchemesPageVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ActionsViewModel _actionsVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::NewTabMenuViewModel _newTabMenuPageVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ExtensionsViewModel _extensionsVM{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Editor::ProfilesPageViewModel _profilesPageVM{ nullptr };
|
||||
|
||||
Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IObservableVector<Windows::Foundation::IInspectable>> _currentSearch{ nullptr };
|
||||
|
||||
|
||||
@@ -162,15 +162,6 @@
|
||||
x:Uid="Nav_Appearance"
|
||||
Tag="GlobalAppearance_Nav" />
|
||||
|
||||
<muxc:NavigationViewItem x:Name="ColorSchemesNavItem"
|
||||
x:Uid="Nav_ColorSchemes"
|
||||
Tag="ColorSchemes_Nav" />
|
||||
|
||||
|
||||
<muxc:NavigationViewItem x:Name="RenderingNavItem"
|
||||
x:Uid="Nav_Rendering"
|
||||
Tag="Rendering_Nav" />
|
||||
|
||||
<muxc:NavigationViewItem x:Name="CompatibilityNavItem"
|
||||
x:Uid="Nav_Compatibility"
|
||||
Tag="Compatibility_Nav" />
|
||||
@@ -192,11 +183,9 @@
|
||||
x:Uid="Nav_Extensions"
|
||||
Tag="Extensions_Nav" />
|
||||
|
||||
<muxc:NavigationViewItemHeader x:Uid="Nav_Profiles" />
|
||||
|
||||
<muxc:NavigationViewItem x:Name="BaseLayerMenuItem"
|
||||
x:Uid="Nav_ProfileDefaults"
|
||||
Tag="GlobalProfile_Nav" />
|
||||
<muxc:NavigationViewItem x:Name="ProfilesNavItem"
|
||||
x:Uid="Nav_Profiles"
|
||||
Tag="Profiles_Nav" />
|
||||
</muxc:NavigationView.MenuItems>
|
||||
|
||||
<muxc:NavigationView.FooterMenuItems>
|
||||
@@ -215,17 +204,7 @@
|
||||
Grid.Row="0">
|
||||
<Frame x:Name="contentFrame"
|
||||
Grid.Row="0"
|
||||
Padding="16,0,16,48">
|
||||
<Frame.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<NavigationThemeTransition>
|
||||
<NavigationThemeTransition.DefaultNavigationTransitionInfo>
|
||||
<DrillInNavigationTransitionInfo />
|
||||
</NavigationThemeTransition.DefaultNavigationTransitionInfo>
|
||||
</NavigationThemeTransition>
|
||||
</TransitionCollection>
|
||||
</Frame.ContentTransitions>
|
||||
</Frame>
|
||||
Padding="16,0,16,48" />
|
||||
</ScrollViewer>
|
||||
<!-- Explicitly set the background color on grid to prevent the navigation animation from overflowing it -->
|
||||
<Grid Grid.Row="1"
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
<ClInclude Include="KeyChordListener.h">
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="KeyChordVisual.h">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Launch.h">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
@@ -119,8 +122,8 @@
|
||||
<DependentUpon>ColorSchemesPageViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RenderingViewModel.h">
|
||||
<DependentUpon>RenderingViewModel.idl</DependentUpon>
|
||||
<ClInclude Include="Profiles.h">
|
||||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InteractionViewModel.h">
|
||||
@@ -167,12 +170,27 @@
|
||||
<DependentUpon>Appearances.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Rendering.h">
|
||||
<DependentUpon>Rendering.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SettingContainer.h">
|
||||
<DependentUpon>SettingContainer.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SettingsCard.h">
|
||||
<DependentUpon>SettingsCard.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SettingsExpander.h">
|
||||
<DependentUpon>SettingsExpander.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StyleExtensions.h">
|
||||
<DependentUpon>StyleExtensions.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ControlSizeTrigger.h">
|
||||
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CornerRadiusFilterConverters.h">
|
||||
<DependentUpon>CornerRadiusFilterConverters.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StringDefaultTemplateSelector.h">
|
||||
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="PreviewConnection.h" />
|
||||
<ClInclude Include="$(GeneratedFilesDir)GeneratedSettingsIndex.g.h" />
|
||||
@@ -216,6 +234,9 @@
|
||||
<Page Include="KeyChordListener.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="KeyChordVisual.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Launch.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@@ -231,6 +252,9 @@
|
||||
<Page Include="Profiles_Base.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Profiles.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Profiles_Base_Orphaned.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@@ -246,12 +270,15 @@
|
||||
<Page Include="Appearances.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Rendering.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="SettingContainerStyle.xaml">
|
||||
<Type>DefaultStyle</Type>
|
||||
</Page>
|
||||
<Page Include="SettingsControlsStyle.xaml">
|
||||
<Type>DefaultStyle</Type>
|
||||
</Page>
|
||||
<Page Include="SettingsControlsImplicitStyles.xaml">
|
||||
<Type>DefaultStyle</Type>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<!-- ========================= Cpp Files ======================== -->
|
||||
<ItemGroup>
|
||||
@@ -297,6 +324,9 @@
|
||||
<ClCompile Include="KeyChordListener.cpp">
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyChordVisual.cpp">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Launch.cpp">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
@@ -331,8 +361,8 @@
|
||||
<DependentUpon>ColorSchemesPageViewModel.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RenderingViewModel.cpp">
|
||||
<DependentUpon>RenderingViewModel.idl</DependentUpon>
|
||||
<ClCompile Include="Profiles.cpp">
|
||||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="InteractionViewModel.cpp">
|
||||
@@ -379,12 +409,27 @@
|
||||
<DependentUpon>Appearances.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Rendering.cpp">
|
||||
<DependentUpon>Rendering.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SettingContainer.cpp">
|
||||
<DependentUpon>SettingContainer.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SettingsCard.cpp">
|
||||
<DependentUpon>SettingsCard.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SettingsExpander.cpp">
|
||||
<DependentUpon>SettingsExpander.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StyleExtensions.cpp">
|
||||
<DependentUpon>StyleExtensions.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ControlSizeTrigger.cpp">
|
||||
<DependentUpon>ControlSizeTrigger.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CornerRadiusFilterConverters.cpp">
|
||||
<DependentUpon>CornerRadiusFilterConverters.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StringDefaultTemplateSelector.cpp">
|
||||
<DependentUpon>StringDefaultTemplateSelector.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
<ClCompile Include="PreviewConnection.cpp">
|
||||
<DependentUpon>PreviewConnection.h</DependentUpon>
|
||||
@@ -427,6 +472,10 @@
|
||||
<DependentUpon>KeyChordListener.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="KeyChordVisual.idl">
|
||||
<DependentUpon>KeyChordVisual.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="Launch.idl">
|
||||
<DependentUpon>Launch.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
@@ -443,10 +492,6 @@
|
||||
<DependentUpon>Compatibility.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="Rendering.idl">
|
||||
<DependentUpon>Rendering.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="SearchIndex.idl" />
|
||||
<Midl Include="MainPage.idl">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
@@ -456,7 +501,10 @@
|
||||
<Midl Include="TerminalColorConverters.idl" />
|
||||
<Midl Include="ColorSchemeViewModel.idl" />
|
||||
<Midl Include="ColorSchemesPageViewModel.idl" />
|
||||
<Midl Include="RenderingViewModel.idl" />
|
||||
<Midl Include="Profiles.idl">
|
||||
<DependentUpon>Profiles.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="InteractionViewModel.idl" />
|
||||
<Midl Include="GlobalAppearanceViewModel.idl" />
|
||||
<Midl Include="LaunchViewModel.idl" />
|
||||
@@ -492,6 +540,24 @@
|
||||
<Midl Include="SettingContainer.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="SettingsCard.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="SettingsExpander.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="StyleExtensions.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="ControlSizeTrigger.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="CornerRadiusFilterConverters.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
<Midl Include="StringDefaultTemplateSelector.idl">
|
||||
<SubType>Code</SubType>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
<!-- ========================= Misc Files ======================== -->
|
||||
<ItemGroup>
|
||||
|
||||
@@ -24,12 +24,17 @@
|
||||
<Midl Include="ActionsViewModel.idl" />
|
||||
<Midl Include="ColorSchemeViewModel.idl" />
|
||||
<Midl Include="ColorSchemesPageViewModel.idl" />
|
||||
<Midl Include="RenderingViewModel.idl" />
|
||||
<Midl Include="InteractionViewModel.idl" />
|
||||
<Midl Include="GlobalAppearanceViewModel.idl" />
|
||||
<Midl Include="LaunchViewModel.idl" />
|
||||
<Midl Include="EnumEntry.idl" />
|
||||
<Midl Include="SettingContainer.idl" />
|
||||
<Midl Include="SettingsCard.idl" />
|
||||
<Midl Include="SettingsExpander.idl" />
|
||||
<Midl Include="StyleExtensions.idl" />
|
||||
<Midl Include="ControlSizeTrigger.idl" />
|
||||
<Midl Include="CornerRadiusFilterConverters.idl" />
|
||||
<Midl Include="StringDefaultTemplateSelector.idl" />
|
||||
<Midl Include="TerminalColorConverters.idl" />
|
||||
<Midl Include="NewTabMenuViewModel.idl" />
|
||||
</ItemGroup>
|
||||
@@ -48,14 +53,17 @@
|
||||
<Page Include="Profiles_Advanced.xaml" />
|
||||
<Page Include="Profiles_Appearance.xaml" />
|
||||
<Page Include="Appearances.xaml" />
|
||||
<Page Include="Rendering.xaml" />
|
||||
<Page Include="Actions.xaml" />
|
||||
<Page Include="EditAction.xaml" />
|
||||
<Page Include="SettingContainerStyle.xaml" />
|
||||
<Page Include="SettingsControlsStyle.xaml" />
|
||||
<Page Include="SettingsControlsImplicitStyles.xaml" />
|
||||
<Page Include="AddProfile.xaml" />
|
||||
<Page Include="KeyChordListener.xaml" />
|
||||
<Page Include="KeyChordVisual.xaml" />
|
||||
<Page Include="NullableColorPicker.xaml" />
|
||||
<Page Include="IconPicker.xaml" />
|
||||
<Page Include="NewTabMenu.xaml" />
|
||||
<Page Include="Profiles.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -12,11 +12,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
inline constexpr std::wstring_view openJsonTag{ L"OpenJson_Nav" };
|
||||
inline constexpr std::wstring_view launchTag{ L"Launch_Nav" };
|
||||
inline constexpr std::wstring_view interactionTag{ L"Interaction_Nav" };
|
||||
inline constexpr std::wstring_view renderingTag{ L"Rendering_Nav" };
|
||||
inline constexpr std::wstring_view compatibilityTag{ L"Compatibility_Nav" };
|
||||
inline constexpr std::wstring_view actionsTag{ L"Actions_Nav" };
|
||||
inline constexpr std::wstring_view newTabMenuTag{ L"NewTabMenu_Nav" };
|
||||
inline constexpr std::wstring_view extensionsTag{ L"Extensions_Nav" };
|
||||
inline constexpr std::wstring_view profilesTag{ L"Profiles_Nav" };
|
||||
inline constexpr std::wstring_view globalProfileTag{ L"GlobalProfile_Nav" };
|
||||
inline constexpr std::wstring_view addProfileTag{ L"AddProfile" };
|
||||
inline constexpr std::wstring_view colorSchemesTag{ L"ColorSchemes_Nav" };
|
||||
@@ -28,11 +28,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
std::pair{ interactionTag, L"\xE7C9" }, /* Touch Pointer */
|
||||
std::pair{ globalAppearanceTag, L"\xE771" }, /* Personalize */
|
||||
std::pair{ colorSchemesTag, L"\xE790" }, /* Color */
|
||||
std::pair{ renderingTag, L"\xE7F8" }, /* Device Laptop No Pic */
|
||||
std::pair{ compatibilityTag, L"\xEC7A" }, /* Developer Tools */
|
||||
std::pair{ actionsTag, L"\xE765" }, /* Keyboard Classic */
|
||||
std::pair{ newTabMenuTag, L"\xE71D" }, /* All Apps */
|
||||
std::pair{ extensionsTag, L"\xEA86" }, /* Puzzle */
|
||||
std::pair{ profilesTag, L"\xE7EE" }, /* Other User */
|
||||
std::pair{ globalProfileTag, L"\xE81E" }, /* Map Layers */
|
||||
std::pair{ addProfileTag, L"\xE710" }, /* Add */
|
||||
std::pair{ openJsonTag, L"\xE713" }, /* Settings */
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
Style="{StaticResource NewTabMenuEntryControlsWrapper}">
|
||||
<TextBlock x:Uid="NewTabMenuEntry_Separator"
|
||||
VerticalAlignment="Center"
|
||||
FontStyle="Italic" />
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
</ContentControl>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
DataContext="{Binding Mode=OneWay}"
|
||||
Style="{StaticResource NewTabMenuEntryControlsWrapper}">
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
FontStyle="Italic"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{x:Bind DisplayText, Mode=OneWay}" />
|
||||
</ContentControl>
|
||||
</DataTemplate>
|
||||
@@ -213,7 +213,7 @@
|
||||
Style="{StaticResource NewTabMenuEntryControlsWrapper}">
|
||||
<TextBlock x:Uid="NewTabMenuEntry_RemainingProfiles"
|
||||
VerticalAlignment="Center"
|
||||
FontStyle="Italic" />
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
</ContentControl>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -227,11 +227,27 @@
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid RowSpacing="12">
|
||||
<Grid x:Name="RootGrid"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
ColumnSpacing="16"
|
||||
RowSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition x:Name="ControlsColumn"
|
||||
Width="*" />
|
||||
<ColumnDefinition x:Name="PreviewColumn"
|
||||
Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<!--
|
||||
In the wide/medium (2-column) states, both PreviewArea and ControlsArea span
|
||||
both rows so the row sizing here doesn't matter.
|
||||
In the narrow (stacked) state, PreviewArea moves to row 0 and ControlsArea
|
||||
moves to row 1, and the rows are resized via the visual state setters.
|
||||
-->
|
||||
<RowDefinition x:Name="PreviewRow"
|
||||
Height="0" />
|
||||
<RowDefinition x:Name="ControlsRow"
|
||||
Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Folder Picker Dialog: used to select a folder to move entries to -->
|
||||
@@ -267,253 +283,390 @@
|
||||
</muxc:TreeView>
|
||||
</ContentDialog>
|
||||
|
||||
<!-- New Tab Menu Content -->
|
||||
<StackPanel Grid.Row="0"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Spacing="8">
|
||||
<Border Height="300"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Margin="0,12,0,0"
|
||||
<Grid x:Name="PreviewArea"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="1"
|
||||
Grid.ColumnSpan="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!--
|
||||
Invisible header placeholder so the preview's top edge aligns with the first
|
||||
SettingContainer in the controls column
|
||||
-->
|
||||
<TextBlock x:Name="PreviewHeaderPlaceholder"
|
||||
Grid.Row="0"
|
||||
Margin="0,4,0,4"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
IsHitTestVisible="False"
|
||||
Opacity="0"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}"
|
||||
Text="Preview" />
|
||||
|
||||
<!-- Preview Border: contains the ListView and the multi-select footer. -->
|
||||
<Border Grid.Row="1"
|
||||
MinHeight="300"
|
||||
Margin="0,4,0,0"
|
||||
VerticalAlignment="Stretch"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="{ThemeResource ControlCornerRadius}">
|
||||
<ListView x:Name="NewTabMenuListView"
|
||||
AllowDrop="True"
|
||||
CanDragItems="True"
|
||||
CanReorderItems="True"
|
||||
ItemTemplateSelector="{StaticResource NewTabMenuEntryTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.CurrentView, Mode=OneWay}"
|
||||
SelectionMode="Multiple" />
|
||||
</Border>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- General Controls -->
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="10">
|
||||
<Button x:Name="MoveToFolderButton"
|
||||
Click="MoveMultiple_Click"
|
||||
IsEnabled="False">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_MoveToFolderTextBlock"
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button x:Name="DeleteMultipleButton"
|
||||
Click="DeleteMultiple_Click"
|
||||
IsEnabled="False"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_DeleteMultipleTextBlock"
|
||||
Margin="8,0,0,0" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Folder View Controls -->
|
||||
<StackPanel Grid.Row="1"
|
||||
MaxWidth="{StaticResource StandardControlMaxWidth}"
|
||||
Visibility="{x:Bind ViewModel.IsFolderView, Mode=OneWay}">
|
||||
<TextBlock x:Uid="NewTabMenu_CurrentFolderTextBlock"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Name -->
|
||||
<local:SettingContainer x:Name="CurrentFolderName"
|
||||
x:Uid="NewTabMenu_CurrentFolderName"
|
||||
CurrentValue="{x:Bind ViewModel.CurrentFolderName, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderName, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="CurrentFolderIcon"
|
||||
x:Uid="NewTabMenu_CurrentFolderIcon"
|
||||
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind ViewModel.CurrentFolderIconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.CurrentFolderUsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.CurrentFolderUsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind ViewModel.CurrentFolderIconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Inlining -->
|
||||
<local:SettingContainer x:Name="CurrentFolderInlining"
|
||||
x:Uid="NewTabMenu_CurrentFolderInlining">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderInlining, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Allow Empty -->
|
||||
<local:SettingContainer x:Name="CurrentFolderAllowEmpty"
|
||||
x:Uid="NewTabMenu_CurrentFolderAllowEmpty">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderAllowEmpty, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Add Entries -->
|
||||
<StackPanel Grid.Row="2">
|
||||
<TextBlock x:Uid="NewTabMenu_AddEntriesTextBlock"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Add Profile -->
|
||||
<local:SettingContainer x:Name="AddProfile"
|
||||
x:Uid="NewTabMenu_AddProfile"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
<!-- Select profile to add -->
|
||||
<ComboBox x:Name="AddProfileComboBox"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
ItemsSource="{x:Bind ViewModel.AvailableProfiles, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.SelectedProfile, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model:Profile">
|
||||
<Grid HorizontalAlignment="Stretch"
|
||||
ColumnSpacing="8">
|
||||
<ListView x:Name="NewTabMenuListView"
|
||||
Grid.Row="0"
|
||||
AllowDrop="True"
|
||||
CanDragItems="True"
|
||||
CanReorderItems="True"
|
||||
ItemTemplateSelector="{StaticResource NewTabMenuEntryTemplateSelector}"
|
||||
ItemsSource="{x:Bind ViewModel.CurrentView, Mode=OneWay}"
|
||||
SelectionMode="Multiple" />
|
||||
|
||||
<!-- Preview Controls -->
|
||||
<Border Grid.Row="1"
|
||||
Padding="8"
|
||||
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
|
||||
BorderThickness="0,1,0,0">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button x:Name="MoveToFolderButton"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Click="MoveMultiple_Click"
|
||||
IsEnabled="False">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- icon -->
|
||||
<ColumnDefinition Width="16" />
|
||||
<!-- profile name -->
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<IconSourceElement Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
IconSource="{x:Bind mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
<FontIcon Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_MoveToFolderTextBlock"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</Button>
|
||||
<Button x:Name="DeleteMultipleButton"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Click="DeleteMultiple_Click"
|
||||
IsEnabled="False"
|
||||
Style="{StaticResource DeleteButtonStyle}">
|
||||
<Grid ColumnSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_DeleteMultipleTextBlock"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
TextWrapping="WrapWholeWords" />
|
||||
</Grid>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<Button x:Name="AddProfileButton"
|
||||
x:Uid="NewTabMenu_AddProfileButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddProfileButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<ScrollViewer x:Name="ControlsArea"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="1"
|
||||
HorizontalScrollMode="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel>
|
||||
<!-- Folder View Controls -->
|
||||
<StackPanel Margin="0,0,0,24"
|
||||
Visibility="{x:Bind ViewModel.IsFolderView, Mode=OneWay}">
|
||||
<TextBlock x:Uid="NewTabMenu_CurrentFolderTextBlock"
|
||||
Margin="0,4,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Name -->
|
||||
<local:SettingContainer x:Name="CurrentFolderName"
|
||||
x:Uid="NewTabMenu_CurrentFolderName"
|
||||
CurrentValue="{x:Bind ViewModel.CurrentFolderName, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderName, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="CurrentFolderIcon"
|
||||
x:Uid="NewTabMenu_CurrentFolderIcon"
|
||||
CurrentValueAccessibleName="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind ViewModel.CurrentFolderIconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(ViewModel.CurrentFolderUsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind ViewModel.CurrentFolderLocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind ViewModel.CurrentFolderUsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind ViewModel.CurrentFolderIconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Inlining -->
|
||||
<local:SettingContainer x:Name="CurrentFolderInlining"
|
||||
x:Uid="NewTabMenu_CurrentFolderInlining">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderInlining, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Allow Empty -->
|
||||
<local:SettingContainer x:Name="CurrentFolderAllowEmpty"
|
||||
x:Uid="NewTabMenu_CurrentFolderAllowEmpty">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.CurrentFolderAllowEmpty, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Separator -->
|
||||
<local:SettingContainer x:Name="AddSeparator"
|
||||
x:Uid="NewTabMenu_AddSeparator"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddSeparatorButton"
|
||||
x:Uid="NewTabMenu_AddSeparatorButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddSeparatorButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
<!-- Add Entries -->
|
||||
<StackPanel>
|
||||
<TextBlock x:Uid="NewTabMenu_AddEntriesTextBlock"
|
||||
Margin="0,4,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Add Folder -->
|
||||
<local:SettingContainer x:Name="AddFolder"
|
||||
x:Uid="NewTabMenu_AddFolder"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
<TextBox x:Name="FolderNameTextBox"
|
||||
x:Uid="NewTabMenu_AddFolder_FolderName"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
KeyDown="AddFolderNameTextBox_KeyDown"
|
||||
Text="{x:Bind ViewModel.AddFolderName, Mode=TwoWay}"
|
||||
TextChanged="AddFolderNameTextBox_TextChanged" />
|
||||
<Button x:Name="AddFolderButton"
|
||||
x:Uid="NewTabMenu_AddFolderButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddFolderButton_Clicked"
|
||||
IsEnabled="False">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
<!-- Add Profile -->
|
||||
<local:SettingContainer x:Name="AddProfile"
|
||||
x:Uid="NewTabMenu_AddProfile"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
|
||||
<!-- Add Match Profiles -->
|
||||
<local:SettingContainer x:Name="AddMatchProfiles"
|
||||
x:Uid="NewTabMenu_AddMatchProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithIcon}">
|
||||
<StackPanel Spacing="8">
|
||||
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
|
||||
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherName, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Source"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherSource, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Commandline"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherCommandline, Mode=TwoWay}" />
|
||||
<Button x:Name="AddMatchProfilesButton"
|
||||
Click="AddMatchProfilesButton_Clicked">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="4">
|
||||
<!-- Select profile to add -->
|
||||
<ComboBox x:Name="AddProfileComboBox"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
ItemsSource="{x:Bind ViewModel.AvailableProfiles, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.SelectedProfile, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="model: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 mtu:IconPathConverter.IconSourceWUX(Icon.Resolved), Mode=OneTime}" />
|
||||
|
||||
<TextBlock Grid.Column="1"
|
||||
Text="{x:Bind Name}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<Button x:Name="AddProfileButton"
|
||||
x:Uid="NewTabMenu_AddProfileButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddProfileButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Separator -->
|
||||
<local:SettingContainer x:Name="AddSeparator"
|
||||
x:Uid="NewTabMenu_AddSeparator"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddSeparatorButton"
|
||||
x:Uid="NewTabMenu_AddSeparatorButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddSeparatorButton_Clicked">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_AddMatchProfilesTextBlock"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Remaining Profiles -->
|
||||
<local:SettingContainer x:Name="AddRemainingProfiles"
|
||||
x:Uid="NewTabMenu_AddRemainingProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddRemainingProfilesButton"
|
||||
x:Uid="NewTabMenu_AddRemainingProfilesButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddRemainingProfilesButton_Clicked"
|
||||
IsEnabled="{x:Bind ViewModel.IsRemainingProfilesEntryMissing, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
<!-- Add Folder -->
|
||||
<local:SettingContainer x:Name="AddFolder"
|
||||
x:Uid="NewTabMenu_AddFolder"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="5">
|
||||
<TextBox x:Name="FolderNameTextBox"
|
||||
x:Uid="NewTabMenu_AddFolder_FolderName"
|
||||
MinWidth="{StaticResource StandardBoxMinWidth}"
|
||||
KeyDown="AddFolderNameTextBox_KeyDown"
|
||||
Text="{x:Bind ViewModel.AddFolderName, Mode=TwoWay}"
|
||||
TextChanged="AddFolderNameTextBox_TextChanged" />
|
||||
<Button x:Name="AddFolderButton"
|
||||
x:Uid="NewTabMenu_AddFolderButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddFolderButton_Clicked"
|
||||
IsEnabled="False">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Match Profiles -->
|
||||
<local:SettingContainer x:Name="AddMatchProfiles"
|
||||
x:Uid="NewTabMenu_AddMatchProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel Spacing="8">
|
||||
<HyperlinkButton x:Uid="NewTabMenu_AddMatchProfiles_Help"
|
||||
NavigateUri="https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Name"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherName, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Source"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherSource, Mode=TwoWay}" />
|
||||
<TextBox x:Uid="NewTabMenu_AddMatchProfiles_Commandline"
|
||||
Text="{x:Bind ViewModel.ProfileMatcherCommandline, Mode=TwoWay}" />
|
||||
<Button x:Name="AddMatchProfilesButton"
|
||||
Click="AddMatchProfilesButton_Clicked">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="NewTabMenu_AddMatchProfilesTextBlock"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Add Remaining Profiles -->
|
||||
<local:SettingContainer x:Name="AddRemainingProfiles"
|
||||
x:Uid="NewTabMenu_AddRemainingProfiles"
|
||||
FontIconGlyph=""
|
||||
Style="{StaticResource SettingContainerWithIcon}">
|
||||
<Button x:Name="AddRemainingProfilesButton"
|
||||
x:Uid="NewTabMenu_AddRemainingProfilesButton"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="AddRemainingProfilesButton_Clicked"
|
||||
IsEnabled="{x:Bind ViewModel.IsRemainingProfilesEntryMissing, Mode=OneWay}">
|
||||
<Button.Content>
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup>
|
||||
<!-- Wide: 2 columns, controls on left with leading icons, preview on right. -->
|
||||
<VisualState x:Name="Wide">
|
||||
<VisualState.StateTriggers>
|
||||
<AdaptiveTrigger MinWindowWidth="1200" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="AddProfile.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
<Setter Target="AddSeparator.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
<Setter Target="AddFolder.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyle}" />
|
||||
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource SettingContainerWithIcon}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<!-- Medium: 2 columns, controls on left WITHOUT leading icons, preview on right. -->
|
||||
<VisualState x:Name="Medium">
|
||||
<VisualState.StateTriggers>
|
||||
<AdaptiveTrigger MinWindowWidth="900" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<Setter Target="AddProfile.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddSeparator.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddFolder.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyle}" />
|
||||
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
|
||||
<!-- Narrow: single column, preview stacked on top, controls below, no icons. -->
|
||||
<VisualState x:Name="Narrow">
|
||||
<VisualState.StateTriggers>
|
||||
<AdaptiveTrigger MinWindowWidth="0" />
|
||||
</VisualState.StateTriggers>
|
||||
<VisualState.Setters>
|
||||
<!-- Collapse the preview column and give the preview row real height so the rows are used instead of the columns. -->
|
||||
<Setter Target="PreviewColumn.Width" Value="0" />
|
||||
<Setter Target="PreviewRow.Height" Value="Auto" />
|
||||
|
||||
<!-- Move PreviewArea to row 0, spanning both columns. -->
|
||||
<Setter Target="PreviewArea.(Grid.Row)" Value="0" />
|
||||
<Setter Target="PreviewArea.(Grid.RowSpan)" Value="1" />
|
||||
<Setter Target="PreviewArea.(Grid.Column)" Value="0" />
|
||||
<Setter Target="PreviewArea.(Grid.ColumnSpan)" Value="2" />
|
||||
|
||||
<!-- Move ControlsArea to row 1, spanning both columns. -->
|
||||
<Setter Target="ControlsArea.(Grid.Row)" Value="1" />
|
||||
<Setter Target="ControlsArea.(Grid.RowSpan)" Value="1" />
|
||||
<Setter Target="ControlsArea.(Grid.Column)" Value="0" />
|
||||
<Setter Target="ControlsArea.(Grid.ColumnSpan)" Value="2" />
|
||||
|
||||
<!-- No icons in the narrow state either (progressive simplification). -->
|
||||
<Setter Target="AddProfile.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddSeparator.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddFolder.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
<Setter Target="AddMatchProfiles.Style" Value="{StaticResource ExpanderSettingContainerStyle}" />
|
||||
<Setter Target="AddRemainingProfiles.Style" Value="{StaticResource DefaultSettingContainer}" />
|
||||
|
||||
<!-- Hide the preview header placeholder in stacked mode (no controls beside the preview to align with). -->
|
||||
<Setter Target="PreviewHeaderPlaceholder.Visibility" Value="Collapsed" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
@@ -127,6 +127,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
_NotifyChanges(L"TabColorPreview");
|
||||
}
|
||||
else if (viewModelProperty == L"Hidden")
|
||||
{
|
||||
_NotifyChanges(L"AccessibleStateDescription");
|
||||
}
|
||||
else if (viewModelProperty == L"Name" || viewModelProperty == L"IsBaseLayer")
|
||||
{
|
||||
_NotifyChanges(L"SectionHeaderText");
|
||||
}
|
||||
});
|
||||
|
||||
_defaultAppearanceViewModel.PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
|
||||
@@ -348,6 +356,27 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return _profile.Orphaned();
|
||||
}
|
||||
|
||||
hstring ProfileViewModel::AccessibleStateDescription() const
|
||||
{
|
||||
const auto hidden = Hidden();
|
||||
const auto orphaned = Orphaned();
|
||||
if (hidden && orphaned)
|
||||
{
|
||||
return til::hstring_format(FMT_COMPILE(L"{}, {}"),
|
||||
RS_(L"Profile_HiddenBadge/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"),
|
||||
RS_(L"Profile_OrphanedBadge/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip"));
|
||||
}
|
||||
if (hidden)
|
||||
{
|
||||
return RS_(L"Profile_HiddenBadge/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip");
|
||||
}
|
||||
if (orphaned)
|
||||
{
|
||||
return RS_(L"Profile_OrphanedBadge/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
hstring ProfileViewModel::TabTitlePreview() const
|
||||
{
|
||||
if (const auto tabTitle{ TabTitle() }; !tabTitle.empty())
|
||||
@@ -357,6 +386,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
return RS_(L"Profile_TabTitleNone");
|
||||
}
|
||||
|
||||
hstring ProfileViewModel::SectionHeaderText() const
|
||||
{
|
||||
if (IsBaseLayer())
|
||||
{
|
||||
return RS_(L"Profile_DefaultsSectionHeader");
|
||||
}
|
||||
return hstring{ RS_fmt(L"Profile_NameSectionHeaderFormat", Name()) };
|
||||
}
|
||||
|
||||
hstring ProfileViewModel::AnswerbackMessagePreview() const
|
||||
{
|
||||
if (const auto answerbackMessage{ AnswerbackMessage() }; !answerbackMessage.empty())
|
||||
|
||||
@@ -100,7 +100,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
bool AutoMarkPromptsAvailable() const noexcept;
|
||||
bool RepositionCursorWithMouseAvailable() const noexcept;
|
||||
|
||||
hstring SectionHeaderText() const;
|
||||
bool Orphaned() const;
|
||||
hstring AccessibleStateDescription() const;
|
||||
hstring TabTitlePreview() const;
|
||||
hstring AnswerbackMessagePreview() const;
|
||||
Windows::UI::Color TabColorPreview() const;
|
||||
|
||||
@@ -105,7 +105,9 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
void CreateUnfocusedAppearance();
|
||||
void DeleteUnfocusedAppearance();
|
||||
|
||||
String SectionHeaderText { get; };
|
||||
Boolean Orphaned { get; };
|
||||
String AccessibleStateDescription { get; };
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Name);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Guid, Guid);
|
||||
OBSERVABLE_PROJECTED_PROFILE_SETTING(String, Source);
|
||||
|
||||
96
src/cascadia/TerminalSettingsEditor/Profiles.cpp
Normal file
96
src/cascadia/TerminalSettingsEditor/Profiles.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "Profiles.h"
|
||||
#include "Profiles.g.cpp"
|
||||
#include "ProfilesPageViewModel.g.cpp"
|
||||
#include "ProfileViewModel.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
Profiles::Profiles()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Automation::AutomationProperties::SetName(DefaultsNavigator(), RS_(L"Profiles_DefaultsNavigator_Title/Text"));
|
||||
Automation::AutomationProperties::SetHelpText(DefaultsNavigator(), RS_(L"Profiles_DefaultsNavigator_Description/Text"));
|
||||
Automation::AutomationProperties::SetName(ColorSchemesNavigator(), RS_(L"Profiles_ColorSchemesNavigator_Title/Text"));
|
||||
Automation::AutomationProperties::SetHelpText(ColorSchemesNavigator(), RS_(L"Profiles_ColorSchemesNavigator_Description/Text"));
|
||||
Automation::AutomationProperties::SetName(AddProfileButton(), RS_(L"Profiles_AddProfileButton/Text"));
|
||||
}
|
||||
|
||||
void Profiles::OnNavigatedTo(const NavigationEventArgs& e)
|
||||
{
|
||||
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
|
||||
_ViewModel = args.ViewModel().as<Editor::ProfilesPageViewModel>();
|
||||
BringIntoViewWhenLoaded(args.ElementToFocus());
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"NavigatedToPage",
|
||||
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
|
||||
TraceLoggingValue("profilesLanding", "PageId", "The identifier of the page that was navigated to"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
|
||||
void Profiles::Defaults_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
_ViewModel.RequestOpenDefaults();
|
||||
}
|
||||
|
||||
void Profiles::ColorSchemes_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
_ViewModel.RequestOpenColorSchemes();
|
||||
}
|
||||
|
||||
void Profiles::AddProfile_Click(const IInspectable& /*sender*/, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
_ViewModel.RequestAddProfile();
|
||||
}
|
||||
|
||||
void Profiles::Profile_Click(const IInspectable& sender, const RoutedEventArgs& /*args*/)
|
||||
{
|
||||
// Profile navigators are buttons whose DataContext is the bound ProfileViewModel.
|
||||
if (const auto element = sender.try_as<FrameworkElement>())
|
||||
{
|
||||
if (const auto profile = element.DataContext().try_as<Editor::ProfileViewModel>())
|
||||
{
|
||||
_ViewModel.RequestOpenProfile(profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProfilesPageViewModel::ProfilesPageViewModel()
|
||||
{
|
||||
_setProfiles(single_threaded_observable_vector<Editor::ProfileViewModel>());
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestOpenDefaults()
|
||||
{
|
||||
OpenDefaultsRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestOpenColorSchemes()
|
||||
{
|
||||
OpenColorSchemesRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestAddProfile()
|
||||
{
|
||||
AddProfileRequested.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
void ProfilesPageViewModel::RequestOpenProfile(const Editor::ProfileViewModel& profile)
|
||||
{
|
||||
OpenProfileRequested.raise(*this, profile);
|
||||
}
|
||||
|
||||
}
|
||||
67
src/cascadia/TerminalSettingsEditor/Profiles.h
Normal file
67
src/cascadia/TerminalSettingsEditor/Profiles.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- Profiles.h
|
||||
|
||||
Abstract:
|
||||
- The Profiles landing page in the Settings UI. The page hosts entry points to
|
||||
the list of individual profiles among other profile-related settings.
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Profiles.g.h"
|
||||
#include "ProfilesPageViewModel.g.h"
|
||||
#include "ProfileViewModel.h"
|
||||
#include "Utils.h"
|
||||
#include "ViewModelHelpers.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct ProfilesPageViewModel : ProfilesPageViewModelT<ProfilesPageViewModel>, ViewModelHelper<ProfilesPageViewModel>
|
||||
{
|
||||
public:
|
||||
ProfilesPageViewModel();
|
||||
|
||||
void RequestOpenDefaults();
|
||||
void RequestOpenColorSchemes();
|
||||
void RequestAddProfile();
|
||||
void RequestOpenProfile(const Editor::ProfileViewModel& profile);
|
||||
|
||||
// DON'T YOU DARE ADD A `WINRT_CALLBACK(PropertyChanged` TO A CLASS DERIVED FROM ViewModelHelper. Do this instead:
|
||||
using ViewModelHelper<ProfilesPageViewModel>::PropertyChanged;
|
||||
|
||||
WINRT_OBSERVABLE_PROPERTY(Windows::Foundation::Collections::IObservableVector<Editor::ProfileViewModel>, Profiles, _propertyChangedHandlers, nullptr);
|
||||
|
||||
public:
|
||||
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::IInspectable> OpenDefaultsRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::IInspectable> OpenColorSchemesRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Windows::Foundation::IInspectable> AddProfileRequested;
|
||||
til::typed_event<Windows::Foundation::IInspectable, Editor::ProfileViewModel> OpenProfileRequested;
|
||||
};
|
||||
|
||||
struct Profiles : public HasScrollViewer<Profiles>, ProfilesT<Profiles>
|
||||
{
|
||||
public:
|
||||
Profiles();
|
||||
|
||||
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
void Defaults_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void ColorSchemes_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void AddProfile_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
void Profile_Click(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_PROPERTY(Editor::ProfilesPageViewModel, ViewModel, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Profiles);
|
||||
BASIC_FACTORY(ProfilesPageViewModel);
|
||||
}
|
||||
31
src/cascadia/TerminalSettingsEditor/Profiles.idl
Normal file
31
src/cascadia/TerminalSettingsEditor/Profiles.idl
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "ProfileViewModel.idl";
|
||||
import "ColorSchemeViewModel.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass ProfilesPageViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
ProfilesPageViewModel();
|
||||
|
||||
Windows.Foundation.Collections.IObservableVector<ProfileViewModel> Profiles { get; };
|
||||
|
||||
void RequestOpenDefaults();
|
||||
void RequestOpenColorSchemes();
|
||||
void RequestAddProfile();
|
||||
void RequestOpenProfile(ProfileViewModel profile);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, IInspectable> OpenDefaultsRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, IInspectable> OpenColorSchemesRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, IInspectable> AddProfileRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ProfileViewModel> OpenProfileRequested;
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass Profiles : Windows.UI.Xaml.Controls.Page
|
||||
{
|
||||
Profiles();
|
||||
ProfilesPageViewModel ViewModel { get; };
|
||||
}
|
||||
}
|
||||
139
src/cascadia/TerminalSettingsEditor/Profiles.xaml
Normal file
139
src/cascadia/TerminalSettingsEditor/Profiles.xaml
Normal file
@@ -0,0 +1,139 @@
|
||||
<!--
|
||||
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:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:model="using:Microsoft.Terminal.Settings.Model"
|
||||
xmlns:mtu="using:Microsoft.Terminal.UI"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<DataTemplate x:Key="ProfileNavigatorTemplate"
|
||||
x:DataType="local:ProfileViewModel">
|
||||
<Button HorizontalAlignment="Stretch"
|
||||
AutomationProperties.HelpText="{x:Bind AccessibleStateDescription, Mode=OneWay}"
|
||||
AutomationProperties.Name="{x:Bind Name, Mode=OneWay}"
|
||||
Click="Profile_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}">
|
||||
<Grid ColumnSpacing="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="16" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ContentControl Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Content="{x:Bind IconPreview, Mode=OneWay}"
|
||||
IsTabStop="False" />
|
||||
<TextBlock Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Name, Mode=OneWay}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<muxc:InfoBadge x:Uid="Profile_HiddenBadge"
|
||||
Grid.Column="2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{x:Bind Hidden, Mode=OneWay}">
|
||||
<muxc:InfoBadge.IconSource>
|
||||
<muxc:FontIconSource FontFamily="Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
</muxc:InfoBadge.IconSource>
|
||||
</muxc:InfoBadge>
|
||||
<muxc:InfoBadge x:Uid="Profile_OrphanedBadge"
|
||||
Grid.Column="2"
|
||||
Margin="0,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Visibility="{x:Bind Orphaned, Mode=OneWay}">
|
||||
<muxc:InfoBadge.IconSource>
|
||||
<muxc:FontIconSource FontFamily="Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
</muxc:InfoBadge.IconSource>
|
||||
</muxc:InfoBadge>
|
||||
</Grid>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}"
|
||||
XYFocusKeyboardNavigation="Enabled">
|
||||
|
||||
<!-- General Profile Settings -->
|
||||
<TextBlock x:Uid="Profiles_GeneralSettingsHeader"
|
||||
Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Defaults navigator -->
|
||||
<Button x:Name="DefaultsNavigator"
|
||||
Click="Defaults_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Uid="Profiles_DefaultsNavigator_Title" />
|
||||
<TextBlock x:Uid="Profiles_DefaultsNavigator_Description"
|
||||
Margin="0,2,0,0"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- Color schemes navigator -->
|
||||
<Button x:Name="ColorSchemesNavigator"
|
||||
Click="ColorSchemes_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Uid="Profiles_ColorSchemesNavigator_Title" />
|
||||
<TextBlock x:Uid="Profiles_ColorSchemesNavigator_Description"
|
||||
Margin="0,2,0,0"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- Terminal profiles section -->
|
||||
<TextBlock x:Uid="Profiles_TerminalProfilesHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Add Profile accent button -->
|
||||
<Button x:Name="AddProfileButton"
|
||||
Margin="0,4,0,0"
|
||||
Click="AddProfile_Click"
|
||||
Style="{StaticResource AccentButtonStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<FontIcon FontSize="{StaticResource StandardIconSize}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="Profiles_AddProfileButton"
|
||||
Style="{StaticResource IconButtonTextBlockStyle}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- List of profiles. Each is a NavigatorButtonStyle button rendered by ProfileNavigatorTemplate. -->
|
||||
<ItemsControl Margin="0,0,0,16"
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource ProfileNavigatorTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.Profiles, Mode=OneWay}"
|
||||
XYFocusKeyboardNavigation="Enabled">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
@@ -80,11 +80,10 @@
|
||||
SourceProfile="{x:Bind Profile, Mode=OneWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneTime}" />
|
||||
|
||||
<!-- Grouping: Transparency -->
|
||||
<!-- Section: Window settings -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_TransparencyHeader"
|
||||
<TextBlock x:Uid="Profile_Section_Window"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Opacity -->
|
||||
<local:SettingContainer x:Name="Opacity"
|
||||
x:Uid="Profile_Opacity"
|
||||
@@ -117,13 +116,6 @@
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<!-- Grouping: Window -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_WindowHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Padding -->
|
||||
<local:SettingContainer x:Name="Padding"
|
||||
x:Uid="Profile_Padding"
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
Automation::AutomationProperties::SetFullDescription(StartingDirectoryUseParentCheckbox(), unbox_value<hstring>(startingDirCheckboxTooltip));
|
||||
|
||||
Automation::AutomationProperties::SetName(DeleteButton(), RS_(L"Profile_DeleteButton/Text"));
|
||||
AppearanceNavigator().Content(box_value(RS_(L"Profile_Appearance/Header")));
|
||||
TerminalNavigator().Content(box_value(RS_(L"Profile_Terminal/Header")));
|
||||
AdvancedNavigator().Content(box_value(RS_(L"Profile_Advanced/Header")));
|
||||
AppearanceNavigator().Header(box_value(RS_(L"Profile_Appearance/Header")));
|
||||
TerminalNavigator().Header(box_value(RS_(L"Profile_Terminal/Header")));
|
||||
AdvancedNavigator().Header(box_value(RS_(L"Profile_Advanced/Header")));
|
||||
}
|
||||
|
||||
void Profiles_Base::OnNavigatedTo(const NavigationEventArgs& e)
|
||||
|
||||
@@ -34,160 +34,171 @@
|
||||
<StackPanel Grid.Row="1"
|
||||
Style="{StaticResource SettingsStackStyle}">
|
||||
|
||||
<!-- Name -->
|
||||
<!--
|
||||
NOTE: Has/Clear is not bound because we don't want the reset button & override text to appear.
|
||||
Additionally, the JSON stubs generated by auto-generated profiles come with a name,
|
||||
so the name will always be overridden.
|
||||
-->
|
||||
<local:SettingContainer x:Name="Name"
|
||||
x:Uid="Profile_Name"
|
||||
CurrentValue="{x:Bind Profile.Name, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Name, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: {Profile.Name} profile (or "Profile defaults") -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock Margin="0,0,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}"
|
||||
Text="{x:Bind Profile.SectionHeaderText, Mode=OneWay}" />
|
||||
<!-- Name -->
|
||||
<!--
|
||||
NOTE: Has/Clear is not bound because we don't want the reset button & override text to appear.
|
||||
Additionally, the JSON stubs generated by auto-generated profiles come with a name,
|
||||
so the name will always be overridden.
|
||||
-->
|
||||
<local:SettingContainer x:Name="Name"
|
||||
x:Uid="Profile_Name"
|
||||
CurrentValue="{x:Bind Profile.Name, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Name, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Commandline -->
|
||||
<local:SettingContainer x:Name="Commandline"
|
||||
x:Uid="Profile_Commandline"
|
||||
ClearSettingValue="{x:Bind Profile.ClearCommandline}"
|
||||
CurrentValue="{x:Bind Profile.Commandline, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasCommandline, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.CommandlineOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<TextBox x:Uid="Profile_CommandlineBox"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Commandline, Mode=TwoWay}" />
|
||||
<Button x:Uid="Profile_CommandlineBrowse"
|
||||
Margin="0,8,0,0"
|
||||
Click="Commandline_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Starting Directory -->
|
||||
<local:SettingContainer x:Name="StartingDirectory"
|
||||
x:Uid="Profile_StartingDirectory"
|
||||
ClearSettingValue="{x:Bind Profile.ClearStartingDirectory}"
|
||||
CurrentValue="{x:Bind Profile.CurrentStartingDirectoryPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasStartingDirectory, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.StartingDirectoryOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBox x:Uid="Profile_StartingDirectoryBox"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.StartingDirectory, Mode=TwoWay}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="StartingDirectoryBrowse"
|
||||
x:Uid="Profile_StartingDirectoryBrowse"
|
||||
Margin="0,12,12,0"
|
||||
Click="StartingDirectory_Click"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
<!-- Commandline -->
|
||||
<local:SettingContainer x:Name="Commandline"
|
||||
x:Uid="Profile_Commandline"
|
||||
ClearSettingValue="{x:Bind Profile.ClearCommandline}"
|
||||
CurrentValue="{x:Bind Profile.Commandline, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasCommandline, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.CommandlineOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<StackPanel>
|
||||
<TextBox x:Uid="Profile_CommandlineBox"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.Commandline, Mode=TwoWay}" />
|
||||
<Button x:Uid="Profile_CommandlineBrowse"
|
||||
Margin="0,8,0,0"
|
||||
Click="Commandline_Click"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
<CheckBox x:Name="StartingDirectoryUseParentCheckbox"
|
||||
x:Uid="Profile_StartingDirectoryUseParentCheckbox"
|
||||
Margin="0,4,0,0"
|
||||
IsChecked="{x:Bind Profile.UseParentProcessDirectory, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="Icon"
|
||||
x:Uid="Profile_Icon"
|
||||
ClearSettingValue="{x:Bind Profile.ClearIcon}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind Profile.IconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.UsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind Profile.UsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind Profile.IconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
<!-- Starting Directory -->
|
||||
<local:SettingContainer x:Name="StartingDirectory"
|
||||
x:Uid="Profile_StartingDirectory"
|
||||
ClearSettingValue="{x:Bind Profile.ClearStartingDirectory}"
|
||||
CurrentValue="{x:Bind Profile.CurrentStartingDirectoryPreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasStartingDirectory, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.StartingDirectoryOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBox x:Uid="Profile_StartingDirectoryBox"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
IsSpellCheckEnabled="False"
|
||||
Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.StartingDirectory, Mode=TwoWay}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Name="StartingDirectoryBrowse"
|
||||
x:Uid="Profile_StartingDirectoryBrowse"
|
||||
Margin="0,12,12,0"
|
||||
Click="StartingDirectory_Click"
|
||||
IsEnabled="{x:Bind mtu:Converters.InvertBoolean(Profile.UseParentProcessDirectory), Mode=OneWay}"
|
||||
Style="{StaticResource BrowseButtonStyle}" />
|
||||
<CheckBox x:Name="StartingDirectoryUseParentCheckbox"
|
||||
x:Uid="Profile_StartingDirectoryUseParentCheckbox"
|
||||
Margin="0,4,0,0"
|
||||
IsChecked="{x:Bind Profile.UseParentProcessDirectory, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Tab Title -->
|
||||
<local:SettingContainer x:Name="TabTitle"
|
||||
x:Uid="Profile_TabTitle"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabTitle}"
|
||||
CurrentValue="{x:Bind Profile.TabTitlePreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabTitle, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabTitleOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.TabTitle, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Elevate -->
|
||||
<local:SettingContainer x:Name="Elevate"
|
||||
x:Uid="Profile_Elevate"
|
||||
ClearSettingValue="{x:Bind Profile.ClearElevate}"
|
||||
HasSettingValue="{x:Bind Profile.HasElevate, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.ElevateOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Elevate, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Tab Color -->
|
||||
<local:SettingContainer x:Name="TabColor"
|
||||
x:Uid="Profile_TabColor"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabColor}"
|
||||
CurrentValue="{x:Bind Profile.TabColorPreview, Mode=OneWay}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.TabColorPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
|
||||
<local:NullableColorPicker x:Uid="Profile_TabColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Profile.DefaultAppearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Profile.TabColor, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Profile.TabThemeColorPreview, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Section: Visual/UI Affordance -->
|
||||
<StackPanel Style="{StaticResource PivotStackStyle}">
|
||||
<TextBlock x:Uid="Profile_Section_VisualUI"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
<!-- Tab Title -->
|
||||
<local:SettingContainer x:Name="TabTitle"
|
||||
x:Uid="Profile_TabTitle"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabTitle}"
|
||||
CurrentValue="{x:Bind Profile.TabTitlePreview, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabTitle, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabTitleOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<TextBox Style="{StaticResource TextBoxSettingStyle}"
|
||||
Text="{x:Bind Profile.TabTitle, Mode=TwoWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Elevate -->
|
||||
<local:SettingContainer x:Name="Elevate"
|
||||
x:Uid="Profile_Elevate"
|
||||
ClearSettingValue="{x:Bind Profile.ClearElevate}"
|
||||
HasSettingValue="{x:Bind Profile.HasElevate, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.ElevateOverrideSource, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Elevate, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Tab Color -->
|
||||
<local:SettingContainer x:Name="TabColor"
|
||||
x:Uid="Profile_TabColor"
|
||||
ClearSettingValue="{x:Bind Profile.ClearTabColor}"
|
||||
CurrentValue="{x:Bind Profile.TabColorPreview, Mode=OneWay}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.TabColorPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
|
||||
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
|
||||
HasSettingValue="{x:Bind Profile.HasTabColor, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.TabColorOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:NullableColorPicker x:Uid="Profile_TabColor_NullableColorPicker"
|
||||
ColorSchemeVM="{x:Bind Profile.DefaultAppearance.CurrentColorScheme, Mode=OneWay}"
|
||||
CurrentColor="{x:Bind Profile.TabColor, Mode=TwoWay}"
|
||||
NullColorPreview="{x:Bind Profile.TabThemeColorPreview, Mode=OneWay}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Hidden -->
|
||||
<local:SettingContainer x:Name="Hidden"
|
||||
x:Uid="Profile_Hidden"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Hidden, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
<!-- Icon -->
|
||||
<local:SettingContainer x:Name="Icon"
|
||||
x:Uid="Profile_Icon"
|
||||
ClearSettingValue="{x:Bind Profile.ClearIcon}"
|
||||
CurrentValueAccessibleName="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
|
||||
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<local:SettingContainer.CurrentValue>
|
||||
<Grid>
|
||||
<ContentControl Width="16"
|
||||
Height="16"
|
||||
Content="{x:Bind Profile.IconPreview, Mode=OneWay}"
|
||||
IsTabStop="False"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.UsingNoIcon), Mode=OneWay}" />
|
||||
<TextBlock Margin="0,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{x:Bind Profile.LocalizedIcon, Mode=OneWay}"
|
||||
Visibility="{x:Bind Profile.UsingNoIcon, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</local:SettingContainer.CurrentValue>
|
||||
<local:SettingContainer.Content>
|
||||
<local:IconPicker CurrentIconPath="{x:Bind Profile.IconPath, Mode=TwoWay}"
|
||||
WindowRoot="{x:Bind WindowRoot, Mode=OneWay}" />
|
||||
</local:SettingContainer.Content>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Hidden -->
|
||||
<local:SettingContainer x:Name="Hidden"
|
||||
x:Uid="Profile_Hidden"
|
||||
Visibility="{x:Bind mtu:Converters.InvertedBooleanToVisibility(Profile.IsBaseLayer), Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind Profile.Hidden, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock x:Uid="Profile_AdditionalSettingsHeader"
|
||||
Margin="0,32,0,4"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<Button x:Name="AppearanceNavigator"
|
||||
Click="Appearance_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}" />
|
||||
<Button x:Name="TerminalNavigator"
|
||||
Click="Terminal_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}" />
|
||||
<Button x:Name="AdvancedNavigator"
|
||||
Click="Advanced_Click"
|
||||
Style="{StaticResource NavigatorButtonStyle}" />
|
||||
<local:SettingsCard x:Name="AppearanceNavigator"
|
||||
Click="Appearance_Click"
|
||||
IsClickEnabled="True" />
|
||||
<local:SettingsCard x:Name="TerminalNavigator"
|
||||
Click="Terminal_Click"
|
||||
IsClickEnabled="True" />
|
||||
<local:SettingsCard x:Name="AdvancedNavigator"
|
||||
Click="Advanced_Click"
|
||||
IsClickEnabled="True" />
|
||||
<!-- Delete Button -->
|
||||
<Border MaxWidth="{StaticResource StandardControlMaxWidth}">
|
||||
<Button x:Name="DeleteButton"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "Rendering.h"
|
||||
#include "Rendering.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)
|
||||
{
|
||||
const auto args = e.Parameter().as<Editor::NavigateToPageArgs>();
|
||||
_ViewModel = args.ViewModel().as<Editor::RenderingViewModel>();
|
||||
BringIntoViewWhenLoaded(args.ElementToFocus());
|
||||
|
||||
TraceLoggingWrite(
|
||||
g_hTerminalSettingsEditorProvider,
|
||||
"NavigatedToPage",
|
||||
TraceLoggingDescription("Event emitted when the user navigates to a page in the settings UI"),
|
||||
TraceLoggingValue("rendering", "PageId", "The identifier of the page that was navigated to"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Rendering.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct Rendering : public HasScrollViewer<Rendering>, RenderingT<Rendering>
|
||||
{
|
||||
Rendering();
|
||||
|
||||
void OnNavigatedTo(const winrt::Windows::UI::Xaml::Navigation::NavigationEventArgs& e);
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
WINRT_OBSERVABLE_PROPERTY(Editor::RenderingViewModel, ViewModel, PropertyChanged.raise, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Rendering);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "RenderingViewModel.idl";
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass Rendering : Windows.UI.Xaml.Controls.Page
|
||||
{
|
||||
Rendering();
|
||||
RenderingViewModel ViewModel { get; };
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
<!--
|
||||
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:local="using:Microsoft.Terminal.Settings.Editor"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="CommonResources.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<DataTemplate x:Key="EnumComboBoxTemplate"
|
||||
x:DataType="local:EnumEntry">
|
||||
<TextBlock Text="{x:Bind EnumName}" />
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</Page.Resources>
|
||||
|
||||
<StackPanel Style="{StaticResource SettingsStackStyle}">
|
||||
<local:SettingContainer x:Name="GraphicsAPI"
|
||||
x:Uid="Globals_GraphicsAPI">
|
||||
<ComboBox AutomationProperties.AccessibilityView="Content"
|
||||
ItemTemplate="{StaticResource EnumComboBoxTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.GraphicsAPIList}"
|
||||
SelectedItem="{x:Bind ViewModel.CurrentGraphicsAPI, Mode=TwoWay}"
|
||||
Style="{StaticResource ComboBoxSettingStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<local:SettingContainer x:Name="DisablePartialInvalidation"
|
||||
x:Uid="Globals_DisablePartialInvalidation">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.DisablePartialInvalidation, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
|
||||
<local:SettingContainer x:Name="SoftwareRendering"
|
||||
x:Uid="Globals_SoftwareRendering">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SoftwareRendering, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
</local:SettingContainer>
|
||||
</StackPanel>
|
||||
</Page>
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "RenderingViewModel.h"
|
||||
|
||||
#include "EnumEntry.h"
|
||||
|
||||
#include "RenderingViewModel.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
RenderingViewModel::RenderingViewModel(CascadiaSettings settings) noexcept :
|
||||
_settings{ std::move(settings) }
|
||||
{
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(GraphicsAPI, GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, L"Globals_GraphicsAPI_", L"Text");
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RenderingViewModel.g.h"
|
||||
#include "Utils.h"
|
||||
#include "ViewModelHelpers.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct RenderingViewModel : RenderingViewModelT<RenderingViewModel>, ViewModelHelper<RenderingViewModel>
|
||||
{
|
||||
explicit RenderingViewModel(Model::CascadiaSettings settings) noexcept;
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.GlobalSettings().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), SoftwareRendering);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings{ nullptr };
|
||||
};
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(RenderingViewModel);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import "EnumEntry.idl";
|
||||
|
||||
#include "ViewModelHelpers.idl.h"
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass RenderingViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
RenderingViewModel(Microsoft.Terminal.Settings.Model.CascadiaSettings settings);
|
||||
|
||||
IInspectable CurrentGraphicsAPI;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> GraphicsAPIList { get; };
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, SoftwareRendering);
|
||||
}
|
||||
}
|
||||
@@ -289,8 +289,8 @@
|
||||
<comment>Header for a control to toggle whether the terminal should automatically detect URLs and make them clickable, or not.</comment>
|
||||
</data>
|
||||
<data name="Globals_SearchWebDefaultQueryUrl.Header" xml:space="preserve">
|
||||
<value>Default URL to use for the "Search web" action</value>
|
||||
<comment>Header for a control to set the query URL when using the "search web" action.</comment>
|
||||
<value>Default URL to use for the "Search web" shortcut</value>
|
||||
<comment>Header for a control to set the query URL when using the "search web" shortcut.</comment>
|
||||
</data>
|
||||
<data name="Globals_SearchWebDefaultQueryUrl.HelpText" xml:space="preserve">
|
||||
<value>The placeholder "%s" will be replaced with the search query.</value>
|
||||
@@ -590,7 +590,7 @@
|
||||
<comment>Additional description for what the "force vt input" setting does. Presented near "Globals_ForceVTInput.Header".</comment>
|
||||
</data>
|
||||
<data name="Globals_AllowHeadless.HelpText" xml:space="preserve">
|
||||
<value>This allows actions such as Global Summon and Quake Mode actions to work even when no windows are open.</value>
|
||||
<value>This allows shortcuts such as Global Summon and Quake Mode shortcuts to work even when no windows are open.</value>
|
||||
<comment>Additional description for what the "allow headless" setting does. Presented near "Globals_AllowHeadless.Header".</comment>
|
||||
</data>
|
||||
<data name="Globals_TabWidthMode.Header" xml:space="preserve">
|
||||
@@ -650,8 +650,8 @@
|
||||
<comment>A description for what the "word delimiters" setting does. Presented near "Globals_WordDelimiters.Header". "Mark" is used in the sense of "choosing something to interact with."</comment>
|
||||
</data>
|
||||
<data name="Nav_Appearance.Content" xml:space="preserve">
|
||||
<value>Appearance</value>
|
||||
<comment>Header for the "appearance" menu item. This navigates to a page that lets you see and modify settings related to the app's appearance.</comment>
|
||||
<value>Personalization</value>
|
||||
<comment>Header for the "personalization" menu item. This navigates to a page that lets you see and modify settings related to the app's appearance.</comment>
|
||||
</data>
|
||||
<data name="Nav_ColorSchemes.Content" xml:space="preserve">
|
||||
<value>Color schemes</value>
|
||||
@@ -677,17 +677,13 @@
|
||||
<value>Defaults</value>
|
||||
<comment>Header for the "defaults" menu item. This navigates to a page that lets you see and modify settings that affect profiles. This is the lowest layer of profile settings that all other profile settings are based on. If a profile doesn't define a setting, this page is responsible for figuring out what that setting is supposed to be.</comment>
|
||||
</data>
|
||||
<data name="Nav_Rendering.Content" xml:space="preserve">
|
||||
<value>Rendering</value>
|
||||
<comment>Header for the "rendering" menu item. This navigates to a page that lets you see and modify settings related to the app's rendering of text in the terminal.</comment>
|
||||
</data>
|
||||
<data name="Nav_Actions.Content" xml:space="preserve">
|
||||
<value>Actions</value>
|
||||
<comment>Header for the "actions" menu item. This navigates to a page that lets you see the available commands in the app.</comment>
|
||||
<value>Shortcuts</value>
|
||||
<comment>Header for the "shortcuts" menu item. This navigates to a page that lets you see the available keyboard shortcuts in the app. (Resource key kept as "Nav_Actions" for stability.)</comment>
|
||||
</data>
|
||||
<data name="Nav_EditAction.Content" xml:space="preserve">
|
||||
<value>Edit Action...</value>
|
||||
<comment>Header for the "edit action" page. This is the page that lets you modify a specific command and its key bindings.</comment>
|
||||
<value>Edit Shortcut...</value>
|
||||
<comment>Header for the "edit shortcut" page. This is the page that lets you modify a specific command and its key bindings. (Resource key kept as "Nav_EditAction" for stability.)</comment>
|
||||
</data>
|
||||
<data name="Nav_Extensions.Content" xml:space="preserve">
|
||||
<value>Extensions</value>
|
||||
@@ -1101,6 +1097,10 @@
|
||||
<value>If enabled, 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>
|
||||
<comment>A description for what the "hidden" setting does. Presented near "Profile_Hidden".</comment>
|
||||
</data>
|
||||
<data name="Profile_HiddenBadge.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Hidden from the dropdown menu</value>
|
||||
<comment>Tooltip shown when hovering the InfoBadge next to a profile name on the Profiles landing page when that profile is hidden from the dropdown menu.</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.Header" xml:space="preserve">
|
||||
<value>Run this profile as Administrator</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
@@ -1291,7 +1291,39 @@
|
||||
</data>
|
||||
<data name="Nav_Profiles.Content" xml:space="preserve">
|
||||
<value>Profiles</value>
|
||||
<comment>Header for the "profiles" menu items. This acts as a divider to introduce profile-related menu items.</comment>
|
||||
<comment>Header for the "profiles" menu item. Navigates to a landing page that lists profile-related settings (defaults, color schemes, the list of terminal profiles, and the add-profile button).</comment>
|
||||
</data>
|
||||
<data name="Nav_Profiles.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Profiles</value>
|
||||
<comment>Tooltip for the "profiles" menu item. Navigates to a landing page that lists profile-related settings.</comment>
|
||||
</data>
|
||||
<data name="Profiles_GeneralSettingsHeader.Text" xml:space="preserve">
|
||||
<value>General Profile Settings</value>
|
||||
<comment>Section header on the Profiles landing page. Introduces general-purpose profile settings such as the defaults shared by all profiles and the color schemes that profiles can use.</comment>
|
||||
</data>
|
||||
<data name="Profiles_TerminalProfilesHeader.Text" xml:space="preserve">
|
||||
<value>Terminal profiles</value>
|
||||
<comment>Section header on the Profiles landing page. Introduces the list of individual terminal profiles configured by the user.</comment>
|
||||
</data>
|
||||
<data name="Profiles_DefaultsNavigator_Title.Text" xml:space="preserve">
|
||||
<value>Defaults</value>
|
||||
<comment>Title for the "Defaults" navigator on the Profiles landing page. Clicking this opens the page where defaults shared by all profiles can be edited.</comment>
|
||||
</data>
|
||||
<data name="Profiles_DefaultsNavigator_Description.Text" xml:space="preserve">
|
||||
<value>Changes made here apply to all profiles unless overridden by a specific profile. These settings do not affect the Windows Terminal appearance.</value>
|
||||
<comment>Help text describing the "Defaults" navigator on the Profiles landing page. Clarifies that the defaults apply to every profile but are not the same as the global Windows Terminal appearance settings.</comment>
|
||||
</data>
|
||||
<data name="Profiles_ColorSchemesNavigator_Title.Text" xml:space="preserve">
|
||||
<value>Color schemes</value>
|
||||
<comment>Title for the "Color schemes" navigator on the Profiles landing page. Clicking this opens the same page reachable from the top-level Color schemes nav item.</comment>
|
||||
</data>
|
||||
<data name="Profiles_ColorSchemesNavigator_Description.Text" xml:space="preserve">
|
||||
<value>Add, edit, or remove the color schemes that your profiles can use.</value>
|
||||
<comment>Help text describing the "Color schemes" navigator on the Profiles landing page.</comment>
|
||||
</data>
|
||||
<data name="Profiles_AddProfileButton.Text" xml:space="preserve">
|
||||
<value>Add a new profile</value>
|
||||
<comment>Text on the accent-colored button on the Profiles landing page. Clicking this opens the page where users can add a new profile.</comment>
|
||||
</data>
|
||||
<data name="Globals_LaunchModeFocus.Content" xml:space="preserve">
|
||||
<value>Focus</value>
|
||||
@@ -1589,10 +1621,6 @@
|
||||
<value>Name</value>
|
||||
<comment>Header for a control to determine the name of the profile. This is a text box.</comment>
|
||||
</data>
|
||||
<data name="Profile_TransparencyHeader.Text" xml:space="preserve">
|
||||
<value>Transparency</value>
|
||||
<comment>Header for a group of settings related to transparency, including the acrylic material background of the app.</comment>
|
||||
</data>
|
||||
<data name="Profile_BackgroundHeader.Text" xml:space="preserve">
|
||||
<value>Background image</value>
|
||||
<comment>Header for a group of settings that control the image presented on the background of the app. Presented near "Profile_BackgroundImage" and other keys starting with "Profile_BackgroundImage".</comment>
|
||||
@@ -1613,10 +1641,6 @@
|
||||
<value>Warnings</value>
|
||||
<comment>Header for a group of settings that control the warnings in the app.</comment>
|
||||
</data>
|
||||
<data name="Profile_WindowHeader.Text" xml:space="preserve">
|
||||
<value>Window</value>
|
||||
<comment>Header for a group of settings that control the appearance of the window frame of the app.</comment>
|
||||
</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>
|
||||
@@ -1766,28 +1790,28 @@
|
||||
<comment>A description for what the delete unfocused appearance button does.</comment>
|
||||
</data>
|
||||
<data name="Actions_Disclaimer.Content" xml:space="preserve">
|
||||
<value>Learn more about actions</value>
|
||||
<comment>Disclaimer presented at the top of the actions page to redirect the user to documentation regarding actions.</comment>
|
||||
<value>Learn more about shortcuts</value>
|
||||
<comment>Disclaimer presented at the top of the shortcuts page to redirect the user to documentation regarding keyboard shortcuts.</comment>
|
||||
</data>
|
||||
<data name="Actions_DeleteButton2.Text" xml:space="preserve">
|
||||
<value>Delete action</value>
|
||||
<comment>Button label that deletes the selected action.</comment>
|
||||
<value>Delete shortcut</value>
|
||||
<comment>Button label that deletes the selected shortcut.</comment>
|
||||
</data>
|
||||
<data name="Actions_Name.Text" xml:space="preserve">
|
||||
<value>Action name</value>
|
||||
<comment>Label for the text box that edits the action name.</comment>
|
||||
<value>Shortcut name</value>
|
||||
<comment>Label for the text box that edits the shortcut name.</comment>
|
||||
</data>
|
||||
<data name="Actions_NameEntryBox.PlaceholderText" xml:space="preserve">
|
||||
<value>Action name</value>
|
||||
<comment>Placeholder text for the text box where the user can edit the action name.</comment>
|
||||
<value>Shortcut name</value>
|
||||
<comment>Placeholder text for the text box where the user can edit the shortcut name.</comment>
|
||||
</data>
|
||||
<data name="Actions_ShortcutAction.Text" xml:space="preserve">
|
||||
<value>Action type</value>
|
||||
<comment>Label for the combo box that edits the action type.</comment>
|
||||
<value>Shortcut type</value>
|
||||
<comment>Label for the combo box that edits the shortcut type (which action runs when this shortcut is invoked).</comment>
|
||||
</data>
|
||||
<data name="Actions_KeyBindingsListView.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Keybindings</value>
|
||||
<comment>Name for a control which contains the list of keybindings for the current command.</comment>
|
||||
<value>Shortcuts</value>
|
||||
<comment>Name for a control which contains the list of keyboard shortcuts for the current command.</comment>
|
||||
</data>
|
||||
<data name="Actions_CommandDetails.Text" xml:space="preserve">
|
||||
<value>Command details</value>
|
||||
@@ -1798,44 +1822,44 @@
|
||||
<comment>Label for the list of editable arguments for the currently selected action.</comment>
|
||||
</data>
|
||||
<data name="Actions_Keybindings.Text" xml:space="preserve">
|
||||
<value>Keybindings</value>
|
||||
<comment>Label for the list of editable keybindings for the current command.</comment>
|
||||
<value>Shortcuts</value>
|
||||
<comment>Label for the list of editable keyboard shortcuts for the current command.</comment>
|
||||
</data>
|
||||
<data name="Actions_AddKeyChord.Text" xml:space="preserve">
|
||||
<value>Add keybinding</value>
|
||||
<comment>Button label that adds a keybinding to the current action.</comment>
|
||||
<value>Add shortcut</value>
|
||||
<comment>Button label that adds a keyboard shortcut to the current action.</comment>
|
||||
</data>
|
||||
<data name="Actions_AdditionalKeyChords" xml:space="preserve">
|
||||
<value>and {} more</value>
|
||||
<comment>Text that will be read out by a screen reader indicating that additional keybindings exist for this command. {} will be replaced by the number of additional keybindings.</comment>
|
||||
</data>
|
||||
<data name="Actions_DeleteConfirmationButton.Content" xml:space="preserve">
|
||||
<value>Yes, delete key binding</value>
|
||||
<comment>Button label that confirms deletion of a key binding entry.</comment>
|
||||
<value>Yes, delete shortcut</value>
|
||||
<comment>Button label that confirms deletion of a keyboard shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_DeleteConfirmationMessage.Text" xml:space="preserve">
|
||||
<value>Are you sure you want to delete this key binding?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete a key binding entry.</comment>
|
||||
<value>Are you sure you want to delete this shortcut?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete a keyboard shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_CommandDeleteConfirmationButton.Content" xml:space="preserve">
|
||||
<value>Yes, delete action</value>
|
||||
<comment>Button label that confirms deletion of an action.</comment>
|
||||
<value>Yes, delete shortcut</value>
|
||||
<comment>Button label that confirms deletion of a shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_CommandDeleteConfirmationMessage.Text" xml:space="preserve">
|
||||
<value>Are you sure you want to delete this action?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete an action.</comment>
|
||||
<value>Are you sure you want to delete this shortcut?</value>
|
||||
<comment>Confirmation message displayed when the user attempts to delete a shortcut entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_InvalidKeyChordMessage" xml:space="preserve">
|
||||
<value>Invalid key chord. Please enter a valid key chord.</value>
|
||||
<comment>Error message displayed when an invalid key chord is input by the user.</comment>
|
||||
<value>Invalid shortcut. Please enter a valid keyboard shortcut.</value>
|
||||
<comment>Error message displayed when an invalid keyboard shortcut is input by the user.</comment>
|
||||
</data>
|
||||
<data name="Actions_RenameConflictConfirmationAcceptButton" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
<comment>Button label that confirms the deletion of a conflicting key binding to allow the current key binding to be registered.</comment>
|
||||
</data>
|
||||
<data name="Actions_RenameConflictConfirmationMessage" xml:space="preserve">
|
||||
<value>The provided key chord is already being used by the following action:</value>
|
||||
<comment>Error message displayed when a key chord that is already in use is input by the user. The name of the conflicting key chord is displayed after this message.</comment>
|
||||
<value>The provided shortcut is already being used by the following action:</value>
|
||||
<comment>Error message displayed when a keyboard shortcut that is already in use is input by the user. The name of the conflicting shortcut is displayed after this message.</comment>
|
||||
</data>
|
||||
<data name="Actions_RenameConflictConfirmationQuestion" xml:space="preserve">
|
||||
<value>Would you like to overwrite it?</value>
|
||||
@@ -1862,12 +1886,60 @@
|
||||
<comment>Text label for a button that can be used to begin making changes to a key binding entry.</comment>
|
||||
</data>
|
||||
<data name="Actions_AddNewTextBlock.Text" xml:space="preserve">
|
||||
<value>Add new</value>
|
||||
<comment>Button label that creates a new action on the actions page.</comment>
|
||||
<value>Add new shortcut</value>
|
||||
<comment>Button label that creates a new keyboard shortcut on the shortcuts page.</comment>
|
||||
</data>
|
||||
<data name="Actions_ActionComboBox.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Action</value>
|
||||
<comment>Label for a control that sets the action of a key binding.</comment>
|
||||
<data name="Actions_ViewAllKeyChordsButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>View all shortcuts</value>
|
||||
<comment>Tooltip for a button on each row of the Shortcuts page that opens a flyout listing every keyboard shortcut registered for that action.</comment>
|
||||
</data>
|
||||
<data name="Actions_NoKeyBindings.Text" xml:space="preserve">
|
||||
<value>No shortcuts</value>
|
||||
<comment>Empty-state message shown inside the "view all shortcuts" flyout (opened from each row's "..." button on the Shortcuts page) when the action has no keyboard shortcuts registered.</comment>
|
||||
</data>
|
||||
<data name="EditAction_ActionType.Header" xml:space="preserve">
|
||||
<value>Shortcut type</value>
|
||||
<comment>Header for the shortcut-type setting on the Edit Shortcut page (lets the user pick which action runs when this shortcut is invoked).</comment>
|
||||
</data>
|
||||
<data name="EditAction_ActionName.Header" xml:space="preserve">
|
||||
<value>Shortcut name</value>
|
||||
<comment>Header for the shortcut-name setting on the Edit Shortcut page (lets the user provide a friendly name for this shortcut).</comment>
|
||||
</data>
|
||||
<data name="EditAction_KeyBindings.Header" xml:space="preserve">
|
||||
<value>Shortcuts</value>
|
||||
<comment>Header for the shortcuts expander on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_KeyBindings.HelpText" xml:space="preserve">
|
||||
<value>Customize keyboard shortcuts to speed up common actions and workflows.</value>
|
||||
<comment>Help text shown under the "Shortcuts" header on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_NewKeyBinding.Header" xml:space="preserve">
|
||||
<value>New shortcut</value>
|
||||
<comment>Header for the "add a new shortcut" row on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_AddKeyBinding.Content" xml:space="preserve">
|
||||
<value>Add shortcut</value>
|
||||
<comment>Label for the accent button that appends a new keyboard shortcut to the current action.</comment>
|
||||
</data>
|
||||
<data name="EditAction_AdditionalCustomizations.Header" xml:space="preserve">
|
||||
<value>Additional customizations</value>
|
||||
<comment>Header for the additional customizations expander on the Edit Action page (contains action name and per-action argument settings).</comment>
|
||||
</data>
|
||||
<data name="EditAction_AdditionalCustomizations.HelpText" xml:space="preserve">
|
||||
<value>Fine tune how shortcuts behave.</value>
|
||||
<comment>Help text shown under the "Additional customizations" header on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_KeyBindingNumberFormat" xml:space="preserve">
|
||||
<value>Shortcut #{}</value>
|
||||
<comment>{Locked="#{}"} Header label for an individual keyboard shortcut inside the "Shortcuts" expander on the Edit Shortcut page. {} is replaced with the 1-based index of the shortcut (e.g. "Shortcut #1").</comment>
|
||||
</data>
|
||||
<data name="EditAction_DeleteCommand.Header" xml:space="preserve">
|
||||
<value>Delete this shortcut</value>
|
||||
<comment>Header for the setting container that holds the "Delete shortcut" button at the bottom of the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="EditAction_DeleteCommand.HelpText" xml:space="preserve">
|
||||
<value>This shortcut will be removed and any shortcuts associated with it will no longer work.</value>
|
||||
<comment>Help text shown under the "Delete this shortcut" setting container on the Edit Shortcut page.</comment>
|
||||
</data>
|
||||
<data name="Actions_NullEnumValue" xml:space="preserve">
|
||||
<value>Use global setting</value>
|
||||
@@ -2398,8 +2470,8 @@
|
||||
<comment>Accessible name for a control allowing the user to select the icon from a list of built in icons.</comment>
|
||||
</data>
|
||||
<data name="Nav_NewTabMenu.Content" xml:space="preserve">
|
||||
<value>New Tab Menu</value>
|
||||
<comment>Header for the "new tab menu" menu item. This navigates to a page that lets you see and modify settings related to the app's new tab menu (i.e. profile ordering, nested folders, dividers, etc.)</comment>
|
||||
<value>Dropdown Menu</value>
|
||||
<comment>Header for the "dropdown menu" menu item (formerly "new tab menu"). This navigates to a page that lets you see and modify settings related to the app's dropdown menu (i.e. profile ordering, nested folders, dividers, etc.)</comment>
|
||||
</data>
|
||||
<data name="NewTabMenuEntry_Separator.Text" xml:space="preserve">
|
||||
<value><Separator></value>
|
||||
@@ -2655,6 +2727,10 @@
|
||||
<data name="Profile_Delete_Orphaned.HelpText" xml:space="preserve">
|
||||
<value>This automatically-detected profile appears to have been uninstalled. Changes you have made to it are preserved, but it cannot be used until it has been reinstalled.</value>
|
||||
</data>
|
||||
<data name="Profile_OrphanedBadge.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Profile is no longer detected</value>
|
||||
<comment>Tooltip shown when hovering the InfoBadge next to a profile name on the Profiles landing page when that profile's source software is no longer installed.</comment>
|
||||
</data>
|
||||
<data name="Profile_Source_Orphaned.Header" xml:space="preserve">
|
||||
<value>Original Source</value>
|
||||
</data>
|
||||
@@ -2780,4 +2856,100 @@
|
||||
<value>This text will be inserted between the paths of multiple files dropped into the terminal.</value>
|
||||
<comment>A description for what the "drag drop delimiter" setting does.</comment>
|
||||
</data>
|
||||
</root>
|
||||
<data name="Launch_Section_LaunchBehavior.Text" xml:space="preserve">
|
||||
<value>Launch behavior</value>
|
||||
<comment>Title of a section that groups settings that control how the terminal opens and behaves when launched.</comment>
|
||||
</data>
|
||||
<data name="Launch_Section_SystemInputDefaults.Text" xml:space="preserve">
|
||||
<value>System & input defaults</value>
|
||||
<comment>Title of a section that groups settings for default system and input behaviors.</comment>
|
||||
</data>
|
||||
<data name="Interaction_Section_Clipboard.Text" xml:space="preserve">
|
||||
<value>Clipboard and paste behavior</value>
|
||||
<comment>Title of a section that groups settings related to selection, copying, and pasting.</comment>
|
||||
</data>
|
||||
<data name="Interaction_Section_TextSelection.Text" xml:space="preserve">
|
||||
<value>Text selection & editing</value>
|
||||
<comment>Title of a section that groups settings related to text selection and editing.</comment>
|
||||
</data>
|
||||
<data name="Interaction_Section_WindowLayout.Text" xml:space="preserve">
|
||||
<value>Window and layout behavior</value>
|
||||
<comment>Title of a section that groups settings related to window sizing, arrangement, and grouping.</comment>
|
||||
</data>
|
||||
<data name="Interaction_Section_MouseScrolling.Text" xml:space="preserve">
|
||||
<value>Mouse & scrolling</value>
|
||||
<comment>Title of a section that groups settings related to mouse and scroll wheel input.</comment>
|
||||
</data>
|
||||
<data name="Interaction_Section_UrlsExternal.Text" xml:space="preserve">
|
||||
<value>URLs & external actions</value>
|
||||
<comment>Title of a section that groups settings related to URLs and external app actions.</comment>
|
||||
</data>
|
||||
<data name="Interaction_Section_Warnings.Text" xml:space="preserve">
|
||||
<value>Warnings</value>
|
||||
<comment>Title of a section that groups warning-related settings.</comment>
|
||||
</data>
|
||||
<data name="Globals_Section_VisualStyle.Text" xml:space="preserve">
|
||||
<value>Visual style</value>
|
||||
<comment>Title of a section that groups settings related to the terminal's visual appearance.</comment>
|
||||
</data>
|
||||
<data name="Globals_Section_TabsLayout.Text" xml:space="preserve">
|
||||
<value>Tabs and layout</value>
|
||||
<comment>Title of a section that groups settings related to tabs and pane layout.</comment>
|
||||
</data>
|
||||
<data name="Globals_Section_WindowBehavior.Text" xml:space="preserve">
|
||||
<value>Window behavior</value>
|
||||
<comment>Title of a section that groups settings related to terminal window behavior.</comment>
|
||||
</data>
|
||||
<data name="Globals_Section_TitleBarIdentity.Text" xml:space="preserve">
|
||||
<value>Title bar & identity</value>
|
||||
<comment>Title of a section that groups settings related to title bar identity and indicators.</comment>
|
||||
</data>
|
||||
<data name="Globals_Section_SystemIntegration.Text" xml:space="preserve">
|
||||
<value>System integration & notifications</value>
|
||||
<comment>Title of a section that groups settings related to system integration and notifications.</comment>
|
||||
</data>
|
||||
<data name="Compatibility_Section_Compatibility.Text" xml:space="preserve">
|
||||
<value>Compatibility</value>
|
||||
<comment>Title of a section that groups compatibility-related settings.</comment>
|
||||
</data>
|
||||
<data name="Compatibility_Section_Rendering.Text" xml:space="preserve">
|
||||
<value>Rendering</value>
|
||||
<comment>Title of a section that groups rendering-related settings.</comment>
|
||||
</data>
|
||||
<data name="Profile_Section_VisualUI.Text" xml:space="preserve">
|
||||
<value>Visual/UI Affordance</value>
|
||||
<comment>Title of a section in a profile page that groups visual and UI settings (tab title, icon, tab color, etc.).</comment>
|
||||
</data>
|
||||
<data name="Profile_Section_Window.Text" xml:space="preserve">
|
||||
<value>Window settings</value>
|
||||
<comment>Title of a section expander on the Profile Appearance page that groups window-level appearance settings (background opacity, acrylic, padding, scrollbar visibility).</comment>
|
||||
</data>
|
||||
<data name="Profile_NameSectionHeaderFormat" xml:space="preserve">
|
||||
<value>{0} profile</value>
|
||||
<comment>Localizable format string used as the section header for a profile (e.g. "PowerShell profile"). {0} is replaced by the profile's name. Reorder the placeholder if your language requires a different word order.</comment>
|
||||
</data>
|
||||
<data name="Profile_DefaultsSectionHeader" xml:space="preserve">
|
||||
<value>Profile defaults</value>
|
||||
<comment>Header used in place of the "{name} profile" header when the page is showing the profile-defaults layer (which has no profile name).</comment>
|
||||
</data>
|
||||
<data name="Appearance_Section_Typography.Text" xml:space="preserve">
|
||||
<value>Typography settings</value>
|
||||
<comment>Title of a section that groups settings controlling how text looks in a profile.</comment>
|
||||
</data>
|
||||
<data name="Appearance_Section_Cursor.Text" xml:space="preserve">
|
||||
<value>Cursor settings</value>
|
||||
<comment>Title of a section that groups settings controlling the cursor.</comment>
|
||||
</data>
|
||||
<data name="Appearance_Section_BackgroundImage.Text" xml:space="preserve">
|
||||
<value>Background image</value>
|
||||
<comment>Title of a section that groups settings controlling the background image.</comment>
|
||||
</data>
|
||||
<data name="Profile_AppearanceNavigator.HelpText" xml:space="preserve">
|
||||
<value>Customize the visual appearance of the profile, including colors, fonts, and text styling.</value>
|
||||
<comment>Help text shown below the "Appearance" navigator button on the profile page.</comment>
|
||||
</data>
|
||||
<data name="Profile_TerminalNavigator.HelpText" xml:space="preserve">
|
||||
<value>Terminal emulation is how a terminal app interprets text and control sequences to behave like a traditional command-line terminal.</value>
|
||||
<comment>Help text shown below the "Terminal" navigator button on the profile page.</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -66,13 +66,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
hstring runtimeObjContext{};
|
||||
if (const auto profileVM = runtimeObj.try_as<Editor::ProfileViewModel>())
|
||||
{
|
||||
// No runtimeObjContext: profile name and icon should be enough
|
||||
runtimeObjLabel = profileVM.Name();
|
||||
runtimeObjContext = RS_(L"Nav_Profiles/Content");
|
||||
}
|
||||
else if (const auto colorSchemeVM = runtimeObj.try_as<Editor::ColorSchemeViewModel>())
|
||||
{
|
||||
// No runtimeObjContext: scheme name and generic icon should be enough
|
||||
runtimeObjLabel = colorSchemeVM.Name();
|
||||
runtimeObjContext = RS_(L"Nav_ColorSchemes/Content");
|
||||
}
|
||||
else if (const auto ntmFolderEntryVM = runtimeObj.try_as<Editor::FolderEntryViewModel>())
|
||||
{
|
||||
@@ -258,6 +258,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
localizedEntry.DisplayTextNeutral = EnglishOnlyResourceLoader().GetLocalizedString(entry.ResourceName);
|
||||
}
|
||||
if (!entry.SecondaryLabelResourceName.empty())
|
||||
{
|
||||
localizedEntry.SecondaryLabelLocalized = GetLibraryResourceString(entry.SecondaryLabelResourceName);
|
||||
}
|
||||
localizedIndex.emplace_back(std::move(localizedEntry));
|
||||
}
|
||||
return localizedIndex;
|
||||
@@ -342,7 +346,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
if (bestScore >= MinimumMatchScore)
|
||||
{
|
||||
scoredResults.emplace_back(bestScore, winrt::make<FilteredSearchResult>(index, &entry));
|
||||
scoredResults.emplace_back(bestScore, winrt::make<FilteredSearchResult>(index, &entry, nullptr, std::nullopt, entry.SecondaryLabelLocalized));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
winrt::hstring DisplayTextLocalized;
|
||||
std::optional<winrt::hstring> DisplayTextNeutral = std::nullopt;
|
||||
// No "Neutral" copy of SecondaryLabelLocalized: unlike DisplayText, the secondary
|
||||
// label is display-only (rendered in the search result row's caption). It is never
|
||||
// passed to the fuzzy matcher, so a single localized string is sufficient.
|
||||
winrt::hstring SecondaryLabelLocalized;
|
||||
const IndexEntry* Entry = nullptr;
|
||||
|
||||
std::array<std::pair<std::optional<winrt::hstring>, int>, 2> GetSearchableFields() const;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "SettingContainer.h"
|
||||
#include "SettingsExpander.h"
|
||||
#include "SettingContainer.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
@@ -54,7 +55,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
L"FontIconGlyph",
|
||||
xaml_typename<hstring>(),
|
||||
xaml_typename<Editor::SettingContainer>(),
|
||||
PropertyMetadata{ box_value(L"") });
|
||||
PropertyMetadata{ box_value(L""), PropertyChangedCallback{ &SettingContainer::_OnFontIconGlyphChanged } });
|
||||
}
|
||||
if (!_CurrentValueProperty)
|
||||
{
|
||||
@@ -134,13 +135,30 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void SettingContainer::_UpdateHelpText()
|
||||
{
|
||||
const auto helpText{ HelpText() };
|
||||
|
||||
// Forward HelpText into the SettingsCard / SettingsExpander Description
|
||||
// slot so it renders through the WCT-ported PART_DescriptionPresenter.
|
||||
// Setting it to nullptr when empty collapses the description visually so we don't
|
||||
// reserve vertical space for a blank line.
|
||||
const auto description{ helpText.empty() ? Windows::Foundation::IInspectable{ nullptr } : box_value(helpText) };
|
||||
|
||||
// Get the correct base to apply automation properties to
|
||||
std::vector<DependencyObject> base;
|
||||
base.reserve(2);
|
||||
base.reserve(3);
|
||||
if (const auto& child{ GetTemplateChild(L"Card") })
|
||||
{
|
||||
if (const auto& card{ child.try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
card.Description(description);
|
||||
base.push_back(child);
|
||||
}
|
||||
}
|
||||
if (const auto& child{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
|
||||
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
expander.Description(description);
|
||||
base.push_back(child);
|
||||
}
|
||||
}
|
||||
@@ -160,7 +178,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
Automation::AutomationProperties::SetName(obj, _GenerateAccessibleName());
|
||||
|
||||
// apply help text as tooltip and full description (automation property)
|
||||
if (const auto& helpText{ HelpText() }; !helpText.empty())
|
||||
if (!helpText.empty())
|
||||
{
|
||||
Automation::AutomationProperties::SetFullDescription(obj, helpText);
|
||||
}
|
||||
@@ -170,15 +188,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
Automation::AutomationProperties::SetFullDescription(obj, L"");
|
||||
}
|
||||
}
|
||||
|
||||
const auto textBlockHidden = HelpText().empty();
|
||||
if (const auto& child{ GetTemplateChild(L"HelpTextBlock") })
|
||||
{
|
||||
if (const auto& textBlock{ child.try_as<Controls::TextBlock>() })
|
||||
{
|
||||
textBlock.Visibility(textBlockHidden ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingContainer::OnApplyTemplate()
|
||||
@@ -223,13 +232,54 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
_UpdateOverrideSystem();
|
||||
_UpdateHelpText();
|
||||
_UpdateHeaderIcon();
|
||||
}
|
||||
|
||||
void SettingContainer::_UpdateHeaderIcon()
|
||||
{
|
||||
// Only forward FontIconGlyph into HeaderIcon when the caller actually
|
||||
// supplied a glyph. Some templates (Warning/Error) already set
|
||||
// SettingsCard.HeaderIcon in XAML to a stacked severity glyph; if we
|
||||
// unconditionally wrote nullptr here we'd clobber that XAML default for
|
||||
// every callsite that doesn't set FontIconGlyph.
|
||||
const auto glyph{ FontIconGlyph() };
|
||||
if (glyph.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Controls::FontIcon fi;
|
||||
fi.Glyph(glyph);
|
||||
const Controls::IconElement icon{ fi };
|
||||
|
||||
if (const auto& cardChild{ GetTemplateChild(L"Card") })
|
||||
{
|
||||
if (const auto& card{ cardChild.try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
card.HeaderIcon(icon);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (const auto& expanderChild{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ expanderChild.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
expander.HeaderIcon(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingContainer::_OnFontIconGlyphChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*args*/)
|
||||
{
|
||||
const auto& obj{ d.try_as<Editor::SettingContainer>() };
|
||||
get_self<SettingContainer>(obj)->_UpdateHeaderIcon();
|
||||
}
|
||||
|
||||
void SettingContainer::SetExpanded(bool expanded)
|
||||
{
|
||||
if (const auto& child{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
|
||||
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
expander.IsExpanded(expanded);
|
||||
}
|
||||
@@ -271,7 +321,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
if (const auto& child{ GetTemplateChild(L"Expander") })
|
||||
{
|
||||
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
|
||||
if (const auto& expander{ child.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
Automation::AutomationProperties::SetName(expander, _GenerateAccessibleName());
|
||||
}
|
||||
|
||||
@@ -48,11 +48,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
static void _OnCurrentValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnHasSettingValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnHelpTextChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnFontIconGlyphChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static hstring _GenerateOverrideMessage(const IInspectable& settingOrigin);
|
||||
hstring _GenerateAccessibleName();
|
||||
void _UpdateOverrideSystem();
|
||||
void _UpdateHelpText();
|
||||
void _UpdateCurrentValueAutoProp();
|
||||
void _UpdateHeaderIcon();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
</Style>
|
||||
<SolidColorBrush x:Key="SubgroupHeaderBrush"
|
||||
Color="{StaticResource TextFillColorSecondary}" />
|
||||
<StaticResource x:Key="ExpanderHeaderBorderBrush"
|
||||
ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
|
||||
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
|
||||
@@ -31,28 +29,14 @@
|
||||
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
|
||||
ResourceKey="SystemFillColorCautionBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityIconForeground"
|
||||
ResourceKey="TextFillColorInverseBrush" />
|
||||
<StaticResource x:Key="SettingContainerWarningSeverityIconForeground"
|
||||
ResourceKey="TextFillColorInverseBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerTitleForeground"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="SettingContainerMessageForeground"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
|
||||
ResourceKey="SystemAccentColorDark2" />
|
||||
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<Style x:Key="SecondaryTextBlockStyle"
|
||||
TargetType="TextBlock" />
|
||||
<!-- Do not mess with the foreground color for High Contrast. Let it ride as is. -->
|
||||
<SolidColorBrush x:Key="SubgroupHeaderBrush"
|
||||
Color="{ThemeResource SystemColorWindowTextColor}" />
|
||||
<StaticResource x:Key="ExpanderHeaderBorderBrush"
|
||||
ResourceKey="SystemColorButtonTextColorBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
|
||||
ResourceKey="SystemColorWindowColorBrush" />
|
||||
@@ -64,16 +48,6 @@
|
||||
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
|
||||
ResourceKey="SystemColorHighlightColorBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityIconForeground"
|
||||
ResourceKey="SystemColorHighlightTextColorBrush" />
|
||||
<StaticResource x:Key="SettingContainerWarningSeverityIconForeground"
|
||||
ResourceKey="SystemColorHighlightTextColorBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerTitleForeground"
|
||||
ResourceKey="SystemColorWindowTextColorBrush" />
|
||||
<StaticResource x:Key="SettingContainerMessageForeground"
|
||||
ResourceKey="SystemColorWindowTextColorBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
|
||||
ResourceKey="SystemAccentColorLight1" />
|
||||
</ResourceDictionary>
|
||||
@@ -84,8 +58,6 @@
|
||||
</Style>
|
||||
<SolidColorBrush x:Key="SubgroupHeaderBrush"
|
||||
Color="{StaticResource TextFillColorSecondary}" />
|
||||
<StaticResource x:Key="ExpanderHeaderBorderBrush"
|
||||
ResourceKey="CardStrokeColorDefaultBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityBackgroundBrush"
|
||||
ResourceKey="SystemFillColorCriticalBackgroundBrush" />
|
||||
@@ -97,30 +69,21 @@
|
||||
<StaticResource x:Key="SettingContainerWarningSeverityIconBackground"
|
||||
ResourceKey="SystemFillColorCautionBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerErrorSeverityIconForeground"
|
||||
ResourceKey="TextFillColorInverseBrush" />
|
||||
<StaticResource x:Key="SettingContainerWarningSeverityIconForeground"
|
||||
ResourceKey="TextFillColorInverseBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerTitleForeground"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="SettingContainerMessageForeground"
|
||||
ResourceKey="TextFillColorPrimaryBrush" />
|
||||
|
||||
<StaticResource x:Key="SettingContainerResetButtonIconForeground"
|
||||
ResourceKey="SystemAccentColorLight2" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<FontWeight x:Key="SettingContainerTitleFontWeight">SemiBold</FontWeight>
|
||||
|
||||
<x:String x:Key="SettingContainerIconBackgroundGlyph"></x:String>
|
||||
<x:String x:Key="SettingContainerErrorIconGlyph"></x:String>
|
||||
<x:String x:Key="SettingContainerWarningIconGlyph"></x:String>
|
||||
|
||||
<Thickness x:Key="SettingContainerIconMargin">0,4,8,4</Thickness>
|
||||
<x:Double x:Key="SettingContainerIconFontSize">16</x:Double>
|
||||
|
||||
<!-- Shared sizing for SettingContainer-style "card" rows (used by SettingsCardStyle and Actions page rows). -->
|
||||
<Thickness x:Key="SettingsCardPadding">16,8,8,8</Thickness>
|
||||
<x:Double x:Key="SettingsCardMinHeight">64</x:Double>
|
||||
<Thickness x:Key="SettingsCardItemMargin">0,4,0,0</Thickness>
|
||||
|
||||
<Style x:Key="StackPanelInExpanderStyle"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
@@ -157,6 +120,21 @@
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
Similar to a local:SettingContainer without actually being one.
|
||||
Used by data-templated rows (i.e. Actions page).
|
||||
-->
|
||||
<Style x:Key="SettingsCardStyle"
|
||||
TargetType="Grid">
|
||||
<Setter Property="MinHeight" Value="{StaticResource SettingsCardMinHeight}" />
|
||||
<Setter Property="Padding" Value="{StaticResource SettingsCardPadding}" />
|
||||
<Setter Property="Background" Value="{ThemeResource ExpanderHeaderBackground}" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource ExpanderHeaderBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{ThemeResource ExpanderHeaderBorderThickness}" />
|
||||
<Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SettingsPageItemHeaderStyle"
|
||||
BasedOn="{StaticResource BodyTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
@@ -178,7 +156,7 @@
|
||||
BasedOn="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="MaxWidth" Value="248" />
|
||||
<Setter Property="Margin" Value="0,0,-16,0" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="FontFamily" Value="Segoe UI, Segoe Fluent Icons, Segoe MDL2 Assets" />
|
||||
@@ -189,45 +167,42 @@
|
||||
Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
|
||||
<local:StringDefaultTemplateSelector x:Key="ExpanderPreviewTemplateSelector"
|
||||
StringTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
|
||||
<!-- A setting container for a setting that has no additional options -->
|
||||
<Style TargetType="local:SettingContainer">
|
||||
<Style x:Key="DefaultSettingContainer"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<local:SettingsCard x:Name="Card"
|
||||
Content="{TemplateBinding Content}">
|
||||
<local:SettingsCard.Header>
|
||||
<StackPanel VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<ContentControl Content="{TemplateBinding Header}"
|
||||
IsTabStop="False" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding Content}" />
|
||||
</Grid>
|
||||
</local:SettingsCard.Header>
|
||||
</local:SettingsCard>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- Implicit default style for SettingContainer; just an alias of DefaultSettingContainer so the named style can be referenced from VisualState setters. -->
|
||||
<Style BasedOn="{StaticResource DefaultSettingContainer}"
|
||||
TargetType="local:SettingContainer" />
|
||||
|
||||
<!-- A basic setting container displaying immutable text as content -->
|
||||
<Style x:Key="SettingContainerWithTextContent"
|
||||
TargetType="local:SettingContainer">
|
||||
@@ -320,151 +295,42 @@
|
||||
<!-- A setting container which can expand -->
|
||||
<Style x:Key="ExpanderSettingContainerStyle"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="Margin" Value="0,4,0,0" />
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ContentPresenter Content="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
A setting container which can expand. Includes space for an icon on the left side of the header.
|
||||
XAML applies the margin/padding of the icon regardless of its
|
||||
existence (which caused inconsistent padding). It's easier to just create
|
||||
another style and move on.
|
||||
-->
|
||||
<Style x:Key="ExpanderSettingContainerStyleWithIcon"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<FontIcon Grid.Column="0"
|
||||
Glyph="{TemplateBinding FontIconGlyph}" />
|
||||
<StackPanel Grid.Column="1"
|
||||
Padding="14,12,0,12"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="2"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{StaticResource ExpanderSettingContainerStringPreviewTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- A setting container which can expand. Supports data template override for preview -->
|
||||
<Style x:Key="ExpanderSettingContainerStyleWithComplexPreview"
|
||||
TargetType="local:SettingContainer">
|
||||
<Setter Property="MaxWidth" Value="1000" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<muxc:Expander x:Name="Expander"
|
||||
Margin="0,4,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Content="{TemplateBinding Content}"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<muxc:Expander.Header>
|
||||
<Grid MinHeight="64">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Grid.Column="0"
|
||||
Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
<ContentPresenter Grid.Column="1"
|
||||
MaxWidth="248"
|
||||
Margin="0,0,-16,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{TemplateBinding CurrentValueTemplate}" />
|
||||
</Grid>
|
||||
</muxc:Expander.Header>
|
||||
</muxc:Expander>
|
||||
<local:SettingsExpander x:Name="Expander"
|
||||
IsExpanded="{TemplateBinding StartExpanded}">
|
||||
<local:SettingsExpander.Header>
|
||||
<StackPanel VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<ContentControl Content="{TemplateBinding Header}"
|
||||
IsTabStop="False" />
|
||||
<Button x:Name="ResetButton"
|
||||
Style="{StaticResource SettingContainerResetButtonStyle}">
|
||||
<FontIcon Glyph=""
|
||||
Style="{StaticResource SettingContainerFontIconStyle}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</local:SettingsExpander.Header>
|
||||
<local:SettingsExpander.Content>
|
||||
<ContentControl MaxWidth="248"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalContentAlignment="Right"
|
||||
Content="{TemplateBinding CurrentValue}"
|
||||
ContentTemplate="{TemplateBinding CurrentValueTemplate}"
|
||||
ContentTemplateSelector="{StaticResource ExpanderPreviewTemplateSelector}"
|
||||
IsTabStop="False" />
|
||||
</local:SettingsExpander.Content>
|
||||
<local:SettingsExpander.ItemsHeader>
|
||||
<ContentPresenter Padding="16,12,16,16"
|
||||
Content="{TemplateBinding Content}" />
|
||||
</local:SettingsExpander.ItemsHeader>
|
||||
</local:SettingsExpander>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@@ -479,47 +345,19 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Background="{ThemeResource SettingContainerWarningSeverityBackgroundBrush}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Grid>
|
||||
<TextBlock x:Name="IconBackground"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingContainerIconMargin}"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerWarningSeverityIconBackground}"
|
||||
Text="{StaticResource SettingContainerIconBackgroundGlyph}" />
|
||||
|
||||
<TextBlock x:Name="StandardIcon"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingContainerIconMargin}"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerWarningSeverityIconForeground}"
|
||||
Text="{StaticResource SettingContainerWarningIconGlyph}" />
|
||||
</Grid>
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
FontWeight="{StaticResource SettingContainerTitleFontWeight}"
|
||||
Foreground="{ThemeResource SettingContainerTitleForeground}"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Foreground="{ThemeResource SettingContainerMessageForeground}"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<local:SettingsCard x:Name="Card"
|
||||
Background="{ThemeResource SettingContainerWarningSeverityBackgroundBrush}">
|
||||
<local:SettingsCard.Header>
|
||||
<ContentControl Content="{TemplateBinding Header}"
|
||||
IsTabStop="False" />
|
||||
</local:SettingsCard.Header>
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerWarningSeverityIconBackground}"
|
||||
Glyph="{StaticResource SettingContainerWarningIconGlyph}" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
</local:SettingsCard>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
@@ -534,47 +372,19 @@
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="local:SettingContainer">
|
||||
<Grid AutomationProperties.Name="{TemplateBinding Header}"
|
||||
Background="{ThemeResource SettingContainerErrorSeverityBackgroundBrush}"
|
||||
Style="{StaticResource NonExpanderGrid}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Style="{StaticResource StackPanelInExpanderStyle}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Grid>
|
||||
<TextBlock x:Name="IconBackground"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingContainerIconMargin}"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerErrorSeverityIconBackground}"
|
||||
Text="{StaticResource SettingContainerIconBackgroundGlyph}" />
|
||||
|
||||
<TextBlock x:Name="StandardIcon"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource SettingContainerIconMargin}"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerErrorSeverityIconForeground}"
|
||||
Text="{StaticResource SettingContainerErrorIconGlyph}" />
|
||||
</Grid>
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
FontWeight="{StaticResource SettingContainerTitleFontWeight}"
|
||||
Foreground="{ThemeResource SettingContainerTitleForeground}"
|
||||
Style="{StaticResource SettingsPageItemHeaderStyle}"
|
||||
Text="{TemplateBinding Header}" />
|
||||
</StackPanel>
|
||||
<TextBlock x:Name="HelpTextBlock"
|
||||
Foreground="{ThemeResource SettingContainerMessageForeground}"
|
||||
Style="{StaticResource SettingsPageItemDescriptionStyle}"
|
||||
Text="{TemplateBinding HelpText}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<local:SettingsCard x:Name="Card"
|
||||
Background="{ThemeResource SettingContainerErrorSeverityBackgroundBrush}">
|
||||
<local:SettingsCard.Header>
|
||||
<ContentControl Content="{TemplateBinding Header}"
|
||||
IsTabStop="False" />
|
||||
</local:SettingsCard.Header>
|
||||
<local:SettingsCard.HeaderIcon>
|
||||
<FontIcon FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
FontSize="{StaticResource SettingContainerIconFontSize}"
|
||||
Foreground="{ThemeResource SettingContainerErrorSeverityIconBackground}"
|
||||
Glyph="{StaticResource SettingContainerErrorIconGlyph}" />
|
||||
</local:SettingsCard.HeaderIcon>
|
||||
</local:SettingsCard>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
670
src/cascadia/TerminalSettingsEditor/SettingsCard.cpp
Normal file
670
src/cascadia/TerminalSettingsEditor/SettingsCard.cpp
Normal file
@@ -0,0 +1,670 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "SettingsCard.h"
|
||||
#include "SettingsCard.g.cpp"
|
||||
#include "SettingsCardAutomationPeer.g.cpp"
|
||||
#include "StyleExtensions.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls::Primitives;
|
||||
using namespace winrt::Windows::UI::Xaml::Input;
|
||||
using namespace winrt::Windows::UI::Xaml::Media;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty SettingsCard::_HeaderProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_DescriptionProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_HeaderIconProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_ActionIconProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_ActionIconToolTipProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_IsClickEnabledProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_IsActionIconVisibleProperty{ nullptr };
|
||||
DependencyProperty SettingsCard::_ContentAlignmentProperty{ nullptr };
|
||||
|
||||
static constexpr std::wstring_view NormalState{ L"Normal" };
|
||||
static constexpr std::wstring_view PointerOverState{ L"PointerOver" };
|
||||
static constexpr std::wstring_view PressedState{ L"Pressed" };
|
||||
static constexpr std::wstring_view DisabledState{ L"Disabled" };
|
||||
|
||||
static constexpr std::wstring_view BitmapHeaderIconEnabledState{ L"BitmapHeaderIconEnabled" };
|
||||
static constexpr std::wstring_view BitmapHeaderIconDisabledState{ L"BitmapHeaderIconDisabled" };
|
||||
|
||||
static constexpr std::wstring_view RightState{ L"Right" };
|
||||
static constexpr std::wstring_view LeftState{ L"Left" };
|
||||
static constexpr std::wstring_view VerticalState{ L"Vertical" };
|
||||
|
||||
static constexpr std::wstring_view NoContentSpacingState{ L"NoContentSpacing" };
|
||||
static constexpr std::wstring_view ContentSpacingState{ L"ContentSpacing" };
|
||||
|
||||
static constexpr std::wstring_view ContentAlignmentStatesGroup{ L"ContentAlignmentStates" };
|
||||
|
||||
static constexpr std::wstring_view ActionIconPresenterHolder{ L"PART_ActionIconPresenterHolder" };
|
||||
static constexpr std::wstring_view HeaderPresenter{ L"PART_HeaderPresenter" };
|
||||
static constexpr std::wstring_view DescriptionPresenter{ L"PART_DescriptionPresenter" };
|
||||
static constexpr std::wstring_view HeaderIconPresenterHolder{ L"PART_HeaderIconPresenterHolder" };
|
||||
static constexpr std::wstring_view ContentPresenterPart{ L"PART_ContentPresenter" };
|
||||
static constexpr std::wstring_view RootGridPart{ L"PART_RootGrid" };
|
||||
|
||||
static constexpr double SettingsCardVerticalHeaderContentSpacing{ 8.0 };
|
||||
|
||||
// Returns true if the given object is null, or is a string that is empty.
|
||||
// Non-string non-null objects (e.g. a TextBlock) are considered "non-empty".
|
||||
static bool _isNullOrEmpty(const winrt::Windows::Foundation::IInspectable& obj)
|
||||
{
|
||||
if (!obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (const auto pv{ obj.try_as<IPropertyValue>() }; pv && pv.Type() == PropertyType::String)
|
||||
{
|
||||
return unbox_value_or<hstring>(obj, hstring{}).empty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SettingsCard::SettingsCard()
|
||||
{
|
||||
_InitializeProperties();
|
||||
}
|
||||
|
||||
void SettingsCard::_InitializeProperties()
|
||||
{
|
||||
if (!_HeaderProperty)
|
||||
{
|
||||
_HeaderProperty = DependencyProperty::Register(
|
||||
L"Header",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnHeaderChanged } });
|
||||
}
|
||||
if (!_DescriptionProperty)
|
||||
{
|
||||
_DescriptionProperty = DependencyProperty::Register(
|
||||
L"Description",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnDescriptionChanged } });
|
||||
}
|
||||
if (!_HeaderIconProperty)
|
||||
{
|
||||
_HeaderIconProperty = DependencyProperty::Register(
|
||||
L"HeaderIcon",
|
||||
xaml_typename<IconElement>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsCard::_OnHeaderIconChanged } });
|
||||
}
|
||||
if (!_ActionIconProperty)
|
||||
{
|
||||
// No metadata default value — a fresh FontIcon is allocated per
|
||||
// card in OnApplyTemplate when the user hasn't set ActionIcon
|
||||
// explicitly. We cannot use a default FontIcon here because
|
||||
// UIElements have a single-parent constraint (one instance can't
|
||||
// be shared across cards) and a default string was rendering
|
||||
// through ContentPresenter -> TextBlock, whose line-height
|
||||
// padding made the Viewbox-scaled glyph visibly smaller than
|
||||
// WCT's SymbolIcon default.
|
||||
_ActionIconProperty = DependencyProperty::Register(
|
||||
L"ActionIcon",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ActionIconToolTipProperty)
|
||||
{
|
||||
_ActionIconToolTipProperty = DependencyProperty::Register(
|
||||
L"ActionIconToolTip",
|
||||
xaml_typename<hstring>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(hstring{}) });
|
||||
}
|
||||
if (!_IsClickEnabledProperty)
|
||||
{
|
||||
_IsClickEnabledProperty = DependencyProperty::Register(
|
||||
L"IsClickEnabled",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(false), PropertyChangedCallback{ &SettingsCard::_OnIsClickEnabledChanged } });
|
||||
}
|
||||
if (!_IsActionIconVisibleProperty)
|
||||
{
|
||||
_IsActionIconVisibleProperty = DependencyProperty::Register(
|
||||
L"IsActionIconVisible",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(true), PropertyChangedCallback{ &SettingsCard::_OnIsActionIconVisibleChanged } });
|
||||
}
|
||||
if (!_ContentAlignmentProperty)
|
||||
{
|
||||
_ContentAlignmentProperty = DependencyProperty::Register(
|
||||
L"ContentAlignment",
|
||||
xaml_typename<Editor::SettingsCardContentAlignment>(),
|
||||
xaml_typename<Editor::SettingsCard>(),
|
||||
PropertyMetadata{ box_value(Editor::SettingsCardContentAlignment::Right), PropertyChangedCallback{ &SettingsCard::_OnContentAlignmentChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
AutomationPeer SettingsCard::OnCreateAutomationPeer()
|
||||
{
|
||||
return winrt::make<implementation::SettingsCardAutomationPeer>(*this);
|
||||
}
|
||||
|
||||
// Pointer overrides: gate the ButtonBase click pipeline on IsClickEnabled.
|
||||
// When IsClickEnabled=false, we do NOT call the base method, so the event
|
||||
// is left unhandled and bubbles up the visual tree. This is what lets the
|
||||
// SettingsExpander header (a ToggleButton hosting a SettingsCard with
|
||||
// IsClickEnabled=false) toggle on a click anywhere across the header row,
|
||||
// not just on the chevron. Mirrors the Community Toolkit's SettingsCard.cs.
|
||||
void SettingsCard::OnPointerPressed(const winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs& e)
|
||||
{
|
||||
if (IsClickEnabled())
|
||||
{
|
||||
base_type::OnPointerPressed(e);
|
||||
_GoToCommonState(PressedState, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::OnPointerReleased(const winrt::Windows::UI::Xaml::Input::PointerRoutedEventArgs& e)
|
||||
{
|
||||
if (IsClickEnabled())
|
||||
{
|
||||
base_type::OnPointerReleased(e);
|
||||
_GoToCommonState(NormalState, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::OnApplyTemplate()
|
||||
{
|
||||
// Match WCT's SettingsCard.OnApplyTemplate() which calls base first so the
|
||||
// template parts are fully wired up before any of our post-template setup
|
||||
// (visibility, visual states, click interaction) runs.
|
||||
base_type::OnApplyTemplate();
|
||||
|
||||
// Inject the shared implicit ToggleSwitch / Slider / ComboBox / TextBox
|
||||
// dictionary so child controls in our Content slot get the Windows 11
|
||||
// settings-page defaults without an explicit Style attribute. Bypasses
|
||||
// the WCT Setter.Value-with-inline-ResourceDictionary pattern, which
|
||||
// crashes WinUI 2 XAML load in this codebase.
|
||||
StyleExtensions::EnsureImplicitStylesMergedInto(*this);
|
||||
|
||||
// Drop any handlers from a previous template.
|
||||
_isEnabledChangedRevoker.revoke();
|
||||
_contentAlignmentStatesChangedRevoker.revoke();
|
||||
_DisableButtonInteraction();
|
||||
if (_contentChangedToken != 0)
|
||||
{
|
||||
UnregisterPropertyChangedCallback(ContentControl::ContentProperty(), _contentChangedToken);
|
||||
_contentChangedToken = 0;
|
||||
}
|
||||
|
||||
_UpdateActionIconVisibility();
|
||||
_UpdateHeaderVisibility();
|
||||
_UpdateDescriptionVisibility();
|
||||
_UpdateHeaderIconVisibility();
|
||||
// Initial visual states.
|
||||
_CheckInitialVisualState();
|
||||
_CheckHeaderIconState();
|
||||
_SetAccessibleContentName();
|
||||
|
||||
// Watch for Content changing later (we may need to refresh the AutomationProperties.Name on it).
|
||||
_contentChangedToken = RegisterPropertyChangedCallback(ContentControl::ContentProperty(), [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_SetAccessibleContentName();
|
||||
}
|
||||
});
|
||||
|
||||
// Apply click-interaction state.
|
||||
if (IsClickEnabled())
|
||||
{
|
||||
_EnableButtonInteraction();
|
||||
}
|
||||
|
||||
_isEnabledChangedRevoker = IsEnabledChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(strongThis->IsEnabled() ? NormalState : DisabledState, true);
|
||||
strongThis->_CheckHeaderIconState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SettingsCard::_CheckInitialVisualState()
|
||||
{
|
||||
VisualStateManager::GoToState(*this, IsEnabled() ? hstring{ NormalState } : hstring{ DisabledState }, true);
|
||||
_UpdateContentAlignmentState();
|
||||
|
||||
// Subscribe to ContentAlignmentStates so we can drive ContentSpacingStates
|
||||
// whenever the alignment shifts to a stacked layout (Vertical, RightWrapped*).
|
||||
if (const auto child{ GetTemplateChild(hstring{ ContentAlignmentStatesGroup }) })
|
||||
{
|
||||
if (const auto group{ child.try_as<VisualStateGroup>() })
|
||||
{
|
||||
_CheckVerticalSpacingState(group.CurrentState());
|
||||
_contentAlignmentStatesChangedRevoker = group.CurrentStateChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const VisualStateChangedEventArgs& args) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_CheckVerticalSpacingState(args.NewState());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_CheckHeaderIconState()
|
||||
{
|
||||
// The Disabled common state recolors text/glyph foregrounds via the brush, but a
|
||||
// BitmapIcon is an image and won't pick up the disabled brush. Lower its opacity
|
||||
// instead, via the BitmapHeaderIconStates group. Mirrors the toolkit's
|
||||
// SettingsCard.cs::CheckHeaderIconState.
|
||||
if (HeaderIcon().try_as<BitmapIcon>())
|
||||
{
|
||||
VisualStateManager::GoToState(*this,
|
||||
hstring{ IsEnabled() ? BitmapHeaderIconEnabledState : BitmapHeaderIconDisabledState },
|
||||
true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset to the enabled state when a non-bitmap icon (or none) is present so the
|
||||
// opacity setter doesn't stick around from a previous bitmap icon.
|
||||
VisualStateManager::GoToState(*this, hstring{ BitmapHeaderIconEnabledState }, true);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_CheckVerticalSpacingState(const VisualState& state)
|
||||
{
|
||||
// Add row spacing whenever the content sits below the header (Vertical or RightWrapped*)
|
||||
// AND there's both Content and (Header or Description) to space apart.
|
||||
//
|
||||
// For the Vertical case we read ContentAlignment() directly rather than
|
||||
// state.Name(): our Left/Vertical visual states are empty placeholders
|
||||
// (the actual layout work happens in _UpdateContentAlignmentState via
|
||||
// direct C++ property writes) and an empty <VisualState> may not have
|
||||
// its name register as CurrentState when GoToState fires in WinUI 2 —
|
||||
// leaving stackedLayout incorrectly false. RightWrapped*, in contrast,
|
||||
// are size-triggered visual states with real setters and ControlSizeTrigger,
|
||||
// so their CurrentState is reliably observed.
|
||||
const auto stateName{ state ? state.Name() : hstring{} };
|
||||
const bool stackedLayout =
|
||||
ContentAlignment() == Editor::SettingsCardContentAlignment::Vertical ||
|
||||
stateName == L"RightWrapped" ||
|
||||
stateName == L"RightWrappedNoIcon";
|
||||
|
||||
const bool hasContent{ static_cast<bool>(Content()) };
|
||||
const bool hasHeaderOrDescription = !_isNullOrEmpty(Header()) || !_isNullOrEmpty(Description());
|
||||
|
||||
const bool shouldSpace = stackedLayout && hasContent && hasHeaderOrDescription;
|
||||
|
||||
VisualStateManager::GoToState(*this,
|
||||
hstring{ shouldSpace ? ContentSpacingState : NoContentSpacingState },
|
||||
true);
|
||||
|
||||
// Belt-and-suspenders for the WinUI 2 quirk: VisualState.Setters activated
|
||||
// by C++ GoToState don't reliably engage. The ContentSpacing setter
|
||||
// targets PART_RootGrid.RowSpacing; set it directly here as well so the
|
||||
// Vertical / RightWrapped stacked-layout cards actually get the breathing
|
||||
// room between header and content that WCT shows.
|
||||
if (const auto child{ GetTemplateChild(hstring{ RootGridPart }) })
|
||||
{
|
||||
if (const auto rootGrid{ child.try_as<Grid>() })
|
||||
{
|
||||
rootGrid.RowSpacing(shouldSpace ? SettingsCardVerticalHeaderContentSpacing : 0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_SetAccessibleContentName()
|
||||
{
|
||||
// If Header is a string and the inner Content lacks an AutomationProperties.Name, propagate the header
|
||||
// into the content so screen readers can announce something meaningful when focus lands there.
|
||||
const auto headerObj{ Header() };
|
||||
if (!headerObj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto headerString{ unbox_value_or<hstring>(headerObj, hstring{}) };
|
||||
if (headerString.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto contentObj{ Content() };
|
||||
if (const auto element{ contentObj.try_as<UIElement>() })
|
||||
{
|
||||
if (Automation::AutomationProperties::GetName(element).empty())
|
||||
{
|
||||
// Don't override ButtonBase content (would clobber its own name) or plain text blocks.
|
||||
if (!element.try_as<ButtonBase>() && !element.try_as<TextBlock>())
|
||||
{
|
||||
Automation::AutomationProperties::SetName(element, headerString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_EnableButtonInteraction()
|
||||
{
|
||||
if (_interactionEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_interactionEnabled = true;
|
||||
|
||||
IsTabStop(true);
|
||||
_pointerEnteredRevoker = PointerEntered(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(PointerOverState, true);
|
||||
}
|
||||
});
|
||||
_pointerExitedRevoker = PointerExited(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
_pointerCaptureLostRevoker = PointerCaptureLost(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
_pointerCanceledRevoker = PointerCanceled(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis = weakThis.get())
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
_previewKeyDownRevoker = PreviewKeyDown(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e) {
|
||||
const auto strongThis = weakThis.get();
|
||||
if (!strongThis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto key = e.Key();
|
||||
if (key == Windows::System::VirtualKey::Enter || key == Windows::System::VirtualKey::Space || key == Windows::System::VirtualKey::GamepadA)
|
||||
{
|
||||
const auto focused{ strongThis->_GetFocusedElement() };
|
||||
if (focused && focused.try_as<Editor::SettingsCard>() == strongThis.as<Editor::SettingsCard>())
|
||||
{
|
||||
strongThis->_GoToCommonState(PressedState, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
_previewKeyUpRevoker = PreviewKeyUp(winrt::auto_revoke, [weakThis = get_weak()](auto&&, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e) {
|
||||
const auto strongThis = weakThis.get();
|
||||
if (!strongThis)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto key = e.Key();
|
||||
if (key == Windows::System::VirtualKey::Enter || key == Windows::System::VirtualKey::Space || key == Windows::System::VirtualKey::GamepadA)
|
||||
{
|
||||
strongThis->_GoToCommonState(NormalState, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SettingsCard::_DisableButtonInteraction()
|
||||
{
|
||||
_interactionEnabled = false;
|
||||
IsTabStop(false);
|
||||
_pointerEnteredRevoker.revoke();
|
||||
_pointerExitedRevoker.revoke();
|
||||
_pointerCaptureLostRevoker.revoke();
|
||||
_pointerCanceledRevoker.revoke();
|
||||
_previewKeyDownRevoker.revoke();
|
||||
_previewKeyUpRevoker.revoke();
|
||||
}
|
||||
|
||||
void SettingsCard::_GoToCommonState(const std::wstring_view& state, bool useTransitions)
|
||||
{
|
||||
VisualStateManager::GoToState(*this, hstring{ state }, useTransitions);
|
||||
}
|
||||
|
||||
FrameworkElement SettingsCard::_GetFocusedElement()
|
||||
{
|
||||
if (const auto root{ XamlRoot() })
|
||||
{
|
||||
return FocusManager::GetFocusedElement(root).try_as<FrameworkElement>();
|
||||
}
|
||||
return FocusManager::GetFocusedElement().try_as<FrameworkElement>();
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateActionIconVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ ActionIconPresenterHolder }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility((IsClickEnabled() && IsActionIconVisible()) ? Visibility::Visible : Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateHeaderVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ HeaderPresenter }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility(_isNullOrEmpty(Header()) ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateDescriptionVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ DescriptionPresenter }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility(_isNullOrEmpty(Description()) ? Visibility::Collapsed : Visibility::Visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateHeaderIconVisibility()
|
||||
{
|
||||
if (const auto child{ GetTemplateChild(hstring{ HeaderIconPresenterHolder }) })
|
||||
{
|
||||
if (const auto frameworkChild{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
frameworkChild.Visibility(HeaderIcon() ? Visibility::Visible : Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_UpdateContentAlignmentState()
|
||||
{
|
||||
// Map ContentAlignment to the visual state name *and* the corresponding
|
||||
// direct layout values. We drive both: GoToState keeps the visual state
|
||||
// machine in sync (so _CheckVerticalSpacingState sees the right CurrentState),
|
||||
// but we *also* apply the layout properties directly to PART_ContentPresenter
|
||||
// because in WinUI 2, attached-property changes (Grid.Row/Grid.Column) and
|
||||
// HorizontalAlignment changes inside VisualState.Setters or Storyboards
|
||||
// don't reliably engage when activated by programmatic VisualStateManager::GoToState
|
||||
// — only by XAML StateTriggers (which is what WCT uses via tk:IsEqualStateTrigger).
|
||||
// Until/unless an equivalent state trigger gets ported, the direct C++ set is
|
||||
// the load-bearing path for Left/Vertical.
|
||||
std::wstring_view state{ RightState };
|
||||
int contentRow{ 0 };
|
||||
int contentColumn{ 2 };
|
||||
auto contentHA{ HorizontalAlignment::Right };
|
||||
|
||||
const auto alignment = ContentAlignment();
|
||||
switch (alignment)
|
||||
{
|
||||
case Editor::SettingsCardContentAlignment::Left:
|
||||
state = LeftState;
|
||||
contentRow = 1;
|
||||
contentColumn = 1;
|
||||
contentHA = HorizontalAlignment::Left;
|
||||
break;
|
||||
case Editor::SettingsCardContentAlignment::Vertical:
|
||||
state = VerticalState;
|
||||
contentRow = 1;
|
||||
contentColumn = 1;
|
||||
contentHA = HorizontalAlignment::Stretch;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VisualStateManager::GoToState(*this, hstring{ state }, true);
|
||||
|
||||
if (const auto child{ GetTemplateChild(hstring{ ContentPresenterPart }) })
|
||||
{
|
||||
if (const auto contentPresenter{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
Grid::SetRow(contentPresenter, contentRow);
|
||||
Grid::SetColumn(contentPresenter, contentColumn);
|
||||
contentPresenter.HorizontalAlignment(contentHA);
|
||||
|
||||
// Vertical mirrors WCT's TemplatedParent Binding setter: propagate
|
||||
// the card's own HorizontalContentAlignment to the inner ContentPresenter
|
||||
// so e.g. HorizontalContentAlignment="Left" + ContentAlignment="Vertical"
|
||||
// actually left-aligns the inner content.
|
||||
if (const auto cp{ contentPresenter.try_as<ContentPresenter>() })
|
||||
{
|
||||
cp.HorizontalContentAlignment(HorizontalContentAlignment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Left collapses the HeaderIcon column regardless of HeaderIcon content.
|
||||
if (const auto child{ GetTemplateChild(hstring{ HeaderIconPresenterHolder }) })
|
||||
{
|
||||
if (const auto headerIconHolder{ child.try_as<FrameworkElement>() })
|
||||
{
|
||||
if (alignment == Editor::SettingsCardContentAlignment::Left)
|
||||
{
|
||||
headerIconHolder.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
headerIconHolder.Visibility(HeaderIcon() ? Visibility::Visible : Visibility::Collapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_OnHeaderChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
const auto self = get_self<SettingsCard>(obj);
|
||||
self->_UpdateHeaderVisibility();
|
||||
self->_SetAccessibleContentName();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnDescriptionChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
get_self<SettingsCard>(obj)->_UpdateDescriptionVisibility();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnHeaderIconChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
const auto self = get_self<SettingsCard>(obj);
|
||||
self->_UpdateHeaderIconVisibility();
|
||||
// HeaderIcon type may have flipped between BitmapIcon and other icon types — re-evaluate
|
||||
// the BitmapHeaderIcon visual state so the disabled-opacity setter is applied (or cleared).
|
||||
self->_CheckHeaderIconState();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnIsClickEnabledChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
const auto self = get_self<SettingsCard>(obj);
|
||||
self->_UpdateActionIconVisibility();
|
||||
if (self->IsClickEnabled())
|
||||
{
|
||||
self->_EnableButtonInteraction();
|
||||
}
|
||||
else
|
||||
{
|
||||
self->_DisableButtonInteraction();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCard::_OnIsActionIconVisibleChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
get_self<SettingsCard>(obj)->_UpdateActionIconVisibility();
|
||||
}
|
||||
|
||||
void SettingsCard::_OnContentAlignmentChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsCard>() };
|
||||
get_self<SettingsCard>(obj)->_UpdateContentAlignmentState();
|
||||
}
|
||||
|
||||
SettingsCardAutomationPeer::SettingsCardAutomationPeer(const Editor::SettingsCard& owner) :
|
||||
SettingsCardAutomationPeerT<SettingsCardAutomationPeer>(owner)
|
||||
{
|
||||
}
|
||||
|
||||
AutomationControlType SettingsCardAutomationPeer::GetAutomationControlTypeCore() const
|
||||
{
|
||||
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
if (card.IsClickEnabled())
|
||||
{
|
||||
return AutomationControlType::Button;
|
||||
}
|
||||
}
|
||||
return AutomationControlType::Group;
|
||||
}
|
||||
|
||||
hstring SettingsCardAutomationPeer::GetClassNameCore() const
|
||||
{
|
||||
return hstring{ L"SettingsCard" };
|
||||
}
|
||||
|
||||
hstring SettingsCardAutomationPeer::GetNameCore() const
|
||||
{
|
||||
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
if (card.IsClickEnabled())
|
||||
{
|
||||
if (const auto manualName{ AutomationProperties::GetName(card) }; !manualName.empty())
|
||||
{
|
||||
return manualName;
|
||||
}
|
||||
if (const auto headerString{ unbox_value_or<hstring>(card.Header(), hstring{}) }; !headerString.empty())
|
||||
{
|
||||
return headerString;
|
||||
}
|
||||
}
|
||||
// Not clickable, or no header text: fall back to AutomationProperties.Name (matching
|
||||
// FrameworkElementAutomationPeer's default behavior).
|
||||
return AutomationProperties::GetName(card);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable SettingsCardAutomationPeer::GetPatternCore(PatternInterface patternInterface) const
|
||||
{
|
||||
if (patternInterface == PatternInterface::Invoke)
|
||||
{
|
||||
if (const auto card{ Owner().try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
if (card.IsClickEnabled())
|
||||
{
|
||||
// Only provide Invoke pattern if the card is clickable.
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
// ButtonBaseAutomationPeer only provides Invoke; everything else returns null.
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
100
src/cascadia/TerminalSettingsEditor/SettingsCard.h
Normal file
100
src/cascadia/TerminalSettingsEditor/SettingsCard.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- SettingsCard
|
||||
|
||||
Abstract:
|
||||
- A base control for building consistent settings experiences. Based
|
||||
on the Windows Community Toolkit's SettingsCard.
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora - 2026 May
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SettingsCard.g.h"
|
||||
#include "SettingsCardAutomationPeer.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct SettingsCard : SettingsCardT<SettingsCard>
|
||||
{
|
||||
public:
|
||||
SettingsCard();
|
||||
|
||||
void OnApplyTemplate();
|
||||
void OnPointerPressed(const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
void OnPointerReleased(const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
|
||||
// Automation peer override.
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Header);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Description);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Controls::IconElement, HeaderIcon);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, ActionIcon);
|
||||
DEPENDENCY_PROPERTY(hstring, ActionIconToolTip);
|
||||
DEPENDENCY_PROPERTY(bool, IsClickEnabled);
|
||||
DEPENDENCY_PROPERTY(bool, IsActionIconVisible);
|
||||
DEPENDENCY_PROPERTY(Editor::SettingsCardContentAlignment, ContentAlignment);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnHeaderChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnDescriptionChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnHeaderIconChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnIsClickEnabledChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnIsActionIconVisibleChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnContentAlignmentChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _EnableButtonInteraction();
|
||||
void _DisableButtonInteraction();
|
||||
void _GoToCommonState(const std::wstring_view& state, bool useTransitions);
|
||||
void _UpdateActionIconVisibility();
|
||||
void _UpdateHeaderVisibility();
|
||||
void _UpdateDescriptionVisibility();
|
||||
void _UpdateHeaderIconVisibility();
|
||||
void _UpdateContentAlignmentState();
|
||||
void _CheckInitialVisualState();
|
||||
void _CheckHeaderIconState();
|
||||
void _CheckVerticalSpacingState(const Windows::UI::Xaml::VisualState& state);
|
||||
void _SetAccessibleContentName();
|
||||
Windows::UI::Xaml::FrameworkElement _GetFocusedElement();
|
||||
|
||||
bool _interactionEnabled{ false };
|
||||
Windows::UI::Xaml::Controls::Control::IsEnabledChanged_revoker _isEnabledChangedRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerEntered_revoker _pointerEnteredRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerExited_revoker _pointerExitedRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerCaptureLost_revoker _pointerCaptureLostRevoker;
|
||||
Windows::UI::Xaml::UIElement::PointerCanceled_revoker _pointerCanceledRevoker;
|
||||
Windows::UI::Xaml::UIElement::PreviewKeyDown_revoker _previewKeyDownRevoker;
|
||||
Windows::UI::Xaml::UIElement::PreviewKeyUp_revoker _previewKeyUpRevoker;
|
||||
Windows::UI::Xaml::VisualStateGroup::CurrentStateChanged_revoker _contentAlignmentStatesChangedRevoker;
|
||||
int64_t _contentChangedToken{ 0 };
|
||||
};
|
||||
|
||||
// AutomationPeer for SettingsCard. Mirrors the Community Toolkit's
|
||||
// SettingsCardAutomationPeer: only exposes Invoke + Button control type when
|
||||
// the card has IsClickEnabled=true; otherwise reports as a Group.
|
||||
struct SettingsCardAutomationPeer : SettingsCardAutomationPeerT<SettingsCardAutomationPeer>
|
||||
{
|
||||
public:
|
||||
SettingsCardAutomationPeer(const Editor::SettingsCard& owner);
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const;
|
||||
hstring GetClassNameCore() const;
|
||||
hstring GetNameCore() const;
|
||||
winrt::Windows::Foundation::IInspectable GetPatternCore(Windows::UI::Xaml::Automation::Peers::PatternInterface patternInterface) const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(SettingsCard);
|
||||
BASIC_FACTORY(SettingsCardAutomationPeer);
|
||||
}
|
||||
46
src/cascadia/TerminalSettingsEditor/SettingsCard.idl
Normal file
46
src/cascadia/TerminalSettingsEditor/SettingsCard.idl
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
enum SettingsCardContentAlignment
|
||||
{
|
||||
Right,
|
||||
Left,
|
||||
Vertical
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SettingsCard : Windows.UI.Xaml.Controls.Primitives.ButtonBase
|
||||
{
|
||||
SettingsCard();
|
||||
|
||||
Object Header;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderProperty { get; };
|
||||
|
||||
Object Description;
|
||||
static Windows.UI.Xaml.DependencyProperty DescriptionProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.Controls.IconElement HeaderIcon;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderIconProperty { get; };
|
||||
|
||||
Object ActionIcon;
|
||||
static Windows.UI.Xaml.DependencyProperty ActionIconProperty { get; };
|
||||
|
||||
String ActionIconToolTip;
|
||||
static Windows.UI.Xaml.DependencyProperty ActionIconToolTipProperty { get; };
|
||||
|
||||
Boolean IsClickEnabled;
|
||||
static Windows.UI.Xaml.DependencyProperty IsClickEnabledProperty { get; };
|
||||
|
||||
Boolean IsActionIconVisible;
|
||||
static Windows.UI.Xaml.DependencyProperty IsActionIconVisibleProperty { get; };
|
||||
|
||||
SettingsCardContentAlignment ContentAlignment;
|
||||
static Windows.UI.Xaml.DependencyProperty ContentAlignmentProperty { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SettingsCardAutomationPeer : Windows.UI.Xaml.Automation.Peers.ButtonBaseAutomationPeer
|
||||
{
|
||||
SettingsCardAutomationPeer(SettingsCard owner);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<!--
|
||||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
|
||||
the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
Implicit Styles that get copied into every SettingsCard / SettingsExpander's
|
||||
own Resources collection at runtime via StyleExtensions::EnsureImplicitStylesMergedInto
|
||||
(called from each control's OnApplyTemplate). This is the WinUI 2 port of WCT's
|
||||
local:StyleExtensions.Resources Setter pattern.
|
||||
|
||||
Why not the WCT Setter.Value-with-inline-ResourceDictionary approach? It
|
||||
crashes WinUI 2 in this codebase with "CommonResources.xaml is not a valid
|
||||
absolute URI" during XAML load. The C++ copy-into-Resources bypasses the
|
||||
broken Setter pipeline entirely.
|
||||
|
||||
Why not Append this dictionary to MergedDictionaries directly? WinUI 2
|
||||
enforces a single-parent constraint on ResourceDictionaries in
|
||||
MergedDictionaries: the second element to merge the same shared dict
|
||||
throws "Element is already the child of another element". The C++ helper
|
||||
instead iterates this dict's entries once (Style references) and copies
|
||||
them into each target's own Resources collection. Style instances are
|
||||
not UIElements and can safely be shared across multiple element Resources.
|
||||
|
||||
Why no BasedOn references? When a ResourceDictionary is loaded via Source=
|
||||
(standalone), it has no parent resource scope at parse time, so
|
||||
{StaticResource SomeKeyInAnotherFile} would fail to resolve. WCT's pattern
|
||||
works because the dict is parsed inline within the owner's resource scope.
|
||||
|
||||
Practical consequence: any implicit style here MUST set every property the
|
||||
final-rendered control needs, because an implicit style without BasedOn
|
||||
fully replaces the framework default style — including the default
|
||||
ControlTemplate. The ToggleSwitch entry below sets a complete custom
|
||||
template suitable for cards. We intentionally do NOT define implicit
|
||||
Slider / ComboBox / TextBox styles here: stripping their default template
|
||||
by way of a minimal implicit style would lose theme-driven CornerRadius,
|
||||
PointerOver/Pressed brushes, the drop-shadow popup, etc. Call sites that
|
||||
need a card-specific MinWidth set it explicitly on the instance.
|
||||
-->
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<!--
|
||||
Right-aligned, compact ToggleSwitch. Replaces the WCT
|
||||
RightAlignedCompactToggleSwitchStyle the toolkit uses as BasedOn.
|
||||
OffContent / OnContent are blanked so the default "Off" / "On" labels
|
||||
don't steal horizontal space next to the switch.
|
||||
-->
|
||||
<Style TargetType="ToggleSwitch">
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right" />
|
||||
<Setter Property="Margin" Value="0,0,10,0" />
|
||||
<Setter Property="MinWidth" Value="0" />
|
||||
<Setter Property="OffContent" Value="" />
|
||||
<Setter Property="OnContent" Value="" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
1100
src/cascadia/TerminalSettingsEditor/SettingsControlsStyle.xaml
Normal file
1100
src/cascadia/TerminalSettingsEditor/SettingsControlsStyle.xaml
Normal file
File diff suppressed because it is too large
Load Diff
342
src/cascadia/TerminalSettingsEditor/SettingsExpander.cpp
Normal file
342
src/cascadia/TerminalSettingsEditor/SettingsExpander.cpp
Normal file
@@ -0,0 +1,342 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "SettingsExpander.h"
|
||||
#include "SettingsExpander.g.cpp"
|
||||
#include "SettingsExpanderAutomationPeer.g.cpp"
|
||||
#include "SettingsExpanderItemStyleSelector.g.cpp"
|
||||
#include "StyleExtensions.h"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation;
|
||||
using namespace winrt::Windows::UI::Xaml::Automation::Peers;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty SettingsExpander::_HeaderProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_DescriptionProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_HeaderIconProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ContentProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_IsExpandedProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemsHeaderProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemsFooterProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemsProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemsSourceProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemTemplateProperty{ nullptr };
|
||||
DependencyProperty SettingsExpander::_ItemContainerStyleSelectorProperty{ nullptr };
|
||||
|
||||
static constexpr std::wstring_view PART_ItemsHost{ L"PART_ItemsHost" };
|
||||
|
||||
SettingsExpander::SettingsExpander()
|
||||
{
|
||||
_InitializeProperties();
|
||||
|
||||
// Items is backed by an observable vector so post-construction mutations
|
||||
// (e.g. user code that adds cards after the expander is on screen) also
|
||||
// refresh the inner ItemsControl. The XAML parser populates Items via
|
||||
// Append before OnApplyTemplate runs, so the eager population path also
|
||||
// works.
|
||||
Items(single_threaded_observable_vector<IInspectable>());
|
||||
}
|
||||
|
||||
void SettingsExpander::_InitializeProperties()
|
||||
{
|
||||
if (!_HeaderProperty)
|
||||
{
|
||||
_HeaderProperty = DependencyProperty::Register(
|
||||
L"Header",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_DescriptionProperty)
|
||||
{
|
||||
_DescriptionProperty = DependencyProperty::Register(
|
||||
L"Description",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_HeaderIconProperty)
|
||||
{
|
||||
_HeaderIconProperty = DependencyProperty::Register(
|
||||
L"HeaderIcon",
|
||||
xaml_typename<IconElement>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ContentProperty)
|
||||
{
|
||||
_ContentProperty = DependencyProperty::Register(
|
||||
L"Content",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_IsExpandedProperty)
|
||||
{
|
||||
_IsExpandedProperty = DependencyProperty::Register(
|
||||
L"IsExpanded",
|
||||
xaml_typename<bool>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ box_value(false), PropertyChangedCallback{ &SettingsExpander::_OnIsExpandedChanged } });
|
||||
}
|
||||
if (!_ItemsHeaderProperty)
|
||||
{
|
||||
_ItemsHeaderProperty = DependencyProperty::Register(
|
||||
L"ItemsHeader",
|
||||
xaml_typename<UIElement>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ItemsFooterProperty)
|
||||
{
|
||||
_ItemsFooterProperty = DependencyProperty::Register(
|
||||
L"ItemsFooter",
|
||||
xaml_typename<UIElement>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ItemsProperty)
|
||||
{
|
||||
_ItemsProperty = DependencyProperty::Register(
|
||||
L"Items",
|
||||
xaml_typename<IVector<IInspectable>>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsExpander::_OnItemsConnectedPropertyChanged } });
|
||||
}
|
||||
if (!_ItemsSourceProperty)
|
||||
{
|
||||
_ItemsSourceProperty = DependencyProperty::Register(
|
||||
L"ItemsSource",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingsExpander::_OnItemsConnectedPropertyChanged } });
|
||||
}
|
||||
if (!_ItemTemplateProperty)
|
||||
{
|
||||
_ItemTemplateProperty = DependencyProperty::Register(
|
||||
L"ItemTemplate",
|
||||
xaml_typename<IInspectable>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
if (!_ItemContainerStyleSelectorProperty)
|
||||
{
|
||||
_ItemContainerStyleSelectorProperty = DependencyProperty::Register(
|
||||
L"ItemContainerStyleSelector",
|
||||
xaml_typename<StyleSelector>(),
|
||||
xaml_typename<Editor::SettingsExpander>(),
|
||||
PropertyMetadata{ nullptr });
|
||||
}
|
||||
}
|
||||
|
||||
AutomationPeer SettingsExpander::OnCreateAutomationPeer()
|
||||
{
|
||||
return winrt::make<implementation::SettingsExpanderAutomationPeer>(*this);
|
||||
}
|
||||
|
||||
void SettingsExpander::OnApplyTemplate()
|
||||
{
|
||||
// Same implicit-styles injection as SettingsCard so a ToggleSwitch /
|
||||
// Slider / ComboBox / TextBox placed directly as SettingsExpander.Content
|
||||
// gets the same Windows 11 defaults.
|
||||
StyleExtensions::EnsureImplicitStylesMergedInto(*this);
|
||||
|
||||
_SetAccessibleName();
|
||||
|
||||
// Drop the prior template's host before locating the new one.
|
||||
_itemsHost = nullptr;
|
||||
|
||||
if (const auto child{ GetTemplateChild(hstring{ PART_ItemsHost }) })
|
||||
{
|
||||
_itemsHost = child.try_as<Controls::ItemsControl>();
|
||||
}
|
||||
|
||||
if (_itemsHost)
|
||||
{
|
||||
// Push our initial ItemsSource through to the host and stamp item-container styles.
|
||||
_UpdateItemsSource();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsExpander::_SetAccessibleName()
|
||||
{
|
||||
if (!AutomationProperties::GetName(*this).empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (const auto headerString{ unbox_value_or<hstring>(Header(), hstring{}) }; !headerString.empty())
|
||||
{
|
||||
AutomationProperties::SetName(*this, headerString);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsExpander::_UpdateItemsSource()
|
||||
{
|
||||
if (!_itemsHost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// ItemsSource wins when set; otherwise fall back to the inline Items collection.
|
||||
if (const auto source{ ItemsSource() })
|
||||
{
|
||||
_itemsHost.ItemsSource(source);
|
||||
}
|
||||
else
|
||||
{
|
||||
_itemsHost.ItemsSource(Items());
|
||||
}
|
||||
|
||||
_ApplyItemContainerStyles();
|
||||
_SubscribeToItemsVectorChanged();
|
||||
}
|
||||
|
||||
// Watch our inline Items vector for changes so containers added after
|
||||
// OnApplyTemplate also get the proper SettingsCard item style. (When
|
||||
// ItemsSource is set, this is a no-op since the parser only touches Items.)
|
||||
void SettingsExpander::_SubscribeToItemsVectorChanged()
|
||||
{
|
||||
_itemsVectorChangedRevoker.revoke();
|
||||
|
||||
if (ItemsSource())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto observable{ Items().try_as<IObservableVector<IInspectable>>() })
|
||||
{
|
||||
_itemsVectorChangedRevoker = observable.VectorChanged(winrt::auto_revoke, [weakThis = get_weak()](auto&&, auto&&) {
|
||||
if (const auto strongThis{ weakThis.get() })
|
||||
{
|
||||
strongThis->_ApplyItemContainerStyles();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the per-item style produced by ItemContainerStyleSelector. ItemsControl
|
||||
// only generates ContentPresenter containers for non-UIElement items, so when
|
||||
// SettingsCards are added directly the cards themselves are the "containers"
|
||||
// and we have to set Style on them ourselves. Mirrors the ElementPrepared path
|
||||
// we used when this was an ItemsRepeater.
|
||||
void SettingsExpander::_ApplyItemContainerStyles()
|
||||
{
|
||||
const auto selector{ ItemContainerStyleSelector() };
|
||||
if (!selector)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto items{ Items() };
|
||||
if (!items)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < items.Size(); ++i)
|
||||
{
|
||||
if (const auto element{ items.GetAt(i).try_as<FrameworkElement>() })
|
||||
{
|
||||
if (element.ReadLocalValue(FrameworkElement::StyleProperty()) == DependencyProperty::UnsetValue())
|
||||
{
|
||||
element.Style(selector.SelectStyle(items.GetAt(i), element));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsExpander::_OnItemsConnectedPropertyChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*e*/)
|
||||
{
|
||||
if (const auto obj{ d.try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
get_self<SettingsExpander>(obj)->_UpdateItemsSource();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsExpander::_OnIsExpandedChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
|
||||
{
|
||||
const auto obj{ d.try_as<Editor::SettingsExpander>() };
|
||||
if (!obj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto self = get_self<SettingsExpander>(obj);
|
||||
const auto newValue = unbox_value_or<bool>(e.NewValue(), false);
|
||||
|
||||
// Notify the automation peer so screen readers see the expand/collapse state change.
|
||||
if (const auto peer{ FrameworkElementAutomationPeer::FromElement(obj).try_as<Editor::SettingsExpanderAutomationPeer>() })
|
||||
{
|
||||
peer.RaiseExpandedChangedEvent(newValue);
|
||||
}
|
||||
|
||||
if (newValue)
|
||||
{
|
||||
self->Expanded.raise(obj, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->Collapsed.raise(obj, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsExpanderAutomationPeer::SettingsExpanderAutomationPeer(const Editor::SettingsExpander& owner) :
|
||||
SettingsExpanderAutomationPeerT<SettingsExpanderAutomationPeer>(owner)
|
||||
{
|
||||
}
|
||||
|
||||
AutomationControlType SettingsExpanderAutomationPeer::GetAutomationControlTypeCore() const
|
||||
{
|
||||
return AutomationControlType::Group;
|
||||
}
|
||||
|
||||
hstring SettingsExpanderAutomationPeer::GetClassNameCore() const
|
||||
{
|
||||
return hstring{ L"SettingsExpander" };
|
||||
}
|
||||
|
||||
hstring SettingsExpanderAutomationPeer::GetNameCore() const
|
||||
{
|
||||
if (const auto expander{ Owner().try_as<Editor::SettingsExpander>() })
|
||||
{
|
||||
if (const auto manualName{ AutomationProperties::GetName(expander) }; !manualName.empty())
|
||||
{
|
||||
return manualName;
|
||||
}
|
||||
if (const auto headerString{ unbox_value_or<hstring>(expander.Header(), hstring{}) }; !headerString.empty())
|
||||
{
|
||||
return headerString;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void SettingsExpanderAutomationPeer::RaiseExpandedChangedEvent(bool newValue)
|
||||
{
|
||||
// Mirrors the toolkit's SettingsExpanderAutomationPeer.RaiseExpandedChangedEvent.
|
||||
// Narrator doesn't actually announce this today (microsoft/microsoft-ui-xaml#3469),
|
||||
// but other AT can subscribe and we keep parity with the toolkit.
|
||||
const auto newState = newValue ? ExpandCollapseState::Expanded : ExpandCollapseState::Collapsed;
|
||||
const auto oldState = newValue ? ExpandCollapseState::Collapsed : ExpandCollapseState::Expanded;
|
||||
RaisePropertyChangedEvent(ExpandCollapsePatternIdentifiers::ExpandCollapseStateProperty(), box_value(oldState), box_value(newState));
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::Style SettingsExpanderItemStyleSelector::SelectStyleCore(const winrt::Windows::Foundation::IInspectable& /*item*/, const Windows::UI::Xaml::DependencyObject& container)
|
||||
{
|
||||
// When the prepared container is a clickable SettingsCard, give it the
|
||||
// clickable item style (which adds the right padding for the chevron).
|
||||
// Otherwise fall back to the default item style.
|
||||
if (const auto card{ container.try_as<Editor::SettingsCard>() })
|
||||
{
|
||||
if (card.IsClickEnabled())
|
||||
{
|
||||
return _ClickableStyle;
|
||||
}
|
||||
}
|
||||
return _DefaultStyle;
|
||||
}
|
||||
}
|
||||
97
src/cascadia/TerminalSettingsEditor/SettingsExpander.h
Normal file
97
src/cascadia/TerminalSettingsEditor/SettingsExpander.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- SettingsExpander
|
||||
|
||||
Abstract:
|
||||
- A collapsable container for grouping multiple SettingsCards. Based
|
||||
on the Windows Community Toolkit's SettingsExpander.
|
||||
|
||||
Author(s):
|
||||
- Carlos Zamora - May 2026 (port from CommunityToolkit.WinUI.Controls.SettingsExpander)
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SettingsExpander.g.h"
|
||||
#include "SettingsExpanderAutomationPeer.g.h"
|
||||
#include "SettingsExpanderItemStyleSelector.g.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct SettingsExpander : SettingsExpanderT<SettingsExpander>
|
||||
{
|
||||
public:
|
||||
SettingsExpander();
|
||||
|
||||
void OnApplyTemplate();
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationPeer OnCreateAutomationPeer();
|
||||
|
||||
til::typed_event<Editor::SettingsExpander, Windows::Foundation::IInspectable> Expanded;
|
||||
til::typed_event<Editor::SettingsExpander, Windows::Foundation::IInspectable> Collapsed;
|
||||
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Header);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Description);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Controls::IconElement, HeaderIcon);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, Content);
|
||||
DEPENDENCY_PROPERTY(bool, IsExpanded);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::UIElement, ItemsHeader);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::UIElement, ItemsFooter);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable>, Items);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, ItemsSource);
|
||||
DEPENDENCY_PROPERTY(Windows::Foundation::IInspectable, ItemTemplate);
|
||||
DEPENDENCY_PROPERTY(Windows::UI::Xaml::Controls::StyleSelector, ItemContainerStyleSelector);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnIsExpandedChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _OnItemsConnectedPropertyChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
|
||||
void _SetAccessibleName();
|
||||
void _UpdateItemsSource();
|
||||
void _SubscribeToItemsVectorChanged();
|
||||
void _ApplyItemContainerStyles();
|
||||
|
||||
Windows::UI::Xaml::Controls::ItemsControl _itemsHost{ nullptr };
|
||||
Windows::Foundation::Collections::IObservableVector<Windows::Foundation::IInspectable>::VectorChanged_revoker _itemsVectorChangedRevoker;
|
||||
};
|
||||
|
||||
// AutomationPeer for SettingsExpander. Reports class name and falls back to
|
||||
// Header text for the name when AutomationProperties.Name is unset.
|
||||
struct SettingsExpanderAutomationPeer : SettingsExpanderAutomationPeerT<SettingsExpanderAutomationPeer>
|
||||
{
|
||||
public:
|
||||
SettingsExpanderAutomationPeer(const Editor::SettingsExpander& owner);
|
||||
|
||||
Windows::UI::Xaml::Automation::Peers::AutomationControlType GetAutomationControlTypeCore() const;
|
||||
hstring GetClassNameCore() const;
|
||||
hstring GetNameCore() const;
|
||||
|
||||
void RaiseExpandedChangedEvent(bool newValue);
|
||||
};
|
||||
|
||||
// StyleSelector used by SettingsExpander to choose between a clickable vs.
|
||||
// non-clickable SettingsCard container style for items in its ItemsControl.
|
||||
// Ported from the Windows Community Toolkit's SettingsExpanderItemStyleSelector.
|
||||
struct SettingsExpanderItemStyleSelector : SettingsExpanderItemStyleSelectorT<SettingsExpanderItemStyleSelector>
|
||||
{
|
||||
SettingsExpanderItemStyleSelector() = default;
|
||||
|
||||
Windows::UI::Xaml::Style SelectStyleCore(const Windows::Foundation::IInspectable& item, const Windows::UI::Xaml::DependencyObject& container);
|
||||
|
||||
WINRT_PROPERTY(Windows::UI::Xaml::Style, DefaultStyle, nullptr);
|
||||
WINRT_PROPERTY(Windows::UI::Xaml::Style, ClickableStyle, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(SettingsExpander);
|
||||
BASIC_FACTORY(SettingsExpanderAutomationPeer);
|
||||
BASIC_FACTORY(SettingsExpanderItemStyleSelector);
|
||||
}
|
||||
62
src/cascadia/TerminalSettingsEditor/SettingsExpander.idl
Normal file
62
src/cascadia/TerminalSettingsEditor/SettingsExpander.idl
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[contentproperty("Content")]
|
||||
[default_interface] runtimeclass SettingsExpander : Windows.UI.Xaml.Controls.Control
|
||||
{
|
||||
SettingsExpander();
|
||||
|
||||
Object Header;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderProperty { get; };
|
||||
|
||||
Object Description;
|
||||
static Windows.UI.Xaml.DependencyProperty DescriptionProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.Controls.IconElement HeaderIcon;
|
||||
static Windows.UI.Xaml.DependencyProperty HeaderIconProperty { get; };
|
||||
|
||||
Object Content;
|
||||
static Windows.UI.Xaml.DependencyProperty ContentProperty { get; };
|
||||
|
||||
Boolean IsExpanded;
|
||||
static Windows.UI.Xaml.DependencyProperty IsExpandedProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.UIElement ItemsHeader;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemsHeaderProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.UIElement ItemsFooter;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemsFooterProperty { get; };
|
||||
|
||||
Windows.Foundation.Collections.IVector<Object> Items;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemsProperty { get; };
|
||||
|
||||
Object ItemsSource;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemsSourceProperty { get; };
|
||||
|
||||
Object ItemTemplate;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemTemplateProperty { get; };
|
||||
|
||||
Windows.UI.Xaml.Controls.StyleSelector ItemContainerStyleSelector;
|
||||
static Windows.UI.Xaml.DependencyProperty ItemContainerStyleSelectorProperty { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<SettingsExpander, Object> Expanded;
|
||||
event Windows.Foundation.TypedEventHandler<SettingsExpander, Object> Collapsed;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SettingsExpanderAutomationPeer : Windows.UI.Xaml.Automation.Peers.FrameworkElementAutomationPeer
|
||||
{
|
||||
SettingsExpanderAutomationPeer(SettingsExpander owner);
|
||||
|
||||
void RaiseExpandedChangedEvent(Boolean newValue);
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SettingsExpanderItemStyleSelector : Windows.UI.Xaml.Controls.StyleSelector
|
||||
{
|
||||
SettingsExpanderItemStyleSelector();
|
||||
|
||||
Windows.UI.Xaml.Style DefaultStyle;
|
||||
Windows.UI.Xaml.Style ClickableStyle;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "StringDefaultTemplateSelector.h"
|
||||
#include "StringDefaultTemplateSelector.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DataTemplate StringDefaultTemplateSelector::SelectTemplateCore(const IInspectable& item, const DependencyObject& /*container*/)
|
||||
{
|
||||
return SelectTemplateCore(item);
|
||||
}
|
||||
|
||||
DataTemplate StringDefaultTemplateSelector::SelectTemplateCore(const IInspectable& item)
|
||||
{
|
||||
if (const auto pv{ item.try_as<IPropertyValue>() }; pv && pv.Type() == PropertyType::String)
|
||||
{
|
||||
return _StringTemplate;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StringDefaultTemplateSelector.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct StringDefaultTemplateSelector : StringDefaultTemplateSelectorT<StringDefaultTemplateSelector>
|
||||
{
|
||||
StringDefaultTemplateSelector() = default;
|
||||
|
||||
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item, const winrt::Windows::UI::Xaml::DependencyObject& container);
|
||||
Windows::UI::Xaml::DataTemplate SelectTemplateCore(const winrt::Windows::Foundation::IInspectable& item);
|
||||
|
||||
WINRT_PROPERTY(winrt::Windows::UI::Xaml::DataTemplate, StringTemplate, nullptr);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(StringDefaultTemplateSelector);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
[default_interface] runtimeclass StringDefaultTemplateSelector : Windows.UI.Xaml.Controls.DataTemplateSelector
|
||||
{
|
||||
StringDefaultTemplateSelector();
|
||||
|
||||
Windows.UI.Xaml.DataTemplate StringTemplate;
|
||||
}
|
||||
}
|
||||
179
src/cascadia/TerminalSettingsEditor/StyleExtensions.cpp
Normal file
179
src/cascadia/TerminalSettingsEditor/StyleExtensions.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "StyleExtensions.h"
|
||||
#include "StyleExtensions.g.cpp"
|
||||
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
DependencyProperty StyleExtensions::_resourcesProperty{ nullptr };
|
||||
ResourceDictionary StyleExtensions::_sharedImplicitStylesDictionary{ nullptr };
|
||||
|
||||
DependencyProperty StyleExtensions::ResourcesProperty()
|
||||
{
|
||||
_InitializeProperties();
|
||||
return _resourcesProperty;
|
||||
}
|
||||
|
||||
void StyleExtensions::_InitializeProperties()
|
||||
{
|
||||
if (!_resourcesProperty)
|
||||
{
|
||||
_resourcesProperty = DependencyProperty::RegisterAttached(
|
||||
L"Resources",
|
||||
xaml_typename<ResourceDictionary>(),
|
||||
xaml_typename<Editor::StyleExtensions>(),
|
||||
PropertyMetadata{ nullptr, PropertyChangedCallback{ &StyleExtensions::_OnResourcesChanged } });
|
||||
}
|
||||
}
|
||||
|
||||
ResourceDictionary StyleExtensions::GetResources(const DependencyObject& target)
|
||||
{
|
||||
return target.GetValue(ResourcesProperty()).try_as<ResourceDictionary>();
|
||||
}
|
||||
|
||||
void StyleExtensions::SetResources(const DependencyObject& target, const ResourceDictionary& value)
|
||||
{
|
||||
target.SetValue(ResourcesProperty(), value);
|
||||
}
|
||||
|
||||
void StyleExtensions::_OnResourcesChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& e)
|
||||
{
|
||||
const auto frameworkElement{ d.try_as<FrameworkElement>() };
|
||||
if (!frameworkElement)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto elementResources{ frameworkElement.Resources() };
|
||||
if (!elementResources)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto mergedDictionaries{ elementResources.MergedDictionaries() };
|
||||
if (!mergedDictionaries)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the previously-merged dictionary (if any). Resource dictionaries
|
||||
// are reference types so IndexOf walks by identity, which is exactly what
|
||||
// we want: the same Setter.Value is shared across every element that uses
|
||||
// this Style, so the OldValue we see here is the exact instance we
|
||||
// appended last time the property changed.
|
||||
if (const auto oldDict{ e.OldValue().try_as<ResourceDictionary>() })
|
||||
{
|
||||
uint32_t index{ 0 };
|
||||
if (mergedDictionaries.IndexOf(oldDict, index))
|
||||
{
|
||||
mergedDictionaries.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new dictionary directly. We deliberately do NOT clone the way
|
||||
// the WCT C# port does: ResourceDictionary is sealed (so we can't tag a
|
||||
// private subclass like the toolkit), and a deep clone would have to
|
||||
// copy the inline dictionary's Source URI — which XAML may leave as a
|
||||
// relative string like "CommonResources.xaml" and which the runtime
|
||||
// then rejects with "is not a valid absolute URI". Sharing the same
|
||||
// dictionary across elements is fine: each element's MergedDictionaries
|
||||
// only holds a reference, and implicit styles are designed to be shared.
|
||||
if (const auto newDict{ e.NewValue().try_as<ResourceDictionary>() })
|
||||
{
|
||||
mergedDictionaries.Append(newDict);
|
||||
|
||||
if (frameworkElement.IsLoaded())
|
||||
{
|
||||
_ForceControlToReloadThemeResources(frameworkElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StyleExtensions::_ForceControlToReloadThemeResources(const FrameworkElement& element)
|
||||
{
|
||||
// Toggle RequestedTheme to force the framework to re-resolve all
|
||||
// {ThemeResource} bindings under this element. Required when the
|
||||
// style is applied to an already-loaded element. Matches the toolkit.
|
||||
const auto currentTheme{ element.RequestedTheme() };
|
||||
element.RequestedTheme(currentTheme == ElementTheme::Dark ? ElementTheme::Light : ElementTheme::Dark);
|
||||
element.RequestedTheme(currentTheme);
|
||||
}
|
||||
|
||||
// Lazy singleton: loads SettingsControlsImplicitStyles.xaml exactly once
|
||||
// for the process lifetime. We do NOT append this dictionary itself to any
|
||||
// element's MergedDictionaries — that triggers "Element is already the
|
||||
// child of another element" once a second element tries to merge it.
|
||||
// Instead, EnsureImplicitStylesMergedInto copies the dictionary's entries
|
||||
// (Style references) into the target's own Resources. Style instances are
|
||||
// reference types but not UIElements, so sharing them across multiple
|
||||
// elements' Resources collections is safe.
|
||||
ResourceDictionary StyleExtensions::_SharedImplicitStylesDictionary()
|
||||
{
|
||||
if (!_sharedImplicitStylesDictionary)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto dict{ ResourceDictionary{} };
|
||||
dict.Source(winrt::Windows::Foundation::Uri{ L"ms-appx:///Microsoft.Terminal.Settings.Editor/SettingsControlsImplicitStyles.xaml" });
|
||||
_sharedImplicitStylesDictionary = dict;
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
return _sharedImplicitStylesDictionary;
|
||||
}
|
||||
|
||||
void StyleExtensions::EnsureImplicitStylesMergedInto(const FrameworkElement& target)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const auto resources{ target.Resources() };
|
||||
if (!resources)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Idempotency marker: if we've already populated this element's
|
||||
// Resources with the implicit styles, skip. Cheap to check
|
||||
// (one hash lookup), independent of MergedDictionaries.
|
||||
const auto markerKey{ box_value(hstring{ L"__SettingsControls_ImplicitStyles" }) };
|
||||
if (resources.HasKey(markerKey))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto sharedDict{ _SharedImplicitStylesDictionary() };
|
||||
if (!sharedDict)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy each entry (Style or other resource) from the shared loaded
|
||||
// dictionary into the target's Resources. Style instances are
|
||||
// reference types that can safely be shared across multiple
|
||||
// element Resources collections (unlike UIElements, which have a
|
||||
// single-parent constraint). We deliberately do NOT
|
||||
// MergedDictionaries.Append(sharedDict) — that path throws
|
||||
// "Element is already the child of another element" once a second
|
||||
// element tries to merge the same shared dict.
|
||||
for (const auto& kv : sharedDict)
|
||||
{
|
||||
if (!resources.HasKey(kv.Key()))
|
||||
{
|
||||
resources.Insert(kv.Key(), kv.Value());
|
||||
}
|
||||
}
|
||||
resources.Insert(markerKey, box_value(true));
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
}
|
||||
35
src/cascadia/TerminalSettingsEditor/StyleExtensions.h
Normal file
35
src/cascadia/TerminalSettingsEditor/StyleExtensions.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StyleExtensions.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
struct StyleExtensions
|
||||
{
|
||||
StyleExtensions() = default;
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty ResourcesProperty();
|
||||
|
||||
static Windows::UI::Xaml::ResourceDictionary GetResources(const Windows::UI::Xaml::DependencyObject& target);
|
||||
static void SetResources(const Windows::UI::Xaml::DependencyObject& target, const Windows::UI::Xaml::ResourceDictionary& value);
|
||||
|
||||
static void EnsureImplicitStylesMergedInto(const Windows::UI::Xaml::FrameworkElement& target);
|
||||
|
||||
private:
|
||||
static void _InitializeProperties();
|
||||
static void _OnResourcesChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& e);
|
||||
static void _ForceControlToReloadThemeResources(const Windows::UI::Xaml::FrameworkElement& element);
|
||||
static Windows::UI::Xaml::ResourceDictionary _SharedImplicitStylesDictionary();
|
||||
|
||||
static Windows::UI::Xaml::DependencyProperty _resourcesProperty;
|
||||
static Windows::UI::Xaml::ResourceDictionary _sharedImplicitStylesDictionary;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(StyleExtensions);
|
||||
}
|
||||
28
src/cascadia/TerminalSettingsEditor/StyleExtensions.idl
Normal file
28
src/cascadia/TerminalSettingsEditor/StyleExtensions.idl
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
// Attached property that lets a Style merge an extra ResourceDictionary into
|
||||
// the target FrameworkElement's Resources.MergedDictionaries. Used by
|
||||
// SettingsCard / SettingsExpander to inject right-aligned ToggleSwitch and
|
||||
// sized Slider / ComboBox / TextBox defaults so children laid out inside a
|
||||
// card look right out of the box. Mirrors the Windows Community Toolkit's
|
||||
// CommunityToolkit.WinUI.Controls.StyleExtensions.
|
||||
static runtimeclass StyleExtensions
|
||||
{
|
||||
static Windows.UI.Xaml.DependencyProperty ResourcesProperty { get; };
|
||||
|
||||
static Windows.UI.Xaml.ResourceDictionary GetResources(Windows.UI.Xaml.DependencyObject target);
|
||||
static void SetResources(Windows.UI.Xaml.DependencyObject target, Windows.UI.Xaml.ResourceDictionary value);
|
||||
|
||||
// Idempotently merges the project's SettingsControlsImplicitStyles.xaml
|
||||
// dictionary into the target's Resources.MergedDictionaries. Called from
|
||||
// SettingsCard / SettingsExpander OnApplyTemplate to give children
|
||||
// (ToggleSwitch / Slider / ComboBox / TextBox) sensible Windows 11
|
||||
// defaults without each call site setting Style explicitly. Loaded from
|
||||
// C++ rather than via the attached DP because the WCT Setter.Value
|
||||
// pattern crashes WinUI 2 in this codebase.
|
||||
static void EnsureImplicitStylesMergedInto(Windows.UI.Xaml.FrameworkElement target);
|
||||
}
|
||||
}
|
||||
@@ -133,11 +133,38 @@ struct HasScrollViewer
|
||||
{
|
||||
if (const auto& controlToFocus{ page->FindName(elementName).try_as<winrt::Windows::UI::Xaml::Controls::Control>() })
|
||||
{
|
||||
// We need to wait for the page to be loaded
|
||||
// or else the call to StartBringIntoView()
|
||||
// will end up doing nothing
|
||||
controlToFocus.StartBringIntoView();
|
||||
controlToFocus.Focus(winrt::Windows::UI::Xaml::FocusState::Programmatic);
|
||||
// Walk up the visual tree from the deep-link target and
|
||||
// expand any ancestor expanders so the target is actually
|
||||
// visible. This handles both:
|
||||
// - Plain muxc:Expander instances used as section groupings
|
||||
// - SettingContainer instances using an expander style
|
||||
// (i.e. ExpanderSettingContainerStyleWithComplexPreview).
|
||||
winrt::Windows::UI::Xaml::DependencyObject ancestor{ controlToFocus };
|
||||
while (ancestor)
|
||||
{
|
||||
if (const auto& expander{ ancestor.try_as<winrt::Microsoft::UI::Xaml::Controls::Expander>() })
|
||||
{
|
||||
expander.IsExpanded(true);
|
||||
}
|
||||
else if (const auto& settingContainer{ ancestor.try_as<winrt::Microsoft::Terminal::Settings::Editor::SettingContainer>() })
|
||||
{
|
||||
settingContainer.SetExpanded(true);
|
||||
}
|
||||
ancestor = winrt::Windows::UI::Xaml::Media::VisualTreeHelper::GetParent(ancestor);
|
||||
}
|
||||
|
||||
// Expanding ancestor expanders triggers asynchronous
|
||||
// layout updates. Defer the bring-into-view + focus to
|
||||
// the next dispatcher tick so the target's final layout
|
||||
// position is known before we scroll/focus.
|
||||
page->Dispatcher().RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, [weakControl{ winrt::weak_ref{ controlToFocus } }]() {
|
||||
if (const auto control = weakControl.get())
|
||||
{
|
||||
control.UpdateLayout();
|
||||
control.StartBringIntoView();
|
||||
control.Focus(winrt::Windows::UI::Xaml::FocusState::Programmatic);
|
||||
}
|
||||
});
|
||||
}
|
||||
page->_loadedRevoker.revoke();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <til/winrt.h>
|
||||
|
||||
#include "Converters.g.cpp"
|
||||
#include "StringNotEmptyToVisibilityConverter.g.cpp"
|
||||
|
||||
#pragma warning(disable : 26497) // We will make these functions constexpr, as they are part of an ABI boundary.
|
||||
#pragma warning(disable : 26440) // The function ... can be declared as noexcept.
|
||||
@@ -80,4 +81,22 @@ namespace winrt::Microsoft::Terminal::UI::implementation
|
||||
{
|
||||
return fontWeight.Weight;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable StringNotEmptyToVisibilityConverter::Convert(winrt::Windows::Foundation::IInspectable const& value, winrt::Windows::UI::Xaml::Interop::TypeName const& /*targetType*/, winrt::Windows::Foundation::IInspectable const& /*parameter*/, winrt::hstring const& /*language*/)
|
||||
{
|
||||
winrt::hstring text;
|
||||
if (value)
|
||||
{
|
||||
if (const auto& str{ value.try_as<winrt::hstring>() })
|
||||
{
|
||||
text = *str;
|
||||
}
|
||||
}
|
||||
return winrt::box_value(Converters::StringNotEmptyToVisibility(text));
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::IInspectable StringNotEmptyToVisibilityConverter::ConvertBack(winrt::Windows::Foundation::IInspectable const& /*value*/, winrt::Windows::UI::Xaml::Interop::TypeName const& /*targetType*/, winrt::Windows::Foundation::IInspectable const& /*parameter*/, winrt::hstring const& /*language*/)
|
||||
{
|
||||
throw winrt::hresult_not_implemented();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "Converters.g.h"
|
||||
#include "StringNotEmptyToVisibilityConverter.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::UI::implementation
|
||||
{
|
||||
@@ -29,11 +30,18 @@ namespace winrt::Microsoft::Terminal::UI::implementation
|
||||
static winrt::Windows::UI::Xaml::Media::SolidColorBrush ColorToBrush(winrt::Windows::UI::Color color);
|
||||
static double FontWeightToDouble(winrt::Windows::UI::Text::FontWeight fontWeight);
|
||||
};
|
||||
|
||||
struct StringNotEmptyToVisibilityConverter : StringNotEmptyToVisibilityConverterT<StringNotEmptyToVisibilityConverter>
|
||||
{
|
||||
StringNotEmptyToVisibilityConverter() = default;
|
||||
|
||||
winrt::Windows::Foundation::IInspectable Convert(winrt::Windows::Foundation::IInspectable const& value, winrt::Windows::UI::Xaml::Interop::TypeName const& targetType, winrt::Windows::Foundation::IInspectable const& parameter, winrt::hstring const& language);
|
||||
winrt::Windows::Foundation::IInspectable ConvertBack(winrt::Windows::Foundation::IInspectable const& value, winrt::Windows::UI::Xaml::Interop::TypeName const& targetType, winrt::Windows::Foundation::IInspectable const& parameter, winrt::hstring const& language);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::UI::factory_implementation
|
||||
{
|
||||
struct Converters : ConvertersT<Converters, implementation::Converters>
|
||||
{
|
||||
};
|
||||
BASIC_FACTORY(Converters);
|
||||
BASIC_FACTORY(StringNotEmptyToVisibilityConverter);
|
||||
}
|
||||
|
||||
@@ -27,4 +27,12 @@ namespace Microsoft.Terminal.UI
|
||||
static Windows.UI.Xaml.Media.SolidColorBrush ColorToBrush(Windows.UI.Color color);
|
||||
static Double FontWeightToDouble(Windows.UI.Text.FontWeight fontWeight);
|
||||
}
|
||||
|
||||
// IValueConverter wrapper around Converters.StringNotEmptyToVisibility, for use
|
||||
// in classic {Binding} scenarios (e.g. ControlTemplates) where x:Bind function
|
||||
// syntax against the static Converters helpers isn't available.
|
||||
runtimeclass StringNotEmptyToVisibilityConverter : [default] Windows.UI.Xaml.Data.IValueConverter
|
||||
{
|
||||
StringNotEmptyToVisibilityConverter();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <Windows.Graphics.Imaging.Interop.h>
|
||||
|
||||
#include <winrt/Windows.UI.Xaml.Controls.h>
|
||||
#include <winrt/Windows.UI.Xaml.Data.h>
|
||||
#include <winrt/Windows.UI.Xaml.Markup.h>
|
||||
#include <winrt/Windows.UI.Xaml.Input.h>
|
||||
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
|
||||
|
||||
@@ -56,11 +56,6 @@ $ClassMap = @{
|
||||
NavigationParam = "ColorSchemes_Nav"
|
||||
SubPage = "BreadcrumbSubPage::None"
|
||||
}
|
||||
"Microsoft::Terminal::Settings::Editor::Rendering" = @{
|
||||
ResourceName = "Nav_Rendering/Content"
|
||||
NavigationParam = "Rendering_Nav"
|
||||
SubPage = "BreadcrumbSubPage::None"
|
||||
}
|
||||
"Microsoft::Terminal::Settings::Editor::Compatibility" = @{
|
||||
ResourceName = "Nav_Compatibility/Content"
|
||||
NavigationParam = "Compatibility_Nav"
|
||||
@@ -85,6 +80,7 @@ $ClassMap = @{
|
||||
ResourceName = "Nav_ProfileDefaults/Content"
|
||||
NavigationParam = "GlobalProfile_Nav"
|
||||
SubPage = "BreadcrumbSubPage::None"
|
||||
SecondaryLabel = "Nav_Profiles/Content"
|
||||
}
|
||||
"Microsoft::Terminal::Settings::Editor::Profiles_Appearance" = @{
|
||||
ResourceName = "Nav_ProfileDefaults/Content"
|
||||
@@ -105,6 +101,12 @@ $ClassMap = @{
|
||||
ResourceName = "Nav_AddNewProfile/Content"
|
||||
NavigationParam = "AddProfile"
|
||||
SubPage = "BreadcrumbSubPage::None"
|
||||
SecondaryLabel = "Nav_Profiles/Content"
|
||||
}
|
||||
"Microsoft::Terminal::Settings::Editor::Profiles" = @{
|
||||
ResourceName = "Nav_Profiles/Content"
|
||||
NavigationParam = "Profiles_Nav"
|
||||
SubPage = "BreadcrumbSubPage::None"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +158,7 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
|
||||
NavigationParam = $ClassMap[$pageClass].NavigationParam
|
||||
SubPage = $ClassMap[$pageClass].SubPage
|
||||
ElementName = $null # No specific element to navigate to, for the page itself
|
||||
SecondaryLabel = $ClassMap[$pageClass].SecondaryLabel # Resource name for the result's sub-text (i.e. parent page name); $null if none
|
||||
File = $filename
|
||||
}
|
||||
}
|
||||
@@ -189,6 +192,7 @@ foreach ($xamlFile in Get-ChildItem -Path $SourceDir -Filter *.xaml)
|
||||
NavigationParam = $ClassMap[$pageClass].NavigationParam
|
||||
SubPage = $ClassMap[$pageClass].SubPage
|
||||
ElementName = "AddNewButton"
|
||||
SecondaryLabel = $ClassMap[$pageClass].SecondaryLabel
|
||||
File = $filename
|
||||
}
|
||||
}
|
||||
@@ -285,8 +289,9 @@ function FormatEntry($e)
|
||||
$formattedResourceName = 'USES_RESOURCE(L"{0}")' -f $e.ResourceName
|
||||
$formattedNavigationParam = 'L"{0}"' -f $e.NavigationParam # null Navigation param resolves to empty string
|
||||
$formattedElementName = 'L"{0}"' -f $e.ElementName
|
||||
$formattedSecondaryLabel = [string]::IsNullOrEmpty($e.SecondaryLabel) ? 'L""' : ('USES_RESOURCE(L"{0}")' -f $e.SecondaryLabel)
|
||||
|
||||
return " IndexEntry{{ {0}, {1}, {2}, {3} }}, // {4}" -f ($formattedResourceName, $formattedNavigationParam, $e.SubPage, $formattedElementName, $e.File)
|
||||
return " IndexEntry{{ {0}, {1}, {2}, {3}, {4} }}, // {5}" -f ($formattedResourceName, $formattedNavigationParam, $e.SubPage, $formattedElementName, $formattedSecondaryLabel, $e.File)
|
||||
}
|
||||
|
||||
function FormatEntries($es) {
|
||||
@@ -294,7 +299,7 @@ function FormatEntries($es) {
|
||||
}
|
||||
|
||||
# Sort and remove duplicates
|
||||
$entries = $entries | Sort-Object ResourceName, ParentPage, NavigationParam, SubPage, ElementName, File -Unique
|
||||
$entries = $entries | Sort-Object ResourceName, ParentPage, NavigationParam, SubPage, ElementName, SecondaryLabel, File -Unique
|
||||
|
||||
$buildTimeEntries = @()
|
||||
$profileEntries = @()
|
||||
@@ -350,6 +355,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
// x:Name of the SettingContainer to navigate to on the page (i.e. "DefaultProfile")
|
||||
wil::zwstring_view ElementName;
|
||||
|
||||
// Resource name of the search result's secondary label (i.e. parent page name like "Nav_Profiles/Content").
|
||||
// Empty if the entry has no secondary label.
|
||||
// NOTE: wrapped in USES_RESOURCE() like ResourceName when non-empty.
|
||||
wil::zwstring_view SecondaryLabelResourceName;
|
||||
};
|
||||
|
||||
const std::array<IndexEntry, $($buildTimeEntries.Count)>& LoadBuildTimeIndex();
|
||||
|
||||
Reference in New Issue
Block a user