2 * Copyright(c) 2021 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 /// SelectedChangedEventArgs is a class to record item selected arguments which will sent to user.
37 /// <since_tizen> 8 </since_tizen>
38 public class SelectedChangedEventArgs : EventArgs
40 /// <summary> Selected state </summary>
41 /// <since_tizen> 8 </since_tizen>
42 public bool IsSelected { get; set; }
46 /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it.
47 /// Button may contain text or an icon.
49 /// <since_tizen> 6 </since_tizen>
50 public partial class Button : Control
52 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
53 [EditorBrowsable(EditorBrowsableState.Never)]
54 public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
56 var instance = (Button)bindable;
57 var newIconOrientation = (IconOrientation?)newValue;
58 if (instance.iconRelativeOrientation != newIconOrientation)
60 instance.iconRelativeOrientation = newIconOrientation;
61 instance.UpdateUIContent();
64 defaultValueCreator: (bindable) => ((Button)bindable).iconRelativeOrientation
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 IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
71 var instance = (Button)bindable;
74 bool newEnabled = (bool)newValue;
75 if (instance.isEnabled != newEnabled)
77 instance.isEnabled = newEnabled;
78 instance.UpdateState();
82 defaultValueCreator: (bindable) => ((Button)bindable).isEnabled);
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 IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
87 var instance = (Button)bindable;
90 bool newSelected = (bool)newValue;
91 if (instance.isSelected != newSelected)
93 instance.isSelected = newSelected;
95 if (instance.isSelectable)
97 instance.UpdateState();
102 defaultValueCreator: (bindable) =>
104 var instance = (Button)bindable;
105 return instance.isSelectable && instance.isSelected;
107 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
108 [EditorBrowsable(EditorBrowsableState.Never)]
109 public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
111 var instance = (Button)bindable;
112 if (newValue != null)
114 bool newSelectable = (bool)newValue;
115 if (instance.isSelectable != newSelectable)
117 instance.isSelectable = newSelectable;
118 instance.UpdateState();
122 defaultValueCreator: (bindable) => ((Button)bindable).isSelectable);
124 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
125 [EditorBrowsable(EditorBrowsableState.Never)]
126 public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
128 var instance = (Button)bindable;
129 instance.iconPadding = (Extents)((Extents)newValue).Clone();
130 instance.UpdateUIContent();
132 defaultValueCreator: (bindable) => ((Button)bindable).iconPadding);
134 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
135 [EditorBrowsable(EditorBrowsableState.Never)]
136 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
138 var instance = (Button)bindable;
139 instance.textPadding = (Extents)((Extents)newValue).Clone();
140 instance.UpdateUIContent();
142 defaultValueCreator: (bindable) => ((Button)bindable).textPadding);
144 private IconOrientation? iconRelativeOrientation;
145 private bool isSelected = false;
146 private bool isSelectable = false;
147 private bool isEnabled = true;
148 private Extents iconPadding;
149 private Extents textPadding;
154 /// Creates a new instance of a Button.
156 /// <since_tizen> 6 </since_tizen>
157 public Button() : base()
162 /// Creates a new instance of a Button with style.
164 /// <param name="style">Create Button by special style defined in UX.</param>
165 /// <since_tizen> 8 </since_tizen>
166 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)
180 /// Calculates current states for the button<br />
182 [EditorBrowsable(EditorBrowsableState.Never)]
183 protected override AccessibilityStates AccessibilityCalculateStates()
185 var states = base.AccessibilityCalculateStates();
186 states.Set(AccessibilityState.Enabled, this.IsEnabled);
191 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
193 /// <since_tizen> 6 </since_tizen>
194 [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
195 public event EventHandler<ClickEventArgs> ClickEvent;
198 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
200 /// <since_tizen> 8 </since_tizen>
201 public event EventHandler<ClickedEventArgs> Clicked;
204 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
206 /// <since_tizen> 6 </since_tizen>
207 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
208 public event EventHandler<StateChangedEventArgs> StateChangedEvent
212 stateChangeHandler += value;
216 stateChangeHandler -= value;
221 /// Icon orientation.
223 /// <since_tizen> 6 </since_tizen>
224 public enum IconOrientation
229 /// <since_tizen> 6 </since_tizen>
234 /// <since_tizen> 6 </since_tizen>
239 /// <since_tizen> 6 </since_tizen>
244 /// <since_tizen> 6 </since_tizen>
249 /// Button's icon part.
251 /// <since_tizen> 8 </since_tizen>
252 public ImageView Icon
256 if (null == buttonIcon)
258 buttonIcon = CreateIcon();
259 if (null != Extension)
261 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
263 if (null != buttonIcon)
266 buttonIcon.Relayout += OnIconRelayout;
278 /// Button's overlay image part.
280 /// <since_tizen> 8 </since_tizen>
281 public ImageView OverlayImage
285 if (null == overlayImage)
287 overlayImage = CreateOverlayImage();
288 if (null != Extension)
290 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
292 if (null != overlayImage)
301 overlayImage = value;
306 /// Button's text part.
308 /// <since_tizen> 8 </since_tizen>
309 public TextLabel TextLabel
313 if (null == buttonText)
315 buttonText = CreateText();
316 if (null != Extension)
318 buttonText = Extension.OnCreateText(this, buttonText);
320 if (null != buttonText)
330 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
335 /// Return currently applied style.
338 /// Modifying contents in style may cause unexpected behaviour.
340 /// <since_tizen> 8 </since_tizen>
341 public ButtonStyle Style => (ButtonStyle)(ViewStyle as ButtonStyle)?.Clone();
344 /// The text of Button.
346 /// <since_tizen> 6 </since_tizen>
351 return TextLabel.Text;
355 TextLabel.Text = value;
357 if (IsHighlighted && String.IsNullOrEmpty(AccessibilityName) && GetAccessibilityNameSignal().Empty())
359 EmitAccessibilityEvent(ObjectPropertyChangeEvent.Name);
365 /// Flag to decide Button can be selected or not.
367 /// <since_tizen> 6 </since_tizen>
368 public bool IsSelectable
372 return (bool)GetValue(IsSelectableProperty);
376 SetValue(IsSelectableProperty, value);
381 /// Translate text string in Button.
383 /// <since_tizen> 6 </since_tizen>
384 public string TranslatableText
388 return TextLabel.TranslatableText;
392 TextLabel.TranslatableText = value;
397 /// Text point size in Button.
399 /// <since_tizen> 6 </since_tizen>
400 public float PointSize
404 return TextLabel.PointSize;
408 TextLabel.PointSize = value;
413 /// Text font family in Button.
415 /// <since_tizen> 6 </since_tizen>
416 public string FontFamily
420 return TextLabel.FontFamily;
424 TextLabel.FontFamily = value;
429 /// Text color in Button.
431 /// <since_tizen> 6 </since_tizen>
432 public Color TextColor
436 return TextLabel.TextColor;
440 TextLabel.TextColor = value;
445 /// Text horizontal alignment in Button.
447 /// <since_tizen> 6 </since_tizen>
448 public HorizontalAlignment TextAlignment
452 return TextLabel.HorizontalAlignment;
456 TextLabel.HorizontalAlignment = value;
461 /// Icon image's resource url in Button.
463 /// <since_tizen> 6 </since_tizen>
464 public string IconURL
468 return Icon.ResourceUrl;
472 Icon.ResourceUrl = value;
477 /// Text string selector in Button.
478 /// Getter returns copied selector value if exist, null otherwise.
479 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
481 /// <since_tizen> 6 </since_tizen>
482 public StringSelector TextSelector
484 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
487 if (value == null || buttonText == null)
489 throw new NullReferenceException("Button.TextSelector is null");
493 buttonText.SetValue(TextLabel.TextSelectorProperty, value);
499 /// Translateable text string selector in Button.
500 /// Getter returns copied selector value if exist, null otherwise.
502 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
503 /// <since_tizen> 6 </since_tizen>
504 public StringSelector TranslatableTextSelector
506 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
509 if (value == null || buttonText == null)
511 throw new NullReferenceException("Button.TranslatableTextSelector is null");
515 buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
521 /// Text color selector in Button.
522 /// Getter returns copied selector value if exist, null otherwise.
524 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
525 /// <since_tizen> 6 </since_tizen>
526 public ColorSelector TextColorSelector
528 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
531 if (value == null || buttonText == null)
533 throw new NullReferenceException("Button.TextColorSelectorProperty is null");
537 buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
543 /// Text font size selector in Button.
544 /// Getter returns copied selector value if exist, null otherwise.
546 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
547 /// <since_tizen> 6 </since_tizen>
548 public FloatSelector PointSizeSelector
550 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
553 if (value == null || buttonText == null)
555 throw new NullReferenceException("Button.PointSizeSelector is null");
559 buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
565 /// Icon image's resource url selector in Button.
566 /// Getter returns copied selector value if exist, null otherwise.
568 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
569 /// <since_tizen> 6 </since_tizen>
570 public StringSelector IconURLSelector
572 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
575 if (value == null || buttonIcon == null)
577 throw new NullReferenceException("Button.IconURLSelector is null");
581 buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
587 /// Flag to decide selected state in Button.
589 /// <since_tizen> 6 </since_tizen>
590 public bool IsSelected
594 return (bool)GetValue(IsSelectedProperty);
598 SetValue(IsSelectedProperty, value);
603 /// Flag to decide enable or disable in Button.
605 /// <since_tizen> 6 </since_tizen>
606 public bool IsEnabled
610 return (bool)GetValue(IsEnabledProperty);
614 SetValue(IsEnabledProperty, value);
619 /// Icon relative orientation in Button, work only when show icon and text.
621 /// <since_tizen> 8 </since_tizen>
622 public IconOrientation? IconRelativeOrientation
626 return (IconOrientation?)GetValue(IconRelativeOrientationProperty) ?? IconOrientation.Left;
630 SetValue(IconRelativeOrientationProperty, value);
635 /// Icon padding in Button, work only when show icon and text.
637 /// <since_tizen> 6 </since_tizen>
638 public Extents IconPadding
640 get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
641 set => SetValue(IconPaddingProperty, value);
645 /// Text padding in Button, work only when show icon and text.
647 /// <since_tizen> 6 </since_tizen>
648 public Extents TextPadding
650 get => (Extents)GetValue(TextPaddingProperty) ?? new Extents();
651 set => SetValue(TextPaddingProperty, value);
655 /// Called after a key event is received by the view that has had its focus set.
657 /// <param name="key">The key event.</param>
658 /// <returns>True if the key event should be consumed.</returns>
659 /// <since_tizen> 6 </since_tizen>
660 public override bool OnKey(Key key)
662 if (!IsEnabled || null == key)
667 if (key.State == Key.StateType.Down)
669 if (key.KeyPressedName == "Return")
675 else if (key.State == Key.StateType.Up)
677 if (key.KeyPressedName == "Return")
679 bool clicked = isPressed && IsEnabled;
685 IsSelected = !IsSelected;
694 ClickedEventArgs eventArgs = new ClickedEventArgs();
695 OnClickedInternal(eventArgs);
699 return base.OnKey(key);
703 /// 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.
705 /// <since_tizen> 8 </since_tizen>
706 public override void OnFocusGained()
708 base.OnFocusGained();
713 /// 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.
715 /// <since_tizen> 8 </since_tizen>
716 public override void OnFocusLost()
723 /// Called after a touch event is received by the owning view.<br />
724 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
726 /// <param name="touch">The touch event.</param>
727 /// <returns>True if the event should be consumed.</returns>
728 /// <since_tizen> 8 </since_tizen>
729 [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
730 #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
731 public override bool OnTouch(Touch touch)
732 #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
734 return base.OnTouch(touch);
738 /// Apply style to button.
740 /// <param name="viewStyle">The style to apply.</param>
741 /// <since_tizen> 8 </since_tizen>
742 public override void ApplyStyle(ViewStyle viewStyle)
744 styleApplied = false;
746 base.ApplyStyle(viewStyle);
748 if (viewStyle is ButtonStyle buttonStyle)
750 Extension = buttonStyle.CreateExtension();
751 if (buttonStyle.Overlay != null)
753 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
756 if (buttonStyle.Text != null)
758 TextLabel?.ApplyStyle(buttonStyle.Text);
761 if (buttonStyle.Icon != null)
763 Icon?.ApplyStyle(buttonStyle.Icon);
772 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
774 /// <since_tizen> 6 </since_tizen>
775 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
776 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
777 public class ClickEventArgs : EventArgs
782 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
784 /// <since_tizen> 6 </since_tizen>
785 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
786 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
787 public class StateChangedEventArgs : EventArgs
789 /// <summary> previous state of Button </summary>
790 /// <since_tizen> 6 </since_tizen>
791 /// It will be removed in API10
792 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
793 [Obsolete("Deprecated in API8; Will be removed in API10")]
794 public ControlStates PreviousState;
795 /// <summary> current state of Button </summary>
796 /// <since_tizen> 6 </since_tizen>
797 /// It will be removed in API10
798 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
799 [Obsolete("Deprecated in API8; Will be removed in API10")]
800 public ControlStates CurrentState;