terminal/src/cascadia/TerminalSettingsEditor/ColorSchemes.xaml
Mike Griese 29be8564f6
Manually dismiss popups when the window moves, or the SUI scrolls (#10922)
## Summary of the Pull Request

BODGY!

This solution was suggested in https://github.com/microsoft/microsoft-ui-xaml/issues/4554#issuecomment-887815332.

When the window moves, or when a ScrollViewer scrolls, dismiss any popups that are visible. This happens automagically when an app is a real XAML app, but it doesn't work for XAML Islands.

## References
* upstream at https://github.com/microsoft/microsoft-ui-xaml/issues/4554

## PR Checklist
* [x] Closes #9320
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

Unfortunately, we've got a bunch of scroll viewers in our SUI. So I did something bodgyx2 to make our life a little easier.

`DismissAllPopups` can be used to dismiss all popups for a particular UI element. However, we've got a bunch of pages with scroll viewers that may or may not have popups in them. Rather than define the same exact body for all their `ViewChanging` events, the `HasScrollViewer` struct will just do it for you!

Inside the `HasScrollViewer` stuct, we can't get at the `XamlRoot()` that our subclass implements. I mean, _we_ can, but when XAML does it's codegen, _XAML_ won't be able to figure it out.

Fortunately for us, we don't need to! The sender is a UIElement, so we can just get _their_ `XamlRoot()`.

So, you can fix this for any SUI page with just a simple 

```diff
-    <ScrollViewer>
+    <ScrollViewer ViewChanging="ViewChanging">
```

```diff
-    struct AddProfile : AddProfileT<AddProfile>
+    struct AddProfile : public HasScrollViewer<AddProfile>, AddProfileT<AddProfile>
```

## Validation Steps Performed

* the window doesn't close when you move it
* the popups _do_ close when you move the window
* the popups close when you scroll any SUI page
2021-08-16 13:41:17 +00:00

375 lines
20 KiB
XML

<!--
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under
the MIT License. See LICENSE in the project root for license information.
-->
<Page x:Class="Microsoft.Terminal.Settings.Editor.ColorSchemes"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: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:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="GroupHeaderStyle"
BasedOn="{StaticResource SubtitleTextBlockStyle}"
TargetType="TextBlock">
<Setter Property="Margin" Value="0,0,0,4" />
</Style>
<Style x:Key="ColorLabelStyle"
TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style x:Key="ColorTableGridStyle"
TargetType="Grid">
<Setter Property="RowSpacing" Value="10" />
<Setter Property="ColumnSpacing" Value="10" />
</Style>
<Style x:Key="ColorControlStyle"
TargetType="ContentControl">
<Setter Property="IsTabStop" Value="False" />
</Style>
<Style x:Key="ColorButtonStyle"
BasedOn="{StaticResource BaseButtonStyle}"
TargetType="Button">
<Setter Property="BorderBrush" Value="{StaticResource SystemBaseLowColor}" />
<Setter Property="Height" Value="30" />
<Setter Property="Width" Value="100" />
</Style>
<Style TargetType="ColorPicker">
<Setter Property="IsColorSliderVisible" Value="False" />
<Setter Property="IsColorChannelTextInputVisible" Value="False" />
<Setter Property="IsHexInputVisible" Value="True" />
<Setter Property="IsAlphaSliderVisible" Value="True" />
<Setter Property="IsAlphaTextInputVisible" Value="True" />
</Style>
<DataTemplate x:Key="ColorTableEntryTemplate"
x:DataType="local:ColorTableEntry">
<Button AutomationProperties.Name="{x:Bind Name}"
Background="{x:Bind local:Converters.ColorToBrush(Color), Mode=OneWay}"
Style="{StaticResource ColorButtonStyle}"
ToolTipService.ToolTip="{x:Bind Name}">
<Button.Resources>
<!-- Resources to colorize hover/pressed states based on the color of the button -->
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="{x:Bind local:Converters.LightenColor(Color), Mode=OneWay}" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="{x:Bind local:Converters.LightenColor(Color), Mode=OneWay}" />
</ResourceDictionary>
<!-- No High contrast dictionary, let's just leave that unchanged. -->
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Button.Resources>
<Button.Flyout>
<Flyout>
<muxc:ColorPicker ColorChanged="ColorPickerChanged"
Tag="{x:Bind Tag, Mode=OneWay}"
Color="{x:Bind Color, Mode=OneWay}" />
</Flyout>
</Button.Flyout>
</Button>
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
<ScrollViewer ViewChanging="ViewChanging">
<StackPanel Margin="{StaticResource StandardIndentMargin}"
Spacing="24">
<!-- Select Color and Add New Button -->
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal"
Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(IsRenaming), Mode=OneWay}">
<!-- Select a color scheme -->
<ComboBox x:Name="ColorSchemeComboBox"
ItemsSource="{x:Bind ColorSchemeList, Mode=OneWay}"
SelectedIndex="0"
SelectionChanged="ColorSchemeSelectionChanged"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="model:ColorScheme">
<TextBlock Text="{x:Bind Name, Mode=OneWay}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- Rename Button -->
<!-- Bind IsEnabled to prevent a the color scheme from returning from the dead -->
<Button x:Name="RenameButton"
x:Uid="Rename"
Click="Rename_Click"
IsEnabled="{x:Bind CanDeleteCurrentScheme, Mode=OneWay}"
Style="{StaticResource SmallButtonStyle}">
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE8AC;" />
</StackPanel>
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal"
Visibility="{x:Bind IsRenaming, Mode=OneWay}">
<!-- Shown when color scheme name is already in use -->
<muxc:TeachingTip x:Name="RenameErrorTip"
x:Uid="ColorScheme_RenameErrorTip" />
<!-- Name text box -->
<TextBox x:Name="NameBox"
PreviewKeyDown="NameBox_PreviewKeyDown"
Style="{StaticResource TextBoxSettingStyle}" />
<!-- Accept rename button -->
<Button x:Name="RenameAcceptButton"
x:Uid="RenameAccept"
Click="RenameAccept_Click"
Style="{StaticResource AccentSmallButtonStyle}">
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE8FB;" />
</StackPanel>
</Button>
<!-- Cancel rename button -->
<Button x:Name="RenameCancelButton"
x:Uid="RenameCancel"
Click="RenameCancel_Click"
Style="{StaticResource SmallButtonStyle}">
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE711;" />
</StackPanel>
</Button>
</StackPanel>
<!-- Add new button -->
<Button x:Name="AddNewButton"
Click="AddNew_Click"
Style="{StaticResource BrowseButtonStyle}">
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="{StaticResource StandardIconSize}"
Glyph="&#xE710;" />
<TextBlock x:Uid="ColorScheme_AddNewButton"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button>
</StackPanel>
<!-- Terminal Colors (Left Column) -->
<StackPanel x:Name="ColorPanel"
Spacing="48">
<StackPanel>
<TextBlock x:Uid="ColorScheme_TerminalColorsHeader"
Style="{StaticResource GroupHeaderStyle}" />
<Grid x:Name="ColorTableGrid"
Style="{StaticResource ColorTableGridStyle}">
<Grid.ColumnDefinitions>
<!-- Labels -->
<ColumnDefinition Width="Auto" />
<!-- Regular Colors -->
<ColumnDefinition Width="Auto" />
<!-- Bright Colors -->
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<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>
</StackPanel>
<!-- System Colors (Right Column) -->
<StackPanel>
<TextBlock x:Uid="ColorScheme_SystemColorsHeader"
Style="{StaticResource GroupHeaderStyle}" />
<Grid Style="{StaticResource ColorTableGridStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Foreground -->
<TextBlock x:Uid="ColorScheme_Foreground"
Grid.Row="0"
Grid.Column="0"
Style="{StaticResource ColorLabelStyle}" />
<ContentControl x:Name="ForegroundButton"
Grid.Row="0"
Grid.Column="1"
Content="{x:Bind CurrentForegroundColor, Mode=TwoWay}"
ContentTemplate="{StaticResource ColorTableEntryTemplate}"
Style="{StaticResource ColorControlStyle}" />
<!-- Background -->
<TextBlock x:Uid="ColorScheme_Background"
Grid.Row="1"
Grid.Column="0"
Style="{StaticResource ColorLabelStyle}" />
<ContentControl x:Name="BackgroundButton"
Grid.Row="1"
Grid.Column="1"
Content="{x:Bind CurrentBackgroundColor, Mode=TwoWay}"
ContentTemplate="{StaticResource ColorTableEntryTemplate}"
Style="{StaticResource ColorControlStyle}" />
<!-- Cursor Color -->
<TextBlock x:Uid="ColorScheme_CursorColor"
Grid.Row="2"
Grid.Column="0"
Style="{StaticResource ColorLabelStyle}" />
<ContentControl x:Name="CursorColorButton"
Grid.Row="2"
Grid.Column="1"
Content="{x:Bind CurrentCursorColor, Mode=TwoWay}"
ContentTemplate="{StaticResource ColorTableEntryTemplate}"
Style="{StaticResource ColorControlStyle}" />
<!-- Selection Background -->
<TextBlock x:Uid="ColorScheme_SelectionBackground"
Grid.Row="3"
Grid.Column="0"
Style="{StaticResource ColorLabelStyle}" />
<ContentControl x:Name="SelectionBackgroundButton"
Grid.Row="3"
Grid.Column="1"
Content="{x:Bind CurrentSelectionBackgroundColor, Mode=TwoWay}"
ContentTemplate="{StaticResource ColorTableEntryTemplate}"
Style="{StaticResource ColorControlStyle}" />
</Grid>
</StackPanel>
</StackPanel>
<!-- Delete Button -->
<StackPanel Style="{StaticResource PivotStackStyle}">
<Button x:Name="DeleteButton"
IsEnabled="{x:Bind CanDeleteCurrentScheme, Mode=OneWay}"
Style="{StaticResource DeleteButtonStyle}">
<Button.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ButtonBackground"
Color="Firebrick" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="#C23232" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="#A21212" />
<SolidColorBrush x:Key="ButtonForeground"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="White" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ButtonBackground"
Color="Firebrick" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="#C23232" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="#A21212" />
<SolidColorBrush x:Key="ButtonForeground"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="White" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="White" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<SolidColorBrush x:Key="ButtonBackground"
Color="{ThemeResource SystemColorButtonFaceColor}" />
<SolidColorBrush x:Key="ButtonBackgroundPointerOver"
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="ButtonBackgroundPressed"
Color="{ThemeResource SystemColorHighlightColor}" />
<SolidColorBrush x:Key="ButtonForeground"
Color="{ThemeResource SystemColorButtonTextColor}" />
<SolidColorBrush x:Key="ButtonForegroundPointerOver"
Color="{ThemeResource SystemColorHighlightTextColor}" />
<SolidColorBrush x:Key="ButtonForegroundPressed"
Color="{ThemeResource SystemColorHighlightTextColor}" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Button.Resources>
<Button.Content>
<StackPanel Orientation="Horizontal">
<FontIcon Glyph="&#xE74D;" />
<TextBlock x:Uid="ColorScheme_DeleteButton"
Style="{StaticResource IconButtonTextBlockStyle}" />
</StackPanel>
</Button.Content>
<Button.Flyout>
<Flyout>
<StackPanel>
<TextBlock x:Uid="ColorScheme_DeleteConfirmationMessage"
Style="{StaticResource CustomFlyoutTextStyle}" />
<Button x:Uid="ColorScheme_DeleteConfirmationButton"
Click="DeleteConfirmation_Click" />
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
<TextBlock x:Name="DeleteButtonDisclaimer"
VerticalAlignment="Center"
Style="{StaticResource DisclaimerStyle}" />
</StackPanel>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<!--
Official guidance states that 640 is the breakpoint between small and medium devices.
Since MinWindowWidth is an inclusive range, we need to add 1 to it.
-->
<AdaptiveTrigger MinWindowWidth="641" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ColorPanel.Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ScrollViewer>
</Page>