[NUI] Fix Switch selection bug. (#1798)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Switch.cs
1 /*
2  * Copyright(c) 2019 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 Tizen.NUI.BaseComponents;
20 using Tizen.NUI.Components.Extension;
21
22 namespace Tizen.NUI.Components
23 {
24     /// <summary>
25     /// Switch is one kind of common component, it can be used as selector.
26     /// User can handle Navigation by adding/inserting/deleting NavigationItem.
27     /// </summary>
28     /// <since_tizen> 6 </since_tizen>
29     public class Switch : Button
30     {
31         private ImageView track = null;
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             Initialize();
43         }
44
45         /// <summary>
46         /// Creates a new instance of a Switch with style.
47         /// </summary>
48         /// <param name="style">Create Switch by special style defined in UX.</param>
49         /// <since_tizen> 8 </since_tizen>
50         public Switch(string style) : base(style)
51         {
52             Initialize();
53         }
54
55         /// <summary>
56         /// Creates a new instance of a Switch with style.
57         /// </summary>
58         /// <param name="switchStyle">Create Switch by style customized by user.</param>
59         /// <since_tizen> 8 </since_tizen>
60         public Switch(SwitchStyle switchStyle) : base(switchStyle)
61         {
62             Initialize();
63         }
64
65         /// <summary>
66         /// An event for the item selected signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
67         /// </summary>
68         /// <since_tizen> 6 </since_tizen>
69         public event EventHandler<SelectEventArgs> SelectedEvent;
70
71         /// <summary>
72         /// Get style of switch.
73         /// </summary>
74         /// <since_tizen> 8 </since_tizen>
75         public new SwitchStyle Style => ViewStyle as SwitchStyle;
76
77         /// <summary>
78         /// Apply style to switch.
79         /// </summary>
80         /// <param name="viewStyle">The style to apply.</param>
81         [EditorBrowsable(EditorBrowsableState.Never)]
82         public override void ApplyStyle(ViewStyle viewStyle)
83         {
84             base.ApplyStyle(viewStyle);
85
86             SwitchStyle swStyle = viewStyle as SwitchStyle;
87
88             if (null != swStyle)
89             {
90                 if (swStyle.Track != null)
91                 {
92                     Track.ApplyStyle(swStyle.Track);
93                 }
94
95                 if (swStyle.Thumb != null)
96                 {
97                     Thumb.ApplyStyle(swStyle.Thumb);
98                 }
99             }
100         }
101
102         /// <summary>
103         /// Switch's track part.
104         /// </summary>
105         /// <since_tizen> 8 </since_tizen>
106         public ImageView Track
107         {
108             get
109             {
110                 if (track == null)
111                 {
112                     track = new ImageView()
113                     {
114                         PositionUsesPivotPoint = true,
115                         ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft,
116                         PivotPoint = Tizen.NUI.PivotPoint.CenterLeft,
117                         WidthResizePolicy = ResizePolicyType.FillToParent,
118                         HeightResizePolicy = ResizePolicyType.FillToParent
119                     };
120
121                     var extension = (SwitchExtension)Extension;
122                     if (extension != null)
123                     {
124                         track = extension.OnCreateTrack(this, track);
125                     }
126                     Add(track);
127                 }
128                 return track;
129             }
130             internal set
131             {
132                 track = value;
133             }
134         }
135
136         /// <summary>
137         /// Switch's thumb part.
138         /// </summary>
139         /// <since_tizen> 8 </since_tizen>
140         public ImageView Thumb
141         {
142             get
143             {
144                 if (thumb == null)
145                 {
146                     thumb = new ImageView()
147                     {
148                         PositionUsesPivotPoint = true,
149                         ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft,
150                         PivotPoint = Tizen.NUI.PivotPoint.CenterLeft,
151                         WidthResizePolicy = ResizePolicyType.Fixed,
152                         HeightResizePolicy = ResizePolicyType.Fixed
153                     };
154
155                     var extension = (SwitchExtension)Extension;
156                     if (extension != null)
157                     {
158                         thumb = extension.OnCreateThumb(this, thumb);
159                     }
160                     Add(thumb);
161                 }
162                 return thumb;
163             }
164             internal set
165             {
166                 thumb = value;
167             }
168         }
169
170         /// <summary>
171         /// Background image's resource url selector in Switch.
172         /// </summary>
173         /// <since_tizen> 6 </since_tizen>
174         public StringSelector SwitchBackgroundImageURLSelector
175         {
176             get
177             {
178                 StringSelector strSl = new StringSelector();
179                 strSl.Clone(Style?.Track?.ResourceUrl);
180                 return strSl;
181             }
182             set
183             {
184                 if (null != value && null != Style?.Track)
185                 {
186                     Style.Track.ResourceUrl = value;
187                 }
188             }
189         }
190
191         /// <summary>
192         /// Handler image's resource url in Switch.
193         /// </summary>
194         /// <since_tizen> 6 </since_tizen>
195         public string SwitchHandlerImageURL
196         {
197             get
198             {
199                 return Style?.Thumb?.ResourceUrl?.All;
200             }
201             set
202             {
203                 if (null != value && null != Style?.Thumb)
204                 {
205                     Style.Thumb.ResourceUrl = value;
206                 }
207             }
208         }
209
210         /// <summary>
211         /// Handler image's resource url selector in Switch.
212         /// </summary>
213         /// <since_tizen> 6 </since_tizen>
214         public StringSelector SwitchHandlerImageURLSelector
215         {
216             get
217             {
218                 StringSelector strSl = new StringSelector();
219                 strSl.Clone(Style?.Thumb?.ResourceUrl);
220                 return strSl;
221             }
222             set
223             {
224                 if (null != value && null != Style?.Thumb)
225                 {
226                     Style.Thumb.ResourceUrl = value;
227                 }
228             }
229         }
230
231         /// <summary>
232         /// Handler image's size in Switch.
233         /// </summary>
234         /// <since_tizen> 6 </since_tizen>
235         public Size SwitchHandlerImageSize
236         {
237             get
238             {
239                 return Style?.Thumb?.Size;
240             }
241             set
242             {
243                 if (null != Style?.Thumb)
244                 {
245                     Style.Thumb.Size = value;
246                 }
247             }
248         }
249
250         /// <summary>
251         /// Dispose Switch and all children on it.
252         /// </summary>
253         /// <param name="type">Dispose type.</param>
254         /// <since_tizen> 6 </since_tizen>
255         protected override void Dispose(DisposeTypes type)
256         {
257             if (disposed) return;
258
259             if (type == DisposeTypes.Explicit)
260             {
261                 Utility.Dispose(Thumb);
262                 Utility.Dispose(Track);
263             }
264
265             base.Dispose(type);
266         }
267
268         /// <summary>
269         /// Called after a key event is received by the view that has had its focus set.
270         /// </summary>
271         /// <param name="key">The key event.</param>
272         /// <returns>True if the key event should be consumed.</returns>
273         /// <since_tizen> 8 </since_tizen>
274         public override bool OnKey(Key key)
275         {
276             return base.OnKey(key);
277         }
278
279         /// <summary>
280         /// Called after a touch event is received by the owning view.<br />
281         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
282         /// </summary>
283         /// <param name="touch">The touch event.</param>
284         /// <returns>True if the event should be consumed.</returns>
285         /// <since_tizen> 8 </since_tizen>
286         public override bool OnTouch(Touch touch)
287         {
288             return base.OnTouch(touch);
289         }
290
291         /// <summary>
292         /// Get Switch style.
293         /// </summary>
294         /// <returns>The default switch style.</returns>
295         /// <since_tizen> 8 </since_tizen>
296         protected override ViewStyle CreateViewStyle()
297         {
298             return new SwitchStyle();
299         }
300
301         /// <inheritdoc/>
302         [EditorBrowsable(EditorBrowsableState.Never)]
303         protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
304         {
305             base.OnControlStateChanged(controlStateChangedInfo);
306
307             if (!IsSelectable)
308             {
309                 return;
310             }
311
312             bool previousSelected = controlStateChangedInfo.PreviousState.Contains(ControlState.Selected);
313
314             if (previousSelected != IsSelected)
315             {
316                 OnSelect();
317             }
318         }
319
320         private void Initialize()
321         {
322             Style.IsSelectable = true;
323         }
324
325         /// <summary>
326         /// Theme change callback when theme is changed, this callback will be trigger.
327         /// </summary>
328         /// <param name="sender">The sender</param>
329         /// <param name="e">The event data</param>
330         [EditorBrowsable(EditorBrowsableState.Never)]
331         protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
332         {
333             SwitchStyle switchStyle = StyleManager.Instance.GetViewStyle(StyleName) as SwitchStyle;
334             if (null != switchStyle)
335             {
336                 Style.CopyFrom(switchStyle);
337             }
338         }
339
340         private void OnSelect()
341         {
342             ((SwitchExtension)Extension)?.OnSelectedChanged(this);
343
344             if (SelectedEvent != null)
345             {
346                 SelectEventArgs eventArgs = new SelectEventArgs();
347                 eventArgs.IsSelected = IsSelected;
348                 SelectedEvent(this, eventArgs);
349             }
350         }
351
352         /// <summary>
353         /// SelectEventArgs is a class to record item selected arguments which will sent to user.
354         /// </summary>
355         /// <since_tizen> 6 </since_tizen>
356         public class SelectEventArgs : EventArgs
357         {
358             /// <summary> Select state of Switch </summary>
359             /// <since_tizen> 6 </since_tizen>
360             public bool IsSelected;
361         }
362     }
363 }