2 * Copyright(c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Collections.Generic;
20 using System.ComponentModel;
21 using System.Runtime.InteropServices;
24 namespace Tizen.NUI.BaseComponents
27 /// AccessibilityRange is used to store data related with Text.
29 [EditorBrowsable(EditorBrowsableState.Never)]
30 public class AccessibilityRange
33 /// Start position in stored text.
35 public int StartOffset { get; set; } = 0;
38 /// End position in stored text.
40 public int EndOffset { get; set; } = 0;
43 /// Text content in stored text.
45 public string Content { get; set; } = "";
49 /// View is the base class for all views.
51 /// <since_tizen> 3 </since_tizen>
52 public partial class View
54 ///////////////////////////////////////////////////////////////////
55 // ****************** Accessibility Attributes ****************** //
56 ///////////////////////////////////////////////////////////////////
59 /// Dictionary of accessibility attributes (key-value pairs of strings).
61 [EditorBrowsable(EditorBrowsableState.Never)]
62 public Dictionary<string, string> AccessibilityAttributes { get; } = new Dictionary<string, string>();
65 /// Dictionary of dynamically-evaluated accessibility attributes (key-value pairs of strings).
67 [EditorBrowsable(EditorBrowsableState.Never)]
68 public Dictionary<string, Func<string>> AccessibilityDynamicAttributes { get; } = new Dictionary<string, Func<string>>();
70 ///////////////////////////////////////////////////////////////////
71 // ************************** Highlight ************************ //
72 ///////////////////////////////////////////////////////////////////
75 /// Clears accessibility highlight.
77 /// <returns>True if cleared, otherwise false when it is not possible</returns>
78 [EditorBrowsable(EditorBrowsableState.Never)]
79 public bool ClearAccessibilityHighlight()
81 bool result = Interop.ControlDevel.DaliToolkitDevelControlClearAccessibilityHighlight(SwigCPtr);
82 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
87 /// Grabs accessibility highlight.
89 /// <returns>True if cleared, otherwise false when it is not possible</returns>
90 [EditorBrowsable(EditorBrowsableState.Never)]
91 public bool GrabAccessibilityHighlight()
93 bool result = Interop.ControlDevel.DaliToolkitDevelControlGrabAccessibilityHighlight(SwigCPtr);
94 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
99 /// Flag to check whether this view is highlighted or not.
101 [EditorBrowsable(EditorBrowsableState.Never)]
102 protected bool IsHighlighted
106 return (this == Accessibility.Accessibility.GetCurrentlyHighlightedView());
110 ///////////////////////////////////////////////////////////////////
111 // ****************** Accessibility Relations ******************* //
112 ///////////////////////////////////////////////////////////////////
115 /// Creates relation between objects.
117 /// <param name="second">Object which will be in relation.</param>
118 /// <param name="relation">Relation type.</param>
119 /// <exception cref="ArgumentNullException">You must pass valid object. NULL could not be in relation.</exception>
120 [EditorBrowsable(EditorBrowsableState.Never)]
121 public void AppendAccessibilityRelation(View second, AccessibilityRelationType relation)
125 throw new ArgumentNullException(nameof(second));
128 Interop.ControlDevel.DaliToolkitDevelControlAppendAccessibilityRelation(SwigCPtr, second.SwigCPtr, (int)relation);
129 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
133 /// Removes accessibility relation.
135 /// <param name="second">Object which will be removed in relation</param>
136 /// <param name="relation">Relation type</param>
137 [EditorBrowsable(EditorBrowsableState.Never)]
138 public void RemoveAccessibilityRelation(View second, AccessibilityRelationType relation)
142 throw new ArgumentNullException(nameof(second));
145 Interop.ControlDevel.DaliToolkitDevelControlRemoveAccessibilityRelation(SwigCPtr, second.SwigCPtr, (int)relation);
146 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
150 /// Removes all previously appended relations.
152 [EditorBrowsable(EditorBrowsableState.Never)]
153 public void ClearAccessibilityRelations()
155 Interop.ControlDevel.DaliToolkitDevelControlClearAccessibilityRelations(SwigCPtr);
156 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
160 /// Gets accessibility collection connected with the current object.
162 /// <returns>A dictionary mapping a relation type to a set of objects in that relation</returns>
163 [EditorBrowsable(EditorBrowsableState.Never)]
164 public Dictionary<AccessibilityRelationType, List<View>> GetAccessibilityRelations()
166 var list = new List<KeyValuePair<int, IntPtr>>();
167 var listHandle = GCHandle.Alloc(list);
168 var callback = new Interop.ControlDevel.GetAccessibilityRelationsCallback(GetAccessibilityRelationsCallback);
170 Interop.ControlDevel.DaliToolkitDevelControlGetAccessibilityRelations(SwigCPtr, callback, GCHandle.ToIntPtr(listHandle));
172 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
174 var result = new Dictionary<AccessibilityRelationType, List<View>>();
176 foreach (var pair in list)
178 var key = (AccessibilityRelationType)pair.Key;
179 var value = this.GetInstanceSafely<View>(pair.Value);
181 if (!result.ContainsKey(key))
183 result[key] = new List<View>();
186 result[key].Add(value);
192 private static void GetAccessibilityRelationsCallback(int relationType, IntPtr relationTarget, IntPtr userData)
194 var handle = GCHandle.FromIntPtr(userData);
195 var list = (List<KeyValuePair<int, IntPtr>>)handle.Target;
197 list.Add(new KeyValuePair<int, IntPtr>(relationType, relationTarget));
200 ///////////////////////////////////////////////////////////////////
201 // ********************* ReadingInfoType *********************** //
202 ///////////////////////////////////////////////////////////////////
205 /// Sets accessibility reading information.
207 /// <param name="type">Reading information type</param>
208 [EditorBrowsable(EditorBrowsableState.Never)]
209 public void SetAccessibilityReadingInfoTypes(AccessibilityReadingInfoTypes type)
211 Interop.ControlDevel.DaliToolkitDevelControlSetAccessibilityReadingInfoTypes(SwigCPtr, (int)type);
212 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
216 /// Gets accessibility reading information.
218 /// <returns>Reading information type</returns>
219 [EditorBrowsable(EditorBrowsableState.Never)]
220 public AccessibilityReadingInfoTypes GetAccessibilityReadingInfoTypes()
222 AccessibilityReadingInfoTypes result = (AccessibilityReadingInfoTypes)Interop.ControlDevel.DaliToolkitDevelControlGetAccessibilityReadingInfoTypes(SwigCPtr);
223 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
227 ///////////////////////////////////////////////////////////////////
228 // ******************** Accessibility States ******************* //
229 ///////////////////////////////////////////////////////////////////
232 /// Notifies sending notifications about the current states to accessibility clients.
235 /// In essence, this is equivalent to calling EmitAccessibilityStateChangedEvent in a loop for all specified states.
236 /// If recursive mode is specified, all children of the Accessibility object will also re-emit the states.
238 /// <param name="states">Accessibility States</param>
239 /// <param name="notifyMode">Controls the notification strategy</param>
240 [EditorBrowsable(EditorBrowsableState.Never)]
241 public void NotifyAccessibilityStatesChange(AccessibilityStates states, AccessibilityStatesNotifyMode notifyMode)
245 throw new ArgumentNullException(nameof(states));
248 Interop.ControlDevel.DaliToolkitDevelControlNotifyAccessibilityStateChange(SwigCPtr, states.BitMask, (int)notifyMode);
249 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
253 /// Gets Accessibility States.
255 /// <returns>Accessibility States</returns>
256 [EditorBrowsable(EditorBrowsableState.Never)]
257 public AccessibilityStates GetAccessibilityStates()
259 var result = new AccessibilityStates { BitMask = Interop.ControlDevel.DaliToolkitDevelControlGetAccessibilityStates(SwigCPtr) };
260 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
264 ///////////////////////////////////////////////////////////////////
265 // ************************ Accessible ************************* //
266 ///////////////////////////////////////////////////////////////////
269 /// Emits accessibility property changed event.
271 /// <param name="changeEvent">Property changed event</param>
272 [EditorBrowsable(EditorBrowsableState.Never)]
273 public void EmitAccessibilityEvent(AccessibilityPropertyChangeEvent changeEvent)
275 Interop.ControlDevel.DaliAccessibilityEmitAccessibilityEvent(SwigCPtr, Convert.ToInt32(changeEvent));
276 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
280 /// Emits accessibility states changed event.
282 /// <param name="state">Accessibility state</param>
283 /// <param name="equal">True if the state is set or enabled, otherwise false</param>
284 [EditorBrowsable(EditorBrowsableState.Never)]
285 public void EmitAccessibilityStateChangedEvent(AccessibilityState state, bool equal)
287 Interop.ControlDevel.DaliAccessibilityEmitAccessibilityStateChangedEvent(SwigCPtr, (int)state, Convert.ToInt32(equal));
288 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
292 /// Emits accessibility text inserted event.
294 /// <param name="cursorPosition">Text cursor position</param>
295 /// <param name="length">Text length</param>
296 /// <param name="content">Inserted text content</param>
297 [EditorBrowsable(EditorBrowsableState.Never)]
298 public void EmitTextInsertedEvent(int cursorPosition, int length, string content)
300 Interop.ControlDevel.DaliAccessibilityEmitTextInsertedEvent(SwigCPtr, cursorPosition, length, content);
301 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
305 /// Emits accessibility text deleted event.
307 /// <param name="cursorPosition">Text cursor position</param>
308 /// <param name="length">Text length</param>
309 /// <param name="content">Inserted text content</param>
310 [EditorBrowsable(EditorBrowsableState.Never)]
311 public void EmitTextDeletedEvent(int cursorPosition, int length, string content)
313 Interop.ControlDevel.DaliAccessibilityEmitTextDeletedEvent(SwigCPtr, cursorPosition, length, content);
314 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
318 /// Emits accessibility text cursor moved event.
320 /// <param name="cursorPosition">The new cursor position</param>
321 [EditorBrowsable(EditorBrowsableState.Never)]
322 public void EmitTextCursorMovedEvent(int cursorPosition)
324 Interop.ControlDevel.DaliAccessibilityEmitTextCursorMovedEvent(SwigCPtr, cursorPosition);
325 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
329 /// Emits accessibility scroll started event.
331 [EditorBrowsable(EditorBrowsableState.Never)]
332 public void EmitScrollStartedEvent()
334 Interop.ControlDevel.DaliAccessibilityEmitScrollStartedEvent(SwigCPtr);
335 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
339 /// Emits accessibility scroll finished event.
341 [EditorBrowsable(EditorBrowsableState.Never)]
342 public void EmitScrollFinishedEvent()
344 Interop.ControlDevel.DaliAccessibilityEmitScrollFinishedEvent(SwigCPtr);
345 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
349 /// Modifiable collection of suppressed AT-SPI events (D-Bus signals).
351 [EditorBrowsable(EditorBrowsableState.Never)]
352 public AccessibilityEvents AccessibilitySuppressedEvents
356 return new AccessibilityEvents { Owner = this };
360 ///////////////////////////////////////////////////////////////////
361 // ************************** Bridge *************************** //
362 ///////////////////////////////////////////////////////////////////
365 /// Registers component as a source of an accessibility "default label".
366 /// The "Default label" is a text that could be read by screen-reader immediately
367 /// after the navigation context has changed (window activates, popup shows up, tab changes)
368 /// and before first UI element is highlighted.
370 [EditorBrowsable(EditorBrowsableState.Never)]
371 public void RegisterDefaultLabel()
373 Interop.ControlDevel.DaliAccessibilityBridgeRegisterDefaultLabel(SwigCPtr);
374 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
378 /// Unregisters component that has been registered previously as a source of an accessibility "default label".
379 /// The "Default label" is a text that could be read by screen-reader immediately
380 /// after the navigation context has changed (window activates, popup shows up, tab changes)
381 /// and before first UI element is highlighted.
383 [EditorBrowsable(EditorBrowsableState.Never)]
384 public void UnregisterDefaultLabel()
386 Interop.ControlDevel.DaliAccessibilityBridgeUnregisterDefaultLabel(SwigCPtr);
387 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
390 [EditorBrowsable(EditorBrowsableState.Never)]
391 protected override void Dispose(bool disposing)
400 if (SwigCPtr.Handle != IntPtr.Zero && global::System.Threading.Thread.CurrentThread.ManagedThreadId == Registry.Instance.SavedApplicationThread.ManagedThreadId)
402 Interop.ControlDevel.DaliAccessibilityDetachAccessibleObject(SwigCPtr);
403 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
406 if (disposing == false)
408 if (IsNativeHandleInvalid() || SwigCMemOwn == false)
410 // at this case, implicit nor explicit dispose is not required. No native object is made.
421 base.Dispose(disposing);
424 [EditorBrowsable(EditorBrowsableState.Never)]
425 protected static readonly string AccessibilityActivateAction = "activate";
426 [EditorBrowsable(EditorBrowsableState.Never)]
427 protected static readonly string AccessibilityReadingSkippedAction = "ReadingSkipped";
428 [EditorBrowsable(EditorBrowsableState.Never)]
429 protected static readonly string AccessibilityReadingCancelledAction = "ReadingCancelled";
430 [EditorBrowsable(EditorBrowsableState.Never)]
431 protected static readonly string AccessibilityReadingStoppedAction = "ReadingStopped";
432 [EditorBrowsable(EditorBrowsableState.Never)]
433 protected static readonly string AccessibilityReadingPausedAction = "ReadingPaused";
434 [EditorBrowsable(EditorBrowsableState.Never)]
435 protected static readonly string AccessibilityReadingResumedAction = "ReadingResumed";
437 [EditorBrowsable(EditorBrowsableState.Never)]
438 private static readonly string[] AccessibilityActions = {
439 AccessibilityActivateAction,
440 AccessibilityReadingSkippedAction,
441 AccessibilityReadingCancelledAction,
442 AccessibilityReadingStoppedAction,
443 AccessibilityReadingPausedAction,
444 AccessibilityReadingResumedAction,
447 [EditorBrowsable(EditorBrowsableState.Never)]
448 protected virtual string AccessibilityGetName()
453 [EditorBrowsable(EditorBrowsableState.Never)]
454 protected virtual string AccessibilityGetDescription()
459 [EditorBrowsable(EditorBrowsableState.Never)]
460 protected virtual bool AccessibilityDoAction(string name)
462 if (name == AccessibilityActivateAction)
464 if (ActivateSignal?.Empty() == false)
466 ActivateSignal?.Emit();
471 return OnAccessibilityActivated();
474 else if (name == AccessibilityReadingSkippedAction)
476 if (ReadingSkippedSignal?.Empty() == false)
478 ReadingSkippedSignal?.Emit();
483 return OnAccessibilityReadingSkipped();
486 else if (name == AccessibilityReadingCancelledAction)
488 if (ReadingCancelledSignal?.Empty() == false)
490 ReadingCancelledSignal?.Emit();
495 return OnAccessibilityReadingCancelled();
498 else if (name == AccessibilityReadingStoppedAction)
500 if (ReadingStoppedSignal?.Empty() == false)
502 ReadingStoppedSignal?.Emit();
507 return OnAccessibilityReadingStopped();
510 else if (name == AccessibilityReadingPausedAction)
512 if (ReadingPausedSignal?.Empty() == false)
514 ReadingPausedSignal?.Emit();
519 return OnAccessibilityReadingPaused();
522 else if (name == AccessibilityReadingResumedAction)
524 if (ReadingResumedSignal?.Empty() == false)
526 ReadingResumedSignal?.Emit();
531 return OnAccessibilityReadingResumed();
540 [EditorBrowsable(EditorBrowsableState.Never)]
541 protected virtual AccessibilityStates AccessibilityCalculateStates()
543 var states = AccessibilityInitialStates;
545 states[AccessibilityState.Focused] = this.State == States.Focused;
546 states[AccessibilityState.Enabled] = this.State != States.Disabled;
547 states[AccessibilityState.Sensitive] = this.Sensitive;
552 [EditorBrowsable(EditorBrowsableState.Never)]
553 protected virtual int AccessibilityGetActionCount()
555 return AccessibilityActions.Length;
558 [EditorBrowsable(EditorBrowsableState.Never)]
559 protected virtual string AccessibilityGetActionName(int index)
561 if (index >= 0 && index < AccessibilityActions.Length)
563 return AccessibilityActions[index];
571 [EditorBrowsable(EditorBrowsableState.Never)]
572 protected virtual bool AccessibilityIsScrollable()
577 [EditorBrowsable(EditorBrowsableState.Never)]
578 protected virtual bool AccessibilityScrollToChild(View child)
584 /// This method is called when the control accessibility is activated.<br />
585 /// Derived classes should override this to perform custom accessibility activation.<br />
587 /// <returns>True if this control can perform accessibility activation.</returns>
588 [EditorBrowsable(EditorBrowsableState.Never)]
589 protected virtual bool OnAccessibilityActivated()
591 return FocusManager.Instance.SetCurrentFocusView(this);
595 /// This method is called when reading is skipped.
597 /// <returns>True if information was served.</returns>
598 [EditorBrowsable(EditorBrowsableState.Never)]
599 protected virtual bool OnAccessibilityReadingSkipped()
605 /// This method is called when reading is cancelled.
607 /// <returns>True if information was served.</returns>
608 [EditorBrowsable(EditorBrowsableState.Never)]
609 protected virtual bool OnAccessibilityReadingCancelled()
615 /// This method is called when reading is stopped.
617 /// <returns>True if information was served.</returns>
618 [EditorBrowsable(EditorBrowsableState.Never)]
619 protected virtual bool OnAccessibilityReadingStopped()
625 /// This method is called when reading was paused.
627 /// <returns>True if information was served.</returns>
628 [EditorBrowsable(EditorBrowsableState.Never)]
629 protected virtual bool OnAccessibilityReadingPaused()
635 /// This method is called when reading is resumed.
637 /// <returns>True if information was served.</returns>
638 [EditorBrowsable(EditorBrowsableState.Never)]
639 protected virtual bool OnAccessibilityReadingResumed()