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 /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it.
27 /// Button may contain text or an icon.
29 /// <since_tizen> 6 </since_tizen>
30 public partial class Button : Control
32 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
33 [EditorBrowsable(EditorBrowsableState.Never)]
34 public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
36 var instance = (Button)bindable;
39 if (instance.buttonStyle != null && instance.buttonStyle.IconRelativeOrientation != (IconOrientation?)newValue)
41 instance.buttonStyle.IconRelativeOrientation = (IconOrientation?)newValue;
42 instance.UpdateUIContent();
46 defaultValueCreator: (bindable) =>
48 var instance = (Button)bindable;
49 return instance.buttonStyle?.IconRelativeOrientation;
51 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
52 [EditorBrowsable(EditorBrowsableState.Never)]
53 public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
55 var instance = (Button)bindable;
58 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsEnabled != (bool)newValue))
60 instance.buttonStyle.IsEnabled = (bool)newValue;
61 instance.UpdateState();
65 defaultValueCreator: (bindable) =>
67 var instance = (Button)bindable;
68 return instance.buttonStyle?.IsEnabled ?? true;
70 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
71 [EditorBrowsable(EditorBrowsableState.Never)]
72 public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
74 var instance = (Button)bindable;
77 if (instance.buttonStyle != null && instance.IsSelectable && (!instance.styleApplied || instance.buttonStyle.IsSelected != (bool)newValue))
79 instance.buttonStyle.IsSelected = (bool)newValue;
80 instance.UpdateState();
84 defaultValueCreator: (bindable) =>
86 var instance = (Button)bindable;
87 return instance.IsSelectable && (instance.buttonStyle.IsSelected ?? false);
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 IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) =>
93 var instance = (Button)bindable;
96 if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsSelectable != (bool)newValue))
98 instance.buttonStyle.IsSelectable = (bool)newValue;
102 defaultValueCreator: (bindable) =>
104 var instance = (Button)bindable;
105 return instance.buttonStyle?.IsSelectable ?? false;
107 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
108 [EditorBrowsable(EditorBrowsableState.Never)]
109 public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
111 var instance = (Button)bindable;
112 if (null != newValue && null != instance.buttonStyle?.IconPadding)
114 instance.buttonStyle.IconPadding.CopyFrom((Extents)newValue);
115 instance.UpdateUIContent();
118 defaultValueCreator: (bindable) =>
120 var instance = (Button)bindable;
121 return instance.buttonStyle?.IconPadding;
123 /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
124 [EditorBrowsable(EditorBrowsableState.Never)]
125 public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
127 var instance = (Button)bindable;
128 if (null != newValue && null != instance.buttonStyle?.TextPadding)
130 instance.buttonStyle.TextPadding.CopyFrom((Extents)newValue);
131 instance.UpdateUIContent();
134 defaultValueCreator: (bindable) =>
136 var instance = (Button)bindable;
137 return instance.buttonStyle?.TextPadding;
143 /// Creates a new instance of a Button.
145 /// <since_tizen> 6 </since_tizen>
146 public Button() : base()
152 /// Creates a new instance of a Button with style.
154 /// <param name="style">Create Button by special style defined in UX.</param>
155 /// <since_tizen> 8 </since_tizen>
156 public Button(string style) : base(style)
162 /// Creates a new instance of a Button with style.
164 /// <param name="buttonStyle">Create Button by style customized by user.</param>
165 /// <since_tizen> 8 </since_tizen>
166 public Button(ButtonStyle buttonStyle) : base(buttonStyle)
172 /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
174 /// <since_tizen> 6 </since_tizen>
175 public event EventHandler<ClickEventArgs> ClickEvent;
178 /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
180 /// <since_tizen> 6 </since_tizen>
181 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
182 public event EventHandler<StateChangedEventArgs> StateChangedEvent
186 stateChangeHandler += value;
190 stateChangeHandler -= value;
195 /// Icon orientation.
197 /// <since_tizen> 6 </since_tizen>
198 public enum IconOrientation
203 /// <since_tizen> 6 </since_tizen>
208 /// <since_tizen> 6 </since_tizen>
213 /// <since_tizen> 6 </since_tizen>
218 /// <since_tizen> 6 </since_tizen>
223 /// Button's icon part.
225 /// <since_tizen> 8 </since_tizen>
226 public ImageView Icon
230 if (null == buttonIcon)
232 buttonIcon = CreateIcon();
233 if (null != Extension)
235 buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
238 buttonIcon.Relayout += OnIconRelayout;
249 /// Button's overlay image part.
251 /// <since_tizen> 8 </since_tizen>
252 public ImageView OverlayImage
256 if (null == overlayImage)
258 overlayImage = CreateOverlayImage();
259 if (null != Extension)
261 overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
263 overlayImage.WidthResizePolicy = ResizePolicyType.FillToParent;
264 overlayImage.HeightResizePolicy = ResizePolicyType.FillToParent;
271 overlayImage = value;
276 /// Button's text part.
278 /// <since_tizen> 8 </since_tizen>
279 public TextLabel TextLabel
283 if (null == buttonText)
285 buttonText = CreateText();
286 if (null != Extension)
288 buttonText = Extension.OnCreateText(this, buttonText);
290 buttonText.HorizontalAlignment = HorizontalAlignment.Center;
291 buttonText.VerticalAlignment = VerticalAlignment.Center;
303 /// Return a copied Style instance of Button
306 /// It returns copied Style instance and changing it does not effect to the Button.
307 /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
309 /// <since_tizen> 8 </since_tizen>
310 public new ButtonStyle Style
314 var result = (ButtonStyle)ViewStyle.Clone();
315 result.CopyPropertiesFromView(this);
316 result.Text.CopyPropertiesFromView(TextLabel);
317 result.Icon.CopyPropertiesFromView(Icon);
318 result.Overlay.CopyPropertiesFromView(OverlayImage);
324 /// The text of Button.
326 /// <since_tizen> 6 </since_tizen>
331 return TextLabel.Text;
335 TextLabel.Text = value;
340 /// Flag to decide Button can be selected or not.
342 /// <since_tizen> 6 </since_tizen>
343 public bool IsSelectable
347 return (bool)GetValue(IsSelectableProperty);
351 SetValue(IsSelectableProperty, value);
356 /// Translate text string in Button.
358 /// <since_tizen> 6 </since_tizen>
359 public string TranslatableText
363 return TextLabel.TranslatableText;
367 TextLabel.TranslatableText = value;
372 /// Text point size in Button.
374 /// <since_tizen> 6 </since_tizen>
375 public float PointSize
379 return TextLabel.PointSize;
383 TextLabel.PointSize = value;
388 /// Text font family in Button.
390 /// <since_tizen> 6 </since_tizen>
391 public string FontFamily
395 return TextLabel.FontFamily;
399 TextLabel.FontFamily = value;
404 /// Text color in Button.
406 /// <since_tizen> 6 </since_tizen>
407 public Color TextColor
411 return TextLabel.TextColor;
415 TextLabel.TextColor = value;
420 /// Text horizontal alignment in Button.
422 /// <since_tizen> 6 </since_tizen>
423 public HorizontalAlignment TextAlignment
427 return TextLabel.HorizontalAlignment;
431 TextLabel.HorizontalAlignment = value;
436 /// Icon image's resource url in Button.
438 /// <since_tizen> 6 </since_tizen>
439 public string IconURL
443 return Icon.ResourceUrl;
447 Icon.ResourceUrl = value;
452 /// Text string selector in Button.
453 /// Getter returns copied selector value if exist, null otherwise.
455 /// <since_tizen> 6 </since_tizen>
456 public StringSelector TextSelector
458 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
459 set => buttonText?.SetValue(TextLabel.TextSelectorProperty, value);
463 /// Translateable text string selector in Button.
464 /// Getter returns copied selector value if exist, null otherwise.
466 /// <since_tizen> 6 </since_tizen>
467 public StringSelector TranslatableTextSelector
469 get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
470 set => buttonText?.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
474 /// Text color selector in Button.
475 /// Getter returns copied selector value if exist, null otherwise.
477 /// <since_tizen> 6 </since_tizen>
478 public ColorSelector TextColorSelector
480 get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
481 set => buttonText?.SetValue(TextLabel.TextColorSelectorProperty, value);
485 /// Text font size selector in Button.
486 /// Getter returns copied selector value if exist, null otherwise.
488 /// <since_tizen> 6 </since_tizen>
489 public FloatSelector PointSizeSelector
491 get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
492 set => buttonText?.SetValue(TextLabel.PointSizeSelectorProperty, value);
496 /// Icon image's resource url selector in Button.
497 /// Getter returns copied selector value if exist, null otherwise.
499 /// <since_tizen> 6 </since_tizen>
500 public StringSelector IconURLSelector
502 get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(ImageView.ResourceUrlSelectorProperty));
503 set => buttonIcon?.SetValue(ImageView.ResourceUrlSelectorProperty, value);
507 /// Flag to decide selected state in Button.
509 /// <since_tizen> 6 </since_tizen>
510 public bool IsSelected
514 return (bool)GetValue(IsSelectedProperty);
518 SetValue(IsSelectedProperty, value);
523 /// Flag to decide enable or disable in Button.
525 /// <since_tizen> 6 </since_tizen>
526 public bool IsEnabled
530 return (bool)GetValue(IsEnabledProperty);
534 SetValue(IsEnabledProperty, value);
539 /// Icon relative orientation in Button, work only when show icon and text.
541 /// <since_tizen> 8 </since_tizen>
542 public IconOrientation? IconRelativeOrientation
546 return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
550 SetValue(IconRelativeOrientationProperty, value);
555 /// Icon padding in Button, work only when show icon and text.
557 /// <since_tizen> 6 </since_tizen>
558 public Extents IconPadding
560 get => (Extents)GetValue(IconPaddingProperty);
561 set => SetValue(IconPaddingProperty, value);
565 /// Text padding in Button, work only when show icon and text.
567 /// <since_tizen> 6 </since_tizen>
568 public Extents TextPadding
570 get => (Extents)GetValue(TextPaddingProperty);
571 set => SetValue(TextPaddingProperty, value);
574 private ButtonStyle buttonStyle => ViewStyle as ButtonStyle;
577 /// Called after a key event is received by the view that has had its focus set.
579 /// <param name="key">The key event.</param>
580 /// <returns>True if the key event should be consumed.</returns>
581 /// <since_tizen> 6 </since_tizen>
582 public override bool OnKey(Key key)
584 if (!IsEnabled || null == key)
589 if (key.State == Key.StateType.Down)
591 if (key.KeyPressedName == "Return")
597 else if (key.State == Key.StateType.Up)
599 if (key.KeyPressedName == "Return")
601 bool clicked = isPressed && IsEnabled;
607 IsSelected = !IsSelected;
616 ClickEventArgs eventArgs = new ClickEventArgs();
617 OnClickInternal(eventArgs);
621 return base.OnKey(key);
625 /// 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.
627 /// <since_tizen> 8 </since_tizen>
628 public override void OnFocusGained()
630 base.OnFocusGained();
635 /// 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.
637 /// <since_tizen> 8 </since_tizen>
638 public override void OnFocusLost()
645 /// Called after a touch event is received by the owning view.<br />
646 /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
648 /// <param name="touch">The touch event.</param>
649 /// <returns>True if the event should be consumed.</returns>
650 /// <since_tizen> 8 </since_tizen>
651 public override bool OnTouch(Touch touch)
653 if (!IsEnabled || null == touch)
658 PointStateType state = touch.GetState(0);
662 case PointStateType.Down:
664 Extension?.SetTouchInfo(touch);
667 case PointStateType.Interrupted:
671 case PointStateType.Up:
673 bool clicked = isPressed && IsEnabled;
679 Extension?.SetTouchInfo(touch);
680 IsSelected = !IsSelected;
684 Extension?.SetTouchInfo(touch);
690 ClickEventArgs eventArgs = new ClickEventArgs();
691 OnClickInternal(eventArgs);
699 return base.OnTouch(touch);
703 /// Apply style to button.
705 /// <param name="viewStyle">The style to apply.</param>
706 /// <since_tizen> 8 </since_tizen>
707 public override void ApplyStyle(ViewStyle viewStyle)
709 styleApplied = false;
711 base.ApplyStyle(viewStyle);
713 if (null != buttonStyle)
715 Extension = buttonStyle.CreateExtension();
716 if (buttonStyle.Overlay != null)
718 OverlayImage?.ApplyStyle(buttonStyle.Overlay);
721 if (buttonStyle.Text != null)
723 TextLabel?.ApplyStyle(buttonStyle.Text);
726 if (buttonStyle.Icon != null)
728 Icon?.ApplyStyle(buttonStyle.Icon);
736 /// ClickEventArgs is a class to record button click event arguments which will sent to user.
738 /// <since_tizen> 6 </since_tizen>
739 public class ClickEventArgs : EventArgs
744 /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
746 /// <since_tizen> 6 </since_tizen>
747 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")]
748 public class StateChangedEventArgs : EventArgs
750 /// <summary> previous state of Button </summary>
751 /// <since_tizen> 6 </since_tizen>
752 [Obsolete("Deprecated in API8; Will be removed in API10")]
753 public ControlStates PreviousState;
754 /// <summary> current state of Button </summary>
755 /// <since_tizen> 6 </since_tizen>
756 [Obsolete("Deprecated in API8; Will be removed in API10")]
757 public ControlStates CurrentState;
761 /// Get current text part to the attached ButtonExtension.
764 /// It returns null if the passed extension is invalid.
766 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
767 /// <return>The button's text part.</return>
768 [EditorBrowsable(EditorBrowsableState.Never)]
769 public TextLabel GetCurrentText(ButtonExtension extension)
771 return (extension == Extension) ? TextLabel : null;
775 /// Get current icon part to the attached ButtonExtension.
778 /// It returns null if the passed extension is invalid.
780 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
781 /// <return>The button's icon part.</return>
782 [EditorBrowsable(EditorBrowsableState.Never)]
783 public ImageView GetCurrentIcon(ButtonExtension extension)
785 return (extension == Extension) ? Icon : null;
789 /// Get current overlay image part to the attached ButtonExtension.
792 /// It returns null if the passed extension is invalid.
794 /// <param name="extension">The extension instance that is currently attached to this Button.</param>
795 /// <return>The button's overlay image part.</return>
796 [EditorBrowsable(EditorBrowsableState.Never)]
797 public ImageView GetCurrentOverlayImage(ButtonExtension extension)
799 return (extension == Extension) ? OverlayImage : null;