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 bool newEnabled = (bool)newValue;
68 if (instance.isEnabled != newEnabled)
70 instance.isEnabled = newEnabled;
72 if (instance.buttonStyle != null)
74 instance.buttonStyle.IsEnabled = newEnabled;
77 instance.UpdateState();
81 defaultValueCreator: (bindable) => ((Button)bindable).isEnabled);
82 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
83 [EditorBrowsable(EditorBrowsableState.Never)]
84 public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
86 var instance = (Button)bindable;
89 bool newSelected = (bool)newValue;
90 if (instance.isSelected != newSelected)
92 instance.isSelected = newSelected;
94 if (instance.buttonStyle != null)
96 instance.buttonStyle.IsSelected = newSelected;
99 if (instance.isSelectable)
101 instance.UpdateState();
106 defaultValueCreator: (bindable) =>
108 var instance = (Button)bindable;
109 return instance.isSelectable && instance.isSelected;
111 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
112 [EditorBrowsable(EditorBrowsableState.Never)]
113 public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
115 var instance = (Button)bindable;
116 if (newValue != null)
118 bool newSelectable = (bool)newValue;
119 if (instance.isSelectable != newSelectable)
121 instance.isSelectable = newSelectable;
123 if (instance.buttonStyle != null)
125 instance.buttonStyle.IsSelectable = newSelectable;
128 instance.UpdateState();
132 defaultValueCreator: (bindable) => ((Button)bindable).isSelectable);
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 IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
138 var instance = (Button)bindable;
139 if (null != newValue && null != instance.buttonStyle?.IconPadding)
141 instance.buttonStyle.IconPadding.CopyFrom((Extents)newValue);
142 instance.UpdateUIContent();
145 defaultValueCreator: (bindable) =>
147 var instance = (Button)bindable;
148 return instance.buttonStyle?.IconPadding;
150 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
151 [EditorBrowsable(EditorBrowsableState.Never)]
152 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
154 var instance = (Button)bindable;
155 if (null != newValue && null != instance.buttonStyle?.TextPadding)
157 instance.buttonStyle.TextPadding.CopyFrom((Extents)newValue);
158 instance.UpdateUIContent();
161 defaultValueCreator: (bindable) =>
163 var instance = (Button)bindable;
164 return instance.buttonStyle?.TextPadding;
167 private bool isSelected = false;
168 private bool isSelectable = false;
169 private bool isEnabled = true;
174 /// Creates a new instance of a Button.
176 /// <since_tizen> 6 </since_tizen>
177 public Button() : base()
183 /// Creates a new instance of a Button with style.
185 /// <param name="style">Create Button by special style defined in UX.</param>
186 /// <since_tizen> 8 </since_tizen>
187 public Button(string style) : base(style)
193 /// Creates a new instance of a Button with style.
195 /// <param name="buttonStyle">Create Button by style customized by user.</param>
196 /// <since_tizen> 8 </since_tizen>
197 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
203 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
205 /// <since_tizen> 6 </since_tizen>
206 [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
207 public event EventHandler<ClickEventArgs> ClickEvent;
210 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
212 /// <since_tizen> 8 </since_tizen>
213 public event EventHandler<ClickedEventArgs> Clicked;
216 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
218 /// <since_tizen> 6 </since_tizen>
219 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
220 public event EventHandler<StateChangedEventArgs> StateChangedEvent
224 stateChangeHandler += value;
228 stateChangeHandler -= value;
233 /// Icon orientation.
235 /// <since_tizen> 6 </since_tizen>
236 public enum IconOrientation
241 /// <since_tizen> 6 </since_tizen>
246 /// <since_tizen> 6 </since_tizen>
251 /// <since_tizen> 6 </since_tizen>
256 /// <since_tizen> 6 </since_tizen>
261 /// Button's icon part.
263 /// <since_tizen> 8 </since_tizen>
264 public ImageView Icon
268 if (null == buttonIcon)
270 buttonIcon = CreateIcon();
271 if (null != Extension)
273 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
275 if (null != buttonIcon)
278 buttonIcon.Relayout += OnIconRelayout;
290 /// Button's overlay image part.
292 /// <since_tizen> 8 </since_tizen>
293 public ImageView OverlayImage
297 if (null == overlayImage)
299 overlayImage = CreateOverlayImage();
300 if (null != Extension)
302 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
304 if (null != overlayImage)
313 overlayImage = value;
318 /// Button's text part.
320 /// <since_tizen> 8 </since_tizen>
321 public TextLabel TextLabel
325 if (null == buttonText)
327 buttonText = CreateText();
328 if (null != Extension)
330 buttonText = Extension.OnCreateText(this, buttonText);
332 if (null != buttonText)
342 AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
347 /// Return a copied Style instance of Button
350 /// It returns copied Style instance and changing it does not effect to the Button.
351 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
353 /// <since_tizen> 8 </since_tizen>
354 public new ButtonStyle Style
358 var result = (ButtonStyle)ViewStyle.Clone();
359 result.CopyPropertiesFromView(this);
360 result.Text.CopyPropertiesFromView(TextLabel);
361 result.Icon.CopyPropertiesFromView(Icon);
362 result.Overlay.CopyPropertiesFromView(OverlayImage);
368 /// The text of Button.
370 /// <since_tizen> 6 </since_tizen>
375 return TextLabel.Text;
379 TextLabel.Text = value;
384 /// Flag to decide Button can be selected or not.
386 /// <since_tizen> 6 </since_tizen>
387 public bool IsSelectable
391 return (bool)GetValue(IsSelectableProperty);
395 SetValue(IsSelectableProperty, value);
400 /// Translate text string in Button.
402 /// <since_tizen> 6 </since_tizen>
403 public string TranslatableText
407 return TextLabel.TranslatableText;
411 TextLabel.TranslatableText = value;
416 /// Text point size in Button.
418 /// <since_tizen> 6 </since_tizen>
419 public float PointSize
423 return TextLabel.PointSize;
427 TextLabel.PointSize = value;
432 /// Text font family in Button.
434 /// <since_tizen> 6 </since_tizen>
435 public string FontFamily
439 return TextLabel.FontFamily;
443 TextLabel.FontFamily = value;
448 /// Text color in Button.
450 /// <since_tizen> 6 </since_tizen>
451 public Color TextColor
455 return TextLabel.TextColor;
459 TextLabel.TextColor = value;
464 /// Text horizontal alignment in Button.
466 /// <since_tizen> 6 </since_tizen>
467 public HorizontalAlignment TextAlignment
471 return TextLabel.HorizontalAlignment;
475 TextLabel.HorizontalAlignment = value;
480 /// Icon image's resource url in Button.
482 /// <since_tizen> 6 </since_tizen>
483 public string IconURL
487 return Icon.ResourceUrl;
491 Icon.ResourceUrl = value;
496 /// Text string selector in Button.
497 /// Getter returns copied selector value if exist, null otherwise.
498 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
500 /// <since_tizen> 6 </since_tizen>
501 public StringSelector TextSelector
503 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
506 if (value == null || buttonText == null)
508 throw new NullReferenceException("Button.TextSelector is null");
512 buttonText.SetValue(TextLabel.TextSelectorProperty, value);
518 /// Translateable text string selector in Button.
519 /// Getter returns copied selector value if exist, null otherwise.
521 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
522 /// <since_tizen> 6 </since_tizen>
523 public StringSelector TranslatableTextSelector
525 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
528 if (value == null || buttonText == null)
530 throw new NullReferenceException("Button.TranslatableTextSelector is null");
534 buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
540 /// Text color selector in Button.
541 /// Getter returns copied selector value if exist, null otherwise.
543 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
544 /// <since_tizen> 6 </since_tizen>
545 public ColorSelector TextColorSelector
547 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
550 if (value == null || buttonText == null)
552 throw new NullReferenceException("Button.TextColorSelectorProperty is null");
556 buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
562 /// Text font size selector in Button.
563 /// Getter returns copied selector value if exist, null otherwise.
565 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
566 /// <since_tizen> 6 </since_tizen>
567 public FloatSelector PointSizeSelector
569 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
572 if (value == null || buttonText == null)
574 throw new NullReferenceException("Button.PointSizeSelector is null");
578 buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
584 /// Icon image's resource url selector in Button.
585 /// Getter returns copied selector value if exist, null otherwise.
587 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
588 /// <since_tizen> 6 </since_tizen>
589 public StringSelector IconURLSelector
591 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
594 if (value == null || buttonIcon == null)
596 throw new NullReferenceException("Button.IconURLSelector is null");
600 buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
606 /// Flag to decide selected state in Button.
608 /// <since_tizen> 6 </since_tizen>
609 public bool IsSelected
613 return (bool)GetValue(IsSelectedProperty);
617 SetValue(IsSelectedProperty, value);
622 /// Flag to decide enable or disable in Button.
624 /// <since_tizen> 6 </since_tizen>
625 public bool IsEnabled
629 return (bool)GetValue(IsEnabledProperty);
633 SetValue(IsEnabledProperty, value);
638 /// Icon relative orientation in Button, work only when show icon and text.
640 /// <since_tizen> 8 </since_tizen>
641 public IconOrientation? IconRelativeOrientation
645 return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
649 SetValue(IconRelativeOrientationProperty, value);
654 /// Icon padding in Button, work only when show icon and text.
656 /// <since_tizen> 6 </since_tizen>
657 public Extents IconPadding
659 get => (Extents)GetValue(IconPaddingProperty);
660 set => SetValue(IconPaddingProperty, value);
664 /// Text padding in Button, work only when show icon and text.
666 /// <since_tizen> 6 </since_tizen>
667 public Extents TextPadding
669 get => (Extents)GetValue(TextPaddingProperty);
670 set => SetValue(TextPaddingProperty, value);
673 private ButtonStyle buttonStyle => ViewStyle as ButtonStyle;
676 /// Called after a key event is received by the view that has had its focus set.
678 /// <param name="key">The key event.</param>
679 /// <returns>True if the key event should be consumed.</returns>
680 /// <since_tizen> 6 </since_tizen>
681 public override bool OnKey(Key key)
683 if (!IsEnabled || null == key)
688 if (key.State == Key.StateType.Down)
690 if (key.KeyPressedName == "Return")
696 else if (key.State == Key.StateType.Up)
698 if (key.KeyPressedName == "Return")
700 bool clicked = isPressed && IsEnabled;
706 IsSelected = !IsSelected;
715 ClickedEventArgs eventArgs = new ClickedEventArgs();
716 OnClickedInternal(eventArgs);
720 return base.OnKey(key);
724 /// 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.
726 /// <since_tizen> 8 </since_tizen>
727 public override void OnFocusGained()
729 base.OnFocusGained();
734 /// 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.
736 /// <since_tizen> 8 </since_tizen>
737 public override void OnFocusLost()
744 /// Called after a touch event is received by the owning view.<br />
745 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
747 /// <param name="touch">The touch event.</param>
748 /// <returns>True if the event should be consumed.</returns>
749 /// <since_tizen> 8 </since_tizen>
750 public override bool OnTouch(Touch touch)
752 return base.OnTouch(touch);
756 /// Apply style to button.
758 /// <param name="viewStyle">The style to apply.</param>
759 /// <since_tizen> 8 </since_tizen>
760 public override void ApplyStyle(ViewStyle viewStyle)
762 styleApplied = false;
764 base.ApplyStyle(viewStyle);
766 if (null != buttonStyle)
768 Extension = buttonStyle.CreateExtension();
769 if (buttonStyle.Overlay != null)
771 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
774 if (buttonStyle.Text != null)
776 TextLabel?.ApplyStyle(buttonStyle.Text);
779 if (buttonStyle.Icon != null)
781 Icon?.ApplyStyle(buttonStyle.Icon);
789 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
791 /// <since_tizen> 6 </since_tizen>
792 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
793 public class ClickEventArgs : EventArgs
798 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
800 /// <since_tizen> 6 </since_tizen>
801 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
802 public class StateChangedEventArgs : EventArgs
804 /// <summary> previous state of Button </summary>
805 /// <since_tizen> 6 </since_tizen>
806 [Obsolete("Deprecated in API8; Will be removed in API10")]
807 public ControlStates PreviousState;
808 /// <summary> current state of Button </summary>
809 /// <since_tizen> 6 </since_tizen>
810 [Obsolete("Deprecated in API8; Will be removed in API10")]
811 public ControlStates CurrentState;