boxInstructions = $"The following Box should read aloud \"{BoxName}. {BoxHelpText}\". Windows does not currently support TapGestures while the Narrator is active.";
toolbarInstructions = $"The Toolbar should have a coffee cup icon. Activating the coffee cup should read aloud \"{toolbarItemName}\". The Toolbar should also show the text \"{toolbarItem2Text}\". Activating this item should read aloud \"{toolbarItem2Text}. {toolbarItemHint2}\".";
break;
+ case Device.Tizen:
+ screenReader = "Screen reader(TTS)";
+ scrollFingers = "two fingers";
+ explore = "Use two fingers to swipe up the screen to read all of the elements on this page.";
+ labeledByInstructions = $"The following Entry should read aloud \"{EntryHelpText}\", plus native instructions on how to use an Entry element. This text comes from the text of the label.";
+ imageInstructions = $"The following Image should read aloud \"{ImageName}. {ImageHelpText}\". Tizen does not currently support TapGestures while the\"{screenReader}\" is active.";
+ boxInstructions = $"Tizen does not currently support accessibility for the BoxView due to platform limitation.";
+ toolbarInstructions = $"The Toolbar should have a coffee cup icon. Activating the coffee cup should read aloud \"{toolbarItemName}\".";
+ break;
default:
screenReader = "the native screen reader";
break;
var instructions4 = new Label { Text = imageInstructions };
var image = new Image { Source = "photo.jpg" };
- // The tap gesture will NOT work on Win
+ // The tap gesture will NOT work on Win and Tizen
image.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => DisplayAlert("Success", "You tapped the image", "OK")) });
image.SetAutomationPropertiesName(ImageName);
image.SetAutomationPropertiesHelpText(ImageHelpText);
+ // Images are ignored by default on Tizen;
+ // make accessible in order to enable the gesture and narration
+ image.SetAutomationPropertiesIsInAccessibleTree(true);
- var instructions6 = new Label { Text = boxInstructions };
+ var instructions5 = new Label { Text = boxInstructions };
var boxView = new BoxView { Color = Color.Purple };
- // The tap gesture will NOT work on Win
+ // The tap gesture will NOT work on Win and Tizen
boxView.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(() => DisplayAlert("Success", "You tapped the box", "OK")) });
boxView.SetAutomationPropertiesName(BoxName);
boxView.SetAutomationPropertiesHelpText(BoxHelpText);
activityIndicator,
instructions4,
image,
- boxView
+ instructions5,
+ boxView,
}
};
--- /dev/null
+using ElmSharp.Accessible;
+
+namespace Xamarin.Forms.Platform.Tizen
+{
+ public static class AccessibilityExtensions
+ {
+ public static string SetAccessibilityName(this IAccessibleObject Control, Element Element, string _defaultAccessibilityName = null)
+ {
+ if (Element == null || Control == null)
+ return _defaultAccessibilityName;
+
+ if (_defaultAccessibilityName == null)
+ _defaultAccessibilityName = Control.Name;
+
+ Control.Name = (string)Element.GetValue(AutomationProperties.NameProperty) ?? _defaultAccessibilityName;
+ return _defaultAccessibilityName;
+ }
+
+ public static string SetAccessibilityDescription(this IAccessibleObject Control, Element Element, string _defaultAccessibilityDescription = null)
+ {
+ if (Element == null || Control == null)
+ return _defaultAccessibilityDescription;
+
+ if (_defaultAccessibilityDescription == null)
+ _defaultAccessibilityDescription = Control.Description;
+
+ Control.Description = (string)Element.GetValue(AutomationProperties.HelpTextProperty) ?? _defaultAccessibilityDescription;
+ return _defaultAccessibilityDescription;
+ }
+
+ public static bool? SetIsAccessibilityElement(this IAccessibleObject Control, Element Element, bool? _defaultIsAccessibilityElement = null)
+ {
+ if (Element == null || Control == null)
+ return _defaultIsAccessibilityElement;
+
+ if (!_defaultIsAccessibilityElement.HasValue)
+ _defaultIsAccessibilityElement = Control.CanHighlight;
+
+ Control.CanHighlight = (bool)((bool?)Element.GetValue(AutomationProperties.IsInAccessibleTreeProperty) ?? _defaultIsAccessibilityElement);
+
+ // Images are ignored by default on Tizen. So, make accessible in order to enable the gesture and narration
+ if (Control.CanHighlight && Element is Image)
+ {
+ Control.Role = AccessRole.PushButton;
+ }
+ return _defaultIsAccessibilityElement;
+ }
+
+ public static void SetLabeledBy(this IAccessibleObject Control, Element Element)
+ {
+ if (Element == null || Control == null)
+ return;
+
+ var targetElement = (VisualElement)Element.GetValue(AutomationProperties.LabeledByProperty);
+ AccessibleObject view = (AccessibleObject)Platform.GetRenderer(targetElement)?.NativeView;
+ if (view != null)
+ {
+ Control.AppendRelation(new LabelledBy() { Target = view });
+ }
+ }
+ }
+}
using System;
using System.ComponentModel;
+using ElmSharp.Accessible;
using EColor = ElmSharp.Color;
namespace Xamarin.Forms.Platform.Tizen.Native
const string StyleRightToolbarButton = "naviframe/title_right";
ToolbarItem _item;
+ string _defaultAccessibilityName;
+ string _defaultAccessibilityDescription;
+ bool? _defaultIsAccessibilityElement;
public ToolbarItemButton(ToolbarItem item) : base(Forms.NativeParent)
{
UpdateText();
UpdateIsEnabled();
UpdateIcon();
+ SetAccessibilityName(true);
+ SetAccessibilityDescription(true);
+ SetIsAccessibilityElement(true);
+ SetLabeledBy(true);
}
void OnDeleted(object sender, EventArgs e)
{
UpdateIcon();
}
+ else if (e.PropertyName == AutomationProperties.NameProperty.PropertyName)
+ {
+ SetAccessibilityName(false);
+ }
+ else if (e.PropertyName == AutomationProperties.HelpTextProperty.PropertyName)
+ {
+ SetAccessibilityDescription(false);
+ }
+ else if (e.PropertyName == AutomationProperties.IsInAccessibleTreeProperty.PropertyName)
+ {
+ SetIsAccessibilityElement(false);
+ }
+ else if (e.PropertyName == AutomationProperties.LabeledByProperty.PropertyName)
+ {
+ SetLabeledBy(false);
+ }
}
void UpdateText()
Style = StyleDefault;
}
}
+
+ void SetAccessibilityName(bool initialize)
+ {
+ if (initialize && (string)_item.GetValue(AutomationProperties.NameProperty) == (default(string)))
+ return;
+
+ var accessibleObject = this as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ _defaultAccessibilityName = accessibleObject.SetAccessibilityName(_item, _defaultAccessibilityName);
+ }
+ }
+
+ void SetAccessibilityDescription(bool initialize)
+ {
+ if (initialize && (string)_item.GetValue(AutomationProperties.HelpTextProperty) == (default(string)))
+ return;
+
+ var accessibleObject = this as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ _defaultAccessibilityDescription = accessibleObject.SetAccessibilityDescription(_item, _defaultAccessibilityDescription);
+ }
+ }
+
+ void SetIsAccessibilityElement(bool initialize)
+ {
+ if (initialize && (bool?)_item.GetValue(AutomationProperties.IsInAccessibleTreeProperty) == default(bool?))
+ return;
+
+ var accessibleObject = this as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ _defaultIsAccessibilityElement = accessibleObject.SetIsAccessibilityElement(_item, _defaultIsAccessibilityElement);
+ }
+ }
+
+ void SetLabeledBy(bool initialize)
+ {
+ if (initialize && (VisualElement)_item.GetValue(AutomationProperties.LabeledByProperty) == default(VisualElement))
+ return;
+
+ var accessibleObject = this as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ accessibleObject.SetLabeledBy(_item);
+ }
+ }
}
}
using System.ComponentModel;
using System.Linq;
using ElmSharp;
+using ElmSharp.Accessible;
using Xamarin.Forms.Internals;
using Xamarin.Forms.Platform.Tizen.Native;
using EFocusDirection = ElmSharp.FocusDirection;
VisualElementRendererFlags _flags = VisualElementRendererFlags.None;
bool _movedCallbackEnabled = false;
+ string _defaultAccessibilityName;
+ string _defaultAccessibilityDescription;
+ bool? _defaultIsAccessibilityElement;
Lazy<CustomFocusManager> _customFocusManager;
RegisterPropertyHandler(VisualElement.TabIndexProperty, UpdateTabIndex);
RegisterPropertyHandler(VisualElement.IsTabStopProperty, UpdateIsTabStop);
+ RegisterPropertyHandler(AutomationProperties.NameProperty, SetAccessibilityName);
+ RegisterPropertyHandler(AutomationProperties.HelpTextProperty, SetAccessibilityDescription);
+ RegisterPropertyHandler(AutomationProperties.IsInAccessibleTreeProperty, SetIsAccessibilityElement);
+ RegisterPropertyHandler(AutomationProperties.LabeledByProperty, SetLabeledBy);
_customFocusManager = new Lazy<CustomFocusManager>(() =>
{
}
}
+ protected virtual void SetAccessibilityName(bool initialize)
+ {
+ if (initialize && (string)Element.GetValue(AutomationProperties.NameProperty) == (default(string)))
+ return;
+
+ var accessibleObject = NativeView as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ _defaultAccessibilityName = accessibleObject.SetAccessibilityName(Element, _defaultAccessibilityName);
+ }
+ }
+
+ protected virtual void SetAccessibilityDescription(bool initialize)
+ {
+ if (initialize && (string)Element.GetValue(AutomationProperties.HelpTextProperty) == (default(string)))
+ return;
+
+ var accessibleObject = NativeView as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ _defaultAccessibilityDescription = accessibleObject.SetAccessibilityDescription(Element, _defaultAccessibilityDescription);
+ }
+ }
+
+ protected virtual void SetIsAccessibilityElement(bool initialize)
+ {
+ if (initialize && (bool?)Element.GetValue(AutomationProperties.IsInAccessibleTreeProperty) == default(bool?))
+ return;
+
+ var accessibleObject = NativeView as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ _defaultIsAccessibilityElement = accessibleObject.SetIsAccessibilityElement(Element, _defaultIsAccessibilityElement);
+ }
+ }
+
+ protected virtual void SetLabeledBy(bool initialize)
+ {
+ if (initialize && (VisualElement)Element.GetValue(AutomationProperties.LabeledByProperty) == default(VisualElement))
+ return;
+
+ var accessibleObject = NativeView as IAccessibleObject;
+ if (accessibleObject != null)
+ {
+ accessibleObject.SetLabeledBy(Element);
+ }
+ }
+
internal virtual void SendVisualElementInitialized(VisualElement element, EvasObject nativeView)
{
element.SendViewInitialized(nativeView);