/*
* 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
{
}
///
/// SelectedChangedEventArgs is a class to record item selected arguments which will sent to user.
///
/// 8
public class SelectedChangedEventArgs : EventArgs
{
/// Selected state
/// 8
public bool IsSelected { get; set; }
}
///
/// 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;
var newIconOrientation = (IconOrientation?)newValue;
if (instance.iconRelativeOrientation != newIconOrientation)
{
instance.iconRelativeOrientation = newIconOrientation;
instance.UpdateUIContent();
}
},
defaultValueCreator: (bindable) => ((Button)bindable).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)
{
bool newEnabled = (bool)newValue;
if (instance.isEnabled != newEnabled)
{
instance.isEnabled = newEnabled;
if (instance.buttonStyle != null)
{
instance.buttonStyle.IsEnabled = newEnabled;
}
instance.UpdateState();
}
}
},
defaultValueCreator: (bindable) => ((Button)bindable).isEnabled);
/// 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)
{
bool newSelected = (bool)newValue;
if (instance.isSelected != newSelected)
{
instance.isSelected = newSelected;
if (instance.buttonStyle != null)
{
instance.buttonStyle.IsSelected = newSelected;
}
if (instance.isSelectable)
{
instance.UpdateState();
}
}
}
},
defaultValueCreator: (bindable) =>
{
var instance = (Button)bindable;
return instance.isSelectable && instance.isSelected;
});
/// 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)
{
bool newSelectable = (bool)newValue;
if (instance.isSelectable != newSelectable)
{
instance.isSelectable = newSelectable;
if (instance.buttonStyle != null)
{
instance.buttonStyle.IsSelectable = newSelectable;
}
instance.UpdateState();
}
}
},
defaultValueCreator: (bindable) => ((Button)bindable).isSelectable);
/// 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;
instance.iconPadding = (Extents)((Extents)newValue).Clone();
instance.UpdateUIContent();
},
defaultValueCreator: (bindable) => ((Button)bindable).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;
instance.textPadding = (Extents)((Extents)newValue).Clone();
instance.UpdateUIContent();
},
defaultValueCreator: (bindable) => ((Button)bindable).textPadding);
private IconOrientation? iconRelativeOrientation;
private bool isSelected = false;
private bool isSelectable = false;
private bool isEnabled = true;
private Extents iconPadding;
private Extents 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);
}
if (null != 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);
}
if (null != overlayImage)
{
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);
}
if (null != buttonText)
{
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) ?? IconOrientation.Left;
}
set
{
SetValue(IconRelativeOrientationProperty, value);
}
}
///
/// Icon padding in Button, work only when show icon and text.
///
/// 6
public Extents IconPadding
{
get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
set => SetValue(IconPaddingProperty, value);
}
///
/// Text padding in Button, work only when show icon and text.
///
/// 6
public Extents TextPadding
{
get => (Extents)GetValue(TextPaddingProperty) ?? new Extents();
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.")]
#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
public override bool OnTouch(Touch touch)
#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
{
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.")]
[global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
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")]
[global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
public class StateChangedEventArgs : EventArgs
{
/// previous state of Button
/// 6
/// It will be removed in API10
[global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
[Obsolete("Deprecated in API8; Will be removed in API10")]
public ControlStates PreviousState;
/// current state of Button
/// 6
/// It will be removed in API10
[global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
[Obsolete("Deprecated in API8; Will be removed in API10")]
public ControlStates CurrentState;
}
}
}