[NUI] Use new Extents in Tizen.NUI.Compoents (#1116)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Button.cs
1 /*
2  * Copyright(c) 2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 using System;
18 using System.ComponentModel;
19 using Tizen.NUI.BaseComponents;
20
21 namespace Tizen.NUI.Components
22 {
23     /// <summary>
24     /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it.
25     /// Button may contain text or an icon.
26     /// </summary>
27     /// <since_tizen> 6 </since_tizen>
28     public class Button : Control
29     {
30         private ImageView backgroundImage;
31         private ImageView shadowImage;
32         private ImageView overlayImage;
33
34         private TextLabel buttonText;
35         private ImageView buttonIcon;
36
37         private ButtonAttributes buttonAttributes;
38         private EventHandler<StateChangedEventArgs> stateChangeHander;
39
40         private bool isSelected = false;
41         private bool isEnabled = true;
42         private bool isPressed = false;
43
44         private Extents iconPadding = null;
45         private Extents textPadding = null;
46
47         /// <summary>
48         /// Creates a new instance of a Button.
49         /// </summary>
50         /// <since_tizen> 6 </since_tizen>
51         public Button() : base()
52         {
53             Initialize();
54         }
55         /// <summary>
56         /// Creates a new instance of a Button with style.
57         /// </summary>
58         /// <param name="style">Create Button by special style defined in UX.</param>
59         /// <since_tizen> 6 </since_tizen>
60         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public Button(string style) : base(style)
63         {
64             Initialize();
65         }
66         /// <summary>
67         /// Creates a new instance of a Button with attributes.
68         /// </summary>
69         /// <param name="attributes">Create Button by attributes customized by user.</param>
70         /// <since_tizen> 6 </since_tizen>
71         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
72         [EditorBrowsable(EditorBrowsableState.Never)]
73         public Button(ButtonAttributes attributes) : base(attributes)
74         {
75             Initialize();
76         }
77         /// <summary>
78         /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
79         /// </summary>
80         /// <since_tizen> 6 </since_tizen>
81         public event EventHandler<ClickEventArgs> ClickEvent;
82         /// <summary>
83         /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
84         /// </summary>
85         /// <since_tizen> 6 </since_tizen>
86         public event EventHandler<StateChangedEventArgs> StateChangedEvent
87         {
88             add
89             {
90                 stateChangeHander += value;
91             }
92             remove
93             {
94                 stateChangeHander -= value;
95             }
96         }
97         /// <summary>
98         /// Icon orientation.
99         /// </summary>
100         /// <since_tizen> 6 </since_tizen>
101         public enum IconOrientation
102         {
103             /// <summary>
104             /// Top.
105             /// </summary>
106             /// <since_tizen> 6 </since_tizen>
107             Top,
108             /// <summary>
109             /// Bottom.
110             /// </summary>
111             /// <since_tizen> 6 </since_tizen>
112             Bottom,
113             /// <summary>
114             /// Left.
115             /// </summary>
116             /// <since_tizen> 6 </since_tizen>
117             Left,
118             /// <summary>
119             /// Right.
120             /// </summary>
121             /// <since_tizen> 6 </since_tizen>
122             Right,
123         }
124         /// <summary>
125         /// Flag to decide Button can be selected or not.
126         /// </summary>
127         /// <since_tizen> 6 </since_tizen>
128         public bool IsSelectable
129         {
130             get
131             {
132                 return buttonAttributes?.IsSelectable ?? false;
133             }
134             set
135             {
136                 buttonAttributes.IsSelectable = value;
137             }
138         }
139         /// <summary>
140         /// Background image's resource url in Button.
141         /// </summary>
142         /// <since_tizen> 6 </since_tizen>
143         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
144         [EditorBrowsable(EditorBrowsableState.Never)]
145         public string BackgroundImageURL
146         {
147             get
148             {
149                 return buttonAttributes?.BackgroundImageAttributes?.ResourceURL?.All;
150             }
151             set
152             {
153                 if (value != null)
154                 {
155                     CreateBackgroundAttributes();
156                     if (buttonAttributes.BackgroundImageAttributes.ResourceURL == null)
157                     {
158                         buttonAttributes.BackgroundImageAttributes.ResourceURL = new StringSelector();
159                     }
160                     buttonAttributes.BackgroundImageAttributes.ResourceURL.All = value;
161                     RelayoutRequest();
162                 }
163             }
164         }
165         /// <summary>
166         /// Background image's border in Button.
167         /// </summary>
168         /// <since_tizen> 6 </since_tizen>
169         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
170         [EditorBrowsable(EditorBrowsableState.Never)]
171         public Rectangle BackgroundImageBorder
172         {
173             get
174             {
175                 return buttonAttributes?.BackgroundImageAttributes?.Border?.All;
176             }
177             set
178             {
179                 if (value != null)
180                 {
181                     CreateBackgroundAttributes();
182                     if (buttonAttributes.BackgroundImageAttributes.Border == null)
183                     {
184                         buttonAttributes.BackgroundImageAttributes.Border = new RectangleSelector();
185                     }
186                     buttonAttributes.BackgroundImageAttributes.Border.All = value;
187                     RelayoutRequest();
188                 }
189             }
190         }
191         /// <summary>
192         /// Shadow image's resource url in Button.
193         /// </summary>
194         /// <since_tizen> 6 </since_tizen>
195         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
196         [EditorBrowsable(EditorBrowsableState.Never)]
197         public string ShadowImageURL
198         {
199             get
200             {
201                 return buttonAttributes?.ShadowImageAttributes?.ResourceURL?.All;
202             }
203             set
204             {
205                 if (value != null)
206                 {
207                     CreateShadowAttributes();
208                     if (buttonAttributes.ShadowImageAttributes.ResourceURL == null)
209                     {
210                         buttonAttributes.ShadowImageAttributes.ResourceURL = new StringSelector();
211                     }
212                     buttonAttributes.ShadowImageAttributes.ResourceURL.All = value;
213                     RelayoutRequest();
214                 }
215             }
216         }
217         /// <summary>
218         /// Shadow image's border in Button.
219         /// </summary>
220         /// <since_tizen> 6 </since_tizen>
221         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
222         [EditorBrowsable(EditorBrowsableState.Never)]
223         public Rectangle ShadowImageBorder
224         {
225             get
226             {
227                 return buttonAttributes?.ShadowImageAttributes?.Border?.All;
228             }
229             set
230             {
231                 if (value != null)
232                 {
233                     CreateShadowAttributes();
234                     if (buttonAttributes.ShadowImageAttributes.Border == null)
235                     {
236                         buttonAttributes.ShadowImageAttributes.Border = new RectangleSelector();
237                     }
238                     buttonAttributes.ShadowImageAttributes.Border.All = value;
239                     RelayoutRequest();
240                 }
241             }
242         }
243         /// <summary>
244         /// Overlay image's resource url in Button.
245         /// </summary>
246         /// <since_tizen> 6 </since_tizen>
247         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
248         [EditorBrowsable(EditorBrowsableState.Never)]
249         public string OverlayImageURL
250         {
251             get
252             {
253                 return buttonAttributes?.OverlayImageAttributes?.ResourceURL?.All;
254             }
255             set
256             {
257                 if (value != null)
258                 {
259                     CreateOverlayAttributes();
260                     if (buttonAttributes.OverlayImageAttributes.ResourceURL == null)
261                     {
262                         buttonAttributes.OverlayImageAttributes.ResourceURL = new StringSelector();
263                     }
264                     buttonAttributes.OverlayImageAttributes.ResourceURL.All = value;
265                     RelayoutRequest();
266                 }
267             }
268         }
269         /// <summary>
270         /// Overlay image's border in Button.
271         /// </summary>
272         /// <since_tizen> 6 </since_tizen>
273         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
274         [EditorBrowsable(EditorBrowsableState.Never)]
275         public Rectangle OverlayImageBorder
276         {
277             get
278             {
279                 return buttonAttributes?.OverlayImageAttributes?.Border?.All;
280             }
281             set
282             {
283                 if (value != null)
284                 {
285                     CreateOverlayAttributes();
286                     if (buttonAttributes.OverlayImageAttributes.Border == null)
287                     {
288                         buttonAttributes.OverlayImageAttributes.Border = new RectangleSelector();
289                     }
290                     buttonAttributes.OverlayImageAttributes.Border.All = value;
291                     RelayoutRequest();
292                 }
293             }
294         }
295         /// <summary>
296         /// Text string in Button.
297         /// </summary>
298         /// <since_tizen> 6 </since_tizen>
299         public string Text
300         {
301             get
302             {
303                 return buttonAttributes?.TextAttributes?.Text?.All;
304             }
305             set
306             {
307                 if (value != null)
308                 {
309                     CreateTextAttributes();
310                     if(buttonAttributes.TextAttributes.Text == null)
311                     {
312                         buttonAttributes.TextAttributes.Text = new StringSelector();
313                     }
314                     buttonAttributes.TextAttributes.Text.All = value;
315
316                     RelayoutRequest();
317                 }
318             }
319         }
320         /// <summary>
321         /// Translate text string in Button.
322         /// </summary>
323         /// <since_tizen> 6 </since_tizen>
324         public string TranslatableText
325         {
326             get
327             {
328                 return buttonAttributes?.TextAttributes?.TranslatableText?.All;
329             }
330             set
331             {
332                 if (value != null)
333                 {
334                     CreateTextAttributes();
335                     if (buttonAttributes.TextAttributes.TranslatableText == null)
336                     {
337                         buttonAttributes.TextAttributes.TranslatableText = new StringSelector();
338                     }
339                     buttonAttributes.TextAttributes.TranslatableText.All = value;
340
341                     RelayoutRequest();
342                 }
343             }
344         }
345         /// <summary>
346         /// Text point size in Button.
347         /// </summary>
348         /// <since_tizen> 6 </since_tizen>
349         public float PointSize
350         {
351             get
352             {
353                 return buttonAttributes?.TextAttributes?.PointSize?.All ?? 0;
354             }
355             set
356             {
357                 CreateTextAttributes();
358                 if (buttonAttributes.TextAttributes.PointSize == null)
359                 {
360                     buttonAttributes.TextAttributes.PointSize = new FloatSelector();
361                 }
362                 buttonAttributes.TextAttributes.PointSize.All = value;
363                 RelayoutRequest();
364             }
365         }
366         /// <summary>
367         /// Text font family in Button.
368         /// </summary>
369         /// <since_tizen> 6 </since_tizen>
370         public string FontFamily
371         {
372             get
373             {
374                 return buttonAttributes?.TextAttributes?.FontFamily;
375             }
376             set
377             {
378                 CreateTextAttributes();
379                 buttonAttributes.TextAttributes.FontFamily = value;
380                 RelayoutRequest();
381             }
382         }
383         /// <summary>
384         /// Text color in Button.
385         /// </summary>
386         /// <since_tizen> 6 </since_tizen>
387         public Color TextColor
388         {
389             get
390             {
391                 return buttonAttributes?.TextAttributes?.TextColor?.All;
392             }
393             set
394             {
395                 CreateTextAttributes();
396                 if (buttonAttributes.TextAttributes.TextColor == null)
397                 {
398                     buttonAttributes.TextAttributes.TextColor = new ColorSelector();
399                 }
400                 buttonAttributes.TextAttributes.TextColor.All = value;
401                 RelayoutRequest();
402             }
403         }
404         /// <summary>
405         /// Text horizontal alignment in Button.
406         /// </summary>
407         /// <since_tizen> 6 </since_tizen>
408         public HorizontalAlignment TextAlignment
409         {
410             get
411             {
412                 return buttonAttributes?.TextAttributes?.HorizontalAlignment ?? HorizontalAlignment.Center;
413             }
414             set
415             {
416                 CreateTextAttributes();
417                 buttonAttributes.TextAttributes.HorizontalAlignment = value;
418                 RelayoutRequest();
419             }
420         }
421         /// <summary>
422         /// Icon image's resource url in Button.
423         /// </summary>
424         /// <since_tizen> 6 </since_tizen>
425         public string IconURL
426         {
427             get
428             {
429                 return buttonAttributes?.IconAttributes?.ResourceURL?.All;
430             }
431             set
432             {
433                 if (value != null)
434                 {
435                     CreateIconAttributes();
436                     if (buttonAttributes.IconAttributes.ResourceURL == null)
437                     {
438                         buttonAttributes.IconAttributes.ResourceURL = new StringSelector();
439                     }
440                     buttonAttributes.IconAttributes.ResourceURL.All = value;
441                     RelayoutRequest();
442                 }
443             }
444         }
445         /// <summary>
446         /// Text string selector in Button.
447         /// </summary>
448         /// <since_tizen> 6 </since_tizen>
449         public StringSelector TextSelector
450         {
451             get
452             {
453                 return buttonAttributes?.TextAttributes?.Text;
454             }
455             set
456             {
457                 if (value != null)
458                 {
459                     CreateTextAttributes();
460                     buttonAttributes.TextAttributes.Text = value.Clone() as StringSelector;
461                     RelayoutRequest();
462                 }
463             }
464         }
465         /// <summary>
466         /// Translateable text string selector in Button.
467         /// </summary>
468         /// <since_tizen> 6 </since_tizen>
469         public StringSelector TranslatableTextSelector
470         {
471             get
472             {
473                 return buttonAttributes?.TextAttributes?.TranslatableText;
474             }
475             set
476             {
477                 if (value != null)
478                 {
479                     CreateTextAttributes();
480                     buttonAttributes.TextAttributes.TranslatableText = value.Clone() as StringSelector;
481                     RelayoutRequest();
482                 }
483             }
484         }
485         /// <summary>
486         /// Text color selector in Button.
487         /// </summary>
488         /// <since_tizen> 6 </since_tizen>
489         public ColorSelector TextColorSelector
490         {
491             get
492             {
493                 return buttonAttributes?.TextAttributes?.TextColor;
494             }
495             set
496             {
497                 if(value != null)
498                 {
499                     CreateTextAttributes();
500                     buttonAttributes.TextAttributes.TextColor = value.Clone() as ColorSelector;
501                     RelayoutRequest();
502                 }
503             }
504         }
505         /// <summary>
506         /// Text font size selector in Button.
507         /// </summary>
508         /// <since_tizen> 6 </since_tizen>
509         public FloatSelector PointSizeSelector
510         {
511             get
512             {
513                 return buttonAttributes?.TextAttributes?.PointSize;
514             }
515             set
516             {
517                 if (value != null)
518                 {
519                     CreateTextAttributes();
520                     buttonAttributes.TextAttributes.PointSize = value.Clone() as FloatSelector;
521                     RelayoutRequest();
522                 }
523             }
524         }
525         /// <summary>
526         /// Icon image's resource url selector in Button.
527         /// </summary>
528         /// <since_tizen> 6 </since_tizen>
529         public StringSelector IconURLSelector
530         {
531             get
532             {
533                 return buttonAttributes?.IconAttributes?.ResourceURL;
534             }
535             set
536             {
537                 if (value != null)
538                 {
539                     CreateIconAttributes();
540                     buttonAttributes.IconAttributes.ResourceURL = value.Clone() as StringSelector;
541                     RelayoutRequest();
542                 }
543             }
544         }
545         /// <summary>
546         /// Background image's resource url selector in Button.
547         /// </summary>
548         /// <since_tizen> 6 </since_tizen>
549         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
550         [EditorBrowsable(EditorBrowsableState.Never)]
551         public StringSelector BackgroundImageURLSelector
552         {
553             get
554             {
555                 return buttonAttributes?.BackgroundImageAttributes?.ResourceURL;
556             }
557             set
558             {
559                 if (value != null)
560                 {
561                     CreateBackgroundAttributes();
562                     buttonAttributes.BackgroundImageAttributes.ResourceURL = value.Clone() as StringSelector;
563                     RelayoutRequest();
564                 }
565             }
566         }
567         /// <summary>
568         /// Background image's border selector in Button.
569         /// </summary>
570         /// <since_tizen> 6 </since_tizen>
571         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
572         [EditorBrowsable(EditorBrowsableState.Never)]
573         public RectangleSelector BackgroundImageBorderSelector
574         {
575             get
576             {
577                 return buttonAttributes?.BackgroundImageAttributes?.Border;
578             }
579             set
580             {
581                 if (value != null)
582                 {
583                     CreateBackgroundAttributes();
584                     buttonAttributes.BackgroundImageAttributes.Border = value.Clone() as RectangleSelector;
585                     RelayoutRequest();
586                 }
587             }
588         }
589         /// <summary>
590         /// Shadow image's resource url selector in Button.
591         /// </summary>
592         /// <since_tizen> 6 </since_tizen>
593         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
594         [EditorBrowsable(EditorBrowsableState.Never)]
595         public StringSelector ShadowImageURLSelector
596         {
597             get
598             {
599                 return buttonAttributes?.ShadowImageAttributes?.ResourceURL;
600             }
601             set
602             {
603                 if (value != null)
604                 {
605                     CreateShadowAttributes();
606                     buttonAttributes.ShadowImageAttributes.ResourceURL = value.Clone() as StringSelector;
607                     RelayoutRequest();
608                 }
609             }
610         }
611         /// <summary>
612         /// Shadow image's border selector in Button.
613         /// </summary>
614         /// <since_tizen> 6 </since_tizen>
615         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
616         [EditorBrowsable(EditorBrowsableState.Never)]
617         public RectangleSelector ShadowImageBorderSelector
618         {
619             get
620             {
621                 return buttonAttributes?.ShadowImageAttributes?.Border;
622             }
623             set
624             {
625                 if (value != null)
626                 {
627                     CreateShadowAttributes();
628                     buttonAttributes.ShadowImageAttributes.Border = value.Clone() as RectangleSelector;
629                     RelayoutRequest();
630                 }
631             }
632         }
633         /// <summary>
634         /// Overlay image's resource url selector in Button.
635         /// </summary>
636         /// <since_tizen> 6 </since_tizen>
637         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
638         [EditorBrowsable(EditorBrowsableState.Never)]
639         public StringSelector OverlayImageURLSelector
640         {
641             get
642             {
643                 return buttonAttributes?.OverlayImageAttributes?.ResourceURL;
644             }
645             set
646             {
647                 if (value != null)
648                 {
649                     CreateOverlayAttributes();
650                     buttonAttributes.OverlayImageAttributes.ResourceURL = value.Clone() as StringSelector;
651                     RelayoutRequest();
652                 }
653             }
654         }
655         /// <summary>
656         /// Overlay image's border selector in Button.
657         /// </summary>
658         /// <since_tizen> 6 </since_tizen>
659         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
660         [EditorBrowsable(EditorBrowsableState.Never)]
661         public RectangleSelector OverlayImageBorderSelector
662         {
663             get
664             {
665                 return buttonAttributes?.OverlayImageAttributes?.Border;
666             }
667             set
668             {
669                 if (value != null)
670                 {
671                     CreateOverlayAttributes();
672                     buttonAttributes.OverlayImageAttributes.Border = value.Clone() as RectangleSelector;
673                     RelayoutRequest();
674                 }
675             }
676         }
677         /// <summary>
678         /// Flag to decide selected state in Button.
679         /// </summary>
680         /// <since_tizen> 6 </since_tizen>
681         public bool IsSelected
682         {
683             get
684             {
685                 return isSelected;
686             }
687             set
688             {
689                 isSelected = value;
690                 UpdateState();
691             }
692         }
693         /// <summary>
694         /// Flag to decide enable or disable in Button.
695         /// </summary>
696         /// <since_tizen> 6 </since_tizen>
697         public bool IsEnabled
698         {
699             get
700             {
701                 return isEnabled;
702             }
703             set
704             {
705                 isEnabled = value;
706                 UpdateState();
707             }
708         }
709
710         /// <summary>
711         /// Icon relative orientation in Button, work only when show icon and text.
712         /// </summary>
713         /// <since_tizen> 6 </since_tizen>
714         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
715         [EditorBrowsable(EditorBrowsableState.Never)]
716         public IconOrientation? IconRelativeOrientation
717         {
718             get
719             {
720                 return buttonAttributes?.IconRelativeOrientation;
721             }
722             set
723             {
724                 if(buttonAttributes != null && buttonAttributes.IconRelativeOrientation != value)
725                 {
726                     buttonAttributes.IconRelativeOrientation = value;
727                     RelayoutRequest();
728                 }
729             }
730         }
731
732         /// <summary>
733         /// Icon padding in Button, work only when show icon and text.
734         /// </summary>
735         /// <since_tizen> 6 </since_tizen>
736         public Extents IconPadding
737         {
738             get
739             {
740                 return iconPadding;
741             }
742             set
743             {
744                 if (null != value)
745                 {
746                     CreateIconAttributes();
747                     buttonAttributes.IconAttributes.Padding.CopyFrom(value);
748
749                     if (null == iconPadding)
750                     {
751                         iconPadding = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
752                         {
753                             buttonAttributes.IconAttributes.Padding.Start = start;
754                             buttonAttributes.IconAttributes.Padding.End = end;
755                             buttonAttributes.IconAttributes.Padding.Top = top;
756                             buttonAttributes.IconAttributes.Padding.Bottom = bottom;
757                             RelayoutRequest();
758                         }, value.Start, value.End, value.Top, value.Bottom);
759                     }
760                     else
761                     {
762                         iconPadding.CopyFrom(value);
763                     }
764
765                     RelayoutRequest();
766                 }
767             }
768         }
769
770         /// <summary>
771         /// Text padding in Button, work only when show icon and text.
772         /// </summary>
773         /// <since_tizen> 6 </since_tizen>
774         public Extents TextPadding
775         {
776             get
777             {
778                 return textPadding;
779             }
780             set
781             {
782                 if (null != value)
783                 {
784                     CreateTextAttributes();
785
786                     buttonAttributes.TextAttributes.Padding.CopyFrom(value);
787
788                     if (null == textPadding)
789                     {
790                         textPadding = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
791                         {
792                             buttonAttributes.TextAttributes.Padding.Start = start;
793                             buttonAttributes.TextAttributes.Padding.End = end;
794                             buttonAttributes.TextAttributes.Padding.Top = top;
795                             buttonAttributes.TextAttributes.Padding.Bottom = bottom;
796                             RelayoutRequest();
797                         }, value.Start, value.End, value.Top, value.Bottom);
798                     }
799                     else
800                     {
801                         textPadding.CopyFrom(value);
802                     }
803
804                     RelayoutRequest();
805                 }
806             }
807         }
808
809         /// <summary>
810         /// Dispose Button and all children on it.
811         /// </summary>
812         /// <param name="type">Dispose type.</param>
813         /// <since_tizen> 6 </since_tizen>
814         protected override void Dispose(DisposeTypes type)
815         {
816             if (disposed)
817             {
818                 return;
819             }
820
821             if (type == DisposeTypes.Explicit)
822             {
823                 if (buttonIcon != null)
824                 {
825                     buttonIcon.Relayout -= OnIconRelayout;
826                     Utility.Dispose(buttonIcon);
827                 }
828                 if (buttonText != null)
829                 {
830                     Utility.Dispose(buttonText);
831                 }
832                 if (overlayImage != null)
833                 {
834                     Utility.Dispose(overlayImage);
835                 }
836                 if (backgroundImage != null)
837                 {
838                     Utility.Dispose(backgroundImage);
839                 }
840                 if (shadowImage != null)
841                 {
842                     Utility.Dispose(shadowImage);
843                 }
844             }
845
846             base.Dispose(type);
847         }
848         /// <summary>
849         /// Called after a key event is received by the view that has had its focus set.
850         /// </summary>
851         /// <param name="key">The key event.</param>
852         /// <returns>True if the key event should be consumed.</returns>
853         /// <since_tizen> 6 </since_tizen>
854         public override bool OnKey(Key key)
855         {
856             if (key.State == Key.StateType.Down)
857             {
858                 if (key.KeyPressedName == "Return")
859                 {
860                     isPressed = true;
861                     UpdateState();
862                     if(isEnabled)
863                     {
864                         ClickEventArgs eventArgs = new ClickEventArgs();
865                         OnClick(eventArgs);
866                     }
867                 }
868             }
869             else if (key.State == Key.StateType.Up)
870             {
871                 if (key.KeyPressedName == "Return")
872                 {
873                     isPressed = false;
874                     if (buttonAttributes.IsSelectable != null && buttonAttributes.IsSelectable == true)
875                     {
876                         isSelected = !isSelected;
877                     }
878                     UpdateState();
879                 }
880             }
881             return base.OnKey(key);
882         }
883
884         /// <summary>
885         /// 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.
886         /// </summary>
887         /// <since_tizen> 6 </since_tizen>
888         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
889         [EditorBrowsable(EditorBrowsableState.Never)]
890         public override void OnFocusGained()
891         {
892             base.OnFocusGained();
893             UpdateState();
894         }
895         /// <summary>
896         /// 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.
897         /// </summary>
898         /// <since_tizen> 6 </since_tizen>
899         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
900         [EditorBrowsable(EditorBrowsableState.Never)]
901         public override void OnFocusLost()
902         {
903             base.OnFocusLost();
904             UpdateState();
905         }
906
907         /// <summary>
908         /// Tap gesture event callback.
909         /// </summary>
910         /// <param name="source">Source which recieved touch event.</param>
911         /// <param name="e">Tap gesture event argument.</param>
912         /// <since_tizen> 6 </since_tizen>
913         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
914         [EditorBrowsable(EditorBrowsableState.Never)]
915         protected override void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e)
916         {
917             if (isEnabled)
918             {
919                 ClickEventArgs eventArgs = new ClickEventArgs();
920                 OnClick(eventArgs);
921                 base.OnTapGestureDetected(source, e);
922             }
923         }
924         /// <summary>
925         /// Called after a touch event is received by the owning view.<br />
926         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
927         /// </summary>
928         /// <param name="touch">The touch event.</param>
929         /// <returns>True if the event should be consumed.</returns>
930         /// <since_tizen> 6 </since_tizen>
931         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
932         [EditorBrowsable(EditorBrowsableState.Never)]
933         public override bool OnTouch(Touch touch)
934         {
935             PointStateType state = touch.GetState(0);
936       
937             switch(state)
938             {
939                 case PointStateType.Down:
940                     isPressed = true;
941                     UpdateState();
942                     return true;
943                 case PointStateType.Interrupted:
944                     isPressed = false;
945                     UpdateState();
946                     return true;
947                 case PointStateType.Up:
948                     isPressed = false;
949                     if (buttonAttributes.IsSelectable != null && buttonAttributes.IsSelectable == true)
950                     {
951                         isSelected = !isSelected;
952                     }
953                     UpdateState();
954                     return true;
955                 default:
956                     break;
957             }
958             return base.OnTouch(touch);
959         }
960         /// <summary>
961         /// Get Button attribues.
962         /// </summary>
963         /// <since_tizen> 6 </since_tizen>
964         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
965         [EditorBrowsable(EditorBrowsableState.Never)]
966         protected override Attributes GetAttributes()
967         {
968             return new ButtonAttributes();
969         }
970         /// <summary>
971         /// Update Button by attributes.
972         /// </summary>
973         /// <since_tizen> 6 </since_tizen>
974         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
975         [EditorBrowsable(EditorBrowsableState.Never)]
976         protected override void OnUpdate()
977         {
978             if (buttonAttributes.ShadowImageAttributes != null)
979             {
980                 if(shadowImage == null)
981                 {
982                     shadowImage = new ImageView()
983                     {
984                         WidthResizePolicy = ResizePolicyType.FillToParent,
985                         HeightResizePolicy = ResizePolicyType.FillToParent
986                     };
987                     this.Add(shadowImage);
988                 }
989                 ApplyAttributes(shadowImage, buttonAttributes.ShadowImageAttributes);
990             }
991
992             if (buttonAttributes.BackgroundImageAttributes != null)
993             {
994                 if(backgroundImage == null)
995                 {
996                     backgroundImage = new ImageView()
997                     {
998                         WidthResizePolicy = ResizePolicyType.FillToParent,
999                         HeightResizePolicy = ResizePolicyType.FillToParent
1000                     };
1001                     this.Add(backgroundImage);
1002                 }
1003                 ApplyAttributes(backgroundImage, buttonAttributes.BackgroundImageAttributes);
1004             }
1005
1006             if (buttonAttributes.OverlayImageAttributes != null)
1007             {
1008                 if(overlayImage == null)
1009                 {
1010                     overlayImage = new ImageView()
1011                     {
1012                         WidthResizePolicy = ResizePolicyType.FillToParent,
1013                         HeightResizePolicy = ResizePolicyType.FillToParent
1014                     };
1015                     this.Add(overlayImage);
1016                 }
1017                 ApplyAttributes(overlayImage, buttonAttributes.OverlayImageAttributes);
1018             }
1019
1020             if (buttonAttributes.TextAttributes != null)
1021             {
1022                 if(buttonText == null)
1023                 {
1024                     buttonText = new TextLabel();
1025                     this.Add(buttonText);
1026                 }
1027                 ApplyAttributes(buttonText, buttonAttributes.TextAttributes);
1028             }
1029
1030             if (buttonAttributes.IconAttributes != null)
1031             {
1032                 if(buttonIcon == null)
1033                 {
1034                     buttonIcon = new ImageView();
1035                     buttonIcon.Relayout += OnIconRelayout;
1036                     this.Add(buttonIcon);
1037                 }
1038                 ApplyAttributes(buttonIcon, buttonAttributes.IconAttributes);
1039             }
1040
1041             MeasureText();
1042             LayoutChild();
1043
1044             Sensitive = isEnabled ? true : false;
1045         }
1046
1047         /// <summary>
1048         /// Update Button State.
1049         /// </summary>
1050         /// <since_tizen> 6 </since_tizen>
1051         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1052         [EditorBrowsable(EditorBrowsableState.Never)]
1053         protected void UpdateState()
1054         {
1055             ControlStates sourceState = State;
1056             ControlStates targetState;
1057
1058             if(isEnabled)
1059             {
1060                 targetState = isPressed ? ControlStates.Pressed : (IsFocused ? (IsSelected ? ControlStates.SelectedFocused : ControlStates.Focused) : (IsSelected ? ControlStates.Selected : ControlStates.Normal));
1061             }
1062             else
1063             {
1064                 targetState = IsSelected ? ControlStates.DisabledSelected : (IsFocused ? ControlStates.DisabledFocused : ControlStates.Disabled);
1065             }
1066             if(sourceState != targetState)
1067             {
1068                 State = targetState;
1069
1070                 OnUpdate();
1071
1072                 StateChangedEventArgs e = new StateChangedEventArgs
1073                 {
1074                     PreviousState = sourceState,
1075                     CurrentState = targetState
1076                 };
1077                 stateChangeHander?.Invoke(this, e);
1078             }
1079         }
1080         /// <summary>
1081         /// It is hijack by using protected, attributes copy problem when class inherited from Button.
1082         /// </summary>
1083         /// <since_tizen> 6 </since_tizen>
1084         private void Initialize()
1085         {
1086             buttonAttributes = attributes as ButtonAttributes;
1087             if (buttonAttributes == null)
1088             {
1089                 throw new Exception("Button attribute parse error.");
1090             }
1091
1092             ApplyAttributes(this, buttonAttributes);
1093             LayoutDirectionChanged += OnLayoutDirectionChanged;
1094         }
1095
1096         /// <summary>
1097         /// Measure text, it can be override.
1098         /// </summary>
1099         /// <since_tizen> 6 </since_tizen>
1100         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1101         [EditorBrowsable(EditorBrowsableState.Never)]
1102         protected virtual void MeasureText()
1103         {
1104             if (buttonAttributes.IconRelativeOrientation == null || buttonIcon == null || buttonText == null)
1105             {
1106                 return;
1107             }
1108             buttonText.WidthResizePolicy = ResizePolicyType.Fixed;
1109             buttonText.HeightResizePolicy = ResizePolicyType.Fixed;
1110             int textPaddingStart = buttonAttributes.TextAttributes.Padding.Start;
1111             int textPaddingEnd = buttonAttributes.TextAttributes.Padding.End;
1112             int textPaddingTop = buttonAttributes.TextAttributes.Padding.Top;
1113             int textPaddingBottom = buttonAttributes.TextAttributes.Padding.Bottom;
1114
1115             int iconPaddingStart = buttonAttributes.IconAttributes.Padding.Start;
1116             int iconPaddingEnd = buttonAttributes.IconAttributes.Padding.End;
1117             int iconPaddingTop = buttonAttributes.IconAttributes.Padding.Top;
1118             int iconPaddingBottom = buttonAttributes.IconAttributes.Padding.Bottom;
1119
1120             if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom)
1121             {
1122                 buttonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd;
1123                 buttonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - buttonIcon.SizeHeight;
1124             }
1125             else
1126             {
1127                 buttonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - buttonIcon.SizeWidth;
1128                 buttonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom;
1129             }
1130         }
1131         /// <summary>
1132         /// Layout child, it can be override.
1133         /// </summary>
1134         /// <since_tizen> 6 </since_tizen>
1135         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1136         [EditorBrowsable(EditorBrowsableState.Never)]
1137         protected virtual void LayoutChild()
1138         {
1139             if (buttonAttributes.IconRelativeOrientation == null || buttonIcon == null || buttonText == null)
1140             {
1141                 return;
1142             }
1143
1144             int textPaddingStart = buttonAttributes.TextAttributes.Padding.Start;
1145             int textPaddingEnd = buttonAttributes.TextAttributes.Padding.End;
1146             int textPaddingTop = buttonAttributes.TextAttributes.Padding.Top;
1147             int textPaddingBottom = buttonAttributes.TextAttributes.Padding.Bottom;
1148
1149             int iconPaddingStart = buttonAttributes.IconAttributes.Padding.Start;
1150             int iconPaddingEnd = buttonAttributes.IconAttributes.Padding.End;
1151             int iconPaddingTop = buttonAttributes.IconAttributes.Padding.Top;
1152             int iconPaddingBottom = buttonAttributes.IconAttributes.Padding.Bottom;
1153
1154             switch (IconRelativeOrientation)
1155             {
1156                 case IconOrientation.Top:
1157                     buttonIcon.PositionUsesPivotPoint = true;
1158                     buttonIcon.ParentOrigin = NUI.ParentOrigin.TopCenter;
1159                     buttonIcon.PivotPoint = NUI.PivotPoint.TopCenter;
1160                     buttonIcon.Position2D = new Position2D(0, iconPaddingTop);
1161
1162                     buttonText.PositionUsesPivotPoint = true;
1163                     buttonText.ParentOrigin = NUI.ParentOrigin.BottomCenter;
1164                     buttonText.PivotPoint = NUI.PivotPoint.BottomCenter;
1165                     buttonText.Position2D = new Position2D(0, -textPaddingBottom);
1166                     break;
1167                 case IconOrientation.Bottom:
1168                     buttonIcon.PositionUsesPivotPoint = true;
1169                     buttonIcon.ParentOrigin = NUI.ParentOrigin.BottomCenter;
1170                     buttonIcon.PivotPoint = NUI.PivotPoint.BottomCenter;
1171                     buttonIcon.Position2D = new Position2D(0, -iconPaddingBottom);
1172
1173                     buttonText.PositionUsesPivotPoint = true;
1174                     buttonText.ParentOrigin = NUI.ParentOrigin.TopCenter;
1175                     buttonText.PivotPoint = NUI.PivotPoint.TopCenter;
1176                     buttonText.Position2D = new Position2D(0, textPaddingTop);
1177                     break;
1178                 case IconOrientation.Left:
1179                     if (LayoutDirection == ViewLayoutDirectionType.LTR)
1180                     {
1181                         buttonIcon.PositionUsesPivotPoint = true;
1182                         buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
1183                         buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
1184                         buttonIcon.Position2D = new Position2D(iconPaddingStart, 0);
1185
1186                         buttonText.PositionUsesPivotPoint = true;
1187                         buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
1188                         buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
1189                         buttonText.Position2D = new Position2D(-textPaddingEnd, 0);
1190                     }
1191                     else
1192                     {
1193                         buttonIcon.PositionUsesPivotPoint = true;
1194                         buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
1195                         buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
1196                         buttonIcon.Position2D = new Position2D(-iconPaddingStart, 0);
1197
1198                         buttonText.PositionUsesPivotPoint = true;
1199                         buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
1200                         buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
1201                         buttonText.Position2D = new Position2D(textPaddingEnd, 0);
1202                     }
1203
1204                     break;
1205                 case IconOrientation.Right:
1206                     if (LayoutDirection == ViewLayoutDirectionType.RTL)
1207                     {
1208                         buttonIcon.PositionUsesPivotPoint = true;
1209                         buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
1210                         buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
1211                         buttonIcon.Position2D = new Position2D(iconPaddingEnd, 0);
1212
1213                         buttonText.PositionUsesPivotPoint = true;
1214                         buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
1215                         buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
1216                         buttonText.Position2D = new Position2D(-textPaddingStart, 0);
1217                     }
1218                     else
1219                     {
1220                         buttonIcon.PositionUsesPivotPoint = true;
1221                         buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
1222                         buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
1223                         buttonIcon.Position2D = new Position2D(-iconPaddingEnd, 0);
1224
1225                         buttonText.PositionUsesPivotPoint = true;
1226                         buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
1227                         buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
1228                         buttonText.Position2D = new Position2D(textPaddingStart, 0);
1229                     }
1230                     break;
1231                 default:
1232                     break;
1233             }
1234         }
1235         /// <summary>
1236         /// Theme change callback when theme is changed, this callback will be trigger.
1237         /// </summary>
1238         /// <since_tizen> 6 </since_tizen>
1239         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
1240         [EditorBrowsable(EditorBrowsableState.Never)]
1241         protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
1242         {
1243             ButtonAttributes tempAttributes = StyleManager.Instance.GetAttributes(style) as ButtonAttributes;
1244             if(tempAttributes != null)
1245             {
1246                 attributes = buttonAttributes = tempAttributes;
1247                 RelayoutRequest();
1248             }
1249         }
1250
1251         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
1252         {
1253             MeasureText();
1254             LayoutChild();
1255         }
1256
1257         private void OnClick(ClickEventArgs eventArgs)
1258         {
1259             ClickEvent?.Invoke(this, eventArgs);
1260         }
1261
1262         private void OnIconRelayout(object sender, EventArgs e)
1263         {
1264             MeasureText();
1265             LayoutChild();
1266         }
1267
1268         private void CreateBackgroundAttributes()
1269         {
1270             if (buttonAttributes.BackgroundImageAttributes == null)
1271             {
1272                 buttonAttributes.BackgroundImageAttributes = new ImageAttributes()
1273                 {
1274                     PositionUsesPivotPoint = true,
1275                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
1276                     PivotPoint = Tizen.NUI.PivotPoint.Center,
1277                     WidthResizePolicy = ResizePolicyType.FillToParent,
1278                     HeightResizePolicy = ResizePolicyType.FillToParent
1279                 };
1280             }
1281         }
1282
1283         private void CreateShadowAttributes()
1284         {
1285             if (buttonAttributes.ShadowImageAttributes == null)
1286             {
1287                 buttonAttributes.ShadowImageAttributes = new ImageAttributes()
1288                 {
1289                     PositionUsesPivotPoint = true,
1290                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
1291                     PivotPoint = Tizen.NUI.PivotPoint.Center,
1292                     WidthResizePolicy = ResizePolicyType.FillToParent,
1293                     HeightResizePolicy = ResizePolicyType.FillToParent
1294                 };
1295             }
1296         }
1297
1298         private void CreateOverlayAttributes()
1299         {
1300             if (buttonAttributes.OverlayImageAttributes == null)
1301             {
1302                 buttonAttributes.OverlayImageAttributes = new ImageAttributes()
1303                 {
1304                     PositionUsesPivotPoint = true,
1305                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
1306                     PivotPoint = Tizen.NUI.PivotPoint.Center,
1307                     WidthResizePolicy = ResizePolicyType.FillToParent,
1308                     HeightResizePolicy = ResizePolicyType.FillToParent
1309                 };
1310             }
1311         }
1312
1313         private void CreateTextAttributes()
1314         {
1315             if (buttonAttributes.TextAttributes == null)
1316             {
1317                 buttonAttributes.TextAttributes = new TextAttributes()
1318                 {
1319                     PositionUsesPivotPoint = true,
1320                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
1321                     PivotPoint = Tizen.NUI.PivotPoint.Center,
1322                     WidthResizePolicy = ResizePolicyType.FillToParent,
1323                     HeightResizePolicy = ResizePolicyType.FillToParent,
1324                     HorizontalAlignment = HorizontalAlignment.Center,
1325                     VerticalAlignment = VerticalAlignment.Center
1326                 };
1327             }
1328         }
1329
1330         private void CreateIconAttributes()
1331         {
1332             if (buttonAttributes.IconAttributes == null)
1333             {
1334                 buttonAttributes.IconAttributes = new ImageAttributes()
1335                 {
1336                     PositionUsesPivotPoint = true,
1337                     ParentOrigin = Tizen.NUI.ParentOrigin.Center,
1338                     PivotPoint = Tizen.NUI.PivotPoint.Center,
1339                     WidthResizePolicy = ResizePolicyType.UseNaturalSize,
1340                     HeightResizePolicy = ResizePolicyType.UseNaturalSize,
1341                 };
1342             }
1343         }
1344         /// <summary>
1345         /// ClickEventArgs is a class to record button click event arguments which will sent to user.
1346         /// </summary>
1347         /// <since_tizen> 6 </since_tizen>
1348         public class ClickEventArgs : EventArgs
1349         {
1350         }
1351         /// <summary>
1352         /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
1353         /// </summary>
1354         /// <since_tizen> 6 </since_tizen>
1355         public class StateChangedEventArgs : EventArgs
1356         {
1357             /// <summary> previous state of Button </summary>
1358             /// <since_tizen> 6 </since_tizen>
1359             public ControlStates PreviousState;
1360             /// <summary> current state of Button </summary>
1361             /// <since_tizen> 6 </since_tizen>
1362             public ControlStates CurrentState;
1363         }
1364
1365     }
1366 }