/*
- * Copyright(c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2021 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.
*/
using System;
using System.ComponentModel;
+using System.Diagnostics;
using Tizen.NUI.BaseComponents;
using Tizen.NUI.Binding;
-using Tizen.NUI.Components.Extension;
+using Tizen.NUI.Accessibility;
namespace Tizen.NUI.Components
{
/// <summary>
+ /// ClickedEventArgs is a class to record button click event arguments which will sent to user.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ public class ClickedEventArgs : EventArgs
+ {
+ }
+
+ /// <summary>
+ /// SelectedChangedEventArgs is a class to record item selected arguments which will sent to user.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ public class SelectedChangedEventArgs : EventArgs
+ {
+ /// <summary> Selected state </summary>
+ /// <since_tizen> 8 </since_tizen>
+ public bool IsSelected { get; set; }
+ }
+
+ /// <summary>
/// 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.
/// </summary>
/// <since_tizen> 6 </since_tizen>
- public class Button : Control
+ 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)
+ var newIconOrientation = (IconOrientation?)newValue;
+ if (instance.iconRelativeOrientation != newIconOrientation)
{
- instance.privateIconRelativeOrientation = (IconOrientation?)newValue;
+ instance.iconRelativeOrientation = newIconOrientation;
+ instance.LayoutItems();
}
},
- defaultValueCreator: (bindable) =>
- {
- var instance = (Button)bindable;
- return instance.privateIconRelativeOrientation;
- });
+ 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)
{
- instance.privateIsEnabled = (bool)newValue;
+ bool newEnabled = (bool)newValue;
+ if (instance.isEnabled != newEnabled)
+ {
+ instance.isEnabled = newEnabled;
+ instance.Sensitive = newEnabled;
+ instance.UpdateState();
+ }
}
},
- defaultValueCreator: (bindable) =>
- {
- var instance = (Button)bindable;
- return instance.privateIsEnabled;
- });
+ 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)
{
- instance.privateIsSelected = (bool)newValue;
+ bool newSelected = (bool)newValue;
+ if (instance.isSelected != newSelected)
+ {
+ instance.isSelected = newSelected;
+
+ if (instance.isSelectable)
+ {
+ instance.UpdateState();
+ }
+ }
}
},
defaultValueCreator: (bindable) =>
{
var instance = (Button)bindable;
- return instance.privateIsSelected;
+ 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)]
var instance = (Button)bindable;
if (newValue != null)
{
- instance.privateIsSelectable = (bool)newValue;
+ bool newSelectable = (bool)newValue;
+ if (instance.isSelectable != newSelectable)
+ {
+ instance.isSelectable = newSelectable;
+ instance.UpdateState();
+ }
}
},
- defaultValueCreator: (bindable) =>
- {
- var instance = (Button)bindable;
- return instance.privateIsSelectable;
- });
+ 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;
- if (null != newValue && null != instance.Style?.IconPadding)
+ if (instance.buttonIcon == null)
{
- instance.Style.IconPadding.CopyFrom((Extents)newValue);
- instance.UpdateUIContent();
+ return;
}
+ instance.buttonIcon.Padding = (Extents)newValue;
},
- defaultValueCreator: (bindable) =>
- {
- var instance = (Button)bindable;
- return instance.Style?.IconPadding;
- });
+ defaultValueCreator: (bindable) => ((Button)bindable).buttonIcon?.Padding);
+
/// 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.Style?.TextPadding)
+ if (instance.buttonText == null)
{
- instance.Style.TextPadding.CopyFrom((Extents)newValue);
- instance.UpdateUIContent();
+ return;
}
+ instance.buttonText.Padding = (Extents)newValue;
},
- defaultValueCreator: (bindable) =>
- {
- var instance = (Button)bindable;
- return instance.Style?.TextPadding;
- });
-
- private EventHandler<StateChangedEventArgs> stateChangeHander;
-
- private bool isSelected = false;
- private bool isEnabled = true;
- private bool isPressed = false;
+ defaultValueCreator: (bindable) => ((Button)bindable).buttonText?.Padding);
- /// <summary>
- /// Button's overlay image part.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected ImageView ButtonOverlayImage { get; set; }
-
- /// <summary>
- /// Button's text part.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected TextLabel ButtonText { get; set; }
-
- /// <summary>
- /// Button's icon part.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected ImageView ButtonIcon { get; set; }
-
- /// <summary>
- /// The last touch information triggering selected state change.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected Touch SelectionChangedByTouch { get; set; }
-
- /// <summary>
- /// The ButtonExtension instance that is injected by ButtonStyle.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected ButtonExtension Extension { get; set; }
-
- /// <summary>
- /// Creates Button's text part.
- /// </summary>
- /// <return>The created Button's text part.</return>
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected virtual TextLabel CreateText()
- {
- return new TextLabel();
- }
-
- /// <summary>
- /// Creates Button's icon part.
- /// </summary>
- /// <return>The created Button's icon part.</return>
+ /// <summary> The bindable property of ItemAlignment. </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- protected virtual ImageView CreateIcon()
+ internal static readonly BindableProperty ItemAlignmentProperty = BindableProperty.Create(nameof(ItemAlignment), typeof(LinearLayout.Alignment), typeof(Button), LinearLayout.Alignment.Center, propertyChanged: (bindable, oldValue, newValue) =>
{
- return new ImageView();
- }
+ var instance = (Button)bindable;
+ instance.itemAlignment = (LinearLayout.Alignment)newValue;
+ instance.LayoutItems();
+ },
+ defaultValueCreator: (bindable) => ((Button)bindable).itemAlignment);
- /// <summary>
- /// Creates Button's overlay image part.
- /// </summary>
- /// <return>The created Button's overlay image part.</return>
+ /// <summary> The bindable property of ItemSpacing. </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- protected virtual ImageView CreateOverlayImage()
+ internal static readonly BindableProperty ItemSpacingProperty = BindableProperty.Create(nameof(ItemSpacing), typeof(Size2D), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
{
- return new ImageView();
- }
+ var instance = (Button)bindable;
+ instance.itemSpacing = (Size2D)newValue;
+ instance.UpdateSizeAndSpacing();
+ },
+ defaultValueCreator: (bindable) => ((Button)bindable).itemSpacing);
- /// <summary>
- /// Called when the Button is Clicked by a user
- /// </summary>
- /// <param name="eventArgs">The click information.</param>
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected virtual void OnClick(ClickEventArgs eventArgs)
- {
- }
+ private IconOrientation? iconRelativeOrientation = IconOrientation.Left;
+ private bool isSelected = false;
+ private bool isSelectable = false;
+ private bool isEnabled = true;
+ private Size2D itemSpacing;
+ private LinearLayout.Alignment itemAlignment;
static Button() { }
/// <since_tizen> 6 </since_tizen>
public Button() : base()
{
- Initialize();
}
/// <summary>
/// <since_tizen> 8 </since_tizen>
public Button(string style) : base(style)
{
- Initialize();
}
/// <summary>
/// <since_tizen> 8 </since_tizen>
public Button(ButtonStyle buttonStyle) : base(buttonStyle)
{
- Initialize();
+ }
+
+ /// <summary>
+ /// Calculates current states for the button<br />
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override AccessibilityStates AccessibilityCalculateStates()
+ {
+ var states = base.AccessibilityCalculateStates();
+ states.Set(AccessibilityState.Checked, this.IsSelected);
+ states.Set(AccessibilityState.Enabled, this.IsEnabled);
+ return states;
}
/// <summary>
/// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
/// </summary>
/// <since_tizen> 6 </since_tizen>
+ [Obsolete("Deprecated in API8; Will be removed in API10. Please use Clicked event instead.")]
public event EventHandler<ClickEventArgs> ClickEvent;
+
+ /// <summary>
+ /// An event for the button clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ public event EventHandler<ClickedEventArgs> Clicked;
+
/// <summary>
/// An event for the button state changed signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
/// </summary>
/// <since_tizen> 6 </since_tizen>
+ [Obsolete("Deprecated in API8; Will be removed in API10. Please use View.ControlStateChangedEvent")]
public event EventHandler<StateChangedEventArgs> StateChangedEvent
{
add
{
- stateChangeHander += value;
+ stateChangeHandler += value;
}
remove
{
- stateChangeHander -= value;
+ stateChangeHandler -= value;
}
}
+
/// <summary>
/// Icon orientation.
/// </summary>
}
/// <summary>
- /// Style of the button.
+ /// Button's icon part.
/// </summary>
/// <since_tizen> 8 </since_tizen>
- public new ButtonStyle Style => ViewStyle as ButtonStyle;
+ public ImageView Icon
+ {
+ get => buttonIcon;
+ internal set
+ {
+ buttonIcon = value;
+ }
+ }
+
+ /// <summary>
+ /// Button's overlay image part.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ public ImageView OverlayImage
+ {
+ get
+ {
+ if (null == overlayImage)
+ {
+ overlayImage = CreateOverlayImage();
+ if (null != Extension)
+ {
+ overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
+ }
+ if (null != overlayImage)
+ {
+ overlayImage.ExcludeLayouting = true;
+ Add(overlayImage);
+ }
+ }
+ return overlayImage;
+ }
+ internal set
+ {
+ overlayImage = value;
+ }
+ }
+
+ /// <summary>
+ /// Button's text part.
+ /// </summary>
+ /// <since_tizen> 8 </since_tizen>
+ public TextLabel TextLabel
+ {
+ get => buttonText;
+ internal set
+ {
+ buttonText = value;
+ AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
+ }
+ }
+
+ /// <summary>
+ /// Return currently applied style.
+ /// </summary>
+ /// <remarks>
+ /// Modifying contents in style may cause unexpected behaviour.
+ /// </remarks>
+ /// <since_tizen> 8 </since_tizen>
+ public ButtonStyle Style => (ButtonStyle)(ViewStyle as ButtonStyle)?.Clone();
/// <summary>
/// The text of Button.
{
get
{
- return Style?.Text?.Text?.GetValue(ControlState);
+ return TextLabel.Text;
}
set
{
- if (null != Style?.Text)
+ TextLabel.Text = value;
+
+ if (IsHighlighted && String.IsNullOrEmpty(AccessibilityName) && GetAccessibilityNameSignal().Empty())
{
- Style.Text.Text = value;
+ EmitAccessibilityEvent(ObjectPropertyChangeEvent.Name);
}
}
}
}
}
- private bool privateIsSelectable
- {
- get
- {
- return Style?.IsSelectable ?? false;
- }
- set
- {
- Style.IsSelectable = value;
- }
- }
-
/// <summary>
/// Translate text string in Button.
/// </summary>
{
get
{
- return Style?.Text?.TranslatableText?.All;
+ return TextLabel.TranslatableText;
}
set
{
- if (null != Style?.Text)
- {
- Style.Text.TranslatableText = value;
- }
+ TextLabel.TranslatableText = value;
}
}
{
get
{
- return Style?.Text?.PointSize?.All ?? 0;
+ return TextLabel.PointSize;
}
set
{
- if (null != Style?.Text)
- {
- Style.Text.PointSize = value;
- }
+ TextLabel.PointSize = value;
}
}
{
get
{
- return Style?.Text?.FontFamily.All;
+ return TextLabel.FontFamily;
}
set
{
- if (null != Style?.Text)
- {
- Style.Text.FontFamily = value;
- }
+ TextLabel.FontFamily = value;
}
}
+
/// <summary>
/// Text color in Button.
/// </summary>
{
get
{
- return Style?.Text?.TextColor?.All;
+ return TextLabel.TextColor;
}
set
{
- if (null != Style?.Text)
- {
- Style.Text.TextColor = value;
- }
+ TextLabel.TextColor = value;
}
}
+
/// <summary>
/// Text horizontal alignment in Button.
/// </summary>
{
get
{
- return Style?.Text?.HorizontalAlignment ?? HorizontalAlignment.Center;
+ return TextLabel.HorizontalAlignment;
}
set
{
- if (null != Style?.Text)
- {
- Style.Text.HorizontalAlignment = value;
- }
+ TextLabel.HorizontalAlignment = value;
}
}
+
/// <summary>
/// Icon image's resource url in Button.
/// </summary>
{
get
{
- return Style?.Icon?.ResourceUrl?.All;
+ return Icon.ResourceUrl;
}
set
{
- if (null != Style?.Icon)
- {
- Style.Icon.ResourceUrl = value;
- }
+ Icon.ResourceUrl = value;
}
}
- private StringSelector textSelector = new StringSelector();
/// <summary>
/// Text string selector in Button.
+ /// Getter returns copied selector value if exist, null otherwise.
+ /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
/// </summary>
/// <since_tizen> 6 </since_tizen>
public StringSelector TextSelector
{
- get
- {
- return textSelector;
- }
+ get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TextSelectorProperty));
set
{
- if (value == null || textSelector == null)
+ if (value == null || buttonText == null)
{
- Tizen.Log.Fatal("NUI", "[Exception] Button.TextSelector is null");
throw new NullReferenceException("Button.TextSelector is null");
}
else
{
- textSelector.Clone(value);
+ buttonText.SetValue(TextLabel.TextSelectorProperty, value);
}
}
}
- private StringSelector translatableTextSelector = new StringSelector();
/// <summary>
- /// Translateable text string selector in Button.
+ /// Translatable text string selector in Button.
+ /// Getter returns copied selector value if exist, null otherwise.
/// </summary>
+ /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
/// <since_tizen> 6 </since_tizen>
public StringSelector TranslatableTextSelector
{
- get
- {
- return translatableTextSelector;
- }
+ get => buttonText == null ? null : new StringSelector((Selector<string>)buttonText.GetValue(TextLabel.TranslatableTextSelectorProperty));
set
{
- if (value == null || translatableTextSelector == null)
+ if (value == null || buttonText == null)
{
- Tizen.Log.Fatal("NUI", "[Exception] Button.TranslatableTextSelector is null");
throw new NullReferenceException("Button.TranslatableTextSelector is null");
}
else
{
- translatableTextSelector.Clone(value);
+ buttonText.SetValue(TextLabel.TranslatableTextSelectorProperty, value);
}
}
}
- private ColorSelector textColorSelector = new ColorSelector();
/// <summary>
/// Text color selector in Button.
+ /// Getter returns copied selector value if exist, null otherwise.
/// </summary>
+ /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
/// <since_tizen> 6 </since_tizen>
public ColorSelector TextColorSelector
{
- get
- {
- return textColorSelector;
- }
+ get => buttonText == null ? null : new ColorSelector((Selector<Color>)buttonText.GetValue(TextLabel.TextColorSelectorProperty));
set
{
- if (value == null || textColorSelector == null)
+ if (value == null || buttonText == null)
{
- Tizen.Log.Fatal("NUI", "[Exception] Button.textColorSelector is null");
- throw new NullReferenceException("Button.textColorSelector is null");
+ throw new NullReferenceException("Button.TextColorSelectorProperty is null");
}
else
{
- textColorSelector.Clone(value);
+ buttonText.SetValue(TextLabel.TextColorSelectorProperty, value);
}
}
}
- private FloatSelector pointSizeSelector = new FloatSelector();
/// <summary>
/// Text font size selector in Button.
+ /// Getter returns copied selector value if exist, null otherwise.
/// </summary>
+ /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
/// <since_tizen> 6 </since_tizen>
public FloatSelector PointSizeSelector
{
- get
- {
- return pointSizeSelector;
- }
+ get => buttonText == null ? null : new FloatSelector((Selector<float?>)buttonText.GetValue(TextLabel.PointSizeSelectorProperty));
set
{
- if (value == null || pointSizeSelector == null)
+ if (value == null || buttonText == null)
{
- Tizen.Log.Fatal("NUI", "[Exception] Button.pointSizeSelector is null");
- throw new NullReferenceException("Button.pointSizeSelector is null");
+ throw new NullReferenceException("Button.PointSizeSelector is null");
}
else
{
- pointSizeSelector.Clone(value);
+ buttonText.SetValue(TextLabel.PointSizeSelectorProperty, value);
}
}
}
- private StringSelector iconURLSelector = new StringSelector();
/// <summary>
/// Icon image's resource url selector in Button.
+ /// Getter returns copied selector value if exist, null otherwise.
/// </summary>
+ /// <exception cref="NullReferenceException">Thrown when setting null value.</exception>
/// <since_tizen> 6 </since_tizen>
public StringSelector IconURLSelector
{
- get
- {
- return iconURLSelector;
- }
+ get => buttonIcon == null ? null : new StringSelector((Selector<string>)buttonIcon.GetValue(ImageView.ResourceUrlSelectorProperty));
set
{
- if (value == null || iconURLSelector == null)
+ if (value == null || buttonIcon == null)
{
- Tizen.Log.Fatal("NUI", "[Exception] Button.iconURLSelector is null");
- throw new NullReferenceException("Button.iconURLSelector is null");
+ throw new NullReferenceException("Button.IconURLSelector is null");
}
else
{
- iconURLSelector.Clone(value);
+ buttonIcon.SetValue(ImageView.ResourceUrlSelectorProperty, value);
}
}
}
SetValue(IsSelectedProperty, value);
}
}
- private bool privateIsSelected
- {
- get
- {
- return isSelected;
- }
- set
- {
- isSelected = value;
-
- UpdateState(SelectionChangedByTouch);
-
- SelectionChangedByTouch = null;
- }
- }
/// <summary>
/// Flag to decide enable or disable in Button.
SetValue(IsEnabledProperty, value);
}
}
- private bool privateIsEnabled
- {
- get
- {
- return isEnabled;
- }
- set
- {
- isEnabled = value;
- UpdateState();
- }
- }
/// <summary>
/// Icon relative orientation in Button, work only when show icon and text.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
+ /// <since_tizen> 8 </since_tizen>
public IconOrientation? IconRelativeOrientation
{
get
{
- return (IconOrientation?)GetValue(IconRelativeOrientationProperty);
+ return (IconOrientation?)GetValue(IconRelativeOrientationProperty) ?? IconOrientation.Left;
}
set
{
SetValue(IconRelativeOrientationProperty, value);
}
}
- private IconOrientation? privateIconRelativeOrientation
- {
- get
- {
- return Style?.IconRelativeOrientation;
- }
- set
- {
- if (Style != null && Style.IconRelativeOrientation != value)
- {
- Style.IconRelativeOrientation = value;
- UpdateUIContent();
- }
- }
- }
/// <summary>
- /// Icon padding in Button, work only when show icon and text.
+ /// Icon padding in Button. It is shortcut of Icon.Padding.
/// </summary>
/// <since_tizen> 6 </since_tizen>
public Extents IconPadding
{
- get => (Extents)GetValue(IconPaddingProperty);
+ get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
set => SetValue(IconPaddingProperty, value);
}
/// <summary>
- /// Text padding in Button, work only when show icon and text.
+ /// Text padding in Button. It is shortcut of TextLabel.Padding.
/// </summary>
/// <since_tizen> 6 </since_tizen>
public Extents TextPadding
{
- get => (Extents)GetValue(TextPaddingProperty);
+ get => (Extents)GetValue(TextPaddingProperty) ?? new Extents();
set => SetValue(TextPaddingProperty, value);
}
/// <summary>
- /// Dispose Button and all children on it.
+ /// The item (text or icon or both) alignment.
/// </summary>
- /// <param name="type">Dispose type.</param>
- /// <since_tizen> 6 </since_tizen>
- protected override void Dispose(DisposeTypes type)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public LinearLayout.Alignment ItemAlignment
{
- if (disposed)
- {
- return;
- }
-
- if (type == DisposeTypes.Explicit)
- {
- Extension?.OnDispose(this);
-
- if (ButtonIcon != null)
- {
- Utility.Dispose(ButtonIcon);
- }
- if (ButtonText != null)
- {
- Utility.Dispose(ButtonText);
- }
- if (ButtonOverlayImage != null)
- {
- Utility.Dispose(ButtonOverlayImage);
- }
- }
+ get => (LinearLayout.Alignment)GetValue(ItemAlignmentProperty);
+ set => SetValue(ItemAlignmentProperty, value);
+ }
- base.Dispose(type);
+ /// <summary>
+ /// The space between icon and text.
+ /// The value is applied when there exist icon and text both.
+ /// The width value is used when the items are arranged horizontally. Otherwise, the height value is used.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Size2D ItemSpacing
+ {
+ get => (Size2D)GetValue(ItemSpacingProperty);
+ set => SetValue(ItemSpacingProperty, value);
}
+
/// <summary>
/// Called after a key event is received by the view that has had its focus set.
/// </summary>
/// <since_tizen> 6 </since_tizen>
public override bool OnKey(Key key)
{
- if (null == key) return false;
+ if (!IsEnabled || null == key)
+ {
+ return false;
+ }
+
if (key.State == Key.StateType.Down)
{
if (key.KeyPressedName == "Return")
{
if (key.KeyPressedName == "Return")
{
- bool clicked = isPressed && isEnabled;
+ bool clicked = isPressed && IsEnabled;
isPressed = false;
- if (Style.IsSelectable != null && Style.IsSelectable == true)
+ if (IsSelectable)
{
IsSelected = !IsSelected;
}
if (clicked)
{
- ClickEventArgs eventArgs = new ClickEventArgs();
- OnClickInternal(eventArgs);
+ ClickedEventArgs eventArgs = new ClickedEventArgs();
+ OnClickedInternal(eventArgs);
}
}
}
/// <summary>
/// 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.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
+ /// <since_tizen> 8 </since_tizen>
public override void OnFocusGained()
{
base.OnFocusGained();
/// <summary>
/// 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.
/// </summary>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
+ /// <since_tizen> 8 </since_tizen>
public override void OnFocusLost()
{
base.OnFocusLost();
/// </summary>
/// <param name="touch">The touch event.</param>
/// <returns>True if the event should be consumed.</returns>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
+ /// <since_tizen> 8 </since_tizen>
+ [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
{
- if (null == touch) return false;
- PointStateType state = touch.GetState(0);
-
- switch (state)
- {
- case PointStateType.Down:
- isPressed = true;
- UpdateState(touch);
- return true;
- case PointStateType.Interrupted:
- isPressed = false;
- UpdateState();
- return true;
- case PointStateType.Up:
- {
- bool clicked = isPressed && isEnabled;
-
- isPressed = false;
-
- if (Style.IsSelectable != null && Style.IsSelectable == true)
- {
- SelectionChangedByTouch = touch;
- IsSelected = !IsSelected;
- }
- else
- {
- UpdateState(touch);
- }
-
- if (clicked)
- {
- ClickEventArgs eventArgs = new ClickEventArgs();
- OnClickInternal(eventArgs);
- }
-
- return true;
- }
- default:
- break;
- }
return base.OnTouch(touch);
}
/// <since_tizen> 8 </since_tizen>
public override void ApplyStyle(ViewStyle viewStyle)
{
- base.ApplyStyle(viewStyle);
-
- ButtonStyle buttonStyle = viewStyle as ButtonStyle;
-
- if (null != buttonStyle)
- {
- ButtonOverlayImage?.ApplyStyle(buttonStyle.Overlay);
- ButtonText?.ApplyStyle(buttonStyle.Text);
- ButtonIcon?.ApplyStyle(buttonStyle.Icon);
- }
- }
-
- /// <summary>
- /// Get Button style.
- /// </summary>
- /// <returns>The default button style.</returns>
- /// <since_tizen> 8 </since_tizen>
- protected override ViewStyle GetViewStyle()
- {
- return new ButtonStyle();
- }
-
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected override void OnUpdate()
- {
- base.OnUpdate();
- UpdateUIContent();
-
- Extension?.OnRelayout(this);
- }
-
- /// <summary>
- /// Update Button State.
- /// </summary>
- /// <param name="touchInfo">The touch information in case the state has changed by touching.</param>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected void UpdateState(Touch touchInfo = null)
- {
- ControlStates sourceState = ControlState;
- ControlStates targetState;
+ Debug.Assert(buttonIcon != null && buttonText != null);
- if (isEnabled)
- {
- // Normal
- targetState = ControlStates.Normal;
+ styleApplied = false;
- // Selected
- targetState |= (IsSelected ? ControlStates.Selected : 0);
+ base.ApplyStyle(viewStyle);
- // Pressed, PressedSelected, Focused, SelectedFocused
- targetState |= (isPressed ? ControlStates.Pressed : (IsFocused ? ControlStates.Focused : 0));
- }
- else
+ if (viewStyle is ButtonStyle buttonStyle)
{
- // Disabled
- targetState = ControlStates.Disabled;
+ Extension = buttonStyle.CreateExtension();
- // DisabledSelected, DisabledFocused
- targetState |= (IsSelected ? ControlStates.Selected : (IsFocused ? ControlStates.Focused : 0));
- }
-
- if (SetControlState(targetState, touchInfo))
- {
- OnUpdate();
+ if (buttonStyle.Overlay != null)
+ {
+ OverlayImage?.ApplyStyle(buttonStyle.Overlay);
+ }
- StateChangedEventArgs e = new StateChangedEventArgs
+ if (Extension != null)
{
- PreviousState = sourceState,
- CurrentState = targetState
- };
- stateChangeHander?.Invoke(this, e);
+ buttonIcon.Unparent();
+ buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
- Extension?.OnControlStateChanged(this, sourceState, touchInfo);
- }
- }
+ buttonText.Unparent();
+ buttonText = Extension.OnCreateText(this, buttonText);
- /// <summary>
- /// It is hijack by using protected, style copy problem when class inherited from Button.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- private void Initialize()
- {
- var style = (ButtonStyle)Style;
-
- Extension = style.CreateExtension();
-
- CreateComponents();
-
- if (ButtonOverlayImage != null)
- {
- Add(ButtonOverlayImage);
- ButtonOverlayImage.ApplyStyle(style.Overlay);
- }
+ LayoutItems();
+ }
- if (ButtonIcon != null)
- {
- Add(ButtonIcon);
- ButtonIcon.ApplyStyle(style.Icon);
- ButtonIcon.Relayout += OnIconRelayout;
- }
+ if (buttonStyle.Text != null)
+ {
+ buttonText.ApplyStyle(buttonStyle.Text);
+ }
- if (null != ButtonText)
- {
- Add(ButtonText);
- ButtonText.ApplyStyle(style.Text);
+ if (buttonStyle.Icon != null)
+ {
+ buttonIcon.ApplyStyle(buttonStyle.Icon);
+ }
}
+ styleApplied = true;
UpdateState();
-
- LayoutDirectionChanged += OnLayoutDirectionChanged;
- }
-
- private void CreateComponents()
- {
- ButtonOverlayImage = CreateOverlayImage();
- ButtonIcon = CreateIcon();
- ButtonText = CreateText();
-
- if (Extension == null)
- {
- return;
- }
-
- // Update component with extension
- ButtonOverlayImage = Extension.OnCreateOverlayImage(this, ButtonOverlayImage);
- ButtonIcon = Extension.OnCreateIcon(this, ButtonIcon);
- ButtonText = Extension.OnCreateText(this, ButtonText);
- }
-
- /// <summary>
- /// Measure text, it can be override.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected virtual void MeasureText()
- {
- if (Style.IconRelativeOrientation == null || ButtonIcon == null || ButtonText == null)
- {
- return;
- }
- ButtonText.WidthResizePolicy = ResizePolicyType.Fixed;
- ButtonText.HeightResizePolicy = ResizePolicyType.Fixed;
- int textPaddingStart = Style.TextPadding.Start;
- int textPaddingEnd = Style.TextPadding.End;
- int textPaddingTop = Style.TextPadding.Top;
- int textPaddingBottom = Style.TextPadding.Bottom;
-
- int iconPaddingStart = Style.IconPadding.Start;
- int iconPaddingEnd = Style.IconPadding.End;
- int iconPaddingTop = Style.IconPadding.Top;
- int iconPaddingBottom = Style.IconPadding.Bottom;
-
- if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom)
- {
- ButtonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd;
- ButtonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - ButtonIcon.SizeHeight;
- }
- else
- {
- ButtonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - ButtonIcon.SizeWidth;
- ButtonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom;
- }
- }
- /// <summary>
- /// Layout child, it can be override.
- /// </summary>
- /// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
- protected virtual void LayoutChild()
- {
- if (Style.IconRelativeOrientation == null || ButtonIcon == null || ButtonText == null)
- {
- return;
- }
-
- var buttonIcon = ButtonIcon;
- var buttonText = ButtonText;
-
- int textPaddingStart = Style.TextPadding.Start;
- int textPaddingEnd = Style.TextPadding.End;
- int textPaddingTop = Style.TextPadding.Top;
- int textPaddingBottom = Style.TextPadding.Bottom;
-
- int iconPaddingStart = Style.IconPadding.Start;
- int iconPaddingEnd = Style.IconPadding.End;
- int iconPaddingTop = Style.IconPadding.Top;
- int iconPaddingBottom = Style.IconPadding.Bottom;
-
- switch (IconRelativeOrientation)
- {
- case IconOrientation.Top:
- buttonIcon.PositionUsesPivotPoint = true;
- buttonIcon.ParentOrigin = NUI.ParentOrigin.TopCenter;
- buttonIcon.PivotPoint = NUI.PivotPoint.TopCenter;
- buttonIcon.Position2D = new Position2D(0, iconPaddingTop);
-
- buttonText.PositionUsesPivotPoint = true;
- buttonText.ParentOrigin = NUI.ParentOrigin.BottomCenter;
- buttonText.PivotPoint = NUI.PivotPoint.BottomCenter;
- buttonText.Position2D = new Position2D(0, -textPaddingBottom);
- break;
- case IconOrientation.Bottom:
- buttonIcon.PositionUsesPivotPoint = true;
- buttonIcon.ParentOrigin = NUI.ParentOrigin.BottomCenter;
- buttonIcon.PivotPoint = NUI.PivotPoint.BottomCenter;
- buttonIcon.Position2D = new Position2D(0, -iconPaddingBottom);
-
- buttonText.PositionUsesPivotPoint = true;
- buttonText.ParentOrigin = NUI.ParentOrigin.TopCenter;
- buttonText.PivotPoint = NUI.PivotPoint.TopCenter;
- buttonText.Position2D = new Position2D(0, textPaddingTop);
- break;
- case IconOrientation.Left:
- if (LayoutDirection == ViewLayoutDirectionType.LTR)
- {
- buttonIcon.PositionUsesPivotPoint = true;
- buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
- buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
- buttonIcon.Position2D = new Position2D(iconPaddingStart, 0);
-
- buttonText.PositionUsesPivotPoint = true;
- buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
- buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
- buttonText.Position2D = new Position2D(-textPaddingEnd, 0);
- }
- else
- {
- buttonIcon.PositionUsesPivotPoint = true;
- buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
- buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
- buttonIcon.Position2D = new Position2D(-iconPaddingStart, 0);
-
- buttonText.PositionUsesPivotPoint = true;
- buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
- buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
- buttonText.Position2D = new Position2D(textPaddingEnd, 0);
- }
-
- break;
- case IconOrientation.Right:
- if (LayoutDirection == ViewLayoutDirectionType.RTL)
- {
- buttonIcon.PositionUsesPivotPoint = true;
- buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterLeft;
- buttonIcon.PivotPoint = NUI.PivotPoint.CenterLeft;
- buttonIcon.Position2D = new Position2D(iconPaddingEnd, 0);
-
- buttonText.PositionUsesPivotPoint = true;
- buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
- buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
- buttonText.Position2D = new Position2D(-textPaddingStart, 0);
- }
- else
- {
- buttonIcon.PositionUsesPivotPoint = true;
- buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
- buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
- buttonIcon.Position2D = new Position2D(-iconPaddingEnd, 0);
-
- buttonText.PositionUsesPivotPoint = true;
- buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
- buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
- buttonText.Position2D = new Position2D(textPaddingStart, 0);
- }
- break;
- default:
- break;
- }
- if (string.IsNullOrEmpty(buttonText.Text))
- {
- buttonIcon.ParentOrigin = NUI.ParentOrigin.Center;
- buttonIcon.PivotPoint = NUI.PivotPoint.Center;
- }
- }
- /// <summary>
- /// Theme change callback when theme is changed, this callback will be trigger.
- /// </summary>
- /// <param name="sender">The sender</param>
- /// <param name="e">The event data</param>
- /// <since_tizen> 8 </since_tizen>
- protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
- {
- ButtonStyle buttonStyle = StyleManager.Instance.GetViewStyle(style) as ButtonStyle;
- if (buttonStyle != null)
- {
- Style.CopyFrom(buttonStyle);
- UpdateUIContent();
- }
- }
-
- private void UpdateUIContent()
- {
- MeasureText();
- LayoutChild();
-
- Sensitive = isEnabled;
- }
-
- private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
- {
- MeasureText();
- LayoutChild();
- }
-
- private void OnClickInternal(ClickEventArgs eventArgs)
- {
- OnClick(eventArgs);
- Extension?.OnClick(this, eventArgs);
- ClickEvent?.Invoke(this, eventArgs);
- }
-
- private void OnIconRelayout(object sender, EventArgs e)
- {
- MeasureText();
- LayoutChild();
}
/// <summary>
/// ClickEventArgs is a class to record button click event arguments which will sent to user.
/// </summary>
/// <since_tizen> 6 </since_tizen>
+ [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
{
}
+
/// <summary>
/// StateChangeEventArgs is a class to record button state change event arguments which will sent to user.
/// </summary>
/// <since_tizen> 6 </since_tizen>
+ [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
{
/// <summary> previous state of Button </summary>
/// <since_tizen> 6 </since_tizen>
+ /// 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;
/// <summary> current state of Button </summary>
/// <since_tizen> 6 </since_tizen>
+ /// 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;
}
-
- /// <summary>
- /// Get current text part to the attached ButtonExtension.
- /// </summary>
- /// <remarks>
- /// It returns null if the passed extension is invaild.
- /// </remarks>
- /// <param name="extension">The extension instance that is currently attached to this Button.</param>
- /// <return>The button's text part.</return>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public TextLabel GetCurrentText(ButtonExtension extension)
- {
- return (extension == Extension) ? ButtonText : null;
- }
-
- /// <summary>
- /// Get current icon part to the attached ButtonExtension.
- /// </summary>
- /// <remarks>
- /// It returns null if the passed extension is invaild.
- /// </remarks>
- /// <param name="extension">The extension instance that is currently attached to this Button.</param>
- /// <return>The button's icon part.</return>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ImageView GetCurrentIcon(ButtonExtension extension)
- {
- return (extension == Extension) ? ButtonIcon : null;
- }
-
- /// <summary>
- /// Get current overlay image part to the attached ButtonExtension.
- /// </summary>
- /// <remarks>
- /// It returns null if the passed extension is invaild.
- /// </remarks>
- /// <param name="extension">The extension instance that is currently attached to this Button.</param>
- /// <return>The button's overlay image part.</return>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ImageView GetCurrentOverlayImage(ButtonExtension extension)
- {
- return (extension == Extension) ? ButtonOverlayImage : null;
- }
}
}