[NUI][AT-SPI] Rename Accessibility.Enabled to .IsEnabled
[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.IsEnabled && 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 GetValue(TextProperty) as string;
360             }
361             set
362             {
363                 SetValue(TextProperty, value);
364                 NotifyPropertyChanged();
365             }
366         }
367         private string InternalText
368         {
369             get
370             {
371                 return TextLabel.Text;
372             }
373             set
374             {
375                 TextLabel.Text = value;
376
377                 if (Accessibility.Accessibility.IsEnabled && IsHighlighted && String.IsNullOrEmpty(AccessibilityName) && GetAccessibilityNameSignal().Empty())
378                 {
379                     EmitAccessibilityEvent(AccessibilityPropertyChangeEvent.Name);
380                 }
381             }
382         }
383
384         /// <summary>
385         /// Flag to decide Button can be selected or not.
386         /// </summary>
387         /// <since_tizen> 6 </since_tizen>
388         public bool IsSelectable
389         {
390             get
391             {
392                 return (bool)GetValue(IsSelectableProperty);
393             }
394             set
395             {
396                 SetValue(IsSelectableProperty, value);
397             }
398         }
399
400         /// <summary>
401         /// Translate text string in Button.
402         /// </summary>
403         /// <since_tizen> 6 </since_tizen>
404         public string TranslatableText
405         {
406             get
407             {
408                 return GetValue(TranslatableTextProperty) as string;
409             }
410             set
411             {
412                 SetValue(TranslatableTextProperty, value);
413                 NotifyPropertyChanged();
414             }
415         }
416         private string InternalTranslatableText
417         {
418             get
419             {
420                 return TextLabel.TranslatableText;
421             }
422             set
423             {
424                 TextLabel.TranslatableText = value;
425             }
426         }
427
428         /// <summary>
429         /// Text point size in Button.
430         /// </summary>
431         /// <since_tizen> 6 </since_tizen>
432         public float PointSize
433         {
434             get
435             {
436                 return (float)GetValue(PointSizeProperty);
437             }
438             set
439             {
440                 SetValue(PointSizeProperty, value);
441                 NotifyPropertyChanged();
442             }
443         }
444         private float InternalPointSize
445         {
446             get
447             {
448                 return TextLabel.PointSize;
449             }
450             set
451             {
452                 TextLabel.PointSize = value;
453             }
454         }
455
456         /// <summary>
457         /// Text font family in Button.
458         /// </summary>
459         /// <since_tizen> 6 </since_tizen>
460         public string FontFamily
461         {
462             get
463             {
464                 return GetValue(FontFamilyProperty) as string;
465             }
466             set
467             {
468                 SetValue(FontFamilyProperty, value);
469                 NotifyPropertyChanged();
470             }
471         }
472         private string InternalFontFamily
473         {
474             get
475             {
476                 return TextLabel.FontFamily;
477             }
478             set
479             {
480                 TextLabel.FontFamily = value;
481             }
482         }
483
484         /// <summary>
485         /// Text color in Button.
486         /// </summary>
487         /// <since_tizen> 6 </since_tizen>
488         public Color TextColor
489         {
490             get
491             {
492                 return GetValue(TextColorProperty) as Color;
493             }
494             set
495             {
496                 SetValue(TextColorProperty, value);
497                 NotifyPropertyChanged();
498             }
499         }
500         private Color InternalTextColor
501         {
502             get
503             {
504                 return TextLabel.TextColor;
505             }
506             set
507             {
508                 TextLabel.TextColor = value;
509             }
510         }
511
512         /// <summary>
513         /// Text horizontal alignment in Button.
514         /// </summary>
515         /// <since_tizen> 6 </since_tizen>
516         public HorizontalAlignment TextAlignment
517         {
518             get
519             {
520                 return (HorizontalAlignment)GetValue(TextAlignmentProperty);
521             }
522             set
523             {
524                 SetValue(TextAlignmentProperty, value);
525                 NotifyPropertyChanged();
526             }
527         }
528         private HorizontalAlignment InternalTextAlignment
529         {
530             get
531             {
532                 return TextLabel.HorizontalAlignment;
533             }
534             set
535             {
536                 TextLabel.HorizontalAlignment = value;
537             }
538         }
539
540         /// <summary>
541         /// Icon image's resource url in Button.
542         /// </summary>
543         /// <since_tizen> 6 </since_tizen>
544         public string IconURL
545         {
546             get
547             {
548                 return GetValue(IconURLProperty) as string;
549             }
550             set
551             {
552                 SetValue(IconURLProperty, value);
553                 NotifyPropertyChanged();
554             }
555         }
556         private string InternalIconURL
557         {
558             get
559             {
560                 return Icon.ResourceUrl;
561             }
562             set
563             {
564                 Icon.ResourceUrl = value;
565             }
566         }
567
568         /// <summary>
569         /// Icon image's size in Button.
570         /// </summary>
571         [EditorBrowsable(EditorBrowsableState.Never)]
572         public Size IconSize
573         {
574             get
575             {
576                 return GetValue(IconSizeProperty) as Size;
577             }
578             set
579             {
580                 SetValue(IconSizeProperty, value);
581                 NotifyPropertyChanged();
582             }
583         }
584         private Size InternalIconSize
585         {
586             get => Icon.Size;
587             set => Icon.Size = value;
588         }
589
590         /// <summary>
591         /// Text string selector in Button.
592         /// Getter returns copied selector value if exist, null otherwise.
593         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
594         /// </summary>
595         /// <since_tizen> 6 </since_tizen>
596         public StringSelector TextSelector
597         {
598             get
599             {
600                 return GetValue(TextSelectorProperty) as StringSelector;
601             }
602             set
603             {
604                 SetValue(TextSelectorProperty, value);
605                 NotifyPropertyChanged();
606             }
607         }
608         private StringSelector InternalTextSelector
609         {
610             get => buttonText?.TextSelector == null ? null : new StringSelector(buttonText.TextSelector);
611             set
612             {
613                 if (value == null || buttonText == null)
614                 {
615                     throw new NullReferenceException("Button.TextSelector is null");
616                 }
617                 else
618                 {
619                     buttonText.TextSelector = value;
620                 }
621             }
622         }
623
624         /// <summary>
625         /// Translatable text string selector in Button.
626         /// Getter returns copied selector value if exist, null otherwise.
627         /// </summary>
628         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
629         /// <since_tizen> 6 </since_tizen>
630         public StringSelector TranslatableTextSelector
631         {
632             get
633             {
634                 return GetValue(TranslatableTextSelectorProperty) as StringSelector;
635             }
636             set
637             {
638                 SetValue(TranslatableTextSelectorProperty, value);
639                 NotifyPropertyChanged();
640             }
641         }
642         private StringSelector InternalTranslatableTextSelector
643         {
644             get => (buttonText?.TranslatableTextSelector == null) ? null : new StringSelector(buttonText.TranslatableTextSelector);
645             set
646             {
647                 if (value == null || buttonText == null)
648                 {
649                     throw new NullReferenceException("Button.TranslatableTextSelector is null");
650                 }
651                 else
652                 {
653                     buttonText.TranslatableTextSelector = value;
654                 }
655             }
656         }
657
658         /// <summary>
659         /// Text color selector in Button.
660         /// Getter returns copied selector value if exist, null otherwise.
661         /// </summary>
662         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
663         /// <since_tizen> 6 </since_tizen>
664         public ColorSelector TextColorSelector
665         {
666             get
667             {
668                 return GetValue(TextColorSelectorProperty) as ColorSelector;
669             }
670             set
671             {
672                 SetValue(TextColorSelectorProperty, value);
673                 NotifyPropertyChanged();
674             }
675         }
676         private ColorSelector InternalTextColorSelector
677         {
678             get => buttonText?.TextColorSelector == null ? null : new ColorSelector(buttonText.TextColorSelector);
679             set
680             {
681                 if (value == null || buttonText == null)
682                 {
683                     throw new NullReferenceException("Button.TextColorSelectorProperty is null");
684                 }
685                 else
686                 {
687                     buttonText.TextColorSelector = value;
688                 }
689             }
690         }
691
692         /// <summary>
693         /// Text font size selector in Button.
694         /// Getter returns copied selector value if exist, null otherwise.
695         /// </summary>
696         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
697         /// <since_tizen> 6 </since_tizen>
698         public FloatSelector PointSizeSelector
699         {
700             get
701             {
702                 return GetValue(PointSizeSelectorProperty) as FloatSelector;
703             }
704             set
705             {
706                 SetValue(PointSizeSelectorProperty, value);
707                 NotifyPropertyChanged();
708             }
709         }
710         private FloatSelector InternalPointSizeSelector
711         {
712             get => buttonText?.PointSizeSelector == null ? null : new FloatSelector(buttonText.PointSizeSelector);
713             set
714             {
715                 if (value == null || buttonText == null)
716                 {
717                     throw new NullReferenceException("Button.PointSizeSelector is null");
718                 }
719                 else
720                 {
721                     buttonText.PointSizeSelector = value;
722                 }
723             }
724         }
725
726         /// <summary>
727         /// Icon image's resource url selector in Button.
728         /// Getter returns copied selector value if exist, null otherwise.
729         /// </summary>
730         /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
731         /// <since_tizen> 6 </since_tizen>
732         public StringSelector IconURLSelector
733         {
734             get
735             {
736                 return GetValue(IconURLSelectorProperty) as StringSelector;
737             }
738             set
739             {
740                 SetValue(IconURLSelectorProperty, value);
741                 NotifyPropertyChanged();
742             }
743         }
744         private StringSelector InternalIconURLSelector
745         {
746             get => buttonIcon?.ResourceUrlSelector == null ? null : new StringSelector(buttonIcon.ResourceUrlSelector);
747             set
748             {
749                 if (value == null || buttonIcon == null)
750                 {
751                     throw new NullReferenceException("Button.IconURLSelector is null");
752                 }
753                 else
754                 {
755                     buttonIcon.ResourceUrlSelector = value;
756                 }
757             }
758         }
759
760         /// <summary>
761         /// Flag to decide selected state in Button.
762         /// </summary>
763         /// <since_tizen> 6 </since_tizen>
764         public bool IsSelected
765         {
766             get
767             {
768                 return (bool)GetValue(IsSelectedProperty);
769             }
770             set
771             {
772                 SetValue(IsSelectedProperty, value);
773             }
774         }
775
776         /// <summary>
777         /// Flag to decide enable or disable in Button.
778         /// </summary>
779         /// <since_tizen> 6 </since_tizen>
780         public bool IsEnabled
781         {
782             get
783             {
784                 return (bool)GetValue(IsEnabledProperty);
785             }
786             set
787             {
788                 SetValue(IsEnabledProperty, value);
789             }
790         }
791
792         /// <summary>
793         /// Icon relative orientation in Button, work only when show icon and text.
794         /// </summary>
795         /// <since_tizen> 8 </since_tizen>
796         public IconOrientation? IconRelativeOrientation
797         {
798             get
799             {
800                 return (IconOrientation?)GetValue(IconRelativeOrientationProperty) ?? IconOrientation.Left;
801             }
802             set
803             {
804                 SetValue(IconRelativeOrientationProperty, value);
805             }
806         }
807
808         /// <summary>
809         /// Icon padding in Button. It is shortcut of Icon.Padding.
810         /// </summary>
811         /// <since_tizen> 6 </since_tizen>
812         public Extents IconPadding
813         {
814             get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
815             set => SetValue(IconPaddingProperty, value);
816         }
817
818         /// <summary>
819         /// Text padding in Button. It is shortcut of TextLabel.Padding.
820         /// </summary>
821         /// <since_tizen> 6 </since_tizen>
822         public Extents TextPadding
823         {
824             get => (Extents)GetValue(TextPaddingProperty) ?? new Extents();
825             set => SetValue(TextPaddingProperty, value);
826         }
827
828         /// <summary>
829         /// The item (text or icon or both) alignment.
830         /// </summary>
831         /// <since_tizen> 9 </since_tizen>
832         public LinearLayout.Alignment ItemAlignment
833         {
834             get => (LinearLayout.Alignment)GetValue(ItemAlignmentProperty);
835             set => SetValue(ItemAlignmentProperty, value);
836         }
837
838         /// <summary>
839         /// The space between icon and text.
840         /// The value is applied when there exist icon and text both.
841         /// The width value is used when the items are arranged horizontally. Otherwise, the height value is used.
842         /// </summary>
843         /// <since_tizen> 9 </since_tizen>
844         public Size2D ItemSpacing
845         {
846             get => (Size2D)GetValue(ItemSpacingProperty);
847             set => SetValue(ItemSpacingProperty, value);
848         }
849
850         /// <summary>
851         /// Called after a key event is received by the view that has had its focus set.
852         /// </summary>
853         /// <param name="key">The key event.</param>
854         /// <returns>True if the key event should be consumed.</returns>
855         /// <since_tizen> 6 </since_tizen>
856         public override bool OnKey(Key key)
857         {
858             if (!IsEnabled || null == key)
859             {
860                 return false;
861             }
862
863             if (key.State == Key.StateType.Down)
864             {
865                 if (key.KeyPressedName == "Return")
866                 {
867                     isPressed = true;
868                     UpdateState();
869                 }
870             }
871             else if (key.State == Key.StateType.Up)
872             {
873                 if (key.KeyPressedName == "Return")
874                 {
875                     bool clicked = isPressed && IsEnabled;
876
877                     isPressed = false;
878
879                     if (IsSelectable)
880                     {
881                         IsSelected = !IsSelected;
882                     }
883                     else
884                     {
885                         UpdateState();
886                     }
887
888                     if (clicked)
889                     {
890                         ClickedEventArgs eventArgs = new ClickedEventArgs();
891                         OnClickedInternal(eventArgs);
892                     }
893                 }
894             }
895             return base.OnKey(key);
896         }
897
898         /// <summary>
899         /// 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.
900         /// </summary>
901         /// <since_tizen> 8 </since_tizen>
902         public override void OnFocusGained()
903         {
904             base.OnFocusGained();
905             UpdateState();
906         }
907
908         /// <summary>
909         /// 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.
910         /// </summary>
911         /// <since_tizen> 8 </since_tizen>
912         public override void OnFocusLost()
913         {
914             base.OnFocusLost();
915             UpdateState();
916         }
917
918         /// <summary>
919         /// Called after a touch event is received by the owning view.<br />
920         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
921         /// </summary>
922         /// <param name="touch">The touch event.</param>
923         /// <returns>True if the event should be consumed.</returns>
924         /// <since_tizen> 8 </since_tizen>
925         [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
926 #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
927         public override bool OnTouch(Touch touch)
928 #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
929         {
930             return base.OnTouch(touch);
931         }
932
933         /// <summary>
934         /// Apply style to button.
935         /// </summary>
936         /// <param name="viewStyle">The style to apply.</param>
937         /// <since_tizen> 8 </since_tizen>
938         public override void ApplyStyle(ViewStyle viewStyle)
939         {
940             Debug.Assert(buttonIcon != null && buttonText != null);
941
942             styleApplied = false;
943
944             base.ApplyStyle(viewStyle);
945
946             if (viewStyle is ButtonStyle buttonStyle)
947             {
948                 Extension = buttonStyle.CreateExtension();
949
950                 if (buttonStyle.Overlay != null)
951                 {
952                     OverlayImage?.ApplyStyle(buttonStyle.Overlay);
953                 }
954
955                 if (Extension != null)
956                 {
957                     buttonIcon.Unparent();
958                     buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
959
960                     buttonText.Unparent();
961                     buttonText = Extension.OnCreateText(this, buttonText);
962
963                     LayoutItems();
964                 }
965
966                 if (buttonStyle.Text != null)
967                 {
968                     buttonText.ThemeChangeSensitive = false;
969                     buttonText.ApplyStyle(buttonStyle.Text);
970                 }
971
972                 if (buttonStyle.Icon != null)
973                 {
974                     buttonIcon.ApplyStyle(buttonStyle.Icon);
975                 }
976             }
977
978             styleApplied = true;
979             UpdateState();
980         }
981
982         /// <summary>
983         /// ClickEventArgs is a class to record button click event arguments which will sent to user.
984         /// </summary>
985         /// <since_tizen> 6 </since_tizen>
986         [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
987         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
988         public class ClickEventArgs : EventArgs
989         {
990         }
991
992         /// <summary>
993         /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
994         /// </summary>
995         /// <since_tizen> 6 </since_tizen>
996         [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
997         [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
998         public class StateChangedEventArgs : EventArgs
999         {
1000             /// <summary> previous state of Button </summary>
1001             /// <since_tizen> 6 </since_tizen>
1002             /// It will be removed in API10
1003             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1004             [Obsolete("Deprecated in API8; Will be removed in API10")]
1005             public ControlStates PreviousState;
1006             /// <summary> current state of Button </summary>
1007             /// <since_tizen> 6 </since_tizen>
1008             /// It will be removed in API10
1009             [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
1010             [Obsolete("Deprecated in API8; Will be removed in API10")]
1011             public ControlStates CurrentState;
1012         }
1013     }
1014 }