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 /// 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;
79 if (instance.buttonStyle != null)
81 instance.buttonStyle.IsEnabled = newEnabled;
84 instance.UpdateState();
88 defaultValueCreator: (bindable) => ((Button)bindable).isEnabled);
89 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
90 [EditorBrowsable(EditorBrowsableState.Never)]
91 public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
93 var instance = (Button)bindable;
96 bool newSelected = (bool)newValue;
97 if (instance.isSelected != newSelected)
99 instance.isSelected = newSelected;
101 if (instance.buttonStyle != null)
103 instance.buttonStyle.IsSelected = newSelected;
106 if (instance.isSelectable)
108 instance.UpdateState();
113 defaultValueCreator: (bindable) =>
115 var instance = (Button)bindable;
116 return instance.isSelectable && instance.isSelected;
118 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
119 [EditorBrowsable(EditorBrowsableState.Never)]
120 public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
122 var instance = (Button)bindable;
123 if (newValue != null)
125 bool newSelectable = (bool)newValue;
126 if (instance.isSelectable != newSelectable)
128 instance.isSelectable = newSelectable;
130 if (instance.buttonStyle != null)
132 instance.buttonStyle.IsSelectable = newSelectable;
135 instance.UpdateState();
139 defaultValueCreator: (bindable) => ((Button)bindable).isSelectable);
141 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
142 [EditorBrowsable(EditorBrowsableState.Never)]
143 public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
145 var instance = (Button)bindable;
146 instance.iconPadding = (Extents)((Extents)newValue).Clone();
147 instance.UpdateUIContent();
149 defaultValueCreator: (bindable) => ((Button)bindable).iconPadding);
151 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
152 [EditorBrowsable(EditorBrowsableState.Never)]
153 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
155 var instance = (Button)bindable;
156 instance.textPadding = (Extents)((Extents)newValue).Clone();
157 instance.UpdateUIContent();
159 defaultValueCreator: (bindable) => ((Button)bindable).textPadding);
161 private IconOrientation? iconRelativeOrientation;
162 private bool isSelected = false;
163 private bool isSelectable = false;
164 private bool isEnabled = true;
165 private Extents iconPadding;
166 private Extents textPadding;
171 /// Creates a new instance of a Button.
173 /// <since_tizen> 6 </since_tizen>
174 public Button() : base()
180 /// Creates a new instance of a Button with style.
182 /// <param name="style">Create Button by special style defined in UX.</param>
183 /// <since_tizen> 8 </since_tizen>
184 public Button(string style) : base(style)
190 /// Creates a new instance of a Button with style.
192 /// <param name="buttonStyle">Create Button by style customized by user.</param>
193 /// <since_tizen> 8 </since_tizen>
194 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
200 /// Calculates current states for the button<br />
202 [EditorBrowsable(EditorBrowsableState.Never)]
203 protected override AccessibilityStates AccessibilityCalculateStates()
205 var states = base.AccessibilityCalculateStates();
206 states.Set(AccessibilityState.Enabled, this.IsEnabled);
211 /// An event for the button clicked 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 Clicked event instead.")]
215 public event EventHandler<ClickEventArgs> ClickEvent;
218 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
220 /// <since_tizen> 8 </since_tizen>
221 public event EventHandler<ClickedEventArgs> Clicked;
224 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
226 /// <since_tizen> 6 </since_tizen>
227 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
228 public event EventHandler<StateChangedEventArgs> StateChangedEvent
232 stateChangeHandler += value;
236 stateChangeHandler -= value;
241 /// Icon orientation.
243 /// <since_tizen> 6 </since_tizen>
244 public enum IconOrientation
249 /// <since_tizen> 6 </since_tizen>
254 /// <since_tizen> 6 </since_tizen>
259 /// <since_tizen> 6 </since_tizen>
264 /// <since_tizen> 6 </since_tizen>
269 /// Button's icon part.
271 /// <since_tizen> 8 </since_tizen>
272 public ImageView Icon
276 if (null == buttonIcon)
278 buttonIcon = CreateIcon();
279 if (null != Extension)
281 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
283 if (null != buttonIcon)
286 buttonIcon.Relayout += OnIconRelayout;
298 /// Button's overlay image part.
300 /// <since_tizen> 8 </since_tizen>
301 public ImageView OverlayImage
305 if (null == overlayImage)
307 overlayImage = CreateOverlayImage();
308 if (null != Extension)
310 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
312 if (null != overlayImage)
321 overlayImage = value;
326 /// Button's text part.
328 /// <since_tizen> 8 </since_tizen>
329 public TextLabel TextLabel
333 if (null == buttonText)
335 buttonText = CreateText();
336 if (null != Extension)
338 buttonText = Extension.OnCreateText(this, buttonText);
340 if (null != buttonText)
350 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
355 /// Return a copied Style instance of Button
358 /// It returns copied Style instance and changing it does not effect to the Button.
359 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
361 /// <since_tizen> 8 </since_tizen>
362 public new ButtonStyle Style
366 var result = (ButtonStyle)ViewStyle.Clone();
367 result.CopyPropertiesFromView(this);
368 result.Text.CopyPropertiesFromView(TextLabel);
369 result.Icon.CopyPropertiesFromView(Icon);
370 result.Overlay.CopyPropertiesFromView(OverlayImage);
376 /// The text of Button.
378 /// <since_tizen> 6 </since_tizen>
383 return TextLabel.Text;
387 TextLabel.Text = value;
389 if (IsHighlighted && String.IsNullOrEmpty(AccessibilityName) && GetNameSignal().Empty())
391 EmitAccessibilityEvent(ObjectPropertyChangeEvent.Name);
397 /// Flag to decide Button can be selected or not.
399 /// <since_tizen> 6 </since_tizen>
400 public bool IsSelectable
404 return (bool)GetValue(IsSelectableProperty);
408 SetValue(IsSelectableProperty, value);
413 /// Translate text string in Button.
415 /// <since_tizen> 6 </since_tizen>
416 public string TranslatableText
420 return TextLabel.TranslatableText;
424 TextLabel.TranslatableText = value;
429 /// Text point size in Button.
431 /// <since_tizen> 6 </since_tizen>
432 public float PointSize
436 return TextLabel.PointSize;
440 TextLabel.PointSize = value;
445 /// Text font family in Button.
447 /// <since_tizen> 6 </since_tizen>
448 public string FontFamily
452 return TextLabel.FontFamily;
456 TextLabel.FontFamily = value;
461 /// Text color in Button.
463 /// <since_tizen> 6 </since_tizen>
464 public Color TextColor
468 return TextLabel.TextColor;
472 TextLabel.TextColor = value;
477 /// Text horizontal alignment in Button.
479 /// <since_tizen> 6 </since_tizen>
480 public HorizontalAlignment TextAlignment
484 return TextLabel.HorizontalAlignment;
488 TextLabel.HorizontalAlignment = value;
493 /// Icon image's resource url in Button.
495 /// <since_tizen> 6 </since_tizen>
496 public string IconURL
500 return Icon.ResourceUrl;
504 Icon.ResourceUrl = value;
509 /// Text string selector in Button.
510 /// Getter returns copied selector value if exist, null otherwise.
511 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
513 /// <since_tizen> 6 </since_tizen>
514 public StringSelector TextSelector
516 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
519 if (value == null || buttonText == null)
521 throw new NullReferenceException("Button.TextSelector is null");
525 buttonText.SetValue(TextLabel.TextSelectorProperty, value);
531 /// Translateable text string selector in Button.
532 /// Getter returns copied selector value if exist, null otherwise.
534 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
535 /// <since_tizen> 6 </since_tizen>
536 public StringSelector TranslatableTextSelector
538 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
541 if (value == null || buttonText == null)
543 throw new NullReferenceException("Button.TranslatableTextSelector is null");
547 buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
553 /// Text color selector in Button.
554 /// Getter returns copied selector value if exist, null otherwise.
556 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
557 /// <since_tizen> 6 </since_tizen>
558 public ColorSelector TextColorSelector
560 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
563 if (value == null || buttonText == null)
565 throw new NullReferenceException("Button.TextColorSelectorProperty is null");
569 buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
575 /// Text font size selector in Button.
576 /// Getter returns copied selector value if exist, null otherwise.
578 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
579 /// <since_tizen> 6 </since_tizen>
580 public FloatSelector PointSizeSelector
582 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
585 if (value == null || buttonText == null)
587 throw new NullReferenceException("Button.PointSizeSelector is null");
591 buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
597 /// Icon image's resource url selector in Button.
598 /// Getter returns copied selector value if exist, null otherwise.
600 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
601 /// <since_tizen> 6 </since_tizen>
602 public StringSelector IconURLSelector
604 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
607 if (value == null || buttonIcon == null)
609 throw new NullReferenceException("Button.IconURLSelector is null");
613 buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
619 /// Flag to decide selected state in Button.
621 /// <since_tizen> 6 </since_tizen>
622 public bool IsSelected
626 return (bool)GetValue(IsSelectedProperty);
630 SetValue(IsSelectedProperty, value);
635 /// Flag to decide enable or disable in Button.
637 /// <since_tizen> 6 </since_tizen>
638 public bool IsEnabled
642 return (bool)GetValue(IsEnabledProperty);
646 SetValue(IsEnabledProperty, value);
651 /// Icon relative orientation in Button, work only when show icon and text.
653 /// <since_tizen> 8 </since_tizen>
654 public IconOrientation? IconRelativeOrientation
658 return (IconOrientation?)GetValue(IconRelativeOrientationProperty) ?? IconOrientation.Left;
662 SetValue(IconRelativeOrientationProperty, value);
667 /// Icon padding in Button, work only when show icon and text.
669 /// <since_tizen> 6 </since_tizen>
670 public Extents IconPadding
672 get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
673 set => SetValue(IconPaddingProperty, value);
677 /// Text padding in Button, work only when show icon and text.
679 /// <since_tizen> 6 </since_tizen>
680 public Extents TextPadding
682 get => (Extents)GetValue(TextPaddingProperty) ?? new Extents();
683 set => SetValue(TextPaddingProperty, value);
686 private ButtonStyle buttonStyle => ViewStyle as ButtonStyle;
689 /// Called after a key event is received by the view that has had its focus set.
691 /// <param name="key">The key event.</param>
692 /// <returns>True if the key event should be consumed.</returns>
693 /// <since_tizen> 6 </since_tizen>
694 public override bool OnKey(Key key)
696 if (!IsEnabled || null == key)
701 if (key.State == Key.StateType.Down)
703 if (key.KeyPressedName == "Return")
709 else if (key.State == Key.StateType.Up)
711 if (key.KeyPressedName == "Return")
713 bool clicked = isPressed && IsEnabled;
719 IsSelected = !IsSelected;
728 ClickedEventArgs eventArgs = new ClickedEventArgs();
729 OnClickedInternal(eventArgs);
733 return base.OnKey(key);
737 /// 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.
739 /// <since_tizen> 8 </since_tizen>
740 public override void OnFocusGained()
742 base.OnFocusGained();
747 /// 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.
749 /// <since_tizen> 8 </since_tizen>
750 public override void OnFocusLost()
757 /// Called after a touch event is received by the owning view.<br />
758 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
760 /// <param name="touch">The touch event.</param>
761 /// <returns>True if the event should be consumed.</returns>
762 /// <since_tizen> 8 </since_tizen>
763 [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
764 #pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
765 public override bool OnTouch(Touch touch)
766 #pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
768 return base.OnTouch(touch);
772 /// Apply style to button.
774 /// <param name="viewStyle">The style to apply.</param>
775 /// <since_tizen> 8 </since_tizen>
776 public override void ApplyStyle(ViewStyle viewStyle)
778 styleApplied = false;
780 base.ApplyStyle(viewStyle);
782 if (null != buttonStyle)
784 Extension = buttonStyle.CreateExtension();
785 if (buttonStyle.Overlay != null)
787 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
790 if (buttonStyle.Text != null)
792 TextLabel?.ApplyStyle(buttonStyle.Text);
795 if (buttonStyle.Icon != null)
797 Icon?.ApplyStyle(buttonStyle.Icon);
805 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
807 /// <since_tizen> 6 </since_tizen>
808 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
809 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
810 public class ClickEventArgs : EventArgs
815 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
817 /// <since_tizen> 6 </since_tizen>
818 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
819 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
820 public class StateChangedEventArgs : EventArgs
822 /// <summary> previous state of Button </summary>
823 /// <since_tizen> 6 </since_tizen>
824 /// It will be removed in API10
825 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
826 [Obsolete("Deprecated in API8; Will be removed in API10")]
827 public ControlStates PreviousState;
828 /// <summary> current state of Button </summary>
829 /// <since_tizen> 6 </since_tizen>
830 /// It will be removed in API10
831 [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
832 [Obsolete("Deprecated in API8; Will be removed in API10")]
833 public ControlStates CurrentState;