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 /// ClickedEventArgs is a class to record button click event arguments which will sent to user.
28 /// <since_tizen> 8 </since_tizen>
29 public class ClickedEventArgs : EventArgs
34 /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it.
35 /// Button may contain text or an icon.
37 /// <since_tizen> 6 </since_tizen>
38 public partial class Button : Control
40 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
41 [EditorBrowsable(EditorBrowsableState.Never)]
42 public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
44 var instance = (Button)bindable;
47 if (instance.buttonStyle != null && instance.buttonStyle.IconRelativeOrientation != (IconOrientation?)newValue)
49 instance.buttonStyle.IconRelativeOrientation = (IconOrientation?)newValue;
50 instance.UpdateUIContent();
54 defaultValueCreator: (bindable) =>
56 var instance = (Button)bindable;
57 return instance.buttonStyle?.IconRelativeOrientation;
59 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
60 [EditorBrowsable(EditorBrowsableState.Never)]
61 public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
63 var instance = (Button)bindable;
66 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsEnabled != (bool)newValue))
68 instance.buttonStyle.IsEnabled = (bool)newValue;
69 instance.UpdateState();
73 defaultValueCreator: (bindable) =>
75 var instance = (Button)bindable;
76 return instance.buttonStyle?.IsEnabled ?? true;
78 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
79 [EditorBrowsable(EditorBrowsableState.Never)]
80 public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
82 var instance = (Button)bindable;
85 if (instance.buttonStyle != null && instance.IsSelectable && (!instance.styleApplied || instance.buttonStyle.IsSelected != (bool)newValue))
87 instance.buttonStyle.IsSelected = (bool)newValue;
88 instance.UpdateState();
92 defaultValueCreator: (bindable) =>
94 var instance = (Button)bindable;
95 return instance.IsSelectable && (instance.buttonStyle.IsSelected ?? false);
97 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
98 [EditorBrowsable(EditorBrowsableState.Never)]
99 public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
101 var instance = (Button)bindable;
102 if (newValue != null)
104 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsSelectable != (bool)newValue))
106 instance.buttonStyle.IsSelectable = (bool)newValue;
110 defaultValueCreator: (bindable) =>
112 var instance = (Button)bindable;
113 return instance.buttonStyle?.IsSelectable ?? false;
115 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
116 [EditorBrowsable(EditorBrowsableState.Never)]
117 public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
119 var instance = (Button)bindable;
120 if (null != newValue && null != instance.buttonStyle?.IconPadding)
122 instance.buttonStyle.IconPadding.CopyFrom((Extents)newValue);
123 instance.UpdateUIContent();
126 defaultValueCreator: (bindable) =>
128 var instance = (Button)bindable;
129 return instance.buttonStyle?.IconPadding;
131 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
132 [EditorBrowsable(EditorBrowsableState.Never)]
133 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
135 var instance = (Button)bindable;
136 if (null != newValue && null != instance.buttonStyle?.TextPadding)
138 instance.buttonStyle.TextPadding.CopyFrom((Extents)newValue);
139 instance.UpdateUIContent();
142 defaultValueCreator: (bindable) =>
144 var instance = (Button)bindable;
145 return instance.buttonStyle?.TextPadding;
151 /// Creates a new instance of a Button.
153 /// <since_tizen> 6 </since_tizen>
154 public Button() : base()
160 /// Creates a new instance of a Button with style.
162 /// <param name="style">Create Button by special style defined in UX.</param>
163 /// <since_tizen> 8 </since_tizen>
164 public Button(string style) : base(style)
170 /// Creates a new instance of a Button with style.
172 /// <param name="buttonStyle">Create Button by style customized by user.</param>
173 /// <since_tizen> 8 </since_tizen>
174 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
180 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
182 /// <since_tizen> 6 </since_tizen>
183 [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
184 public event EventHandler<ClickEventArgs> ClickEvent;
187 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
189 /// <since_tizen> 8 </since_tizen>
190 public event EventHandler<ClickedEventArgs> Clicked;
193 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
195 /// <since_tizen> 6 </since_tizen>
196 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
197 public event EventHandler<StateChangedEventArgs> StateChangedEvent
201 stateChangeHandler += value;
205 stateChangeHandler -= value;
210 /// Icon orientation.
212 /// <since_tizen> 6 </since_tizen>
213 public enum IconOrientation
218 /// <since_tizen> 6 </since_tizen>
223 /// <since_tizen> 6 </since_tizen>
228 /// <since_tizen> 6 </since_tizen>
233 /// <since_tizen> 6 </since_tizen>
238 /// Button's icon part.
240 /// <since_tizen> 8 </since_tizen>
241 public ImageView Icon
245 if (null == buttonIcon)
247 buttonIcon = CreateIcon();
248 if (null != Extension)
250 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
253 buttonIcon.Relayout += OnIconRelayout;
264 /// Button's overlay image part.
266 /// <since_tizen> 8 </since_tizen>
267 public ImageView OverlayImage
271 if (null == overlayImage)
273 overlayImage = CreateOverlayImage();
274 if (null != Extension)
276 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
278 overlayImage.WidthResizePolicy = ResizePolicyType.FillToParent;
279 overlayImage.HeightResizePolicy = ResizePolicyType.FillToParent;
286 overlayImage = value;
291 /// Button's text part.
293 /// <since_tizen> 8 </since_tizen>
294 public TextLabel TextLabel
298 if (null == buttonText)
300 buttonText = CreateText();
301 if (null != Extension)
303 buttonText = Extension.OnCreateText(this, buttonText);
305 buttonText.HorizontalAlignment = HorizontalAlignment.Center;
306 buttonText.VerticalAlignment = VerticalAlignment.Center;
318 /// Return a copied Style instance of Button
321 /// It returns copied Style instance and changing it does not effect to the Button.
322 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
324 /// <since_tizen> 8 </since_tizen>
325 public new ButtonStyle Style
329 var result = (ButtonStyle)ViewStyle.Clone();
330 result.CopyPropertiesFromView(this);
331 result.Text.CopyPropertiesFromView(TextLabel);
332 result.Icon.CopyPropertiesFromView(Icon);
333 result.Overlay.CopyPropertiesFromView(OverlayImage);
339 /// The text of Button.
341 /// <since_tizen> 6 </since_tizen>
346 return TextLabel.Text;
350 TextLabel.Text = value;
355 /// Flag to decide Button can be selected or not.
357 /// <since_tizen> 6 </since_tizen>
358 public bool IsSelectable
362 return (bool)GetValue(IsSelectableProperty);
366 SetValue(IsSelectableProperty, value);
371 /// Translate text string in Button.
373 /// <since_tizen> 6 </since_tizen>
374 public string TranslatableText
378 return TextLabel.TranslatableText;
382 TextLabel.TranslatableText = value;
387 /// Text point size in Button.
389 /// <since_tizen> 6 </since_tizen>
390 public float PointSize
394 return TextLabel.PointSize;
398 TextLabel.PointSize = value;
403 /// Text font family in Button.
405 /// <since_tizen> 6 </since_tizen>
406 public string FontFamily
410 return TextLabel.FontFamily;
414 TextLabel.FontFamily = value;
419 /// Text color in Button.
421 /// <since_tizen> 6 </since_tizen>
422 public Color TextColor
426 return TextLabel.TextColor;
430 TextLabel.TextColor = value;
435 /// Text horizontal alignment in Button.
437 /// <since_tizen> 6 </since_tizen>
438 public HorizontalAlignment TextAlignment
442 return TextLabel.HorizontalAlignment;
446 TextLabel.HorizontalAlignment = value;
451 /// Icon image's resource url in Button.
453 /// <since_tizen> 6 </since_tizen>
454 public string IconURL
458 return Icon.ResourceUrl;
462 Icon.ResourceUrl = value;
467 /// Text string selector in Button.
468 /// Getter returns copied selector value if exist, null otherwise.
470 /// <since_tizen> 6 </since_tizen>
471 public StringSelector TextSelector
473 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
474 set => buttonText?.SetValue(TextLabel.TextSelectorProperty, value);
478 /// Translateable text string selector in Button.
479 /// Getter returns copied selector value if exist, null otherwise.
481 /// <since_tizen> 6 </since_tizen>
482 public StringSelector TranslatableTextSelector
484 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
485 set => buttonText?.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
489 /// Text color selector in Button.
490 /// Getter returns copied selector value if exist, null otherwise.
492 /// <since_tizen> 6 </since_tizen>
493 public ColorSelector TextColorSelector
495 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
496 set => buttonText?.SetValue(TextLabel.TextColorSelectorProperty, value);
500 /// Text font size selector in Button.
501 /// Getter returns copied selector value if exist, null otherwise.
503 /// <since_tizen> 6 </since_tizen>
504 public FloatSelector PointSizeSelector
506 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
507 set => buttonText?.SetValue(TextLabel.PointSizeSelectorProperty, value);
511 /// Icon image's resource url selector in Button.
512 /// Getter returns copied selector value if exist, null otherwise.
514 /// <since_tizen> 6 </since_tizen>
515 public StringSelector IconURLSelector
517 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(ImageView.ResourceUrlSelectorProperty));
518 set => buttonIcon?.SetValue(ImageView.ResourceUrlSelectorProperty, value);
522 /// Flag to decide selected state in Button.
524 /// <since_tizen> 6 </since_tizen>
525 public bool IsSelected
529 return (bool)GetValue(IsSelectedProperty);
533 SetValue(IsSelectedProperty, value);
538 /// Flag to decide enable or disable in Button.
540 /// <since_tizen> 6 </since_tizen>
541 public bool IsEnabled
545 return (bool)GetValue(IsEnabledProperty);
549 SetValue(IsEnabledProperty, value);
554 /// Icon relative orientation in Button, work only when show icon and text.
556 /// <since_tizen> 8 </since_tizen>
557 public IconOrientation? IconRelativeOrientation
561 return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
565 SetValue(IconRelativeOrientationProperty, value);
570 /// Icon padding in Button, work only when show icon and text.
572 /// <since_tizen> 6 </since_tizen>
573 public Extents IconPadding
575 get => (Extents)GetValue(IconPaddingProperty);
576 set => SetValue(IconPaddingProperty, value);
580 /// Text padding in Button, work only when show icon and text.
582 /// <since_tizen> 6 </since_tizen>
583 public Extents TextPadding
585 get => (Extents)GetValue(TextPaddingProperty);
586 set => SetValue(TextPaddingProperty, value);
589 private ButtonStyle buttonStyle => ViewStyle as ButtonStyle;
592 /// Called after a key event is received by the view that has had its focus set.
594 /// <param name="key">The key event.</param>
595 /// <returns>True if the key event should be consumed.</returns>
596 /// <since_tizen> 6 </since_tizen>
597 public override bool OnKey(Key key)
599 if (!IsEnabled || null == key)
604 if (key.State == Key.StateType.Down)
606 if (key.KeyPressedName == "Return")
612 else if (key.State == Key.StateType.Up)
614 if (key.KeyPressedName == "Return")
616 bool clicked = isPressed && IsEnabled;
622 IsSelected = !IsSelected;
631 ClickedEventArgs eventArgs = new ClickedEventArgs();
632 OnClickedInternal(eventArgs);
636 return base.OnKey(key);
640 /// 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.
642 /// <since_tizen> 8 </since_tizen>
643 public override void OnFocusGained()
645 base.OnFocusGained();
650 /// 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.
652 /// <since_tizen> 8 </since_tizen>
653 public override void OnFocusLost()
660 /// Called after a touch event is received by the owning view.<br />
661 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
663 /// <param name="touch">The touch event.</param>
664 /// <returns>True if the event should be consumed.</returns>
665 /// <since_tizen> 8 </since_tizen>
666 public override bool OnTouch(Touch touch)
668 if (!IsEnabled || null == touch)
673 PointStateType state = touch.GetState(0);
677 case PointStateType.Down:
679 Extension?.SetTouchInfo(touch);
682 case PointStateType.Interrupted:
686 case PointStateType.Up:
688 bool clicked = isPressed && IsEnabled;
694 Extension?.SetTouchInfo(touch);
695 IsSelected = !IsSelected;
699 Extension?.SetTouchInfo(touch);
705 ClickedEventArgs eventArgs = new ClickedEventArgs();
706 OnClickedInternal(eventArgs);
714 return base.OnTouch(touch);
718 /// Apply style to button.
720 /// <param name="viewStyle">The style to apply.</param>
721 /// <since_tizen> 8 </since_tizen>
722 public override void ApplyStyle(ViewStyle viewStyle)
724 styleApplied = false;
726 base.ApplyStyle(viewStyle);
728 if (null != buttonStyle)
730 Extension = buttonStyle.CreateExtension();
731 if (buttonStyle.Overlay != null)
733 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
736 if (buttonStyle.Text != null)
738 TextLabel?.ApplyStyle(buttonStyle.Text);
741 if (buttonStyle.Icon != null)
743 Icon?.ApplyStyle(buttonStyle.Icon);
751 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
753 /// <since_tizen> 6 </since_tizen>
754 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
755 public class ClickEventArgs : EventArgs
760 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
762 /// <since_tizen> 6 </since_tizen>
763 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
764 public class StateChangedEventArgs : EventArgs
766 /// <summary> previous state of Button </summary>
767 /// <since_tizen> 6 </since_tizen>
768 [Obsolete("Deprecated in API8; Will be removed in API10")]
769 public ControlStates PreviousState;
770 /// <summary> current state of Button </summary>
771 /// <since_tizen> 6 </since_tizen>
772 [Obsolete("Deprecated in API8; Will be removed in API10")]
773 public ControlStates CurrentState;
777 /// Get current text part to the attached ButtonExtension.
780 /// It returns null if the passed extension is invalid.
782 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
783 /// <return>The button's text part.</return>
784 [EditorBrowsable(EditorBrowsableState.Never)]
785 public TextLabel GetCurrentText(ButtonExtension extension)
787 return (extension == Extension) ? TextLabel : null;
791 /// Get current icon part to the attached ButtonExtension.
794 /// It returns null if the passed extension is invalid.
796 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
797 /// <return>The button's icon part.</return>
798 [EditorBrowsable(EditorBrowsableState.Never)]
799 public ImageView GetCurrentIcon(ButtonExtension extension)
801 return (extension == Extension) ? Icon : null;
805 /// Get current overlay image part to the attached ButtonExtension.
808 /// It returns null if the passed extension is invalid.
810 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
811 /// <return>The button's overlay image part.</return>
812 [EditorBrowsable(EditorBrowsableState.Never)]
813 public ImageView GetCurrentOverlayImage(ButtonExtension extension)
815 return (extension == Extension) ? OverlayImage : null;