Skip to content

Commit

Permalink
Make SUI previews readable by screen readers
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-zamora committed Jan 9, 2025
1 parent b25fe55 commit bdaebad
Show file tree
Hide file tree
Showing 17 changed files with 156 additions and 11 deletions.
42 changes: 42 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Appearances.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
// box, prevent it from ever being changed again.
_NotifyChanges(L"UseDesktopBGImage", L"BackgroundImageSettingsVisible");
}
else if (viewModelProperty == L"BackgroundImageAlignment")
{
_NotifyChanges(L"BackgroundImageAlignmentCurrentValue");
}
else if (viewModelProperty == L"Foreground")
{
_NotifyChanges(L"ForegroundPreview");
Expand Down Expand Up @@ -912,6 +916,44 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
BackgroundImagePath(path);
}

hstring AppearanceViewModel::BackgroundImageAlignmentCurrentValue() const
{
const auto alignment = BackgroundImageAlignment();
hstring alignmentResourceKey = L"Profile_BackgroundImageAlignment";
if (alignment == (ConvergedAlignment::Vertical_Center | ConvergedAlignment::Horizontal_Center))
{
alignmentResourceKey = alignmentResourceKey + L"Center";
}
else
{
// Append vertical alignment to the resource key
switch (alignment & static_cast<ConvergedAlignment>(0x0F))
{
case ConvergedAlignment::Vertical_Bottom:
alignmentResourceKey = alignmentResourceKey + L"Bottom";
break;
case ConvergedAlignment::Vertical_Top:
alignmentResourceKey = alignmentResourceKey + L"Top";
break;
}

// Append horizontal alignment to the resource key
switch (alignment & static_cast<ConvergedAlignment>(0xF0))
{
case ConvergedAlignment::Horizontal_Left:
alignmentResourceKey = alignmentResourceKey + L"Left";
break;
case ConvergedAlignment::Horizontal_Right:
alignmentResourceKey = alignmentResourceKey + L"Right";
break;
}
}
alignmentResourceKey = alignmentResourceKey + L"/[using:Windows.UI.Xaml.Controls]ToolTipService/ToolTip";

// We can't use the RS_ macro here because the resource key is dynamic
return GetLibraryResourceString(alignmentResourceKey);
}

bool AppearanceViewModel::UseDesktopBGImage()
{
return BackgroundImagePath() == L"desktopWallpaper";
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsEditor/Appearances.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
bool BackgroundImageSettingsVisible();
void SetBackgroundImageOpacityFromPercentageValue(double percentageValue);
void SetBackgroundImagePath(winrt::hstring path);
hstring BackgroundImageAlignmentCurrentValue() const;

void ClearColorScheme();
Editor::ColorSchemeViewModel CurrentColorScheme() const;
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsEditor/Appearances.idl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace Microsoft.Terminal.Settings.Editor

Boolean UseDesktopBGImage;
Boolean BackgroundImageSettingsVisible { get; };
String BackgroundImageAlignmentCurrentValue { get; };

void ClearColorScheme();
ColorSchemeViewModel CurrentColorScheme;
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Appearances.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
<!-- This currently only display the Dark color scheme, even if the user has a pair of schemes set. -->
<local:SettingContainer x:Uid="Profile_ColorScheme"
ClearSettingValue="{x:Bind Appearance.ClearColorScheme}"
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}">
Expand Down Expand Up @@ -209,6 +210,7 @@
x:Uid="Profile_Foreground"
ClearSettingValue="{x:Bind Appearance.ClearForeground}"
CurrentValue="{x:Bind Appearance.ForegroundPreview, Mode=OneWay}"
CurrentValueAccessibleName="{x:Bind Appearance.ForegroundPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasForeground, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.ForegroundOverrideSource, Mode=OneWay}"
Expand All @@ -224,6 +226,7 @@
x:Uid="Profile_Background"
ClearSettingValue="{x:Bind Appearance.ClearBackground}"
CurrentValue="{x:Bind Appearance.BackgroundPreview, Mode=OneWay}"
CurrentValueAccessibleName="{x:Bind Appearance.BackgroundPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasBackground, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.BackgroundOverrideSource, Mode=OneWay}"
Expand All @@ -239,6 +242,7 @@
x:Uid="Profile_SelectionBackground"
ClearSettingValue="{x:Bind Appearance.ClearSelectionBackground}"
CurrentValue="{x:Bind Appearance.SelectionBackgroundPreview, Mode=OneWay}"
CurrentValueAccessibleName="{x:Bind Appearance.SelectionBackgroundPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasSelectionBackground, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.SelectionBackgroundOverrideSource, Mode=OneWay}"
Expand Down Expand Up @@ -508,6 +512,7 @@
x:Uid="Profile_CursorColor"
ClearSettingValue="{x:Bind Appearance.ClearCursorColor}"
CurrentValue="{x:Bind Appearance.CursorColorPreview, Mode=OneWay}"
CurrentValueAccessibleName="{x:Bind Appearance.CursorColorPreview, Converter={StaticResource ColorToStringConverter}, Mode=OneWay}"
CurrentValueTemplate="{StaticResource ColorPreviewTemplate}"
HasSettingValue="{x:Bind Appearance.HasCursorColor, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.CursorColorOverrideSource, Mode=OneWay}"
Expand Down Expand Up @@ -568,6 +573,7 @@
<!-- Background Image Alignment -->
<local:SettingContainer x:Uid="Profile_BackgroundImageAlignment"
ClearSettingValue="{x:Bind Appearance.ClearBackgroundImageAlignment}"
CurrentValue="{x:Bind Appearance.BackgroundImageAlignmentCurrentValue, Mode=OneWay}"
HasSettingValue="{x:Bind Appearance.HasBackgroundImageAlignment, Mode=OneWay}"
SettingOverrideSource="{x:Bind Appearance.BackgroundImageAlignmentOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}"
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsEditor/Launch.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@
Style="{StaticResource ComboBoxSettingStyle}" />
</local:SettingContainer>

