[NUI] Refactoring Theme and StyleManager (#1981)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Button.cs
1 /*
2  * Copyright(c) 2020 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.Binding;
21 using Tizen.NUI.Components.Extension;
22 using Tizen.NUI.Accessibility;
23
24 namespace Tizen.NUI.Components
25 {
26     /// <summary>
27     /// ClickedEventArgs is a class to record button click event arguments which will sent to user.
28     /// </summary>
29     /// <since_tizen> 8 </since_tizen>
30     public class ClickedEventArgs : EventArgs
31     {
32     }
33
34     /// <summary>
35     /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it.
36     /// Button may contain text or an icon.
37     /// </summary>
38     /// <since_tizen> 6 </since_tizen>
39     public partial class Button : Control
40     {
41         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
42         [EditorBrowsable(EditorBrowsableState.Never)]
43         public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
44         {
45             var instance = (Button)bindable;
46             if (newValue != null)
47             {
48                 if (instance.buttonStyle != null && instance.buttonStyle.IconRelativeOrientation != (IconOrientation?)newValue)
49                 {
50                     instance.buttonStyle.IconRelativeOrientation = (IconOrientation?)newValue;
51                     instance.UpdateUIContent();
52                 }
53             }
54         },
55         defaultValueCreator: (bindable) =>
56         {
57             var instance = (Button)bindable;
58             return instance.buttonStyle?.IconRelativeOrientation;
59         });
60         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
63         {
64             var instance = (Button)bindable;
65             if (newValue != null)
66             {
67                 bool newEnabled = (bool)newValue;
68                 if (instance.isEnabled != newEnabled)
69                 {
70                     instance.isEnabled = newEnabled;
71
72                     if (instance.buttonStyle != null)
73                     {
74                         instance.buttonStyle.IsEnabled = newEnabled;
75                     }
76
77                     instance.UpdateState();
78                 }
79             }
80         },
81         defaultValueCreator: (bindable) => ((Button)bindable).isEnabled);
82         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
83         [EditorBrowsable(EditorBrowsableState.Never)]
84         public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
85         {
86             var instance = (Button)bindable;
87             if (newValue != null)
88             {
89                 bool newSelected = (bool)newValue;
90                 if (instance.isSelected != newSelected)
91                 {
92                     instance.isSelected = newSelected;
93
94                     if (instance.buttonStyle != null)
95                     {
96                         instance.buttonStyle.IsSelected = newSelected;
97                     }
98
99                     if (instance.isSelectable)
100                     {
101                         instance.UpdateState();
102                     }
103                 }
104             }
105         },
106         defaultValueCreator: (bindable) =>
107         {
108             var instance = (Button)bindable;
109             return instance.isSelectable && instance.isSelected;
110         });
111         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
112         [EditorBrowsable(EditorBrowsableState.Never)]
113         public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
114         {
115             var instance = (Button)bindable;
116             if (newValue != null)
117             {
118                 bool newSelectable = (bool)newValue;
119                 if (instance.isSelectable != newSelectable)
120                 {
121                     instance.isSelectable = newSelectable;
122
123                     if (instance.buttonStyle != null)
124                     {
125                         instance.buttonStyle.IsSelectable = newSelectable;
126                     }
127
128                     instance.UpdateState();
129                 }
130             }
131         },
132         defaultValueCreator: (bindable) => ((Button)bindable).isSelectable);
133
134         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
135         [EditorBrowsable(EditorBrowsableState.Never)]
136         public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
137         {
138             var instance = (Button)bindable;
139             if (null != newValue && null != instance.buttonStyle?.IconPadding)
140             {
141                 instance.buttonStyle.IconPadding.CopyFrom((Extents)newValue);
142                 instance.UpdateUIContent();
143             }
144         },
145         defaultValueCreator: (bindable) =>
146         {
147             var instance = (Button)bindable;
148             return instance.buttonStyle?.IconPadding;
149         });
150         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
151         [EditorBrowsable(EditorBrowsableState.Never)]
152         public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
153         {
154             var instance = (Button)bindable;
155             if (null != newValue && null != instance.buttonStyle?.TextPadding)
156             {
157                 instance.buttonStyle.TextPadding.CopyFrom((Extents)newValue);
158                 instance.UpdateUIContent();
159             }
160         },
161         defaultValueCreator: (bindable) =>
162         {
163             var instance = (Button)bindable;
164             return instance.buttonStyle?.TextPadding;
165         });
166
167         private bool isSelected = false;
168         private bool isSelectable = false;
169         private bool isEnabled = true;
170
171         static Button() { }
172
173         /// <summary>
174         /// Creates a new instance of a Button.
175         /// </summary>
176         /// <since_tizen> 6 </since_tizen>
177         public Button() : base()
178         {
179             Initialize();
180         }
181
182         /// <summary>
183         /// Creates a new instance of a Button with style.
184         /// </summary>
185         /// <param name="style">Create Button by special style defined in UX.</param>
186         /// <since_tizen> 8 </since_tizen>
187         public Button(string style) : base(style)
188         {
189             Initialize();
190         }
191
192         /// <summary>
193         /// Creates a new instance of a Button with style.
194         /// </summary>
195         /// <param name="buttonStyle">Create Button by style customized by user.</param>
196         /// <since_tizen> 8 </since_tizen>
197         public Button(ButtonStyle buttonStyle) : base(buttonStyle)
198         {
199             Initialize();
200         }
201
202         /// <summary>
203         /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
204         /// </summary>
205         /// <since_tizen> 6 </since_tizen>
206         [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
207         public event EventHandler<ClickEventArgs> ClickEvent;
208
209         /// <summary>
210         /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
211         /// </summary>
212         /// <since_tizen> 8 </since_tizen>
213         public event EventHandler<ClickedEventArgs> Clicked;
214
215         /// <summary>
216         /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
217         /// </summary>
218         /// <since_tizen> 6 </since_tizen>
219         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
220         public event EventHandler<StateChangedEventArgs> StateChangedEvent
221         {
222             add
223             {
224                 stateChangeHandler += value;
225             }
226             remove
227             {
228                 stateChangeHandler -= value;
229             }
230         }
231
232         /// <summary>
233         /// Icon orientation.
234         /// </summary>
235         /// <since_tizen> 6 </since_tizen>
236         public enum IconOrientation
237         {
238             /// <summary>
239             /// Top.
240             /// </summary>
241             /// <since_tizen> 6 </since_tizen>
242             Top,
243             /// <summary>
244             /// Bottom.
245             /// </summary>
246             /// <since_tizen> 6 </since_tizen>
247             Bottom,
248             /// <summary>
249             /// Left.
250             /// </summary>
251             /// <since_tizen> 6 </since_tizen>
252             Left,
253             /// <summary>
254             /// Right.
255             /// </summary>
256             /// <since_tizen> 6 </since_tizen>
257             Right,
258         }
259
260         /// <summary>
261         /// Button's icon part.
262         /// </summary>
263         /// <since_tizen> 8 </since_tizen>
264         public ImageView Icon
265         {
266             get
267             {
268                 if (null == buttonIcon)
269                 {
270                     buttonIcon = CreateIcon();
271                     if (null != Extension)
272                     {
273                         buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
274                     }
275                     if (null != buttonIcon)
276                     {
277                         Add(buttonIcon);
278                         buttonIcon.Relayout += OnIconRelayout;
279                     }
280                 }
281                 return buttonIcon;
282             }
283             internal set
284             {
285                 buttonIcon = value;
286             }
287         }
288
289         /// <summary>
290         /// Button's overlay image part.
291         /// </summary>
292         /// <since_tizen> 8 </since_tizen>
293         public ImageView OverlayImage
294         {
295             get
296             {
297                 if (null == overlayImage)
298                 {
299                     overlayImage = CreateOverlayImage();
300                     if (null != Extension)
301                     {
302                         overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
303                     }
304                     if (null != overlayImage)
305                     {
306                         Add(overlayImage);
307                     }
308                 }
309                 return overlayImage;
310             }
311             internal set
312             {
313                 overlayImage = value;
314             }
315         }
316
317         /// <summary>
318         /// Button's text part.
319         /// </summary>
320         /// <since_tizen> 8 </since_tizen>
321         public TextLabel TextLabel
322         {
323             get
324             {
325                 if (null == buttonText)
326                 {
327                     buttonText = CreateText();
328                     if (null != Extension)
329                     {
330                         buttonText = Extension.OnCreateText(this, buttonText);
331                     }
332                     if (null != buttonText)
333                     {
334                         Add(buttonText);
335                     }
336                 }
337                 return buttonText;
338             }
339             internal set
340             {
341                 buttonText = value;
342                 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
343             }
344         }
345
346         /// <summary>
347         /// Return a copied Style instance of Button
348         /// </summary>
349         /// <remarks>
350         /// It returns copied Style instance and changing it does not effect to the Button.
351         /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
352         /// </remarks>
353         /// <since_tizen> 8 </since_tizen>
354         public new ButtonStyle Style
355         {
356             get
357             {
358                 var result = (ButtonStyle)ViewStyle.Clone();
359                 result.CopyPropertiesFromView(this);
360                 result.Text.CopyPropertiesFromView(TextLabel);
361                 result.Icon.CopyPropertiesFromView(Icon);
362                 result.Overlay.CopyPropertiesFromView(OverlayImage);
363                 return result;
364             }
365         }
366
367         /// <summary>
368         /// The text of Button.
369         /// </summary>
370         /// <since_tizen> 6 </since_tizen>
371         public string Text
372         {
373             get
374             {
375                 return TextLabel.Text;
376             }
377             set
378             {
379                 TextLabel.Text = value;
380             }
381         }
382
383         /// <summary>
384         /// Flag to decide Button can be selected or not.
385         /// </summary>
386         /// <since_tizen> 6 </since_tizen>
387         public bool IsSelectable
388         {
389             get
390             {
391                 return (bool)GetValue(IsSelectableProperty);
392             }
393             set
394             {
395                 SetValue(IsSelectableProperty, value);
396             }
397         }
398
399         /// <summary>
400         /// Translate text string in Button.
401         /// </summary>
402         /// <since_tizen> 6 </since_tizen>
403         public string TranslatableText
404         {
405             get
406             {
407                 return TextLabel.TranslatableText;
408             }
409             set
410             {
411                 TextLabel.TranslatableText = value;
412             }
413         }
414
415         /// <summary>
416         /// Text point size in Button.
417         /// </summary>
418         /// <since_tizen> 6 </since_tizen>
419         public float PointSize
420         {
421             get
422             {
423                 return TextLabel.PointSize;
424             }
425             set
426             {
427                 TextLabel.PointSize = value;
428             }
429         }
430
431         /// <summary>
432         /// Text font family in Button.
433         /// </summary>
434         /// <since_tizen> 6 </since_tizen>
435         public string FontFamily
436         {
437             get
438             {
439                 return TextLabel.FontFamily;
440             }
441             set
442             {
443                 TextLabel.FontFamily = value;
444             }
445         }
446
447         /// <summary>
448         /// Text color in Button.
449         /// </summary>
450         /// <since_tizen> 6 </since_tizen>
451         public Color TextColor
452         {
453             get
454             {
455                 return TextLabel.TextColor;
456             }
457             set
458             {
459                 TextLabel.TextColor = value;
460             }
461         }
462
463         /// <summary>
464         /// Text horizontal alignment in Button.
465         /// </summary>
466         /// <since_tizen> 6 </since_tizen>
467         public HorizontalAlignment TextAlignment
468         {
469             get
470             {
471                 return TextLabel.HorizontalAlignment;
472             }
473             set
474             {
475                 TextLabel.HorizontalAlignment = value;
476             }
477         }
478
479         /// <summary>
480         /// Icon image's resource url in Button.
481         /// </summary>
482         /// <since_tizen> 6 </since_tizen>
483         public string IconURL
484         {
485             get
486             {
487                 return Icon.ResourceUrl;
488             }
489             set
490             {
491                 Icon.ResourceUrl = value;
492             }
493         }
494
495         /// <summary>
496         /// Text string selector in Button.
497         /// Getter returns copied selector value if exist, null otherwise.
498         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
499         /// </summary>
500         /// <since_tizen> 6 </since_tizen>
501         public StringSelector TextSelector
502         {
503             get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
504             set
505             {
506                 if (value == null || buttonText == null)
507                 {
508                     throw new NullReferenceException("Button.TextSelector is null");
509                 }
510                 else
511                 {
512                     buttonText.SetValue(TextLabel.TextSelectorProperty, value);
513                 }
514             }
515         }
516
517         /// <summary>
518         /// Translateable text string selector in Button.
519         /// Getter returns copied selector value if exist, null otherwise.
520         /// </summary>
521         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
522         /// <since_tizen> 6 </since_tizen>
523         public StringSelector TranslatableTextSelector
524         {
525             get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
526             set
527             {
528                 if (value == null || buttonText == null)
529                 {
530                     throw new NullReferenceException("Button.TranslatableTextSelector is null");
531                 }
532                 else
533                 {
534                     buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
535                 }
536             }
537         }
538
539         /// <summary>
540         /// Text color selector in Button.
541         /// Getter returns copied selector value if exist, null otherwise.
542         /// </summary>
543         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
544         /// <since_tizen> 6 </since_tizen>
545         public ColorSelector TextColorSelector
546         {
547             get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
548             set
549             {
550                 if (value == null || buttonText == null)
551                 {
552                     throw new NullReferenceException("Button.TextColorSelectorProperty is null");
553                 }
554                 else
555                 {
556                     buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
557                 }
558             }
559         }
560
561         /// <summary>
562         /// Text font size selector in Button.
563         /// Getter returns copied selector value if exist, null otherwise.
564         /// </summary>
565         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
566         /// <since_tizen> 6 </since_tizen>
567         public FloatSelector PointSizeSelector
568         {
569             get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
570             set
571             {
572                 if (value == null || buttonText == null)
573                 {
574                     throw new NullReferenceException("Button.PointSizeSelector is null");
575                 }
576                 else
577                 {
578                     buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
579                 }
580             }
581         }
582
583         /// <summary>
584         /// Icon image's resource url selector in Button.
585         /// Getter returns copied selector value if exist, null otherwise.
586         /// </summary>
587         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
588         /// <since_tizen> 6 </since_tizen>
589         public StringSelector IconURLSelector
590         {
591             get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
592             set
593             {
594                 if (value == null || buttonIcon == null)
595                 {
596                     throw new NullReferenceException("Button.IconURLSelector is null");
597                 }
598                 else
599                 {
600                     buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
601                 }
602             }
603         }
604
605         /// <summary>
606         /// Flag to decide selected state in Button.
607         /// </summary>
608         /// <since_tizen> 6 </since_tizen>
609         public bool IsSelected
610         {
611             get
612             {
613                 return (bool)GetValue(IsSelectedProperty);
614             }
615             set
616             {
617                 SetValue(IsSelectedProperty, value);
618             }
619         }
620
621         /// <summary>
622         /// Flag to decide enable or disable in Button.
623         /// </summary>
624         /// <since_tizen> 6 </since_tizen>
625         public bool IsEnabled
626         {
627             get
628             {
629                 return (bool)GetValue(IsEnabledProperty);
630             }
631             set
632             {
633                 SetValue(IsEnabledProperty, value);
634             }
635         }
636
637         /// <summary>
638         /// Icon relative orientation in Button, work only when show icon and text.
639         /// </summary>
640         /// <since_tizen> 8 </since_tizen>
641         public IconOrientation? IconRelativeOrientation
642         {
643             get
644             {
645                 return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
646             }
647             set
648             {
649                 SetValue(IconRelativeOrientationProperty, value);
650             }
651         }
652
653         /// <summary>
654         /// Icon padding in Button, work only when show icon and text.
655         /// </summary>
656         /// <since_tizen> 6 </since_tizen>
657         public Extents IconPadding
658         {
659             get => (Extents)GetValue(IconPaddingProperty);
660             set => SetValue(IconPaddingProperty, value);
661         }
662
663         /// <summary>
664         /// Text padding in Button, work only when show icon and text.
665         /// </summary>
666         /// <since_tizen> 6 </since_tizen>
667         public Extents TextPadding
668         {
669             get => (Extents)GetValue(TextPaddingProperty);
670             set => SetValue(TextPaddingProperty, value);
671         }
672
673         private ButtonStyle buttonStyle => ViewStyle as ButtonStyle;
674
675         /// <summary>
676         /// Called after a key event is received by the view that has had its focus set.
677         /// </summary>
678         /// <param name="key">The key event.</param>
679         /// <returns>True if the key event should be consumed.</returns>
680         /// <since_tizen> 6 </since_tizen>
681         public override bool OnKey(Key key)
682         {
683             if (!IsEnabled || null == key)
684             {
685                 return false;
686             }
687
688             if (key.State == Key.StateType.Down)
689             {
690                 if (key.KeyPressedName == "Return")
691                 {
692                     isPressed = true;
693                     UpdateState();
694                 }
695             }
696             else if (key.State == Key.StateType.Up)
697             {
698                 if (key.KeyPressedName == "Return")
699                 {
700                     bool clicked = isPressed && IsEnabled;
701
702                     isPressed = false;
703
704                     if (IsSelectable)
705                     {
706                         IsSelected = !IsSelected;
707                     }
708                     else
709                     {
710                         UpdateState();
711                     }
712
713                     if (clicked)
714                     {
715                         ClickedEventArgs eventArgs = new ClickedEventArgs();
716                         OnClickedInternal(eventArgs);
717                     }
718                 }
719             }
720             return base.OnKey(key);
721         }
722
723         /// <summary>
724         /// Called when the control gain key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is gained.
725         /// </summary>
726         /// <since_tizen> 8 </since_tizen>
727         public override void OnFocusGained()
728         {
729             base.OnFocusGained();
730             UpdateState();
731         }
732
733         /// <summary>
734         /// Called when the control loses key input focus. Should be overridden by derived classes if they need to customize what happens when the focus is lost.
735         /// </summary>
736         /// <since_tizen> 8 </since_tizen>
737         public override void OnFocusLost()
738         {
739             base.OnFocusLost();
740             UpdateState();
741         }
742
743         /// <summary>
744         /// Called after a touch event is received by the owning view.<br />
745         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
746         /// </summary>
747         /// <param name="touch">The touch event.</param>
748         /// <returns>True if the event should be consumed.</returns>
749         /// <since_tizen> 8 </since_tizen>
750         public override bool OnTouch(Touch touch)
751         {
752             return base.OnTouch(touch);
753         }
754
755         /// <summary>
756         /// Apply style to button.
757         /// </summary>
758         /// <param name="viewStyle">The style to apply.</param>
759         /// <since_tizen> 8 </since_tizen>
760         public override void ApplyStyle(ViewStyle viewStyle)
761         {
762             styleApplied = false;
763
764             base.ApplyStyle(viewStyle);
765
766             if (null != buttonStyle)
767             {
768                 Extension = buttonStyle.CreateExtension();
769                 if (buttonStyle.Overlay != null)
770                 {
771                     OverlayImage?.ApplyStyle(buttonStyle.Overlay);
772                 }
773
774                 if (buttonStyle.Text != null)
775                 {
776                     TextLabel?.ApplyStyle(buttonStyle.Text);
777                 }
778
779                 if (buttonStyle.Icon != null)
780                 {
781                     Icon?.ApplyStyle(buttonStyle.Icon);
782                 }
783             }
784
785             styleApplied = true;
786         }
787
788         /// <summary>
789         /// ClickEventArgs is a class to record button click event arguments which will sent to user.
790         /// </summary>
791         /// <since_tizen> 6 </since_tizen>
792         [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
793         public class ClickEventArgs : EventArgs
794         {
795         }
796
797         /// <summary>
798         /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
799         /// </summary>
800         /// <since_tizen> 6 </since_tizen>
801         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
802         public class StateChangedEventArgs : EventArgs
803         {
804             /// <summary> previous state of Button </summary>
805             /// <since_tizen> 6 </since_tizen>
806             [Obsolete("Deprecated in API8; Will be removed in API10")]
807             public ControlStates PreviousState;
808             /// <summary> current state of Button </summary>
809             /// <since_tizen> 6 </since_tizen>
810             [Obsolete("Deprecated in API8; Will be removed in API10")]
811             public ControlStates CurrentState;
812         }
813     }
814 }