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