<!-- Launch Size -->
<local:SettingContainer x:Uid="Globals_LaunchSize"
CurrentValue="{x:Bind ViewModel.LaunchSizeCurrentValue, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
<Grid ColumnSpacing="10"
RowSpacing="10">
Expand Down
9 changes: 9 additions & 0 deletions src/cascadia/TerminalSettingsEditor/LaunchViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
{
_NotifyChanges(L"LaunchParametersCurrentValue");
}
else if (viewModelProperty == L"InitialCols" || viewModelProperty == L"InitialRows")
{
_NotifyChanges(L"LaunchSizeCurrentValue");
}
});
}

Expand Down Expand Up @@ -205,6 +209,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}

winrt::hstring LaunchViewModel::LaunchSizeCurrentValue() const
{
return winrt::hstring{ fmt::format(FMT_COMPILE(L"{} × {}"), InitialCols(), InitialRows()) };
}

winrt::hstring LaunchViewModel::LaunchParametersCurrentValue()
{
const auto launchModeString = CurrentLaunchMode().as<EnumEntry>()->EnumName();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsEditor/LaunchViewModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
winrt::Windows::Foundation::IInspectable CurrentLanguage();
void CurrentLanguage(const winrt::Windows::Foundation::IInspectable& tag);

winrt::hstring LaunchSizeCurrentValue() const;
winrt::hstring LaunchParametersCurrentValue();
double InitialPosX();
double InitialPosY();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsEditor/LaunchViewModel.idl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace Microsoft.Terminal.Settings.Editor
IInspectable CurrentDefaultInputScope;
IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> DefaultInputScopeList { get; };

String LaunchSizeCurrentValue { get; };
String LaunchParametersCurrentValue { get; };
Double InitialPosX;
Double InitialPosY;
Expand Down
9 changes: 9 additions & 0 deletions src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
return _profile.Orphaned();
}

hstring ProfileViewModel::TabTitlePreview() const
{
if (const auto tabTitle{ TabTitle() }; !tabTitle.empty())
{
return tabTitle;
}
return RS_(L"Profile_TabTitleNone");
}

