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 if (instance.buttonIcon != null)
133 instance.buttonIcon.Margin = instance.iconPadding;
136 defaultValueCreator: (bindable) => ((Button)bindable).iconPadding);
138 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
139 [EditorBrowsable(EditorBrowsableState.Never)]
140 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
142 var instance = (Button)bindable;
143 instance.textPadding = (Extents)((Extents)newValue).Clone();
144 if (instance.buttonText != null)
146 instance.buttonText.Margin = instance.textPadding;
149 defaultValueCreator: (bindable) => ((Button)bindable).textPadding);
151 private IconOrientation? iconRelativeOrientation = IconOrientation.Left;
152 private bool isSelected = false;
153 private bool isSelectable = false;
154 private bool isEnabled = true;
155 private Extents iconPadding;
156 private Extents textPadding;
161 /// Creates a new instance of a Button.
163 /// <since_tizen> 6 </since_tizen>
164 public Button() : base()
169 /// Creates a new instance of a Button with style.
171 /// <param name="style">Create Button by special style defined in UX.</param>
172 /// <since_tizen> 8 </since_tizen>
173 public Button(string style) : base(style)
178 /// Creates a new instance of a Button with style.
180 /// <param name="buttonStyle">Create Button by style customized by user.</param>
181 /// <since_tizen> 8 </since_tizen>
182 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
187 /// Calculates current states for the button<br />
189 [EditorBrowsable(EditorBrowsableState.Never)]
190 protected override AccessibilityStates AccessibilityCalculateStates()
192 var states = base.AccessibilityCalculateStates();
193 states.Set(AccessibilityState.Enabled, this.IsEnabled);
198 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
200 /// <since_tizen> 6 </since_tizen>
201 [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
202 public event EventHandler<ClickEventArgs> ClickEvent;
205 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
207 /// <since_tizen> 8 </since_tizen>
208 public event EventHandler<ClickedEventArgs> Clicked;
211 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
213 /// <since_tizen> 6 </since_tizen>
214 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
215 public event EventHandler<StateChangedEventArgs> StateChangedEvent
219 stateChangeHandler += value;
223 stateChangeHandler -= value;
228 /// Icon orientation.
230 /// <since_tizen> 6 </since_tizen>
231 public enum IconOrientation
236 /// <since_tizen> 6 </since_tizen>
241 /// <since_tizen> 6 </since_tizen>
246 /// <since_tizen> 6 </since_tizen>
251 /// <since_tizen> 6 </since_tizen>
256 /// Button's icon part.
258 /// <since_tizen> 8 </since_tizen>
259 public ImageView Icon
269 /// Button's overlay image part.
271 /// <since_tizen> 8 </since_tizen>
272 public ImageView OverlayImage
276 if (null == overlayImage)
278 overlayImage = CreateOverlayImage();
279 if (null != Extension)
281 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
283 if (null != overlayImage)
285 overlayImage.ExcludeLayouting = true;
293 overlayImage = value;
298 /// Button's text part.
300 /// <since_tizen> 8 </since_tizen>
301 public TextLabel TextLabel
307 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
312 /// Return currently applied style.
315 /// Modifying contents in style may cause unexpected behaviour.
317 /// <since_tizen> 8 </since_tizen>
318 public ButtonStyle Style => (ButtonStyle)(ViewStyle as ButtonStyle)?.Clone();
321 /// The text of Button.
323 /// <since_tizen> 6 </since_tizen>
328 return TextLabel.Text;
332 TextLabel.Text = value;
334 if (IsHighlighted && String.IsNullOrEmpty(AccessibilityName) && GetAccessibilityNameSignal().Empty())
336 EmitAccessibilityEvent(ObjectPropertyChangeEvent.Name);
342 /// Flag to decide Button can be selected or not.
344 /// <since_tizen> 6 </since_tizen>
345 public bool IsSelectable
349 return (bool)GetValue(IsSelectableProperty);
353 SetValue(IsSelectableProperty, value);
358 /// Translate text string in Button.
360 /// <since_tizen> 6 </since_tizen>
361 public string TranslatableText
365 return TextLabel.TranslatableText;
369 TextLabel.TranslatableText = value;
374 /// Text point size in Button.
376 /// <since_tizen> 6 </since_tizen>
377 public float PointSize
381 return TextLabel.PointSize;
385 TextLabel.PointSize = value;
390 /// Text font family in Button.
392 /// <since_tizen> 6 </since_tizen>
393 public string FontFamily
397 return TextLabel.FontFamily;
401 TextLabel.FontFamily = value;
406 /// Text color in Button.
408 /// <since_tizen> 6 </since_tizen>
409 public Color TextColor
413 return TextLabel.TextColor;
417 TextLabel.TextColor = value;
422 /// Text horizontal alignment in Button.
424 /// <since_tizen> 6 </since_tizen>
425 public HorizontalAlignment TextAlignment
429 return TextLabel.HorizontalAlignment;
433 TextLabel.HorizontalAlignment = value;
438 /// Icon image's resource url in Button.
440 /// <since_tizen> 6 </since_tizen>
441 public string IconURL
445 return Icon.ResourceUrl;
449 Icon.ResourceUrl = value;
454 /// Text string selector in Button.
455 /// Getter returns copied selector value if exist, null otherwise.
456 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
458 /// <since_tizen> 6 </since_tizen>
459 public StringSelector TextSelector
461 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
464 if (value == null || buttonText == null)
466 throw new NullReferenceException("Button.TextSelector is null");
470 buttonText.SetValue(TextLabel.TextSelectorProperty, value);
476 /// Translatable text string selector in Button.
477 /// Getter returns copied selector value if exist, null otherwise.
479 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
480 /// <since_tizen> 6 </since_tizen>
481 public StringSelector TranslatableTextSelector
483 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
486 if (value == null || buttonText == null)
488 throw new NullReferenceException("Button.TranslatableTextSelector is null");
492 buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
498 /// Text color selector in Button.
499 /// Getter returns copied selector value if exist, null otherwise.
501 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
502 /// <since_tizen> 6 </since_tizen>
503 public ColorSelector TextColorSelector
505 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
508 if (value == null || buttonText == null)
510 throw new NullReferenceException("Button.TextColorSelectorProperty is null");
514 buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
520 /// Text font size selector in Button.
521 /// Getter returns copied selector value if exist, null otherwise.
523 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
524 /// <since_tizen> 6 </since_tizen>
525 public FloatSelector PointSizeSelector
527 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
530 if (value == null || buttonText == null)
532 throw new NullReferenceException("Button.PointSizeSelector is null");
536 buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
542 /// Icon image's resource url selector in Button.
543 /// Getter returns copied selector value if exist, null otherwise.
545 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
546 /// <since_tizen> 6 </since_tizen>
547 public StringSelector IconURLSelector
549 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
552 if (value == null || buttonIcon == null)
554 throw new NullReferenceException("Button.IconURLSelector is null");
558 buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
564 /// Flag to decide selected state in Button.
566 /// <since_tizen> 6 </since_tizen>
567 public bool IsSelected
571 return (bool)GetValue(IsSelectedProperty);
575 SetValue(IsSelectedProperty, value);
580 /// Flag to decide enable or disable in Button.
582 /// <since_tizen> 6 </since_tizen>
583 public bool IsEnabled
587 return (bool)GetValue(IsEnabledProperty);
591 SetValue(IsEnabledProperty, value);
596 /// Icon relative orientation in Button, work only when show icon and text.
598 /// <since_tizen> 8 </since_tizen>
599 public IconOrientation? IconRelativeOrientation
603 return (IconOrientation?)GetValue(IconRelativeOrientationProperty) ?? IconOrientation.Left;
607 SetValue(IconRelativeOrientationProperty, value);
612 /// Icon padding in Button, work only when show icon and text.
614 /// <since_tizen> 6 </since_tizen>
615 public Extents IconPadding
617 get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
618 set => SetValue(IconPaddingProperty, value);
622 /// Text padding in Button, work only when show icon and text.
624 /// <since_tizen> 6 </since_tizen>
625 public Extents TextPadding
627 get => (Extents)GetValue(TextPaddingProperty) ?? new Extents();
628 set => SetValue(TextPaddingProperty, value);
632 /// Called after a key event is received by the view that has had its focus set.
634 /// <param name="key">The key event.</param>
635 /// <returns>True if the key event should be consumed.</returns>
636 /// <since_tizen> 6 </since_tizen>
637 public override bool OnKey(Key key)
639 if (!IsEnabled || null == key)
644 if (key.State == Key.StateType.Down)
646 if (key.KeyPressedName == "Return")
652 else if (key.State == Key.StateType.Up)
654 if (key.KeyPressedName == "Return")
656 bool clicked = isPressed && IsEnabled;
662 IsSelected = !IsSelected;
671 ClickedEventArgs eventArgs = new ClickedEventArgs();
672 OnClickedInternal(eventArgs);
676 return base.OnKey(key);
680 /// 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.
682 /// <since_tizen> 8 </since_tizen>
683 public override void OnFocusGained()
685 base.OnFocusGained();
690 /// 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.
692 /// <since_tizen> 8 </since_tizen>
693 public override void OnFocusLost()
700 /// Called after a touch event is received by the owning view.<br />
701 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
703 /// <param name="touch">The touch event.</param>
704 /// <returns>True if the event should be consumed.</returns>
705 /// <since_tizen> 8 </since_tizen>
706 [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
707 #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
708 public override bool OnTouch(Touch touch)
709 #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
711 return base.OnTouch(touch);
715 /// Apply style to button.
717 /// <param name="viewStyle">The style to apply.</param>
718 /// <since_tizen> 8 </since_tizen>
719 public override void ApplyStyle(ViewStyle viewStyle)
721 Debug.Assert(buttonIcon != null && buttonText != null);
723 styleApplied = false;
725 base.ApplyStyle(viewStyle);
727 if (viewStyle is ButtonStyle buttonStyle)
729 Extension = buttonStyle.CreateExtension();
731 if (buttonStyle.Overlay != null)
733 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
736 if (Extension != null)
738 buttonIcon.Unparent();
739 buttonText.Unparent();
740 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
741 buttonText = Extension.OnCreateText(this, buttonText);
745 if (buttonStyle.Text != null)
747 buttonText.ApplyStyle(buttonStyle.Text);
750 if (buttonStyle.Icon != null)
752 buttonIcon.ApplyStyle(buttonStyle.Icon);
761 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
763 /// <since_tizen> 6 </since_tizen>
764 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
765 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
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 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
776 public class StateChangedEventArgs : EventArgs
778 /// <summary> previous state of Button </summary>
779 /// <since_tizen> 6 </since_tizen>
780 /// It will be removed in API10
781 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
782 [Obsolete("Deprecated in API8; Will be removed in API10")]
783 public ControlStates PreviousState;
784 /// <summary> current state of Button </summary>
785 /// <since_tizen> 6 </since_tizen>
786 /// It will be removed in API10
787 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
788 [Obsolete("Deprecated in API8; Will be removed in API10")]
789 public ControlStates CurrentState;