From 929ce1fe81dcfabc27d6c84ae2b5d193af4e24e7 Mon Sep 17 00:00:00 2001 From: Karen Lai <7976322+karenbtlai@users.noreply.github.com> Date: Wed, 11 Mar 2020 15:07:43 -0700 Subject: [PATCH] ProgressRing Automation Peer (#2065) * automationPeer scaffolding * fix build errors * remove IRangeValueProvider\ * implemement indeterminate behaviour for narrator * create localized resource * progressBar resources for all states * changes from comments * changes from comments * re add IRangeValueProvider * fix: stuck in updating state with indeterminate as default * move Resources.resw in Strings\en-us folder * Update ProgressBar.vcxitems Fix Resources.resw path * Update ProgressRing.vcxitems Co-authored-by: Ranjesh <28935693+ranjeshj@users.noreply.github.com> --- .../ProgressRingAutomationPeer.properties.cpp | 16 +++ dev/ProgressBar/ProgressBar.cpp | 2 - dev/ProgressBar/ProgressBar.vcxitems | 5 +- dev/ProgressBar/ProgressBarAutomationPeer.cpp | 31 ++++ dev/ProgressBar/ProgressBarAutomationPeer.h | 5 +- dev/ProgressBar/Strings/en-us/Resources.resw | 132 ++++++++++++++++++ dev/ProgressRing/ProgressRing.cpp | 6 + dev/ProgressRing/ProgressRing.h | 2 +- dev/ProgressRing/ProgressRing.idl | 12 ++ dev/ProgressRing/ProgressRing.vcxitems | 7 +- .../ProgressRing.vcxitems.filters | 6 +- .../ProgressRingAutomationPeer.cpp | 103 ++++++++++++++ dev/ProgressRing/ProgressRingAutomationPeer.h | 34 +++++ dev/ProgressRing/Strings/en-us/Resources.resw | 124 ++++++++++++++++ dev/ResourceHelper/ResourceAccessor.h | 4 + 15 files changed, 480 insertions(+), 9 deletions(-) create mode 100644 dev/Generated/ProgressRingAutomationPeer.properties.cpp create mode 100644 dev/ProgressBar/Strings/en-us/Resources.resw create mode 100644 dev/ProgressRing/ProgressRingAutomationPeer.cpp create mode 100644 dev/ProgressRing/ProgressRingAutomationPeer.h create mode 100644 dev/ProgressRing/Strings/en-us/Resources.resw diff --git a/dev/Generated/ProgressRingAutomationPeer.properties.cpp b/dev/Generated/ProgressRingAutomationPeer.properties.cpp new file mode 100644 index 0000000000..cfcc1e136b --- /dev/null +++ b/dev/Generated/ProgressRingAutomationPeer.properties.cpp @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +// DO NOT EDIT! This file was generated by CustomTasks.DependencyPropertyCodeGen +#include "pch.h" +#include "common.h" +#include "ProgressRingAutomationPeer.h" + +namespace winrt::Microsoft::UI::Xaml::Automation::Peers +{ + CppWinRTActivatableClassWithBasicFactory(ProgressRingAutomationPeer) +} + +#include "ProgressRingAutomationPeer.g.cpp" + + diff --git a/dev/ProgressBar/ProgressBar.cpp b/dev/ProgressBar/ProgressBar.cpp index e777b403c3..30d69de5f7 100644 --- a/dev/ProgressBar/ProgressBar.cpp +++ b/dev/ProgressBar/ProgressBar.cpp @@ -135,8 +135,6 @@ void ProgressBar::SetProgressBarIndicatorWidth() { indeterminateProgressBarIndicator2.Width(progressBarWidth * 0.6); // 60% of ProgressBar Width } - - return; } else if (std::abs(maximum - minimum) > DBL_EPSILON) { diff --git a/dev/ProgressBar/ProgressBar.vcxitems b/dev/ProgressBar/ProgressBar.vcxitems index 2f10f790ad..33847bd6e0 100644 --- a/dev/ProgressBar/ProgressBar.vcxitems +++ b/dev/ProgressBar/ProgressBar.vcxitems @@ -37,4 +37,7 @@ - \ No newline at end of file + + + + diff --git a/dev/ProgressBar/ProgressBarAutomationPeer.cpp b/dev/ProgressBar/ProgressBarAutomationPeer.cpp index 8dd590f604..cca6b40d87 100644 --- a/dev/ProgressBar/ProgressBarAutomationPeer.cpp +++ b/dev/ProgressBar/ProgressBarAutomationPeer.cpp @@ -20,6 +20,14 @@ winrt::IInspectable ProgressBarAutomationPeer::GetPatternCore(winrt::PatternInte { if (patternInterface == winrt::PatternInterface::RangeValue) { + if (auto progressBar = Owner().try_as()) + { + if (progressBar.IsIndeterminate()) + { + return nullptr; + } + } + return *this; } @@ -31,6 +39,29 @@ hstring ProgressBarAutomationPeer::GetClassNameCore() return winrt::hstring_name_of(); } +winrt::hstring ProgressBarAutomationPeer::GetNameCore() +{ + //Check to see if the item has a defined AutomationProperties.Name + winrt::hstring name = __super::GetNameCore(); + + if (auto progressBar = Owner().try_as()) + { + if (progressBar.ShowError()) + { + return winrt::hstring{ ResourceAccessor::GetLocalizedStringResource(SR_ProgressBarErrorStatus) + name }; + } + else if (progressBar.ShowPaused()) + { + return winrt::hstring{ ResourceAccessor::GetLocalizedStringResource(SR_ProgressBarPausedStatus) + name }; + } + else if (progressBar.IsIndeterminate()) + { + return winrt::hstring{ ResourceAccessor::GetLocalizedStringResource(SR_ProgressBarIndeterminateStatus) + name }; + } + } + return name; +} + winrt::AutomationControlType ProgressBarAutomationPeer::GetAutomationControlTypeCore() { return winrt::AutomationControlType::ProgressBar; diff --git a/dev/ProgressBar/ProgressBarAutomationPeer.h b/dev/ProgressBar/ProgressBarAutomationPeer.h index c6fa8a4b3f..e8673c0c2f 100644 --- a/dev/ProgressBar/ProgressBarAutomationPeer.h +++ b/dev/ProgressBar/ProgressBarAutomationPeer.h @@ -15,9 +15,11 @@ class ProgressBarAutomationPeer : // IAutomationPeerOverrides winrt::IInspectable GetPatternCore(winrt::PatternInterface const& patternInterface); - hstring GetClassNameCore(); + winrt::hstring GetClassNameCore(); + winrt::hstring GetNameCore(); winrt::AutomationControlType GetAutomationControlTypeCore(); + // IRangeValueProvider is necessary here to override IsReadOnly() to true. bool IsReadOnly() { return true; } double Value(); double SmallChange(); @@ -26,6 +28,7 @@ class ProgressBarAutomationPeer : double Maximum(); void SetValue(double value); + private: com_ptr GetImpl(); }; diff --git a/dev/ProgressBar/Strings/en-us/Resources.resw b/dev/ProgressBar/Strings/en-us/Resources.resw new file mode 100644 index 0000000000..83ae0c2caf --- /dev/null +++ b/dev/ProgressBar/Strings/en-us/Resources.resw @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Error + This is used to announce Error state. + + + Busy + This is used to announce Indeterminate state. + + + Paused + This is used to announce Paused state. + + \ No newline at end of file diff --git a/dev/ProgressRing/ProgressRing.cpp b/dev/ProgressRing/ProgressRing.cpp index 2520c4cc3b..bdf19db0bb 100644 --- a/dev/ProgressRing/ProgressRing.cpp +++ b/dev/ProgressRing/ProgressRing.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include "common.h" #include "ProgressRing.h" +#include "ProgressRingAutomationPeer.h" #include "RuntimeProfiler.h" #include "ResourceAccessor.h" #include "math.h" @@ -39,6 +40,11 @@ ProgressRing::ProgressRing() SizeChanged({ this, &ProgressRing::OnSizeChanged }); } +winrt::AutomationPeer ProgressRing::OnCreateAutomationPeer() +{ + return winrt::make(*this); +} + void ProgressRing::OnApplyTemplate() { winrt::IControlProtected controlProtected{ *this }; diff --git a/dev/ProgressRing/ProgressRing.h b/dev/ProgressRing/ProgressRing.h index 814dfeb4e2..3dae9e08f0 100644 --- a/dev/ProgressRing/ProgressRing.h +++ b/dev/ProgressRing/ProgressRing.h @@ -19,10 +19,10 @@ class ProgressRing : public: ProgressRing(); + winrt::AutomationPeer OnCreateAutomationPeer(); // IFrameworkElement void OnApplyTemplate(); - void OnStrokeThicknessPropertyChanged(const winrt::DependencyPropertyChangedEventArgs& args); void OnIsIndeterminatePropertyChanged(const winrt::DependencyPropertyChangedEventArgs& args); void OnForegroundPropertyChanged(const winrt::DependencyObject&, const winrt::DependencyProperty&); void OnForegroundColorPropertyChanged(const winrt::DependencyObject&, const winrt::DependencyProperty&); diff --git a/dev/ProgressRing/ProgressRing.idl b/dev/ProgressRing/ProgressRing.idl index 7ccffb541f..de44015028 100644 --- a/dev/ProgressRing/ProgressRing.idl +++ b/dev/ProgressRing/ProgressRing.idl @@ -14,3 +14,15 @@ unsealed runtimeclass ProgressRing : Windows.UI.Xaml.Controls.Primitives.RangeBa } } + +namespace MU_XAP_NAMESPACE +{ + +[WUXC_VERSION_PREVIEW] +[webhosthidden] +unsealed runtimeclass ProgressRingAutomationPeer : Windows.UI.Xaml.Automation.Peers.RangeBaseAutomationPeer +{ + ProgressRingAutomationPeer(MU_XC_NAMESPACE.ProgressRing owner); +} + +} diff --git a/dev/ProgressRing/ProgressRing.vcxitems b/dev/ProgressRing/ProgressRing.vcxitems index 89b0d2c6c3..7c34844ab7 100644 --- a/dev/ProgressRing/ProgressRing.vcxitems +++ b/dev/ProgressRing/ProgressRing.vcxitems @@ -16,11 +16,13 @@ + + @@ -37,4 +39,7 @@ - \ No newline at end of file + + + + diff --git a/dev/ProgressRing/ProgressRing.vcxitems.filters b/dev/ProgressRing/ProgressRing.vcxitems.filters index 0d0bca9e80..dde15376da 100644 --- a/dev/ProgressRing/ProgressRing.vcxitems.filters +++ b/dev/ProgressRing/ProgressRing.vcxitems.filters @@ -3,11 +3,13 @@ + + @@ -18,8 +20,6 @@ - - {76115a89-641e-4eaa-ac72-f01887e6cb2d} - + \ No newline at end of file diff --git a/dev/ProgressRing/ProgressRingAutomationPeer.cpp b/dev/ProgressRing/ProgressRingAutomationPeer.cpp new file mode 100644 index 0000000000..72b8e1b943 --- /dev/null +++ b/dev/ProgressRing/ProgressRingAutomationPeer.cpp @@ -0,0 +1,103 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#include "pch.h" +#include "common.h" +#include "ResourceAccessor.h" +#include "ProgressRing.h" +#include "ProgressRingAutomationPeer.h" +#include "Utils.h" + +#include "ProgressRingAutomationPeer.properties.cpp" + +ProgressRingAutomationPeer::ProgressRingAutomationPeer(winrt::ProgressRing const& owner) + : ReferenceTracker(owner) +{ +} + +// IAutomationPeerOverrides +winrt::IInspectable ProgressRingAutomationPeer::GetPatternCore(winrt::PatternInterface const& patternInterface) +{ + if (patternInterface == winrt::PatternInterface::RangeValue) + { + if (auto progressRing = Owner().try_as()) + { + if (progressRing.IsIndeterminate()) + { + return nullptr; + } + } + + return *this; + } + + return __super::GetPatternCore(patternInterface); +} + +winrt::hstring ProgressRingAutomationPeer::GetClassNameCore() +{ + return winrt::hstring_name_of(); +} + +winrt::hstring ProgressRingAutomationPeer::GetNameCore() +{ + //Check to see if the item has a defined AutomationProperties.Name + winrt::hstring name = __super::GetNameCore(); + + if (auto progressRing = Owner().try_as()) + { + if (progressRing.IsIndeterminate()) + { + return winrt::hstring{ ResourceAccessor::GetLocalizedStringResource(SR_ProgressRingIndeterminateStatus) + name }; + } + } + return name; +} + +winrt::AutomationControlType ProgressRingAutomationPeer::GetAutomationControlTypeCore() +{ + return winrt::AutomationControlType::ProgressBar; +} + +com_ptr ProgressRingAutomationPeer::GetImpl() +{ + com_ptr impl = nullptr; + + if (auto progressRing = Owner().try_as()) + { + impl = winrt::get_self(progressRing)->get_strong(); + } + + return impl; +} + +// IRangeValueProvider +double ProgressRingAutomationPeer::Value() +{ + return GetImpl()->Value(); +} + +double ProgressRingAutomationPeer::SmallChange() +{ + return std::numeric_limits::quiet_NaN(); +} + +double ProgressRingAutomationPeer::LargeChange() +{ + return std::numeric_limits::quiet_NaN(); +} + +double ProgressRingAutomationPeer::Minimum() +{ + return GetImpl()->Minimum(); +} + +double ProgressRingAutomationPeer::Maximum() +{ + return GetImpl()->Maximum(); +} + +void ProgressRingAutomationPeer::SetValue(double value) +{ + GetImpl()->Value(value); +} diff --git a/dev/ProgressRing/ProgressRingAutomationPeer.h b/dev/ProgressRing/ProgressRingAutomationPeer.h new file mode 100644 index 0000000000..b72df37c31 --- /dev/null +++ b/dev/ProgressRing/ProgressRingAutomationPeer.h @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#pragma once + +#include "ProgressRing.h" +#include "ProgressRingAutomationPeer.g.h" + +class ProgressRingAutomationPeer : + public ReferenceTracker +{ + +public: + ProgressRingAutomationPeer(winrt::ProgressRing const& owner); + + // IAutomationPeerOverrides + winrt::IInspectable GetPatternCore(winrt::PatternInterface const& patternInterface); + hstring GetClassNameCore(); + winrt::hstring GetNameCore(); + winrt::AutomationControlType GetAutomationControlTypeCore(); + + // IRangeValueProvider is necessary here to override IsReadOnly() to true. + bool IsReadOnly() { return true; } + double Value(); + double SmallChange(); + double LargeChange(); + double Minimum(); + double Maximum(); + void SetValue(double value); + +private: + com_ptr GetImpl(); +}; + diff --git a/dev/ProgressRing/Strings/en-us/Resources.resw b/dev/ProgressRing/Strings/en-us/Resources.resw new file mode 100644 index 0000000000..786b7e0625 --- /dev/null +++ b/dev/ProgressRing/Strings/en-us/Resources.resw @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Busy + This is used to announce Indeterminate state. + + \ No newline at end of file diff --git a/dev/ResourceHelper/ResourceAccessor.h b/dev/ResourceHelper/ResourceAccessor.h index 7bdad2820b..527705b4b0 100644 --- a/dev/ResourceHelper/ResourceAccessor.h +++ b/dev/ResourceHelper/ResourceAccessor.h @@ -112,6 +112,10 @@ class ResourceAccessor sealed #define SR_PlaceAfterString L"PlaceAfterString" #define SR_PlaceBeforeString L"PlaceBeforeString" #define SR_PlaceBetweenString L"PlaceBetweenString" +#define SR_ProgressRingIndeterminateStatus L"ProgressRingIndeterminateStatus" +#define SR_ProgressBarIndeterminateStatus L"ProgressBarIndeterminateStatus" +#define SR_ProgressBarPausedStatus L"ProgressBarPausedStatus" +#define SR_ProgressBarErrorStatus L"ProgressBarErrorStatus" #define SR_RatingLocalizedControlType L"RatingLocalizedControlType" #define SR_SplitButtonSecondaryButtonName L"SplitButtonSecondaryButtonName" #define SR_ProofingMenuItemLabel L"ProofingMenuItemLabel"