Editor::AppearanceViewModel ProfileViewModel::DefaultAppearance()
{
return _defaultAppearanceViewModel;
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsEditor/ProfileViewModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
bool RepositionCursorWithMouseAvailable() const noexcept;

bool Orphaned() const;
hstring TabTitlePreview() const;

til::typed_event<Editor::ProfileViewModel, Editor::DeleteProfileEventArgs> DeleteProfileRequested;

Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ namespace Microsoft.Terminal.Settings.Editor
IInspectable CurrentBuiltInIcon;
Windows.Foundation.Collections.IVector<IInspectable> BuiltInIcons { get; };

String TabTitlePreview { get; };

void CreateUnfocusedAppearance();
void DeleteUnfocusedAppearance();

Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
<!-- Icon -->
<local:SettingContainer x:Uid="Profile_Icon"
ClearSettingValue="{x:Bind Profile.ClearIcon}"
CurrentValueAccessibleName="{x:Bind Profile.Icon, Mode=OneWay}"
HasSettingValue="{x:Bind Profile.HasIcon, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.IconOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyleWithComplexPreview}">
Expand All @@ -110,6 +111,7 @@
<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"
Expand Down Expand Up @@ -199,7 +201,7 @@
<!-- Tab Title -->
<local:SettingContainer x:Uid="Profile_TabTitle"
ClearSettingValue="{x:Bind Profile.ClearTabTitle}"
CurrentValue="{x:Bind Profile.TabTitle, Mode=OneWay}"
CurrentValue="{x:Bind Profile.TabTitlePreview, Mode=OneWay}"
HasSettingValue="{x:Bind Profile.HasTabTitle, Mode=OneWay}"
SettingOverrideSource="{x:Bind Profile.TabTitleOverrideSource, Mode=OneWay}"
Style="{StaticResource ExpanderSettingContainerStyle}">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2316,4 +2316,8 @@
<data name="Profile_Source_Orphaned.HelpText" xml:space="preserve">
<value>Indicates the software that originally created this profile.</value>
</data>
</root>
<data name="Profile_TabTitleNone" xml:space="preserve">
<value>None</value>
<comment>Text displayed when the tab title is not defined.</comment>
</data>
</root>
72 changes: 63 additions & 9 deletions src/cascadia/TerminalSettingsEditor/SettingContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
DependencyProperty SettingContainer::_FontIconGlyphProperty{ nullptr };
DependencyProperty SettingContainer::_CurrentValueProperty{ nullptr };
DependencyProperty SettingContainer::_CurrentValueTemplateProperty{ nullptr };
DependencyProperty SettingContainer::_CurrentValueAccessibleNameProperty{ nullptr };
DependencyProperty SettingContainer::_HasSettingValueProperty{ nullptr };
DependencyProperty SettingContainer::_SettingOverrideSourceProperty{ nullptr };
DependencyProperty SettingContainer::_StartExpandedProperty{ nullptr };
Expand Down Expand Up @@ -63,7 +64,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
L"CurrentValue",
xaml_typename<IInspectable>(),
xaml_typename<Editor::SettingContainer>(),
PropertyMetadata{ nullptr });
PropertyMetadata{ nullptr, PropertyChangedCallback{ &SettingContainer::_OnCurrentValueChanged } });
}
if (!_CurrentValueTemplateProperty)
{
Expand All @@ -74,6 +75,15 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
xaml_typename<Editor::SettingContainer>(),
PropertyMetadata{ nullptr });
}
if (!_CurrentValueAccessibleNameProperty)
{
_CurrentValueAccessibleNameProperty =
DependencyProperty::Register(
L"CurrentValueAccessibleName",
xaml_typename<Windows::UI::Xaml::DataTemplate>(),
xaml_typename<Editor::SettingContainer>(),
PropertyMetadata{ box_value(L""), PropertyChangedCallback{ &SettingContainer::_OnCurrentValueChanged } });
}
if (!_HasSettingValueProperty)
{
_HasSettingValueProperty =
Expand Down Expand Up @@ -103,6 +113,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}

void SettingContainer::_OnCurrentValueChanged(const Windows::UI::Xaml::DependencyObject& d, const Windows::UI::Xaml::DependencyPropertyChangedEventArgs& /*e*/)
{
const auto& obj{ d.try_as<Editor::SettingContainer>() };
get_self<SettingContainer>(obj)->_UpdateCurrentValueAutoProp();
}

void SettingContainer::_OnHasSettingValueChanged(const DependencyObject& d, const DependencyPropertyChangedEventArgs& /*args*/)
{
// update visibility for override message and reset button
Expand Down Expand Up @@ -174,14 +190,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation

for (const auto& obj : base)
{
// apply header as name (automation property)
if (const auto& header{ Header() })
{
if (const auto headerText{ header.try_as<hstring>() })
{
Automation::AutomationProperties::SetName(obj, *headerText);
}
}
// apply header and current value as name (automation property)
Automation::AutomationProperties::SetName(obj, _GenerateAccessibleName());

// apply help text as tooltip and full description (automation property)
if (const auto& helpText{ HelpText() }; !helpText.empty())
Expand Down Expand Up @@ -247,6 +257,17 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
}

void SettingContainer::_UpdateCurrentValueAutoProp()
{
if (const auto& child{ GetTemplateChild(L"Expander") })
{
if (const auto& expander{ child.try_as<Microsoft::UI::Xaml::Controls::Expander>() })
{
Automation::AutomationProperties::SetName(expander, _GenerateAccessibleName());
}
}
}

// Method Description:
// - Helper function for generating the override message
// Arguments:
Expand Down Expand Up @@ -279,4 +300,37 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
}
return RS_(L"SettingContainer_OverrideMessageBaseLayer");
}

// Method Description:
// - Helper function for generating the accessible name
// Return Value:
// - text specifying the accessible name. Includes header and current value, if available.
hstring SettingContainer::_GenerateAccessibleName()
{
hstring name{};
if (const auto& header{ Header() })
{
if (const auto headerText{ header.try_as<hstring>() })
{
name = *headerText;
}

// append current value to the name, if it exists
if (const auto currentValAccessibleName{ CurrentValueAccessibleName() }; !currentValAccessibleName.empty())
{
// prefer CurrentValueAccessibleName, if it exists
name = name + L": " + currentValAccessibleName;
}
else if (const auto& currentVal{ CurrentValue() })
{
// the accessible name was not defined, so try to
// extract the value directly from the CurrentValue property
if (const auto currentValText{ currentVal.try_as<hstring>() })
{
name = name + L": " + *currentValText;
}
}
}
return name;
}
}
Loading

0 comments on commit bdaebad

Please sign in to comment.