2 * Copyright(c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.ComponentModel;
19 using Tizen.NUI.BaseComponents;
20 using Tizen.NUI.Binding;
21 using Tizen.NUI.Components.Extension;
23 namespace Tizen.NUI.Components
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.
29 /// <since_tizen> 6 </since_tizen>
30 public partial class Button : Control
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) =>
36 var instance = (Button)bindable;
39 if (instance.Style != null && instance.Style.IconRelativeOrientation != (IconOrientation?)newValue)
41 instance.Style.IconRelativeOrientation = (IconOrientation?)newValue;
42 instance.UpdateUIContent();
46 defaultValueCreator: (bindable) =>
48 var instance = (Button)bindable;
49 return instance.Style?.IconRelativeOrientation;
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) =>
55 var instance = (Button)bindable;
58 instance.isEnabled = (bool)newValue;
59 instance.UpdateState();
62 defaultValueCreator: (bindable) =>
64 var instance = (Button)bindable;
65 return instance.isEnabled;
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) =>
71 var instance = (Button)bindable;
74 instance.isSelected = (bool)newValue;
75 instance.UpdateState();
78 defaultValueCreator: (bindable) =>
80 var instance = (Button)bindable;
81 return instance.isSelected;
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) =>
87 var instance = (Button)bindable;
90 instance.Style.IsSelectable = (bool)newValue;
93 defaultValueCreator: (bindable) =>
95 var instance = (Button)bindable;
96 return instance.Style?.IsSelectable ?? false;
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) =>
102 var instance = (Button)bindable;
103 if (null != newValue && null != instance.Style?.IconPadding)
105 instance.Style.IconPadding.CopyFrom((Extents)newValue);
106 instance.UpdateUIContent();
109 defaultValueCreator: (bindable) =>
111 var instance = (Button)bindable;
112 return instance.Style?.IconPadding;
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) =>
118 var instance = (Button)bindable;
119 if (null != newValue && null != instance.Style?.TextPadding)
121 instance.Style.TextPadding.CopyFrom((Extents)newValue);
122 instance.UpdateUIContent();
125 defaultValueCreator: (bindable) =>
127 var instance = (Button)bindable;
128 return instance.Style?.TextPadding;
134 /// Creates a new instance of a Button.
136 /// <since_tizen> 6 </since_tizen>
137 public Button() : base()
143 /// Creates a new instance of a Button with style.
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)
153 /// Creates a new instance of a Button with style.
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)
163 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
165 /// <since_tizen> 6 </since_tizen>
166 public event EventHandler<ClickEventArgs> ClickEvent;
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 />
171 /// <since_tizen> 6 </since_tizen>
172 public event EventHandler<StateChangedEventArgs> StateChangedEvent
176 stateChangeHander += value;
180 stateChangeHander -= value;
185 /// Icon orientation.
187 /// <since_tizen> 6 </since_tizen>
188 public enum IconOrientation
193 /// <since_tizen> 6 </since_tizen>
198 /// <since_tizen> 6 </since_tizen>
203 /// <since_tizen> 6 </since_tizen>
208 /// <since_tizen> 6 </since_tizen>
213 /// Button's icon part.
215 /// <since_tizen> 8 </since_tizen>
216 public ImageView Icon
220 if (null == buttonIcon)
222 buttonIcon = CreateIcon();
223 if (null != Extension)
225 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
228 buttonIcon.Relayout += OnIconRelayout;
239 /// Button's overlay image part.
241 /// <since_tizen> 8 </since_tizen>
242 public ImageView OverlayImage
246 if (null == overlayImage)
248 overlayImage = CreateOverlayImage();
249 if (null != Extension)
251 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
253 overlayImage.WidthResizePolicy = ResizePolicyType.FillToParent;
254 overlayImage.HeightResizePolicy = ResizePolicyType.FillToParent;
261 overlayImage = value;
266 /// Button's text part.
268 /// <since_tizen> 8 </since_tizen>
269 public TextLabel TextLabel
273 if (null == buttonText)
275 buttonText = CreateText();
276 if (null != Extension)
278 buttonText = Extension.OnCreateText(this, buttonText);
280 buttonText.HorizontalAlignment = HorizontalAlignment.Center;
281 buttonText.VerticalAlignment = VerticalAlignment.Center;
293 /// Return a copied Style instance of Button
296 /// It returns copied Style instance and changing it does not effect to the Button.
297 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
299 /// <since_tizen> 8 </since_tizen>
300 public new ButtonStyle Style => ViewStyle as ButtonStyle;
303 /// The text of Button.
305 /// <since_tizen> 6 </since_tizen>
310 return Style?.Text?.Text?.GetValue(ControlState);
314 if (null != Style?.Text)
316 Style.Text.Text = value;
322 /// Flag to decide Button can be selected or not.
324 /// <since_tizen> 6 </since_tizen>
325 public bool IsSelectable
329 return (bool)GetValue(IsSelectableProperty);
333 SetValue(IsSelectableProperty, value);
338 /// Translate text string in Button.
340 /// <since_tizen> 6 </since_tizen>
341 public string TranslatableText
345 return Style?.Text?.TranslatableText?.All;
349 if (null != Style?.Text)
351 Style.Text.TranslatableText = value;
357 /// Text point size in Button.
359 /// <since_tizen> 6 </since_tizen>
360 public float PointSize
364 return Style?.Text?.PointSize?.All ?? 0;
368 if (null != Style?.Text)
370 Style.Text.PointSize = value;
376 /// Text font family in Button.
378 /// <since_tizen> 6 </since_tizen>
379 public string FontFamily
383 return Style?.Text?.FontFamily.All;
387 if (null != Style?.Text)
389 Style.Text.FontFamily = value;
395 /// Text color in Button.
397 /// <since_tizen> 6 </since_tizen>
398 public Color TextColor
402 return Style?.Text?.TextColor?.All;
406 if (null != Style?.Text)
408 Style.Text.TextColor = value;
414 /// Text horizontal alignment in Button.
416 /// <since_tizen> 6 </since_tizen>
417 public HorizontalAlignment TextAlignment
421 return Style?.Text?.HorizontalAlignment ?? HorizontalAlignment.Center;
425 if (null != Style?.Text)
427 Style.Text.HorizontalAlignment = value;
433 /// Icon image's resource url in Button.
435 /// <since_tizen> 6 </since_tizen>
436 public string IconURL
440 return Style?.Icon?.ResourceUrl?.All;
444 if (null != Style?.Icon)
446 Style.Icon.ResourceUrl = value;
452 /// Text string selector in Button.
454 /// <since_tizen> 6 </since_tizen>
455 public StringSelector TextSelector
463 if (value == null || textSelector == null)
465 Tizen.Log.Fatal("NUI", "[Exception] Button.TextSelector is null");
466 throw new NullReferenceException("Button.TextSelector is null");
470 textSelector.Clone(value);
476 /// Translateable text string selector in Button.
478 /// <since_tizen> 6 </since_tizen>
479 public StringSelector TranslatableTextSelector
483 return translatableTextSelector;
487 if (value == null || translatableTextSelector == null)
489 Tizen.Log.Fatal("NUI", "[Exception] Button.TranslatableTextSelector is null");
490 throw new NullReferenceException("Button.TranslatableTextSelector is null");
494 translatableTextSelector.Clone(value);
500 /// Text color selector in Button.
502 /// <since_tizen> 6 </since_tizen>
503 public ColorSelector TextColorSelector
507 return textColorSelector;
511 if (value == null || textColorSelector == null)
513 Tizen.Log.Fatal("NUI", "[Exception] Button.textColorSelector is null");
514 throw new NullReferenceException("Button.textColorSelector is null");
518 textColorSelector.Clone(value);
524 /// Text font size selector in Button.
526 /// <since_tizen> 6 </since_tizen>
527 public FloatSelector PointSizeSelector
531 return pointSizeSelector;
535 if (value == null || pointSizeSelector == null)
537 Tizen.Log.Fatal("NUI", "[Exception] Button.pointSizeSelector is null");
538 throw new NullReferenceException("Button.pointSizeSelector is null");
542 pointSizeSelector.Clone(value);
548 /// Icon image's resource url selector in Button.
550 /// <since_tizen> 6 </since_tizen>
551 public StringSelector IconURLSelector
555 return iconURLSelector;
559 if (value == null || iconURLSelector == null)
561 Tizen.Log.Fatal("NUI", "[Exception] Button.iconURLSelector is null");
562 throw new NullReferenceException("Button.iconURLSelector is null");
566 iconURLSelector.Clone(value);
572 /// Flag to decide selected state in Button.
574 /// <since_tizen> 6 </since_tizen>
575 public bool IsSelected
579 return (bool)GetValue(IsSelectedProperty);
583 SetValue(IsSelectedProperty, value);
588 /// Flag to decide enable or disable in Button.
590 /// <since_tizen> 6 </since_tizen>
591 public bool IsEnabled
595 return (bool)GetValue(IsEnabledProperty);
599 SetValue(IsEnabledProperty, value);
604 /// Icon relative orientation in Button, work only when show icon and text.
606 /// <since_tizen> 8 </since_tizen>
607 public IconOrientation? IconRelativeOrientation
611 return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
615 SetValue(IconRelativeOrientationProperty, value);
620 /// Icon padding in Button, work only when show icon and text.
622 /// <since_tizen> 6 </since_tizen>
623 public Extents IconPadding
625 get => (Extents)GetValue(IconPaddingProperty);
626 set => SetValue(IconPaddingProperty, value);
630 /// Text padding in Button, work only when show icon and text.
632 /// <since_tizen> 6 </since_tizen>
633 public Extents TextPadding
635 get => (Extents)GetValue(TextPaddingProperty);
636 set => SetValue(TextPaddingProperty, value);
640 /// Called after a key event is received by the view that has had its focus set.
642 /// <param name="key">The key event.</param>
643 /// <returns>True if the key event should be consumed.</returns>
644 /// <since_tizen> 6 </since_tizen>
645 public override bool OnKey(Key key)
647 if (null == key) return false;
648 if (key.State == Key.StateType.Down)
650 if (key.KeyPressedName == "Return")
656 else if (key.State == Key.StateType.Up)
658 if (key.KeyPressedName == "Return")
660 bool clicked = isPressed && isEnabled;
664 if (Style.IsSelectable != null && Style.IsSelectable == true)
666 IsSelected = !IsSelected;
675 ClickEventArgs eventArgs = new ClickEventArgs();
676 OnClickInternal(eventArgs);
680 return base.OnKey(key);
684 /// 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.
686 /// <since_tizen> 8 </since_tizen>
687 public override void OnFocusGained()
689 base.OnFocusGained();
694 /// 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.
696 /// <since_tizen> 8 </since_tizen>
697 public override void OnFocusLost()
704 /// Called after a touch event is received by the owning view.<br />
705 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
707 /// <param name="touch">The touch event.</param>
708 /// <returns>True if the event should be consumed.</returns>
709 /// <since_tizen> 8 </since_tizen>
710 public override bool OnTouch(Touch touch)
712 if (null == touch) return false;
713 PointStateType state = touch.GetState(0);
717 case PointStateType.Down:
719 Extension?.SetTouchInfo(touch);
722 case PointStateType.Interrupted:
726 case PointStateType.Up:
728 bool clicked = isPressed && isEnabled;
732 if (Style.IsSelectable != null && Style.IsSelectable == true)
734 Extension?.SetTouchInfo(touch);
735 IsSelected = !IsSelected;
739 Extension?.SetTouchInfo(touch);
745 ClickEventArgs eventArgs = new ClickEventArgs();
746 OnClickInternal(eventArgs);
754 return base.OnTouch(touch);
758 /// Apply style to button.
760 /// <param name="viewStyle">The style to apply.</param>
761 /// <since_tizen> 8 </since_tizen>
762 public override void ApplyStyle(ViewStyle viewStyle)
764 base.ApplyStyle(viewStyle);
766 ButtonStyle buttonStyle = viewStyle as ButtonStyle;
767 if (null != buttonStyle)
769 Extension = buttonStyle.CreateExtension();
770 if (buttonStyle.Overlay != null)
772 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
775 if (buttonStyle.Text != null)
777 TextLabel?.ApplyStyle(buttonStyle.Text);
780 if (buttonStyle.Icon != null)
782 Icon?.ApplyStyle(buttonStyle.Icon);
788 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
790 /// <since_tizen> 6 </since_tizen>
791 public class ClickEventArgs : EventArgs
796 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
798 /// <since_tizen> 6 </since_tizen>
799 public class StateChangedEventArgs : EventArgs
801 /// <summary> previous state of Button </summary>
802 /// <since_tizen> 6 </since_tizen>
803 public ControlStates PreviousState;
804 /// <summary> current state of Button </summary>
805 /// <since_tizen> 6 </since_tizen>
806 public ControlStates CurrentState;
810 /// Get current text part to the attached ButtonExtension.
813 /// It returns null if the passed extension is invaild.
815 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
816 /// <return>The button's text part.</return>
817 [EditorBrowsable(EditorBrowsableState.Never)]
818 public TextLabel GetCurrentText(ButtonExtension extension)
820 return (extension == Extension) ? TextLabel : null;
824 /// Get current icon part to the attached ButtonExtension.
827 /// It returns null if the passed extension is invaild.
829 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
830 /// <return>The button's icon part.</return>
831 [EditorBrowsable(EditorBrowsableState.Never)]
832 public ImageView GetCurrentIcon(ButtonExtension extension)
834 return (extension == Extension) ? Icon : null;
838 /// Get current overlay image part to the attached ButtonExtension.
841 /// It returns null if the passed extension is invaild.
843 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
844 /// <return>The button's overlay image part.</return>
845 [EditorBrowsable(EditorBrowsableState.Never)]
846 public ImageView GetCurrentOverlayImage(ButtonExtension extension)
848 return (extension == Extension) ? OverlayImage : null;