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"