terminal/src/cascadia/TerminalSettingsEditor/Launch.xaml
Carlos Zamora 3b7b200b59
Represent inheritance in Settings UI (#8919)
## Summary of the Pull Request
Introduces the `SettingContainer`. `SettingContainer` is used to wrap a setting in the settings UI and provide the following functionality:
- a reset button next to the header
- tooltips and automation properties for the setting being wrapped
- a comment stating if you are currently overriding a setting

## References
[Spec - Inheritance in Settings UI](https://github.com/microsoft/terminal/blob/main/doc/specs/%231564%20-%20Settings%20UI/cascading-settings.md)
#8804 - removes the ambiguity of leaving a setting blank
#6800 - Settings UI Epic
#8899 - Automation properties for Settings UI
#8768 - Keyboard Navigation

## PR Checklist
* [X] Closes #8804

## Detailed Description of the Pull Request / Additional comments
A few highlights in this PR:
- CommonResources.xaml:
  - we need to merge the SettingContainerStyle.xaml in there. Otherwise, XAML doesn't merge these files properly and can't apply the template.
- Profiles.cpp:
  - view model checks if the starting directory and background image were reset, to determine which value to show when unchecking the special value
  - `Profiles::OnNavigatedTo()` needs a property changed handler to update its own "Current<Setting>" and update the UI properly
- Profiles.xaml:
  - basically wrapped all of the settings we want to be inheritable in there
  - `Binding` is used instead of `x:Bind` in some places because `x:Bind` can't find the parent `SettingContainer` and gives you a compiler error.
- Resources.resw:
  - had to set the "HeaderText" and "HelpText" on each setting container. Does a decent localization burden, unfortunately.
- `SettingContainer` files
  - This operates by creating a template and applying that template over other settings. This allows you to inject the existing controls inside of this. This means that we need to provide our UIElements names and access/modify them via `OnApplyTemplate`
  - We had to remove the header from each individual control, and have `SettingContainer` be in charge of it. This allows us to add the reset button in there.
  - Due to the problem mentioned earlier about CommonResources.xaml, we can't reference anything from CommonResources.xaml.
  - Using `DependencyProperty` to let us set a few properties in the XML files. Particularly, `Has<Setting>` and `Clear<Setting>` are what do all the heavy lifting of interacting with the inheritance model.

## Demo
![Inheritance Demo](https://user-images.githubusercontent.com/11050425/106192086-92a56680-6160-11eb-838c-4ec0beb54965.gif)

## Validation Steps Performed
- Verified correct binding behavior with the following generic setting controls:
  - radio buttons
  - toggle switch
  - text block
  - slider
  - settings with browse buttons
  - the background image alignment control
  - controls with special check boxes (starting directory and background image)

## Next Steps
- The automation properties have been verified using NVDA. This is a part of resolving #8899.
- The override text is currently "Overrides a setting". According to #8269, we actually want to add a hyperlink in there that navigates to the parent profile object. This will be a follow-up task as it requires settings model changes.
2021-02-08 18:04:43 +00:00

104 lines
5.3 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.Launch"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.Terminal.Settings.Editor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:SettingsModel="using:Microsoft.Terminal.Settings.Model"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CommonResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:DataType="local:EnumEntry" x:Key="EnumRadioButtonTemplate">
<RadioButton Content="{x:Bind EnumName, Mode=OneWay}"/>
</DataTemplate>
<SettingsModel:IconPathConverter x:Key="IconSourceConverter"/>
<Style x:Key="LaunchSizeNumberBoxStyle" TargetType="muxc:NumberBox" BasedOn="{StaticResource NumberBoxSettingStyle}">
<Setter Property="SmallChange" Value="1"/>
<Setter Property="LargeChange" Value="10"/>
<Setter Property="Minimum" Value="1"/>
</Style>
</ResourceDictionary>
</Page.Resources>
<ScrollViewer>
<StackPanel>
<StackPanel Style="{StaticResource SettingsStackStyle}">
<!--Default Profile-->
<local:SettingContainer x:Uid="Globals_DefaultProfile"
Margin="0">
<ComboBox x:Name="DefaultProfile"
ItemsSource="{x:Bind State.Settings.AllProfiles, Mode=OneWay}"
SelectedItem="{x:Bind CurrentDefaultProfile, Mode=TwoWay}"
Style="{StaticResource ComboBoxSettingStyle}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="SettingsModel:Profile">
<Grid HorizontalAlignment="Stretch" ColumnSpacing="8">
<Grid.ColumnDefinitions>
<!-- icon -->
<ColumnDefinition Width="16"/>
<!-- profile name -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<IconSourceElement
Grid.Column="0"
Width="16"
Height="16"
IconSource="{x:Bind Icon,
Mode=OneWay,
Converter={StaticResource IconSourceConverter}}"/>
<TextBlock Grid.Column="1"
Text="{x:Bind Name}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</local:SettingContainer>
<!--Start on User Login-->
<local:SettingContainer x:Uid="Globals_StartOnUserLogin">
<ToggleSwitch IsOn="{x:Bind State.Settings.GlobalSettings.StartOnUserLogin, Mode=TwoWay}"/>
</local:SettingContainer>
<!--Launch Mode-->
<local:SettingContainer x:Uid="Globals_LaunchMode">
<muxc:RadioButtons SelectedItem="{x:Bind CurrentLaunchMode, Mode=TwoWay}"
ItemsSource="{x:Bind LaunchModeList}"
ItemTemplate="{StaticResource EnumRadioButtonTemplate}"/>
</local:SettingContainer>
</StackPanel>
<!--Launch Size-->
<StackPanel Style="{StaticResource SettingsStackStyle}">
<!--Header-->
<TextBlock x:Uid="Globals_LaunchSize"
Style="{StaticResource SubtitleTextBlockStyle}"/>
<!--Columns-->
<local:SettingContainer x:Uid="Globals_InitialCols"
Margin="0">
<muxc:NumberBox Value="{x:Bind State.Settings.GlobalSettings.InitialCols, Mode=TwoWay}"
Style="{StaticResource LaunchSizeNumberBoxStyle}"/>
</local:SettingContainer>
<!--Rows-->
<local:SettingContainer x:Uid="Globals_InitialRows">
<muxc:NumberBox Value="{x:Bind State.Settings.GlobalSettings.InitialRows, Mode=TwoWay}"
Style="{StaticResource LaunchSizeNumberBoxStyle}"/>
</local:SettingContainer>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Page>