terminal/src/cascadia/TerminalApp/CommandPalette.xaml
Carlos Zamora 2608e94822
Introduce TerminalSettingsModel project (#7667)
Introduces a new TerminalSettingsModel (TSM) project. This project is
responsible for (de)serializing and exposing Windows Terminal's settings
as WinRT objects.

## References
#885: TSM epic
#1564: Settings UI is dependent on this for data binding and settings access
#6904: TSM Spec

In the process of ripping out TSM from TerminalApp, a few other changes
were made to make this possible:
1. AppLogic's `ApplicationDisplayName` and `ApplicationVersion` was
   moved to `CascadiaSettings`
   - These are defined as static functions. They also no longer check if
     `AppLogic::Current()` is nullptr.
2. `enum LaunchMode` was moved from TerminalApp to TSM
3. `AzureConnectionType` and `TelnetConnectionType` were moved from the
   profile generators to their respective TerminalConnections
4. CascadiaSettings' `SettingsPath` and `DefaultSettingsPath` are
   exposed as `hstring` instead of `std::filesystem::path`
5. `Command::ExpandCommands()` was exposed via the IDL
   - This required some of the warnings to be saved to an `IVector`
     instead of `std::vector`, among some other small changes.
6. The localization resources had to be split into two halves.
   - Resource file linked in init.cpp. Verified at runtime thanks to the
     StaticResourceLoader.
7. Added constructors to some `ActionArgs`
8. Utils.h/cpp were moved to `cascadia/inc`. `JsonKey()` was moved to
   `JsonUtils`. Both TermApp and TSM need access to Utils.h/cpp.

A large amount of work includes moving to the new namespace
(`TerminalApp` --> `Microsoft::Terminal::Settings::Model`).

Fixing the tests had its own complications. Testing required us to split
up TSM into a DLL and LIB, similar to TermApp. Discussion on creating a
non-local test variant can be found in #7743.

Closes #885
2020-10-06 09:56:59 -07:00

281 lines
14 KiB
XML

<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information. -->
<UserControl
x:Class="TerminalApp.CommandPalette"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TerminalApp"
xmlns:mux="using:Microsoft.UI.Xaml.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Windows10version1903="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract, 8)"
xmlns:SettingsModel="using:Microsoft.Terminal.Settings.Model"
TabNavigation="Cycle"
IsTabStop="True"
AllowFocusOnInteraction="True"
PointerPressed="_rootPointerPressed"
PreviewKeyDown="_previewKeyDownHandler"
KeyDown="_keyDownHandler"
PreviewKeyUp="_keyUpHandler"
mc:Ignorable="d"
AutomationProperties.Name="{x:Bind ControlName, Mode=OneWay}">
<UserControl.Resources>
<ResourceDictionary>
<!-- ThemeShadow is only on 18362. This "Windows10version1903" bit
adds it conditionally -->
<Windows10version1903:ThemeShadow x:Name="CommandPaletteShadow" />
<!-- This creates an instance of our CommandKeyChordVisibilityConverter we can reference below -->
<local:EmptyStringVisibilityConverter x:Key="CommandKeyChordVisibilityConverter"/>
<local:EmptyStringVisibilityConverter x:Key="ParentCommandVisibilityConverter"/>
<local:HasNestedCommandsVisibilityConverter x:Key="HasNestedCommandsVisibilityConverter"/>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark">
<Style x:Key="CommandPaletteBackground" TargetType="Grid">
<Setter Property="Background" Value="#333333" />
</Style>
<!-- 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="1" />
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
<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">
<Style x:Key="CommandPaletteBackground" TargetType="Grid">
<Setter Property="Background" Value="#CCCCCC" />
</Style>
<!-- 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="CornerRadius" Value="1" />
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
<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">
<Style x:Key="CommandPaletteBackground" TargetType="Grid">
<Setter Property="Background" Value="{ThemeResource SystemColorWindowColor}" />
</Style>
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
<Style x:Key="KeyChordBorderStyle" TargetType="Border"/>
<Style x:Key="KeyChordTextBlockStyle" TargetType="TextBlock"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="6*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="8*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<!-- Setting the row/col span of this shadow backdrop is a bit of a hack. In
order to receive pointer events, an element needs to be _not_ transparent.
However, we want to be able to eat all the clicks outside the immediate
bounds of the command palette, and we don't want a semi-transparent overlay
over all of the UI. Fortunately, if we make this _shadowBackdrop the size of
the entire page, then it can be mostly transparent, and cause the root grid
to receive clicks _anywhere_ in its bounds. -->
<Grid
x:Name="_shadowBackdrop"
Background="Transparent"
Grid.Column="0"
Grid.Row="0"
Grid.ColumnSpan="3"
Grid.RowSpan="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</Grid>
<Grid
x:Name="_backdrop"
Style="{ThemeResource CommandPaletteBackground}"
CornerRadius="{ThemeResource ControlCornerRadius}"
PointerPressed="_backdropPointerPressed"
Margin="8"
Grid.Column="1"
Grid.Row="0"
Windows10version1903:Shadow="{StaticResource CommandPaletteShadow}"
HorizontalAlignment="Stretch"
VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox
Grid.Row="0"
x:Name="_searchBox"
Margin="8"
IsSpellCheckEnabled="False"
TextChanged="_filterTextChanged"
PlaceholderText="{x:Bind SearchBoxText, Mode=OneWay}"
Text="">
</TextBox>
<TextBlock
Padding="16, 0, 16, 4"
x:Name="_parentCommandText"
FontStyle="Italic"
Visibility="{x:Bind ParentCommandName,
Mode=OneWay,
Converter={StaticResource ParentCommandVisibilityConverter}}"
Grid.Row="1"
Text="{x:Bind ParentCommandName, Mode=OneWay}">
</TextBlock>
<TextBlock
Padding="16"
x:Name="_noMatchesText"
FontStyle="Italic"
Visibility="Collapsed"
Grid.Row="1"
Text="{x:Bind NoMatchesText, Mode=OneWay}">
</TextBlock>
<ListView
Grid.Row="2"
x:Name="_filteredActionsView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
SelectionMode="Single"
CanReorderItems="False"
AllowDrop="False"
IsItemClickEnabled="True"
ItemClick="_listItemClicked"
PreviewKeyDown="_keyDownHandler"
ItemsSource="{x:Bind FilteredActions}">
<ItemsControl.ItemTemplate >
<DataTemplate x:DataType="SettingsModel:Command">
<!-- This HorizontalContentAlignment="Stretch" is important
to make sure it takes the entire width of the line -->
<ListViewItem HorizontalContentAlignment="Stretch"
AutomationProperties.Name="{x:Bind Name, Mode=OneWay}"
AutomationProperties.AcceleratorKey="{x:Bind KeyChordText, Mode=OneWay}">
<Grid HorizontalAlignment="Stretch" ColumnSpacing="8" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16"/> <!-- icon -->
<ColumnDefinition Width="Auto"/> <!-- command label -->
<ColumnDefinition Width="*"/> <!-- key chord -->
<ColumnDefinition Width="16"/> <!-- gutter for scrollbar -->
</Grid.ColumnDefinitions>
<IconSourceElement
Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind IconSource, Mode=OneWay}"/>
<TextBlock Grid.Column="1"
HorizontalAlignment="Left"
Text="{x:Bind Name, Mode=OneWay}" />
<!-- The block for the key chord is only visible
when there's actual text set as the label. See
CommandKeyChordVisibilityConverter for details. -->
<Border
Grid.Column="2"
Visibility="{x:Bind KeyChordText,
Mode=OneWay,
Converter={StaticResource CommandKeyChordVisibilityConverter}}"
Style="{ThemeResource KeyChordBorderStyle}"
Padding="2,0,2,0"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<TextBlock
Style="{ThemeResource KeyChordTextBlockStyle}"
FontSize="12"
Text="{x:Bind KeyChordText, Mode=OneWay}" />
</Border>
<!-- xE70E is ChevronUp. Rotated 90 degrees, it's _ChevronRight_ -->
<FontIcon
FontFamily="Segoe MDL2 Assets"
Glyph="&#xE70E;"
HorizontalAlignment="Right"
Visibility="{x:Bind HasNestedCommands,
Mode=OneWay,
Converter={StaticResource HasNestedCommandsVisibilityConverter}}"
Grid.Column="2">
<FontIcon.RenderTransform>
<RotateTransform CenterX="0.5" CenterY="0.5" Angle="90"/>
</FontIcon.RenderTransform>
</FontIcon>
</Grid>
</ListViewItem>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
</Grid>
</Grid>
</UserControl>