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