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;
23 namespace Tizen.NUI.Components
26 /// ClickedEventArgs is a class to record button click event arguments which will sent to user.
28 /// <since_tizen> 8 </since_tizen>
29 public class ClickedEventArgs : EventArgs
34 /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it.
35 /// Button may contain text or an icon.
37 /// <since_tizen> 6 </since_tizen>
38 public partial class Button : Control
40 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
41 [EditorBrowsable(EditorBrowsableState.Never)]
42 public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
44 var instance = (Button)bindable;
47 if (instance.buttonStyle != null && instance.buttonStyle.IconRelativeOrientation != (IconOrientation?)newValue)
49 instance.buttonStyle.IconRelativeOrientation = (IconOrientation?)newValue;
50 instance.UpdateUIContent();
54 defaultValueCreator: (bindable) =>
56 var instance = (Button)bindable;
57 return instance.buttonStyle?.IconRelativeOrientation;
59 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
60 [EditorBrowsable(EditorBrowsableState.Never)]
61 public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
63 var instance = (Button)bindable;
66 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsEnabled != (bool)newValue))
68 instance.buttonStyle.IsEnabled = (bool)newValue;
69 instance.UpdateState();
73 defaultValueCreator: (bindable) =>
75 var instance = (Button)bindable;
76 return instance.buttonStyle?.IsEnabled ?? true;
78 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
79 [EditorBrowsable(EditorBrowsableState.Never)]
80 public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
82 var instance = (Button)bindable;
85 if (instance.buttonStyle != null && instance.IsSelectable && (!instance.styleApplied || instance.buttonStyle.IsSelected != (bool)newValue))
87 instance.buttonStyle.IsSelected = (bool)newValue;
88 instance.UpdateState();
92 defaultValueCreator: (bindable) =>
94 var instance = (Button)bindable;
95 return instance.IsSelectable && (instance.buttonStyle.IsSelected ?? false);
97 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
98 [EditorBrowsable(EditorBrowsableState.Never)]
99 public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
101 var instance = (Button)bindable;
102 if (newValue != null)
104 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsSelectable != (bool)newValue))
106 instance.buttonStyle.IsSelectable = (bool)newValue;
110 defaultValueCreator: (bindable) =>
112 var instance = (Button)bindable;
113 return instance.buttonStyle?.IsSelectable ?? false;
115 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
116 [EditorBrowsable(EditorBrowsableState.Never)]
117 public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
119 var instance = (Button)bindable;
120 if (null != newValue && null != instance.buttonStyle?.IconPadding)
122 instance.buttonStyle.IconPadding.CopyFrom((Extents)newValue);
123 instance.UpdateUIContent();
126 defaultValueCreator: (bindable) =>
128 var instance = (Button)bindable;
129 return instance.buttonStyle?.IconPadding;
131 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
132 [EditorBrowsable(EditorBrowsableState.Never)]
133 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
135 var instance = (Button)bindable;
136 if (null != newValue && null != instance.buttonStyle?.TextPadding)
138 instance.buttonStyle.TextPadding.CopyFrom((Extents)newValue);
139 instance.UpdateUIContent();
142 defaultValueCreator: (bindable) =>
144 var instance = (Button)bindable;
145 return instance.buttonStyle?.TextPadding;
151 /// Creates a new instance of a Button.
153 /// <since_tizen> 6 </since_tizen>
154 public Button() : base()
160 /// Creates a new instance of a Button with style.
162 /// <param name="style">Create Button by special style defined in UX.</param>
163 /// <since_tizen> 8 </since_tizen>
164 public Button(string style) : base(style)
170 /// Creates a new instance of a Button with style.
172 /// <param name="buttonStyle">Create Button by style customized by user.</param>
173 /// <since_tizen> 8 </since_tizen>
174 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
180 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
182 /// <since_tizen> 6 </since_tizen>
183 [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
184 public event EventHandler<ClickEventArgs> ClickEvent;
187 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
189 /// <since_tizen> 8 </since_tizen>
190 public event EventHandler<ClickedEventArgs> Clicked;
193 /// An event for the button state changed 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 View.ControlStateChangedEvent")]
197 public event EventHandler<StateChangedEventArgs> StateChangedEvent
201 stateChangeHandler += value;
205 stateChangeHandler -= value;
210 /// Icon orientation.
212 /// <since_tizen> 6 </since_tizen>
213 public enum IconOrientation
218 /// <since_tizen> 6 </since_tizen>
223 /// <since_tizen> 6 </since_tizen>
228 /// <since_tizen> 6 </since_tizen>
233 /// <since_tizen> 6 </since_tizen>
238 /// Button's icon part.
240 /// <since_tizen> 8 </since_tizen>
241 public ImageView Icon
245 if (null == buttonIcon)
247 buttonIcon = CreateIcon();
248 if (null != Extension)
250 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
253 buttonIcon.Relayout += OnIconRelayout;
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 overlayImage.WidthResizePolicy = ResizePolicyType.FillToParent;
279 overlayImage.HeightResizePolicy = ResizePolicyType.FillToParent;
286 overlayImage = value;
291 /// Button's text part.
293 /// <since_tizen> 8 </since_tizen>
294 public TextLabel TextLabel
298 if (null == buttonText)
300 buttonText = CreateText();
301 if (null != Extension)
303 buttonText = Extension.OnCreateText(this, buttonText);
305 buttonText.HorizontalAlignment = HorizontalAlignment.Center;
306 buttonText.VerticalAlignment = VerticalAlignment.Center;
318 /// Return a copied Style instance of Button
321 /// It returns copied Style instance and changing it does not effect to the Button.
322 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
324 /// <since_tizen> 8 </since_tizen>
325 public new ButtonStyle Style
329 var result = (ButtonStyle)ViewStyle.Clone();
330 result.CopyPropertiesFromView(this);
331 result.Text.CopyPropertiesFromView(TextLabel);
332 result.Icon.CopyPropertiesFromView(Icon);
333 result.Overlay.CopyPropertiesFromView(OverlayImage);
339 /// The text of Button.
341 /// <since_tizen> 6 </since_tizen>
346 return TextLabel.Text;
350 TextLabel.Text = value;
355 /// Flag to decide Button can be selected or not.
357 /// <since_tizen> 6 </since_tizen>
358 public bool IsSelectable
362 return (bool)GetValue(IsSelectableProperty);
366 SetValue(IsSelectableProperty, value);
371 /// Translate text string in Button.
373 /// <since_tizen> 6 </since_tizen>
374 public string TranslatableText
378 return TextLabel.TranslatableText;
382 TextLabel.TranslatableText = value;
387 /// Text point size in Button.
389 /// <since_tizen> 6 </since_tizen>
390 public float PointSize
394 return TextLabel.PointSize;
398 TextLabel.PointSize = value;
403 /// Text font family in Button.
405 /// <since_tizen> 6 </since_tizen>
406 public string FontFamily
410 return TextLabel.FontFamily;
414 TextLabel.FontFamily = value;
419 /// Text color in Button.
421 /// <since_tizen> 6 </since_tizen>
422 public Color TextColor
426 return TextLabel.TextColor;
430 TextLabel.TextColor = value;
435 /// Text horizontal alignment in Button.
437 /// <since_tizen> 6 </since_tizen>
438 public HorizontalAlignment TextAlignment
442 return TextLabel.HorizontalAlignment;
446 TextLabel.HorizontalAlignment = value;
451 /// Icon image's resource url in Button.
453 /// <since_tizen> 6 </since_tizen>
454 public string IconURL
458 return Icon.ResourceUrl;
462 Icon.ResourceUrl = value;
467 /// Text string selector in Button.
468 /// Getter returns copied selector value if exist, null otherwise.
469 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
471 /// <since_tizen> 6 </since_tizen>
472 public StringSelector TextSelector
474 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
477 if (value == null || buttonText == null)
479 throw new NullReferenceException("Button.TextSelector is null");
483 buttonText.SetValue(TextLabel.TextSelectorProperty, value);
489 /// Translateable text string selector in Button.
490 /// Getter returns copied selector value if exist, null otherwise.
492 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
493 /// <since_tizen> 6 </since_tizen>
494 public StringSelector TranslatableTextSelector
496 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
499 if (value == null || buttonText == null)
501 throw new NullReferenceException("Button.TranslatableTextSelector is null");
505 buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
511 /// Text color selector in Button.
512 /// Getter returns copied selector value if exist, null otherwise.
514 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
515 /// <since_tizen> 6 </since_tizen>
516 public ColorSelector TextColorSelector
518 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
521 if (value == null || buttonText == null)
523 throw new NullReferenceException("Button.TextColorSelectorProperty is null");
527 buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
533 /// Text font size selector in Button.
534 /// Getter returns copied selector value if exist, null otherwise.
536 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
537 /// <since_tizen> 6 </since_tizen>
538 public FloatSelector PointSizeSelector
540 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
543 if (value == null || buttonText == null)
545 throw new NullReferenceException("Button.PointSizeSelector is null");
549 buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
555 /// Icon image's resource url selector in Button.
556 /// Getter returns copied selector value if exist, null otherwise.
558 /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
559 /// <since_tizen> 6 </since_tizen>
560 public StringSelector IconURLSelector
562 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
565 if (value == null || buttonIcon == null)
567 throw new NullReferenceException("Button.IconURLSelector is null");
571 buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
577 /// Flag to decide selected state in Button.
579 /// <since_tizen> 6 </since_tizen>
580 public bool IsSelected
584 return (bool)GetValue(IsSelectedProperty);
588 SetValue(IsSelectedProperty, value);
593 /// Flag to decide enable or disable in Button.
595 /// <since_tizen> 6 </since_tizen>
596 public bool IsEnabled
600 return (bool)GetValue(IsEnabledProperty);
604 SetValue(IsEnabledProperty, value);
609 /// Icon relative orientation in Button, work only when show icon and text.
611 /// <since_tizen> 8 </since_tizen>
612 public IconOrientation? IconRelativeOrientation
616 return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
620 SetValue(IconRelativeOrientationProperty, value);
625 /// Icon padding in Button, work only when show icon and text.
627 /// <since_tizen> 6 </since_tizen>
628 public Extents IconPadding
630 get => (Extents)GetValue(IconPaddingProperty);
631 set => SetValue(IconPaddingProperty, value);
635 /// Text padding in Button, work only when show icon and text.
637 /// <since_tizen> 6 </since_tizen>
638 public Extents TextPadding
640 get => (Extents)GetValue(TextPaddingProperty);
641 set => SetValue(TextPaddingProperty, value);
644 private ButtonStyle buttonStyle => ViewStyle as ButtonStyle;
647 /// Called after a key event is received by the view that has had its focus set.
649 /// <param name="key">The key event.</param>
650 /// <returns>True if the key event should be consumed.</returns>
651 /// <since_tizen> 6 </since_tizen>
652 public override bool OnKey(Key key)
654 if (!IsEnabled || null == key)
659 if (key.State == Key.StateType.Down)
661 if (key.KeyPressedName == "Return")
667 else if (key.State == Key.StateType.Up)
669 if (key.KeyPressedName == "Return")
671 bool clicked = isPressed && IsEnabled;
677 IsSelected = !IsSelected;
686 ClickedEventArgs eventArgs = new ClickedEventArgs();
687 OnClickedInternal(eventArgs);
691 return base.OnKey(key);
695 /// 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.
697 /// <since_tizen> 8 </since_tizen>
698 public override void OnFocusGained()
700 base.OnFocusGained();
705 /// 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.
707 /// <since_tizen> 8 </since_tizen>
708 public override void OnFocusLost()
715 /// Called after a touch event is received by the owning view.<br />
716 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
718 /// <param name="touch">The touch event.</param>
719 /// <returns>True if the event should be consumed.</returns>
720 /// <since_tizen> 8 </since_tizen>
721 public override bool OnTouch(Touch touch)
723 return base.OnTouch(touch);
727 /// Apply style to button.
729 /// <param name="viewStyle">The style to apply.</param>
730 /// <since_tizen> 8 </since_tizen>
731 public override void ApplyStyle(ViewStyle viewStyle)
733 styleApplied = false;
735 base.ApplyStyle(viewStyle);
737 if (null != buttonStyle)
739 Extension = buttonStyle.CreateExtension();
740 if (buttonStyle.Overlay != null)
742 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
745 if (buttonStyle.Text != null)
747 TextLabel?.ApplyStyle(buttonStyle.Text);
750 if (buttonStyle.Icon != null)
752 Icon?.ApplyStyle(buttonStyle.Icon);
760 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
762 /// <since_tizen> 6 </since_tizen>
763 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")]
764 public class ClickEventArgs : EventArgs
769 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
771 /// <since_tizen> 6 </since_tizen>
772 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
773 public class StateChangedEventArgs : EventArgs
775 /// <summary> previous state of Button </summary>
776 /// <since_tizen> 6 </since_tizen>
777 [Obsolete("Deprecated in API8; Will be removed in API10")]
778 public ControlStates PreviousState;
779 /// <summary> current state of Button </summary>
780 /// <since_tizen> 6 </since_tizen>
781 [Obsolete("Deprecated in API8; Will be removed in API10")]
782 public ControlStates CurrentState;
786 /// Get current text part to the attached ButtonExtension.
789 /// It returns null if the passed extension is invalid.
791 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
792 /// <return>The button's text part.</return>
793 [EditorBrowsable(EditorBrowsableState.Never)]
794 public TextLabel GetCurrentText(ButtonExtension extension)
796 return (extension == Extension) ? TextLabel : null;
800 /// Get current icon part to the attached ButtonExtension.
803 /// It returns null if the passed extension is invalid.
805 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
806 /// <return>The button's icon part.</return>
807 [EditorBrowsable(EditorBrowsableState.Never)]
808 public ImageView GetCurrentIcon(ButtonExtension extension)
810 return (extension == Extension) ? Icon : null;
814 /// Get current overlay image part to the attached ButtonExtension.
817 /// It returns null if the passed extension is invalid.
819 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
820 /// <return>The button's overlay image part.</return>
821 [EditorBrowsable(EditorBrowsableState.Never)]
822 public ImageView GetCurrentOverlayImage(ButtonExtension extension)
824 return (extension == Extension) ? OverlayImage : null;