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;
22 using Tizen.NUI.Accessibility;
24 namespace Tizen.NUI.Components
27 /// ClickedEventArgs is a class to record button click event arguments which will sent to user.
29 /// <since_tizen> 8 </since_tizen>
30 public class ClickedEventArgs : EventArgs
35 /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it.
36 /// Button may contain text or an icon.
38 /// <since_tizen> 6 </since_tizen>
39 public partial class Button : Control
41 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
42 [EditorBrowsable(EditorBrowsableState.Never)]
43 public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
45 var instance = (Button)bindable;
48 if (instance.buttonStyle != null && instance.buttonStyle.IconRelativeOrientation != (IconOrientation?)newValue)
50 instance.buttonStyle.IconRelativeOrientation = (IconOrientation?)newValue;
51 instance.UpdateUIContent();
55 defaultValueCreator: (bindable) =>
57 var instance = (Button)bindable;
58 return instance.buttonStyle?.IconRelativeOrientation;
60 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
61 [EditorBrowsable(EditorBrowsableState.Never)]
62 public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
64 var instance = (Button)bindable;
67 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsEnabled != (bool)newValue))
69 instance.buttonStyle.IsEnabled = (bool)newValue;
70 instance.UpdateState();
74 defaultValueCreator: (bindable) =>
76 var instance = (Button)bindable;
77 return instance.buttonStyle?.IsEnabled ?? true;
79 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
80 [EditorBrowsable(EditorBrowsableState.Never)]
81 public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
83 var instance = (Button)bindable;
86 if (instance.buttonStyle != null && instance.IsSelectable && (!instance.styleApplied || instance.buttonStyle.IsSelected != (bool)newValue))
88 instance.buttonStyle.IsSelected = (bool)newValue;
89 instance.UpdateState();
93 defaultValueCreator: (bindable) =>
95 var instance = (Button)bindable;
96 return instance.IsSelectable && (instance.buttonStyle.IsSelected ?? 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 IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
102 var instance = (Button)bindable;
103 if (newValue != null)
105 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsSelectable != (bool)newValue))
107 instance.buttonStyle.IsSelectable = (bool)newValue;
111 defaultValueCreator: (bindable) =>
113 var instance = (Button)bindable;
114 return instance.buttonStyle?.IsSelectable ?? false;
116 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
117 [EditorBrowsable(EditorBrowsableState.Never)]
118 public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
120 var instance = (Button)bindable;
121 if (null != newValue && null != instance.buttonStyle?.IconPadding)
123 instance.buttonStyle.IconPadding.CopyFrom((Extents)newValue);
124 instance.UpdateUIContent();
127 defaultValueCreator: (bindable) =>
129 var instance = (Button)bindable;
130 return instance.buttonStyle?.IconPadding;
132 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
133 [EditorBrowsable(EditorBrowsableState.Never)]
134 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
136 var instance = (Button)bindable;
137 if (null != newValue && null != instance.buttonStyle?.TextPadding)
139 instance.buttonStyle.TextPadding.CopyFrom((Extents)newValue);
140 instance.UpdateUIContent();
143 defaultValueCreator: (bindable) =>
145 var instance = (Button)bindable;
146 return instance.buttonStyle?.TextPadding;
152 /// Creates a new instance of a Button.
154 /// <since_tizen> 6 </since_tizen>
155 public Button() : base()
161 /// Creates a new instance of a Button with style.
163 /// <param name="style">Create Button by special style defined in UX.</param>
164 /// <since_tizen> 8 </since_tizen>
165 public Button(string style) : base(style)
171 /// Creates a new instance of a Button with style.
173 /// <param name="buttonStyle">Create Button by style customized by user.</param>
174 /// <since_tizen> 8 </since_tizen>
175 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
181 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
183 /// <since_tizen> 6 </since_tizen>
184 [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
185 public event EventHandler<ClickEventArgs> ClickEvent;
188 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
190 /// <since_tizen> 8 </since_tizen>
191 public event EventHandler<ClickedEventArgs> Clicked;
194 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
196 /// <since_tizen> 6 </since_tizen>
197 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
198 public event EventHandler<StateChangedEventArgs> StateChangedEvent
202 stateChangeHandler += value;
206 stateChangeHandler -= value;
211 /// Icon orientation.
213 /// <since_tizen> 6 </since_tizen>
214 public enum IconOrientation
219 /// <since_tizen> 6 </since_tizen>
224 /// <since_tizen> 6 </since_tizen>
229 /// <since_tizen> 6 </since_tizen>
234 /// <since_tizen> 6 </since_tizen>
239 /// Button's icon part.
241 /// <since_tizen> 8 </since_tizen>
242 public ImageView Icon
246 if (null == buttonIcon)
248 buttonIcon = CreateIcon();
249 if (null != Extension)
251 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
254 buttonIcon.Relayout += OnIconRelayout;
265 /// Button's overlay image part.
267 /// <since_tizen> 8 </since_tizen>
268 public ImageView OverlayImage
272 if (null == overlayImage)
274 overlayImage = CreateOverlayImage();
275 if (null != Extension)
277 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
279 overlayImage.WidthResizePolicy = ResizePolicyType.FillToParent;
280 overlayImage.HeightResizePolicy = ResizePolicyType.FillToParent;
287 overlayImage = value;
292 /// Button's text part.
294 /// <since_tizen> 8 </since_tizen>
295 public TextLabel TextLabel
299 if (null == buttonText)
301 buttonText = CreateText();
302 if (null != Extension)
304 buttonText = Extension.OnCreateText(this, buttonText);
306 buttonText.HorizontalAlignment = HorizontalAlignment.Center;
307 buttonText.VerticalAlignment = VerticalAlignment.Center;
315 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
320 /// Return a copied Style instance of Button
323 /// It returns copied Style instance and changing it does not effect to the Button.
324 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
326 /// <since_tizen> 8 </since_tizen>
327 public new ButtonStyle Style
331 var result = (ButtonStyle)ViewStyle.Clone();
332 result.CopyPropertiesFromView(this);
333 result.Text.CopyPropertiesFromView(TextLabel);
334 result.Icon.CopyPropertiesFromView(Icon);
335 result.Overlay.CopyPropertiesFromView(OverlayImage);
341 /// The text of Button.
343 /// <since_tizen> 6 </since_tizen>
348 return TextLabel.Text;
352 TextLabel.Text = value;
357 /// Flag to decide Button can be selected or not.
359 /// <since_tizen> 6 </since_tizen>
360 public bool IsSelectable
364 return (bool)GetValue(IsSelectableProperty);
368 SetValue(IsSelectableProperty, value);
373 /// Translate text string in Button.
375 /// <since_tizen> 6 </since_tizen>
376 public string TranslatableText
380 return TextLabel.TranslatableText;
384 TextLabel.TranslatableText = value;
389 /// Text point size in Button.
391 /// <since_tizen> 6 </since_tizen>
392 public float PointSize
396 return TextLabel.PointSize;
400 TextLabel.PointSize = value;
405 /// Text font family in Button.
407 /// <since_tizen> 6 </since_tizen>
408 public string FontFamily
412 return TextLabel.FontFamily;
416 TextLabel.FontFamily = value;
421 /// Text color in Button.
423 /// <since_tizen> 6 </since_tizen>
424 public Color TextColor
428 return TextLabel.TextColor;
432 TextLabel.TextColor = value;
437 /// Text horizontal alignment in Button.
439 /// <since_tizen> 6 </since_tizen>
440 public HorizontalAlignment TextAlignment
444 return TextLabel.HorizontalAlignment;
448 TextLabel.HorizontalAlignment = value;
453 /// Icon image's resource url in Button.
455 /// <since_tizen> 6 </since_tizen>
456 public string IconURL
460 return Icon.ResourceUrl;
464 Icon.ResourceUrl = value;
469 /// Text string selector in Button.
470 /// Getter returns copied selector value if exist, null otherwise.
471 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
473 /// <since_tizen> 6 </since_tizen>
474 public StringSelector TextSelector
476 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
479 if (value == null || buttonText == null)
481 throw new NullReferenceException("Button.TextSelector is null");
485 buttonText.SetValue(TextLabel.TextSelectorProperty, value);
491 /// Translateable text string selector in Button.
492 /// Getter returns copied selector value if exist, null otherwise.
494 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
495 /// <since_tizen> 6 </since_tizen>
496 public StringSelector TranslatableTextSelector
498 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
501 if (value == null || buttonText == null)
503 throw new NullReferenceException("Button.TranslatableTextSelector is null");
507 buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
513 /// Text color selector in Button.
514 /// Getter returns copied selector value if exist, null otherwise.
516 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
517 /// <since_tizen> 6 </since_tizen>
518 public ColorSelector TextColorSelector
520 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
523 if (value == null || buttonText == null)
525 throw new NullReferenceException("Button.TextColorSelectorProperty is null");
529 buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
535 /// Text font size selector in Button.
536 /// Getter returns copied selector value if exist, null otherwise.
538 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
539 /// <since_tizen> 6 </since_tizen>
540 public FloatSelector PointSizeSelector
542 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
545 if (value == null || buttonText == null)
547 throw new NullReferenceException("Button.PointSizeSelector is null");
551 buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
557 /// Icon image's resource url selector in Button.
558 /// Getter returns copied selector value if exist, null otherwise.
560 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
561 /// <since_tizen> 6 </since_tizen>
562 public StringSelector IconURLSelector
564 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
567 if (value == null || buttonIcon == null)
569 throw new NullReferenceException("Button.IconURLSelector is null");
573 buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
579 /// Flag to decide selected state in Button.
581 /// <since_tizen> 6 </since_tizen>
582 public bool IsSelected
586 return (bool)GetValue(IsSelectedProperty);
590 SetValue(IsSelectedProperty, value);
595 /// Flag to decide enable or disable in Button.
597 /// <since_tizen> 6 </since_tizen>
598 public bool IsEnabled
602 return (bool)GetValue(IsEnabledProperty);
606 SetValue(IsEnabledProperty, value);
611 /// Icon relative orientation in Button, work only when show icon and text.
613 /// <since_tizen> 8 </since_tizen>
614 public IconOrientation? IconRelativeOrientation
618 return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
622 SetValue(IconRelativeOrientationProperty, value);
627 /// Icon padding in Button, work only when show icon and text.
629 /// <since_tizen> 6 </since_tizen>
630 public Extents IconPadding
632 get => (Extents)GetValue(IconPaddingProperty);
633 set => SetValue(IconPaddingProperty, value);
637 /// Text padding in Button, work only when show icon and text.
639 /// <since_tizen> 6 </since_tizen>
640 public Extents TextPadding
642 get => (Extents)GetValue(TextPaddingProperty);
643 set => SetValue(TextPaddingProperty, value);
646 private ButtonStyle buttonStyle => ViewStyle as ButtonStyle;
649 /// Called after a key event is received by the view that has had its focus set.
651 /// <param name="key">The key event.</param>
652 /// <returns>True if the key event should be consumed.</returns>
653 /// <since_tizen> 6 </since_tizen>
654 public override bool OnKey(Key key)
656 if (!IsEnabled || null == key)
661 if (key.State == Key.StateType.Down)
663 if (key.KeyPressedName == "Return")
669 else if (key.State == Key.StateType.Up)
671 if (key.KeyPressedName == "Return")
673 bool clicked = isPressed && IsEnabled;
679 IsSelected = !IsSelected;
688 ClickedEventArgs eventArgs = new ClickedEventArgs();
689 OnClickedInternal(eventArgs);
693 return base.OnKey(key);
697 /// 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.
699 /// <since_tizen> 8 </since_tizen>
700 public override void OnFocusGained()
702 base.OnFocusGained();
707 /// 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.
709 /// <since_tizen> 8 </since_tizen>
710 public override void OnFocusLost()
717 /// Called after a touch event is received by the owning view.<br />
718 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
720 /// <param name="touch">The touch event.</param>
721 /// <returns>True if the event should be consumed.</returns>
722 /// <since_tizen> 8 </since_tizen>
723 public override bool OnTouch(Touch touch)
725 return base.OnTouch(touch);
729 /// Apply style to button.
731 /// <param name="viewStyle">The style to apply.</param>
732 /// <since_tizen> 8 </since_tizen>
733 public override void ApplyStyle(ViewStyle viewStyle)
735 styleApplied = false;
737 base.ApplyStyle(viewStyle);
739 if (null != buttonStyle)
741 Extension = buttonStyle.CreateExtension();
742 if (buttonStyle.Overlay != null)
744 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
747 if (buttonStyle.Text != null)
749 TextLabel?.ApplyStyle(buttonStyle.Text);
752 if (buttonStyle.Icon != null)
754 Icon?.ApplyStyle(buttonStyle.Icon);
762 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
764 /// <since_tizen> 6 </since_tizen>
765 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
766 public class ClickEventArgs : EventArgs
771 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
773 /// <since_tizen> 6 </since_tizen>
774 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
775 public class StateChangedEventArgs : EventArgs
777 /// <summary> previous state of Button </summary>
778 /// <since_tizen> 6 </since_tizen>
779 [Obsolete("Deprecated in API8; Will be removed in API10")]
780 public ControlStates PreviousState;
781 /// <summary> current state of Button </summary>
782 /// <since_tizen> 6 </since_tizen>
783 [Obsolete("Deprecated in API8; Will be removed in API10")]
784 public ControlStates CurrentState;
788 /// Get current text part to the attached ButtonExtension.
791 /// It returns null if the passed extension is invalid.
793 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
794 /// <return>The button's text part.</return>
795 [EditorBrowsable(EditorBrowsableState.Never)]
796 public TextLabel GetCurrentText(ButtonExtension extension)
798 return (extension == Extension) ? TextLabel : null;
802 /// Get current icon part to the attached ButtonExtension.
805 /// It returns null if the passed extension is invalid.
807 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
808 /// <return>The button's icon part.</return>
809 [EditorBrowsable(EditorBrowsableState.Never)]
810 public ImageView GetCurrentIcon(ButtonExtension extension)
812 return (extension == Extension) ? Icon : null;
816 /// Get current overlay image part to the attached ButtonExtension.
819 /// It returns null if the passed extension is invalid.
821 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
822 /// <return>The button's overlay image part.</return>
823 [EditorBrowsable(EditorBrowsableState.Never)]
824 public ImageView GetCurrentOverlayImage(ButtonExtension extension)
826 return (extension == Extension) ? OverlayImage : null;