[NUI][ATSPI] Calculate states based on DALi
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Switch.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17 using System;
18 using System.ComponentModel;
19 using System.Diagnostics;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Components.Extension;
22
23 namespace Tizen.NUI.Components
24 {
25     /// <summary>
26     /// Switch is a kind of <see cref="Button"/> component that uses icon part as a toggle shape.
27     /// The icon part consists of track and thumb.
28     /// </summary>
29     /// <since_tizen> 6 </since_tizen>
30     public class Switch : Button
31     {
32         private ImageView thumb = null;
33
34         static Switch() { }
35
36         /// <summary>
37         /// Creates a new instance of a Switch.
38         /// </summary>
39         /// <since_tizen> 6 </since_tizen>
40         public Switch() : base()
41         {
42         }
43
44         /// <summary>
45         /// Creates a new instance of a Switch with style.
46         /// </summary>
47         /// <param name="style">Create Switch by special style defined in UX.</param>
48         /// <since_tizen> 8 </since_tizen>
49         public Switch(string style) : base(style)
50         {
51         }
52
53         /// <summary>
54         /// Creates a new instance of a Switch with style.
55         /// </summary>
56         /// <param name="switchStyle">Create Switch by style customized by user.</param>
57         /// <since_tizen> 8 </since_tizen>
58         public Switch(SwitchStyle switchStyle) : base(switchStyle)
59         {
60         }
61
62         /// <summary>
63         /// Initialize AT-SPI object.
64         /// </summary>
65         [EditorBrowsable(EditorBrowsableState.Never)]
66         public override void OnInitialize()
67         {
68             base.OnInitialize();
69             SetAccessibilityConstructor(Role.ToggleButton);
70
71             IsSelectable = true;
72 #if PROFILE_MOBILE
73             Feedback = true;
74 #endif
75         }
76
77         /// <summary>
78         /// Informs AT-SPI bridge about the set of AT-SPI states associated with this object.
79         /// </summary>
80         [EditorBrowsable(EditorBrowsableState.Never)]
81         protected override AccessibilityStates AccessibilityCalculateStates(ulong states)
82         {
83             var accessibilityStates = base.AccessibilityCalculateStates(states);
84             FlagSetter(ref accessibilityStates, AccessibilityStates.Checked, this.IsSelected);
85             return accessibilityStates;
86         }
87
88         /// <summary>
89         /// An event for the item selected signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
90         /// </summary>
91         /// <since_tizen> 6 </since_tizen>
92         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SelectedChanged event instead.")]
93         public event EventHandler<SelectEventArgs> SelectedEvent;
94
95         /// <summary>
96         /// An event for the item selected signal which can be used to subscribe or unsubscribe the event handler provided by the user.
97         /// </summary>
98         /// <since_tizen> 8 </since_tizen>
99         public event EventHandler<SelectedChangedEventArgs> SelectedChanged;
100
101         /// <summary>
102         /// Return currently applied style.
103         /// </summary>
104         /// <remarks>
105         /// Modifying contents in style may cause unexpected behaviour.
106         /// </remarks>
107         /// <since_tizen> 8 </since_tizen>
108         public new SwitchStyle Style => (SwitchStyle)(ViewStyle as SwitchStyle)?.Clone();
109
110         /// <summary>
111         /// Apply style to switch.
112         /// </summary>
113         /// <param name="viewStyle">The style to apply.</param>
114         [EditorBrowsable(EditorBrowsableState.Never)]
115         public override void ApplyStyle(ViewStyle viewStyle)
116         {
117             if (viewStyle is SwitchStyle switchStyle)
118             {
119                 if (Extension is SwitchExtension extension)
120                 {
121                     Icon.Unparent();
122                     thumb.Unparent();
123                     Icon = extension.OnCreateTrack(this, Icon);
124                     thumb = extension.OnCreateThumb(this, thumb);
125                     Icon.Add(thumb);
126                     LayoutItems();
127                 }
128
129                 if (switchStyle.Track != null)
130                 {
131                     Track.ApplyStyle(switchStyle.Track);
132                 }
133
134                 if (switchStyle.Thumb != null)
135                 {
136                     Thumb.ApplyStyle(switchStyle.Thumb);
137                 }
138             }
139
140             base.ApplyStyle(viewStyle);
141         }
142
143         /// <summary>
144         /// Switch's track part.
145         /// </summary>
146         /// <since_tizen> 8 </since_tizen>
147         public ImageView Track
148         {
149             get => Icon;
150             internal set
151             {
152                 Icon = value;
153             }
154         }
155
156         /// <summary>
157         /// Switch's thumb part.
158         /// </summary>
159         /// <since_tizen> 8 </since_tizen>
160         public ImageView Thumb
161         {
162             get => thumb;
163             internal set
164             {
165                 thumb = value;
166             }
167         }
168
169         /// <summary>
170         /// Switch's track part image url selector.
171         /// </summary>
172         /// <since_tizen> 6 </since_tizen>
173         public StringSelector SwitchBackgroundImageURLSelector
174         {
175             get => new StringSelector(Icon.ResourceUrlSelector);
176             set
177             {
178                 Debug.Assert(Icon != null);
179                 Icon.ResourceUrlSelector = value;
180             }
181         }
182
183         /// <summary>
184         /// Handler image's resource url in Switch.
185         /// </summary>
186         /// <since_tizen> 6 </since_tizen>
187         public string SwitchHandlerImageURL
188         {
189             get
190             {
191                 return Thumb.ResourceUrl;
192             }
193             set
194             {
195                 Thumb.ResourceUrl = value;
196             }
197         }
198
199         /// <summary>
200         /// Handler image's resource url selector in Switch.
201         /// Getter returns copied selector value if exist, null otherwise.
202         /// </summary>
203         /// <since_tizen> 6 </since_tizen>
204         public StringSelector SwitchHandlerImageURLSelector
205         {
206             get => new StringSelector(thumb.ResourceUrlSelector);
207             set
208             {
209                 Debug.Assert(thumb != null);
210                 thumb.ResourceUrlSelector = value;
211             }
212         }
213
214         /// <summary>
215         /// Handler image's size in Switch.
216         /// </summary>
217         /// <since_tizen> 6 </since_tizen>
218         public Size SwitchHandlerImageSize
219         {
220             get
221             {
222                 return Thumb.Size;
223             }
224             set
225             {
226                 Thumb.Size = value;
227             }
228         }
229
230         /// <summary>
231         /// Dispose Switch and all children on it.
232         /// </summary>
233         /// <param name="type">Dispose type.</param>
234         /// <since_tizen> 6 </since_tizen>
235         protected override void Dispose(DisposeTypes type)
236         {
237             if (disposed) return;
238
239             if (type == DisposeTypes.Explicit)
240             {
241                 Utility.Dispose(thumb);
242             }
243
244             base.Dispose(type);
245         }
246
247         /// <summary>
248         /// Called after a key event is received by the view that has had its focus set.
249         /// </summary>
250         /// <param name="key">The key event.</param>
251         /// <returns>True if the key event should be consumed.</returns>
252         /// <since_tizen> 8 </since_tizen>
253         public override bool OnKey(Key key)
254         {
255             return base.OnKey(key);
256         }
257
258         /// <summary>
259         /// Called after a touch event is received by the owning view.<br />
260         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
261         /// </summary>
262         /// <param name="touch">The touch event.</param>
263         /// <returns>True if the event should be consumed.</returns>
264         /// <since_tizen> 8 </since_tizen>
265         [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
266 #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
267         public override bool OnTouch(Touch touch)
268 #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
269         {
270             return base.OnTouch(touch);
271         }
272
273         /// <summary>
274         /// Get Switch style.
275         /// </summary>
276         /// <returns>The default switch style.</returns>
277         /// <since_tizen> 8 </since_tizen>
278         protected override ViewStyle CreateViewStyle()
279         {
280             return new SwitchStyle();
281         }
282
283         /// <inheritdoc/>
284         [EditorBrowsable(EditorBrowsableState.Never)]
285         protected override ImageView CreateIcon()
286         {
287             var icon = new ImageView()
288             {
289                 AccessibilityHighlightable = false,
290                 EnableControlStatePropagation = true
291             };
292
293             thumb = new ImageView();
294             icon.Add(thumb);
295
296             return icon;
297         }
298
299         /// <inheritdoc/>
300         [EditorBrowsable(EditorBrowsableState.Never)]
301         protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
302         {
303             base.OnControlStateChanged(controlStateChangedInfo);
304
305             if (!IsSelectable)
306             {
307                 return;
308             }
309
310             bool previousSelected = controlStateChangedInfo.PreviousState.Contains(ControlState.Selected);
311
312             if (previousSelected != IsSelected)
313             {
314                 OnSelect();
315             }
316         }
317
318         private void OnSelect()
319         {
320             if (Accessibility.Accessibility.Enabled && IsHighlighted)
321             {
322                 EmitAccessibilityStatesChangedEvent(AccessibilityStates.Checked, IsSelected);
323             }
324
325             ((SwitchExtension)Extension)?.OnSelectedChanged(this);
326
327             if (SelectedEvent != null)
328             {
329                 SelectEventArgs eventArgs = new SelectEventArgs();
330                 eventArgs.IsSelected = IsSelected;
331                 SelectedEvent(this, eventArgs);
332             }
333
334             if (SelectedChanged != null)
335             {
336                 SelectedChangedEventArgs eventArgs = new SelectedChangedEventArgs();
337                 eventArgs.IsSelected = IsSelected;
338                 SelectedChanged(this, eventArgs);
339             }
340         }
341
342         /// <summary>
343         /// SelectEventArgs is a class to record item selected arguments which will sent to user.
344         /// </summary>
345         /// <since_tizen> 6 </since_tizen>
346         /// It will be removed in API10
347         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SelectedChangedEventArgs instead.")]
348         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
349         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
350         public class SelectEventArgs : EventArgs
351         {
352             /// <summary> Select state of Switch </summary>
353             /// <since_tizen> 6 </since_tizen>
354             public bool IsSelected;
355         }
356     }
357 }