/* * Copyright(c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using System.ComponentModel; using Tizen.NUI.BaseComponents; using Tizen.NUI.Binding; using Tizen.NUI.Components.Extension; using Tizen.NUI.Accessibility; namespace Tizen.NUI.Components { /// /// ClickedEventArgs is a class to record button click event arguments which will sent to user. /// /// 8 public class ClickedEventArgs : EventArgs { } /// /// Button is one kind of common component, a button clearly describes what action will occur when the user selects it. /// Button may contain text or an icon. /// /// 6 public partial class Button : Control { /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IconRelativeOrientationProperty = BindableProperty.Create(nameof(IconRelativeOrientation), typeof(IconOrientation?), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { if (instance.buttonStyle != null && instance.buttonStyle.IconRelativeOrientation != (IconOrientation?)newValue) { instance.buttonStyle.IconRelativeOrientation = (IconOrientation?)newValue; instance.UpdateUIContent(); } } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.buttonStyle?.IconRelativeOrientation; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create(nameof(IsEnabled), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsEnabled != (bool)newValue)) { instance.buttonStyle.IsEnabled = (bool)newValue; instance.UpdateState(); } } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.buttonStyle?.IsEnabled ?? true; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IsSelectedProperty = BindableProperty.Create(nameof(IsSelected), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { if (instance.buttonStyle != null && instance.IsSelectable && (!instance.styleApplied || instance.buttonStyle.IsSelected != (bool)newValue)) { instance.buttonStyle.IsSelected = (bool)newValue; instance.UpdateState(); } } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.IsSelectable && (instance.buttonStyle.IsSelected ?? false); }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IsSelectableProperty = BindableProperty.Create(nameof(IsSelectable), typeof(bool), typeof(Button), true, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (newValue != null) { if (instance.buttonStyle != null && (!instance.styleApplied || instance.buttonStyle.IsSelectable != (bool)newValue)) { instance.buttonStyle.IsSelectable = (bool)newValue; } } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.buttonStyle?.IsSelectable ?? false; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty IconPaddingProperty = BindableProperty.Create(nameof(IconPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (null != newValue && null != instance.buttonStyle?.IconPadding) { instance.buttonStyle.IconPadding.CopyFrom((Extents)newValue); instance.UpdateUIContent(); } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.buttonStyle?.IconPadding; }); /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty TextPaddingProperty = BindableProperty.Create(nameof(TextPadding), typeof(Extents), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) => { var instance = (Button)bindable; if (null != newValue && null != instance.buttonStyle?.TextPadding) { instance.buttonStyle.TextPadding.CopyFrom((Extents)newValue); instance.UpdateUIContent(); } }, defaultValueCreator: (bindable) => { var instance = (Button)bindable; return instance.buttonStyle?.TextPadding; }); static Button() { } /// /// Creates a new instance of a Button. /// /// 6 public Button() : base() { Initialize(); } /// /// Creates a new instance of a Button with style. /// /// Create Button by special style defined in UX. /// 8 public Button(string style) : base(style) { Initialize(); } /// /// Creates a new instance of a Button with style. /// /// Create Button by style customized by user. /// 8 public Button(ButtonStyle buttonStyle) : base(buttonStyle) { Initialize(); } /// /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
///
/// 6 [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")] public event EventHandler ClickEvent; /// /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user. /// /// 8 public event EventHandler Clicked; /// /// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.
///
/// 6 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")] public event EventHandler StateChangedEvent { add { stateChangeHandler += value; } remove { stateChangeHandler -= value; } } /// /// Icon orientation. /// /// 6 public enum IconOrientation { /// /// Top. /// /// 6 Top, /// /// Bottom. /// /// 6 Bottom, /// /// Left. /// /// 6 Left, /// /// Right. /// /// 6 Right, } /// /// Button's icon part. /// /// 8 public ImageView Icon { get { if (null == buttonIcon) { buttonIcon = CreateIcon(); if (null != Extension) { buttonIcon = Extension.OnCreateIcon(this, buttonIcon); } Add(buttonIcon); buttonIcon.Relayout += OnIconRelayout; } return buttonIcon; } internal set { buttonIcon = value; } } /// /// Button's overlay image part. /// /// 8 public ImageView OverlayImage { get { if (null == overlayImage) { overlayImage = CreateOverlayImage(); if (null != Extension) { overlayImage = Extension.OnCreateOverlayImage(this, overlayImage); } overlayImage.WidthResizePolicy = ResizePolicyType.FillToParent; overlayImage.HeightResizePolicy = ResizePolicyType.FillToParent; Add(overlayImage); } return overlayImage; } internal set { overlayImage = value; } } /// /// Button's text part. /// /// 8 public TextLabel TextLabel { get { if (null == buttonText) { buttonText = CreateText(); if (null != Extension) { buttonText = Extension.OnCreateText(this, buttonText); } buttonText.HorizontalAlignment = HorizontalAlignment.Center; buttonText.VerticalAlignment = VerticalAlignment.Center; Add(buttonText); } return buttonText; } internal set { buttonText = value; AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text); } } /// /// Return a copied Style instance of Button /// /// /// It returns copied Style instance and changing it does not effect to the Button. /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle) /// /// 8 public new ButtonStyle Style { get { var result = (ButtonStyle)ViewStyle.Clone(); result.CopyPropertiesFromView(this); result.Text.CopyPropertiesFromView(TextLabel); result.Icon.CopyPropertiesFromView(Icon); result.Overlay.CopyPropertiesFromView(OverlayImage); return result; } } /// /// The text of Button. /// /// 6 public string Text { get { return TextLabel.Text; } set { TextLabel.Text = value; } } /// /// Flag to decide Button can be selected or not. /// /// 6 public bool IsSelectable { get { return (bool)GetValue(IsSelectableProperty); } set { SetValue(IsSelectableProperty, value); } } /// /// Translate text string in Button. /// /// 6 public string TranslatableText { get { return TextLabel.TranslatableText; } set { TextLabel.TranslatableText = value; } } /// /// Text point size in Button. /// /// 6 public float PointSize { get { return TextLabel.PointSize; } set { TextLabel.PointSize = value; } } /// /// Text font family in Button. /// /// 6 public string FontFamily { get { return TextLabel.FontFamily; } set { TextLabel.FontFamily = value; } } /// /// Text color in Button. /// /// 6 public Color TextColor { get { return TextLabel.TextColor; } set { TextLabel.TextColor = value; } } /// /// Text horizontal alignment in Button. /// /// 6 public HorizontalAlignment TextAlignment { get { return TextLabel.HorizontalAlignment; } set { TextLabel.HorizontalAlignment = value; } } /// /// Icon image's resource url in Button. /// /// 6 public string IconURL { get { return Icon.ResourceUrl; } set { Icon.ResourceUrl = value; } } /// /// Text string selector in Button. /// Getter returns copied selector value if exist, null otherwise. /// Thrown when setting null value. /// /// 6 public StringSelector TextSelector { get => buttonText == null ? null : new StringSelector((Selector)buttonText.GetValue(TextLabel.TextSelectorProperty)); set { if (value == null || buttonText == null) { throw new NullReferenceException("Button.TextSelector is null"); } else { buttonText.SetValue(TextLabel.TextSelectorProperty, value); } } } /// /// Translateable text string selector in Button. /// Getter returns copied selector value if exist, null otherwise. /// /// Thrown when setting null value. /// 6 public StringSelector TranslatableTextSelector { get => buttonText == null ? null : new StringSelector((Selector)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty)); set { if (value == null || buttonText == null) { throw new NullReferenceException("Button.TranslatableTextSelector is null"); } else { buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value); } } } /// /// Text color selector in Button. /// Getter returns copied selector value if exist, null otherwise. /// /// Thrown when setting null value. /// 6 public ColorSelector TextColorSelector { get => buttonText == null ? null : new ColorSelector((Selector)buttonText.GetValue(TextLabel.TextColorSelectorProperty)); set { if (value == null || buttonText == null) { throw new NullReferenceException("Button.TextColorSelectorProperty is null"); } else { buttonText.SetValue(TextLabel.TextColorSelectorProperty, value); } } } /// /// Text font size selector in Button. /// Getter returns copied selector value if exist, null otherwise. /// /// Thrown when setting null value. /// 6 public FloatSelector PointSizeSelector { get => buttonText == null ? null : new FloatSelector((Selector)buttonText.GetValue(TextLabel.PointSizeSelectorProperty)); set { if (value == null || buttonText == null) { throw new NullReferenceException("Button.PointSizeSelector is null"); } else { buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value); } } } /// /// Icon image's resource url selector in Button. /// Getter returns copied selector value if exist, null otherwise. /// /// Thrown when setting null value. /// 6 public StringSelector IconURLSelector { get => buttonIcon == null ? null : new StringSelector((Selector)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty)); set { if (value == null || buttonIcon == null) { throw new NullReferenceException("Button.IconURLSelector is null"); } else { buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value); } } } /// /// Flag to decide selected state in Button. /// /// 6 public bool IsSelected { get { return (bool)GetValue(IsSelectedProperty); } set { SetValue(IsSelectedProperty, value); } } /// /// Flag to decide enable or disable in Button. /// /// 6 public bool IsEnabled { get { return (bool)GetValue(IsEnabledProperty); } set { SetValue(IsEnabledProperty, value); } } /// /// Icon relative orientation in Button, work only when show icon and text. /// /// 8 public IconOrientation? IconRelativeOrientation { get { return (IconOrientation?)GetValue(IconRelativeOrientationProperty); } set { SetValue(IconRelativeOrientationProperty, value); } } /// /// Icon padding in Button, work only when show icon and text. /// /// 6 public Extents IconPadding { get => (Extents)GetValue(IconPaddingProperty); set => SetValue(IconPaddingProperty, value); } /// /// Text padding in Button, work only when show icon and text. /// /// 6 public Extents TextPadding { get => (Extents)GetValue(TextPaddingProperty); set => SetValue(TextPaddingProperty, value); } private ButtonStyle buttonStyle => ViewStyle as ButtonStyle; /// /// Called after a key event is received by the view that has had its focus set. /// /// The key event. /// True if the key event should be consumed. /// 6 public override bool OnKey(Key key) { if (!IsEnabled || null == key) { return false; } if (key.State == Key.StateType.Down) { if (key.KeyPressedName == "Return") { isPressed = true; UpdateState(); } } else if (key.State == Key.StateType.Up) { if (key.KeyPressedName == "Return") { bool clicked = isPressed && IsEnabled; isPressed = false; if (IsSelectable) { IsSelected = !IsSelected; } else { UpdateState(); } if (clicked) { ClickedEventArgs eventArgs = new ClickedEventArgs(); OnClickedInternal(eventArgs); } } } return base.OnKey(key); } /// /// 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. /// /// 8 public override void OnFocusGained() { base.OnFocusGained(); UpdateState(); } /// /// 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. /// /// 8 public override void OnFocusLost() { base.OnFocusLost(); UpdateState(); } /// /// Called after a touch event is received by the owning view.
/// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).
///
/// The touch event. /// True if the event should be consumed. /// 8 [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")] public override bool OnTouch(Touch touch) { return base.OnTouch(touch); } /// /// Apply style to button. /// /// The style to apply. /// 8 public override void ApplyStyle(ViewStyle viewStyle) { styleApplied = false; base.ApplyStyle(viewStyle); if (null != buttonStyle) { Extension = buttonStyle.CreateExtension(); if (buttonStyle.Overlay != null) { OverlayImage?.ApplyStyle(buttonStyle.Overlay); } if (buttonStyle.Text != null) { TextLabel?.ApplyStyle(buttonStyle.Text); } if (buttonStyle.Icon != null) { Icon?.ApplyStyle(buttonStyle.Icon); } } styleApplied = true; } /// /// ClickEventArgs is a class to record button click event arguments which will sent to user. /// /// 6 [Obsolete("Deprecated in API8; Will be removed in API10. Please use ClickedEventArgs instead.")] public class ClickEventArgs : EventArgs { } /// /// StateChangeEventArgs is a class to record button state change event arguments which will sent to user. /// /// 6 [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEventArgs")] public class StateChangedEventArgs : EventArgs { /// previous state of Button /// 6 [Obsolete("Deprecated in API8; Will be removed in API10")] public ControlStates PreviousState; /// current state of Button /// 6 [Obsolete("Deprecated in API8; Will be removed in API10")] public ControlStates CurrentState; } /// /// Get current text part to the attached ButtonExtension. /// /// /// It returns null if the passed extension is invalid. /// /// The extension instance that is currently attached to this Button. /// The button's text part. [EditorBrowsable(EditorBrowsableState.Never)] public TextLabel GetCurrentText(ButtonExtension extension) { return (extension == Extension) ? TextLabel : null; } /// /// Get current icon part to the attached ButtonExtension. /// /// /// It returns null if the passed extension is invalid. /// /// The extension instance that is currently attached to this Button. /// The button's icon part. [EditorBrowsable(EditorBrowsableState.Never)] public ImageView GetCurrentIcon(ButtonExtension extension) { return (extension == Extension) ? Icon : null; } /// /// Get current overlay image part to the attached ButtonExtension. /// /// /// It returns null if the passed extension is invalid. /// /// The extension instance that is currently attached to this Button. /// The button's overlay image part. [EditorBrowsable(EditorBrowsableState.Never)] public ImageView GetCurrentOverlayImage(ButtonExtension extension) { return (extension == Extension) ? OverlayImage : null; } } }