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 System.Diagnostics;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Binding;
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.LayoutItems();
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.Sensitive = newEnabled;
79 instance.UpdateState();
83 defaultValueCreator: (bindable) => ((Button)bindable).isEnabled);
84 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
85 [EditorBrowsable(EditorBrowsableState.Never)]
86 public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
88 var instance = (Button)bindable;
91 bool newSelected = (bool)newValue;
92 if (instance.isSelected != newSelected)
94 instance.isSelected = newSelected;
96 if (instance.isSelectable)
98 instance.UpdateState();
103 defaultValueCreator: (bindable) =>
105 var instance = (Button)bindable;
106 return instance.isSelectable && instance.isSelected;
108 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
109 [EditorBrowsable(EditorBrowsableState.Never)]
110 public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
112 var instance = (Button)bindable;
113 if (newValue != null)
115 bool newSelectable = (bool)newValue;
116 if (instance.isSelectable != newSelectable)
118 instance.isSelectable = newSelectable;
119 instance.UpdateState();
123 defaultValueCreator: (bindable) => ((Button)bindable).isSelectable);
125 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
126 [EditorBrowsable(EditorBrowsableState.Never)]
127 public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
129 var instance = (Button)bindable;
130 instance.iconPadding = (Extents)((Extents)newValue).Clone();
131 instance.OnTextOrIconUpdated();
133 defaultValueCreator: (bindable) => ((Button)bindable).iconPadding);
135 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
136 [EditorBrowsable(EditorBrowsableState.Never)]
137 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
139 var instance = (Button)bindable;
140 instance.textPadding = (Extents)((Extents)newValue).Clone();
141 instance.OnTextOrIconUpdated();
143 defaultValueCreator: (bindable) => ((Button)bindable).textPadding);
145 private IconOrientation? iconRelativeOrientation = IconOrientation.Left;
146 private bool isSelected = false;
147 private bool isSelectable = false;
148 private bool isEnabled = true;
149 private Extents iconPadding;
150 private Extents textPadding;
155 /// Creates a new instance of a Button.
157 /// <since_tizen> 6 </since_tizen>
158 public Button() : base()
163 /// Creates a new instance of a Button with style.
165 /// <param name="style">Create Button by special style defined in UX.</param>
166 /// <since_tizen> 8 </since_tizen>
167 public Button(string style) : base(style)
172 /// Creates a new instance of a Button with style.
174 /// <param name="buttonStyle">Create Button by style customized by user.</param>
175 /// <since_tizen> 8 </since_tizen>
176 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
181 /// Calculates current states for the button<br />
183 [EditorBrowsable(EditorBrowsableState.Never)]
184 protected override AccessibilityStates AccessibilityCalculateStates()
186 var states = base.AccessibilityCalculateStates();
187 states.Set(AccessibilityState.Checked, this.IsSelected);
188 states.Set(AccessibilityState.Enabled, this.IsEnabled);
193 /// An event for the button clicked 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 Clicked event instead.")]
197 public event EventHandler<ClickEventArgs> ClickEvent;
200 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
202 /// <since_tizen> 8 </since_tizen>
203 public event EventHandler<ClickedEventArgs> Clicked;
206 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
208 /// <since_tizen> 6 </since_tizen>
209 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
210 public event EventHandler<StateChangedEventArgs> StateChangedEvent
214 stateChangeHandler += value;
218 stateChangeHandler -= value;
223 /// Icon orientation.
225 /// <since_tizen> 6 </since_tizen>
226 public enum IconOrientation
231 /// <since_tizen> 6 </since_tizen>
236 /// <since_tizen> 6 </since_tizen>
241 /// <since_tizen> 6 </since_tizen>
246 /// <since_tizen> 6 </since_tizen>
251 /// Button's icon part.
253 /// <since_tizen> 8 </since_tizen>
254 public ImageView Icon
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 if (null != overlayImage)
280 overlayImage.ExcludeLayouting = true;
288 overlayImage = value;
293 /// Button's text part.
295 /// <since_tizen> 8 </since_tizen>
296 public TextLabel TextLabel
302 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
307 /// Return currently applied style.
310 /// Modifying contents in style may cause unexpected behaviour.
312 /// <since_tizen> 8 </since_tizen>
313 public ButtonStyle Style => (ButtonStyle)(ViewStyle as ButtonStyle)?.Clone();
316 /// The text of Button.
318 /// <since_tizen> 6 </since_tizen>
323 return TextLabel.Text;
327 TextLabel.Text = value;
329 if (IsHighlighted && String.IsNullOrEmpty(AccessibilityName) && GetAccessibilityNameSignal().Empty())
331 EmitAccessibilityEvent(ObjectPropertyChangeEvent.Name);
337 /// Flag to decide Button can be selected or not.
339 /// <since_tizen> 6 </since_tizen>
340 public bool IsSelectable
344 return (bool)GetValue(IsSelectableProperty);
348 SetValue(IsSelectableProperty, value);
353 /// Translate text string in Button.
355 /// <since_tizen> 6 </since_tizen>
356 public string TranslatableText
360 return TextLabel.TranslatableText;
364 TextLabel.TranslatableText = value;
369 /// Text point size in Button.
371 /// <since_tizen> 6 </since_tizen>
372 public float PointSize
376 return TextLabel.PointSize;
380 TextLabel.PointSize = value;
385 /// Text font family in Button.
387 /// <since_tizen> 6 </since_tizen>
388 public string FontFamily
392 return TextLabel.FontFamily;
396 TextLabel.FontFamily = value;
401 /// Text color in Button.
403 /// <since_tizen> 6 </since_tizen>
404 public Color TextColor
408 return TextLabel.TextColor;
412 TextLabel.TextColor = value;
417 /// Text horizontal alignment in Button.
419 /// <since_tizen> 6 </since_tizen>
420 public HorizontalAlignment TextAlignment
424 return TextLabel.HorizontalAlignment;
428 TextLabel.HorizontalAlignment = value;
433 /// Icon image's resource url in Button.
435 /// <since_tizen> 6 </since_tizen>
436 public string IconURL
440 return Icon.ResourceUrl;
444 Icon.ResourceUrl = value;
449 /// Text string selector in Button.
450 /// Getter returns copied selector value if exist, null otherwise.
451 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
453 /// <since_tizen> 6 </since_tizen>
454 public StringSelector TextSelector
456 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
459 if (value == null || buttonText == null)
461 throw new NullReferenceException("Button.TextSelector is null");
465 buttonText.SetValue(TextLabel.TextSelectorProperty, value);
471 /// Translatable text string selector in Button.
472 /// Getter returns copied selector value if exist, null otherwise.
474 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
475 /// <since_tizen> 6 </since_tizen>
476 public StringSelector TranslatableTextSelector
478 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
481 if (value == null || buttonText == null)
483 throw new NullReferenceException("Button.TranslatableTextSelector is null");
487 buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
493 /// Text color selector in Button.
494 /// Getter returns copied selector value if exist, null otherwise.
496 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
497 /// <since_tizen> 6 </since_tizen>
498 public ColorSelector TextColorSelector
500 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
503 if (value == null || buttonText == null)
505 throw new NullReferenceException("Button.TextColorSelectorProperty is null");
509 buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
515 /// Text font size selector in Button.
516 /// Getter returns copied selector value if exist, null otherwise.
518 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
519 /// <since_tizen> 6 </since_tizen>
520 public FloatSelector PointSizeSelector
522 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
525 if (value == null || buttonText == null)
527 throw new NullReferenceException("Button.PointSizeSelector is null");
531 buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
537 /// Icon image's resource url selector in Button.
538 /// Getter returns copied selector value if exist, null otherwise.
540 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
541 /// <since_tizen> 6 </since_tizen>
542 public StringSelector IconURLSelector
544 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
547 if (value == null || buttonIcon == null)
549 throw new NullReferenceException("Button.IconURLSelector is null");
553 buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
559 /// Flag to decide selected state in Button.
561 /// <since_tizen> 6 </since_tizen>
562 public bool IsSelected
566 return (bool)GetValue(IsSelectedProperty);
570 SetValue(IsSelectedProperty, value);
575 /// Flag to decide enable or disable in Button.
577 /// <since_tizen> 6 </since_tizen>
578 public bool IsEnabled
582 return (bool)GetValue(IsEnabledProperty);
586 SetValue(IsEnabledProperty, value);
591 /// Icon relative orientation in Button, work only when show icon and text.
593 /// <since_tizen> 8 </since_tizen>
594 public IconOrientation? IconRelativeOrientation
598 return (IconOrientation?)GetValue(IconRelativeOrientationProperty) ?? IconOrientation.Left;
602 SetValue(IconRelativeOrientationProperty, value);
607 /// Icon padding in Button, work only when show icon and text.
609 /// <since_tizen> 6 </since_tizen>
610 public Extents IconPadding
612 get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
613 set => SetValue(IconPaddingProperty, value);
617 /// Text padding in Button, work only when show icon and text.
619 /// <since_tizen> 6 </since_tizen>
620 public Extents TextPadding
622 get => (Extents)GetValue(TextPaddingProperty) ?? new Extents();
623 set => SetValue(TextPaddingProperty, value);
627 /// Called after a key event is received by the view that has had its focus set.
629 /// <param name="key">The key event.</param>
630 /// <returns>True if the key event should be consumed.</returns>
631 /// <since_tizen> 6 </since_tizen>
632 public override bool OnKey(Key key)
634 if (!IsEnabled || null == key)
639 if (key.State == Key.StateType.Down)
641 if (key.KeyPressedName == "Return")
647 else if (key.State == Key.StateType.Up)
649 if (key.KeyPressedName == "Return")
651 bool clicked = isPressed && IsEnabled;
657 IsSelected = !IsSelected;
666 ClickedEventArgs eventArgs = new ClickedEventArgs();
667 OnClickedInternal(eventArgs);
671 return base.OnKey(key);
675 /// 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.
677 /// <since_tizen> 8 </since_tizen>
678 public override void OnFocusGained()
680 base.OnFocusGained();
685 /// 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.
687 /// <since_tizen> 8 </since_tizen>
688 public override void OnFocusLost()
695 /// Called after a touch event is received by the owning view.<br />
696 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
698 /// <param name="touch">The touch event.</param>
699 /// <returns>True if the event should be consumed.</returns>
700 /// <since_tizen> 8 </since_tizen>
701 [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
702 #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
703 public override bool OnTouch(Touch touch)
704 #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
706 return base.OnTouch(touch);
710 /// Apply style to button.
712 /// <param name="viewStyle">The style to apply.</param>
713 /// <since_tizen> 8 </since_tizen>
714 public override void ApplyStyle(ViewStyle viewStyle)
716 Debug.Assert(buttonIcon != null && buttonText != null);
718 styleApplied = false;
720 base.ApplyStyle(viewStyle);
722 if (viewStyle is ButtonStyle buttonStyle)
724 Extension = buttonStyle.CreateExtension();
726 if (buttonStyle.Overlay != null)
728 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
731 if (Extension != null)
733 buttonIcon.Unparent();
734 buttonIcon.Relayout -= OnIconRelayout;
735 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
736 buttonIcon.Relayout += OnIconRelayout;
738 buttonText.Unparent();
739 buttonText.Relayout -= OnTextRelayout;
740 buttonText = Extension.OnCreateText(this, buttonText);
741 buttonText.Relayout += OnTextRelayout;
746 if (buttonStyle.Text != null)
748 buttonText.ApplyStyle(buttonStyle.Text);
751 if (buttonStyle.Icon != null)
753 buttonIcon.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 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
767 public class ClickEventArgs : EventArgs
772 /// StateChangeEventArgs is a class to record button state change 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 View.ControlStateChangedEventArgs")]
776 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
777 public class StateChangedEventArgs : EventArgs
779 /// <summary> previous state of Button </summary>
780 /// <since_tizen> 6 </since_tizen>
781 /// It will be removed in API10
782 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
783 [Obsolete("Deprecated in API8; Will be removed in API10")]
784 public ControlStates PreviousState;
785 /// <summary> current state of Button </summary>
786 /// <since_tizen> 6 </since_tizen>
787 /// It will be removed in API10
788 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
789 [Obsolete("Deprecated in API8; Will be removed in API10")]
790 public ControlStates CurrentState;