63e2e5378fa04d28536da5aa6a74b381c2ca2a46
[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 partial 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             AccessibilityRole = Role.ToggleButton;
70
71             IsSelectable = true;
72
73             Feedback = true;
74         }
75
76         /// <summary>
77         /// Informs AT-SPI bridge about the set of AT-SPI states associated with this object.
78         /// </summary>
79         [EditorBrowsable(EditorBrowsableState.Never)]
80         protected override AccessibilityStates AccessibilityCalculateStates()
81         {
82             var states = base.AccessibilityCalculateStates();
83
84             states[AccessibilityState.Checked] = this.IsSelected;
85
86             return states;
87         }
88
89         /// <summary>
90         /// An event for the item selected signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
91         /// </summary>
92         /// <since_tizen> 6 </since_tizen>
93         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SelectedChanged event instead.")]
94         public event EventHandler<SelectEventArgs> SelectedEvent;
95
96         /// <summary>
97         /// An event for the item selected signal which can be used to subscribe or unsubscribe the event handler provided by the user.
98         /// </summary>
99         /// <since_tizen> 8 </since_tizen>
100         public event EventHandler<SelectedChangedEventArgs> SelectedChanged;
101
102         /// <summary>
103         /// Return currently applied style.
104         /// </summary>
105         /// <remarks>
106         /// Modifying contents in style may cause unexpected behaviour.
107         /// </remarks>
108         /// <since_tizen> 8 </since_tizen>
109         public new SwitchStyle Style => (SwitchStyle)(ViewStyle as SwitchStyle)?.Clone();
110
111         /// <summary>
112         /// Apply style to switch.
113         /// </summary>
114         /// <param name="viewStyle">The style to apply.</param>
115         [EditorBrowsable(EditorBrowsableState.Never)]
116         public override void ApplyStyle(ViewStyle viewStyle)
117         {
118             if (viewStyle is SwitchStyle switchStyle)
119             {
120                 if (Extension is SwitchExtension extension)
121                 {
122                     Icon.Unparent();
123                     thumb.Unparent();
124                     Icon = extension.OnCreateTrack(this, Icon);
125                     thumb = extension.OnCreateThumb(this, thumb);
126                     Icon.Add(thumb);
127                     LayoutItems();
128                 }
129
130                 if (switchStyle.Track != null)
131                 {
132                     Track.ApplyStyle(switchStyle.Track);
133                 }
134
135                 if (switchStyle.Thumb != null)
136                 {
137                     Thumb.ApplyStyle(switchStyle.Thumb);
138                 }
139             }
140
141             base.ApplyStyle(viewStyle);
142         }
143
144         /// <summary>
145         /// Switch's track part.
146         /// </summary>
147         /// <since_tizen> 8 </since_tizen>
148         public ImageView Track
149         {
150             get => Icon;
151             internal set
152             {
153                 Icon = value;
154             }
155         }
156
157         /// <summary>
158         /// Switch's thumb part.
159         /// </summary>
160         /// <since_tizen> 8 </since_tizen>
161         public ImageView Thumb
162         {
163             get => thumb;
164             internal set
165             {
166                 thumb = value;
167             }
168         }
169
170         /// <summary>
171         /// Switch's track part image url selector.
172         /// </summary>
173         /// <since_tizen> 6 </since_tizen>
174         public StringSelector SwitchBackgroundImageURLSelector
175         {
176             get
177             {
178                 return GetValue(SwitchBackgroundImageURLSelectorProperty) as StringSelector;
179             }
180             set
181             {
182                 SetValue(SwitchBackgroundImageURLSelectorProperty, value);
183                 NotifyPropertyChanged();
184             }
185         }
186         private StringSelector InternalSwitchBackgroundImageURLSelector
187         {
188             get => Icon?.ResourceUrlSelector == null ? null : new StringSelector(Icon.ResourceUrlSelector);
189             set
190             {
191                 Debug.Assert(Icon != null);
192                 Icon.ResourceUrlSelector = value;
193             }
194         }
195
196         /// <summary>
197         /// Handler image's resource url in Switch.
198         /// </summary>
199         /// <since_tizen> 6 </since_tizen>
200         public string SwitchHandlerImageURL
201         {
202             get
203             {
204                 return GetValue(SwitchHandlerImageURLProperty) as string;
205             }
206             set
207             {
208                 SetValue(SwitchHandlerImageURLProperty, value);
209                 NotifyPropertyChanged();
210             }
211         }
212         private string InternalSwitchHandlerImageURL
213         {
214             get
215             {
216                 return Thumb.ResourceUrl;
217             }
218             set
219             {
220                 Thumb.ResourceUrl = value;
221             }
222         }
223
224         /// <summary>
225         /// Handler image's resource url selector in Switch.
226         /// Getter returns copied selector value if exist, null otherwise.
227         /// </summary>
228         /// <since_tizen> 6 </since_tizen>
229         public StringSelector SwitchHandlerImageURLSelector
230         {
231             get
232             {
233                 return GetValue(SwitchHandlerImageURLSelectorProperty) as StringSelector;
234             }
235             set
236             {
237                 SetValue(SwitchHandlerImageURLSelectorProperty, value);
238                 NotifyPropertyChanged();
239             }
240         }
241         private StringSelector InternalSwitchHandlerImageURLSelector
242         {
243             get => new StringSelector(thumb.ResourceUrlSelector);
244             set
245             {
246                 Debug.Assert(thumb != null);
247                 thumb.ResourceUrlSelector = value;
248             }
249         }
250
251         /// <summary>
252         /// Handler image's size in Switch.
253         /// </summary>
254         /// <since_tizen> 6 </since_tizen>
255         public Size SwitchHandlerImageSize
256         {
257             get
258             {
259                 return GetValue(SwitchHandlerImageSizeProperty) as Size;
260             }
261             set
262             {
263                 SetValue(SwitchHandlerImageSizeProperty, value);
264                 NotifyPropertyChanged();
265             }
266         }
267         private Size InternalSwitchHandlerImageSize
268         {
269             get
270             {
271                 return Thumb.Size;
272             }
273             set
274             {
275                 Thumb.Size = value;
276             }
277         }
278
279         /// <summary>
280         /// Dispose Switch and all children on it.
281         /// </summary>
282         /// <param name="type">Dispose type.</param>
283         /// <since_tizen> 6 </since_tizen>
284         protected override void Dispose(DisposeTypes type)
285         {
286             if (disposed) return;
287
288             if (type == DisposeTypes.Explicit)
289             {
290                 Utility.Dispose(thumb);
291             }
292
293             base.Dispose(type);
294         }
295
296         /// <summary>
297         /// Called after a key event is received by the view that has had its focus set.
298         /// </summary>
299         /// <param name="key">The key event.</param>
300         /// <returns>True if the key event should be consumed.</returns>
301         /// <since_tizen> 8 </since_tizen>
302         public override bool OnKey(Key key)
303         {
304             return base.OnKey(key);
305         }
306
307         /// <summary>
308         /// Called after a touch event is received by the owning view.<br />
309         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
310         /// </summary>
311         /// <param name="touch">The touch event.</param>
312         /// <returns>True if the event should be consumed.</returns>
313         /// <since_tizen> 8 </since_tizen>
314         [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
315 #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
316         public override bool OnTouch(Touch touch)
317 #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
318         {
319             return base.OnTouch(touch);
320         }
321
322         /// <summary>
323         /// Get Switch style.
324         /// </summary>
325         /// <returns>The default switch style.</returns>
326         /// <since_tizen> 8 </since_tizen>
327         protected override ViewStyle CreateViewStyle()
328         {
329             return new SwitchStyle();
330         }
331
332         /// <inheritdoc/>
333         [EditorBrowsable(EditorBrowsableState.Never)]
334         protected override ImageView CreateIcon()
335         {
336             var icon = new ImageView()
337             {
338                 AccessibilityHighlightable = false,
339                 EnableControlStatePropagation = true
340             };
341
342             thumb = new ImageView();
343             icon.Add(thumb);
344
345             return icon;
346         }
347
348         /// <inheritdoc/>
349         [EditorBrowsable(EditorBrowsableState.Never)]
350         protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
351         {
352             base.OnControlStateChanged(controlStateChangedInfo);
353
354             if (!IsSelectable)
355             {
356                 return;
357             }
358
359             bool previousSelected = controlStateChangedInfo.PreviousState.Contains(ControlState.Selected);
360
361             if (previousSelected != IsSelected)
362             {
363                 OnSelect();
364             }
365         }
366
367         private void OnSelect()
368         {
369             if (Accessibility.Accessibility.IsEnabled && IsHighlighted)
370             {
371                 EmitAccessibilityStateChangedEvent(AccessibilityState.Checked, IsSelected);
372             }
373
374             ((SwitchExtension)Extension)?.OnSelectedChanged(this);
375
376             if (SelectedEvent != null)
377             {
378                 SelectEventArgs eventArgs = new SelectEventArgs();
379                 eventArgs.IsSelected = IsSelected;
380                 SelectedEvent(this, eventArgs);
381             }
382
383             if (SelectedChanged != null)
384             {
385                 SelectedChangedEventArgs eventArgs = new SelectedChangedEventArgs();
386                 eventArgs.IsSelected = IsSelected;
387                 SelectedChanged(this, eventArgs);
388             }
389         }
390
391         /// <summary>
392         /// SelectEventArgs is a class to record item selected arguments which will sent to user.
393         /// </summary>
394         /// <since_tizen> 6 </since_tizen>
395         /// It will be removed in API10
396         [Obsolete("Deprecated in API8; Will be removed in API10. Please use SelectedChangedEventArgs instead.")]
397         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
398         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
399         public class SelectEventArgs : EventArgs
400         {
401             /// <summary> Select state of Switch </summary>
402             /// <since_tizen> 6 </since_tizen>
403             public bool IsSelected;
404         }
405     }
406 }