[NUI][AT-SPI] Rename Accessibility.Enabled to .IsEnabled
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Button.cs
index 1eaaa2b..6a8035f 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2019 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.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
     {
-        private ImageView backgroundImage;
-        private ImageView shadowImage;
-        private ImageView overlayImage;
+        /// 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.LayoutItems();
+            }
+        },
+        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;
+                    instance.Sensitive = 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), false, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (Button)bindable;
+            if (newValue != null)
+            {
+                bool newSelected = (bool)newValue;
+                if (instance.isSelected != newSelected)
+                {
+                    instance.isSelected = newSelected;
+
+                    if (instance.isSelectable)
+                    {
+                        instance.UpdateState();
+                    }
+
+                    if (Accessibility.Accessibility.IsEnabled && instance.IsHighlighted)
+                    {
+                        instance.EmitAccessibilityStatesChangedEvent(AccessibilityStates.Checked, newSelected);
+                    }
+                }
+            }
+        },
+        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;
+                    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;
+            if (instance.buttonIcon == null)
+            {
+                return;
+            }
+            instance.buttonIcon.Padding = (Extents)newValue;
+        },
+        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 (instance.buttonText == null)
+            {
+                return;
+            }
+            instance.buttonText.Padding = (Extents)newValue;
+        },
+        defaultValueCreator: (bindable) => ((Button)bindable).buttonText?.Padding);
 
-        private TextLabel buttonText;
-        private ImageView buttonIcon;
+        /// <summary> The bindable property of ItemAlignment. </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        internal static readonly BindableProperty ItemAlignmentProperty = BindableProperty.Create(nameof(ItemAlignment), typeof(LinearLayout.Alignment), typeof(Button), LinearLayout.Alignment.Center, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (Button)bindable;
+            var newAlignment = (LinearLayout.Alignment)newValue;
+
+            if (instance.itemAlignment != newAlignment)
+            {
+                instance.itemAlignment = newAlignment;
+                instance.LayoutItems();
+            }
+        },
+        defaultValueCreator: (bindable) => ((Button)bindable).itemAlignment);
 
-        private ButtonAttributes buttonAttributes;
-        private EventHandler<StateChangedEventArgs> stateChangeHander;
+        /// <summary> The bindable property of ItemSpacing. </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        internal static readonly BindableProperty ItemSpacingProperty = BindableProperty.Create(nameof(ItemSpacing), typeof(Size2D), typeof(Button), null, propertyChanged: (bindable, oldValue, newValue) =>
+        {
+            var instance = (Button)bindable;
+            instance.itemSpacing = (Size2D)newValue;
+            instance.UpdateSizeAndSpacing();
+        },
+        defaultValueCreator: (bindable) => ((Button)bindable).itemSpacing);
 
+        private IconOrientation? iconRelativeOrientation = IconOrientation.Left;
         private bool isSelected = false;
+        private bool isSelectable = false;
         private bool isEnabled = true;
-        private bool isPressed = false;
+        private Size2D itemSpacing;
+        private LinearLayout.Alignment itemAlignment = LinearLayout.Alignment.Center;
+
+        static Button() { }
+
         /// <summary>
         /// Creates a new instance of a Button.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
         public Button() : base()
         {
-            Initialize();
         }
+
         /// <summary>
         /// Creates a new instance of a Button with style.
         /// </summary>
         /// <param name="style">Create Button by special style defined in UX.</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)]
+        /// <since_tizen> 8 </since_tizen>
         public Button(string style) : base(style)
         {
-            Initialize();
         }
+
         /// <summary>
-        /// Creates a new instance of a Button with attributes.
+        /// Creates a new instance of a Button with style.
+        /// </summary>
+        /// <param name="buttonStyle">Create Button by style customized by user.</param>
+        /// <since_tizen> 8 </since_tizen>
+        public Button(ButtonStyle buttonStyle) : base(buttonStyle)
+        {
+        }
+
+        /// <summary>
+        /// Calculates current states for the button<br />
         /// </summary>
-        /// <param name="attributes">Create Button by attributes customized by user.</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)]
-        public Button(ButtonAttributes attributes) : base(attributes)
+        protected override AccessibilityStates AccessibilityCalculateStates(ulong states)
         {
-            Initialize();
+            var accessibilityStates = base.AccessibilityCalculateStates(states);
+            FlagSetter(ref accessibilityStates, AccessibilityStates.Checked, this.IsSelected);
+            FlagSetter(ref accessibilityStates, AccessibilityStates.Enabled, this.IsEnabled);
+            return accessibilityStates;
         }
+
         /// <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>
@@ -117,248 +282,177 @@ namespace Tizen.NUI.Components
             /// <since_tizen> 6 </since_tizen>
             Right,
         }
+
         /// <summary>
-        /// Flag to decide Button can be selected or not.
+        /// Button's icon part.
         /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public bool IsSelectable
+        /// <since_tizen> 8 </since_tizen>
+        public ImageView Icon
         {
-            get
-            {
-                return buttonAttributes?.IsSelectable ?? false;
-            }
-            set
+            get => buttonIcon;
+            internal set
             {
-                buttonAttributes.IsSelectable = value;
+                buttonIcon = value;
             }
         }
+
         /// <summary>
-        /// Background image's resource url in Button.
+        /// Button's overlay image part.
         /// </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)]
-        public string BackgroundImageURL
+        /// <since_tizen> 8 </since_tizen>
+        public ImageView OverlayImage
         {
             get
             {
-                return buttonAttributes?.BackgroundImageAttributes?.ResourceURL?.All;
-            }
-            set
-            {
-                if (value != null)
+                if (null == overlayImage)
                 {
-                    CreateBackgroundAttributes();
-                    if (buttonAttributes.BackgroundImageAttributes.ResourceURL == null)
+                    overlayImage = CreateOverlayImage();
+                    if (null != Extension)
                     {
-                        buttonAttributes.BackgroundImageAttributes.ResourceURL = new StringSelector();
+                        overlayImage = Extension.OnCreateOverlayImage(this, overlayImage);
+                    }
+                    if (null != overlayImage)
+                    {
+                        overlayImage.ExcludeLayouting = true;
+                        Add(overlayImage);
                     }
-                    buttonAttributes.BackgroundImageAttributes.ResourceURL.All = value;
-                    RelayoutRequest();
                 }
+                return overlayImage;
+            }
+            internal set
+            {
+                overlayImage = value;
             }
         }
+
         /// <summary>
-        /// Background image's border in Button.
+        /// Button's text part.
         /// </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)]
-        public Rectangle BackgroundImageBorder
+        /// <since_tizen> 8 </since_tizen>
+        public TextLabel TextLabel
         {
-            get
+            get => buttonText;
+            internal set
             {
-                return buttonAttributes?.BackgroundImageAttributes?.Border?.All;
-            }
-            set
-            {
-                if (value != null)
-                {
-                    CreateBackgroundAttributes();
-                    if (buttonAttributes.BackgroundImageAttributes.Border == null)
-                    {
-                        buttonAttributes.BackgroundImageAttributes.Border = new RectangleSelector();
-                    }
-                    buttonAttributes.BackgroundImageAttributes.Border.All = value;
-                    RelayoutRequest();
-                }
+                buttonText = value;
+                AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Label, buttonText.Text);
             }
         }
+
         /// <summary>
-        /// Shadow image's resource url in Button.
+        /// The last applied style object copy.
+        /// </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.
         /// </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)]
-        public string ShadowImageURL
+        public string Text
         {
             get
             {
-                return buttonAttributes?.ShadowImageAttributes?.ResourceURL?.All;
+                return GetValue(TextProperty) as string;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateShadowAttributes();
-                    if (buttonAttributes.ShadowImageAttributes.ResourceURL == null)
-                    {
-                        buttonAttributes.ShadowImageAttributes.ResourceURL = new StringSelector();
-                    }
-                    buttonAttributes.ShadowImageAttributes.ResourceURL.All = value;
-                    RelayoutRequest();
-                }
+                SetValue(TextProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Shadow image's border in Button.
-        /// </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)]
-        public Rectangle ShadowImageBorder
+        private string InternalText
         {
             get
             {
-                return buttonAttributes?.ShadowImageAttributes?.Border?.All;
+                return TextLabel.Text;
             }
             set
             {
-                if (value != null)
+                TextLabel.Text = value;
+
+                if (Accessibility.Accessibility.IsEnabled && IsHighlighted && String.IsNullOrEmpty(AccessibilityName) && GetAccessibilityNameSignal().Empty())
                 {
-                    CreateShadowAttributes();
-                    if (buttonAttributes.ShadowImageAttributes.Border == null)
-                    {
-                        buttonAttributes.ShadowImageAttributes.Border = new RectangleSelector();
-                    }
-                    buttonAttributes.ShadowImageAttributes.Border.All = value;
-                    RelayoutRequest();
+                    EmitAccessibilityEvent(AccessibilityPropertyChangeEvent.Name);
                 }
             }
         }
+
         /// <summary>
-        /// Overlay image's resource url in Button.
+        /// Flag to decide Button can be selected or not.
         /// </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)]
-        public string OverlayImageURL
+        public bool IsSelectable
         {
             get
             {
-                return buttonAttributes?.OverlayImageAttributes?.ResourceURL?.All;
+                return (bool)GetValue(IsSelectableProperty);
             }
             set
             {
-                if (value != null)
-                {
-                    CreateOverlayAttributes();
-                    if (buttonAttributes.OverlayImageAttributes.ResourceURL == null)
-                    {
-                        buttonAttributes.OverlayImageAttributes.ResourceURL = new StringSelector();
-                    }
-                    buttonAttributes.OverlayImageAttributes.ResourceURL.All = value;
-                    RelayoutRequest();
-                }
+                SetValue(IsSelectableProperty, value);
             }
         }
+
         /// <summary>
-        /// Overlay image's border in Button.
+        /// Translate text string in Button.
         /// </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)]
-        public Rectangle OverlayImageBorder
+        public string TranslatableText
         {
             get
             {
-                return buttonAttributes?.OverlayImageAttributes?.Border?.All;
+                return GetValue(TranslatableTextProperty) as string;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateOverlayAttributes();
-                    if (buttonAttributes.OverlayImageAttributes.Border == null)
-                    {
-                        buttonAttributes.OverlayImageAttributes.Border = new RectangleSelector();
-                    }
-                    buttonAttributes.OverlayImageAttributes.Border.All = value;
-                    RelayoutRequest();
-                }
+                SetValue(TranslatableTextProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Text string in Button.
-        /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public string Text
+        private string InternalTranslatableText
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.Text?.All;
+                return TextLabel.TranslatableText;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateTextAttributes();
-                    if(buttonAttributes.TextAttributes.Text == null)
-                    {
-                        buttonAttributes.TextAttributes.Text = new StringSelector();
-                    }
-                    buttonAttributes.TextAttributes.Text.All = value;
-
-                    RelayoutRequest();
-                }
+                TextLabel.TranslatableText = value;
             }
         }
+
         /// <summary>
-        /// Translate text string in Button.
+        /// Text point size in Button.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public string TranslatableText
+        public float PointSize
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.TranslatableText?.All;
+                return (float)GetValue(PointSizeProperty);
             }
             set
             {
-                if (value != null)
-                {
-                    CreateTextAttributes();
-                    if (buttonAttributes.TextAttributes.TranslatableText == null)
-                    {
-                        buttonAttributes.TextAttributes.TranslatableText = new StringSelector();
-                    }
-                    buttonAttributes.TextAttributes.TranslatableText.All = value;
-
-                    RelayoutRequest();
-                }
+                SetValue(PointSizeProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Text point size in Button.
-        /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public float PointSize
+        private float InternalPointSize
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.PointSize?.All ?? 0;
+                return TextLabel.PointSize;
             }
             set
             {
-                CreateTextAttributes();
-                if (buttonAttributes.TextAttributes.PointSize == null)
-                {
-                    buttonAttributes.TextAttributes.PointSize = new FloatSelector();
-                }
-                buttonAttributes.TextAttributes.PointSize.All = value;
-                RelayoutRequest();
+                TextLabel.PointSize = value;
             }
         }
+
         /// <summary>
         /// Text font family in Button.
         /// </summary>
@@ -367,309 +461,302 @@ namespace Tizen.NUI.Components
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.FontFamily;
+                return GetValue(FontFamilyProperty) as string;
             }
             set
             {
-                CreateTextAttributes();
-                buttonAttributes.TextAttributes.FontFamily = value;
-                RelayoutRequest();
+                SetValue(FontFamilyProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Text color in Button.
-        /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public Color TextColor
+        private string InternalFontFamily
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.TextColor?.All;
+                return TextLabel.FontFamily;
             }
             set
             {
-                CreateTextAttributes();
-                if (buttonAttributes.TextAttributes.TextColor == null)
-                {
-                    buttonAttributes.TextAttributes.TextColor = new ColorSelector();
-                }
-                buttonAttributes.TextAttributes.TextColor.All = value;
-                RelayoutRequest();
+                TextLabel.FontFamily = value;
             }
         }
+
         /// <summary>
-        /// Text horizontal alignment in Button.
+        /// Text color in Button.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public HorizontalAlignment TextAlignment
+        public Color TextColor
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.HorizontalAlignment ?? HorizontalAlignment.Center;
+                return GetValue(TextColorProperty) as Color;
             }
             set
             {
-                CreateTextAttributes();
-                buttonAttributes.TextAttributes.HorizontalAlignment = value;
-                RelayoutRequest();
+                SetValue(TextColorProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Icon image's resource url in Button.
-        /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public string IconURL
+        private Color InternalTextColor
         {
             get
             {
-                return buttonAttributes?.IconAttributes?.ResourceURL?.All;
+                return TextLabel.TextColor;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateIconAttributes();
-                    if (buttonAttributes.IconAttributes.ResourceURL == null)
-                    {
-                        buttonAttributes.IconAttributes.ResourceURL = new StringSelector();
-                    }
-                    buttonAttributes.IconAttributes.ResourceURL.All = value;
-                    RelayoutRequest();
-                }
+                TextLabel.TextColor = value;
             }
         }
+
         /// <summary>
-        /// Text string selector in Button.
+        /// Text horizontal alignment in Button.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public StringSelector TextSelector
+        public HorizontalAlignment TextAlignment
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.Text;
+                return (HorizontalAlignment)GetValue(TextAlignmentProperty);
             }
             set
             {
-                if (value != null)
-                {
-                    CreateTextAttributes();
-                    buttonAttributes.TextAttributes.Text = value.Clone() as StringSelector;
-                    RelayoutRequest();
-                }
+                SetValue(TextAlignmentProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Translateable text string selector in Button.
-        /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public StringSelector TranslatableTextSelector
+        private HorizontalAlignment InternalTextAlignment
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.TranslatableText;
+                return TextLabel.HorizontalAlignment;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateTextAttributes();
-                    buttonAttributes.TextAttributes.TranslatableText = value.Clone() as StringSelector;
-                    RelayoutRequest();
-                }
+                TextLabel.HorizontalAlignment = value;
             }
         }
+
         /// <summary>
-        /// Text color selector in Button.
+        /// Icon image's resource url in Button.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public ColorSelector TextColorSelector
+        public string IconURL
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.TextColor;
+                return GetValue(IconURLProperty) as string;
             }
             set
             {
-                if(value != null)
-                {
-                    CreateTextAttributes();
-                    buttonAttributes.TextAttributes.TextColor = value.Clone() as ColorSelector;
-                    RelayoutRequest();
-                }
+                SetValue(IconURLProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Text font size selector in Button.
-        /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public FloatSelector PointSizeSelector
+        private string InternalIconURL
         {
             get
             {
-                return buttonAttributes?.TextAttributes?.PointSize;
+                return Icon.ResourceUrl;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateTextAttributes();
-                    buttonAttributes.TextAttributes.PointSize = value.Clone() as FloatSelector;
-                    RelayoutRequest();
-                }
+                Icon.ResourceUrl = value;
             }
         }
+
         /// <summary>
-        /// Icon image's resource url selector in Button.
+        /// Icon image's size in Button.
         /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        public StringSelector IconURLSelector
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Size IconSize
         {
             get
             {
-                return buttonAttributes?.IconAttributes?.ResourceURL;
+                return GetValue(IconSizeProperty) as Size;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateIconAttributes();
-                    buttonAttributes.IconAttributes.ResourceURL = value.Clone() as StringSelector;
-                    RelayoutRequest();
-                }
+                SetValue(IconSizeProperty, value);
+                NotifyPropertyChanged();
             }
         }
+        private Size InternalIconSize
+        {
+            get => Icon.Size;
+            set => Icon.Size = value;
+        }
+
         /// <summary>
-        /// Background image's resource url selector in Button.
+        /// 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>
-        /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public StringSelector BackgroundImageURLSelector
+        public StringSelector TextSelector
         {
             get
             {
-                return buttonAttributes?.BackgroundImageAttributes?.ResourceURL;
+                return GetValue(TextSelectorProperty) as StringSelector;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateBackgroundAttributes();
-                    buttonAttributes.BackgroundImageAttributes.ResourceURL = value.Clone() as StringSelector;
-                    RelayoutRequest();
-                }
+                SetValue(TextSelectorProperty, value);
+                NotifyPropertyChanged();
             }
         }
-        /// <summary>
-        /// Background image's border selector in Button.
-        /// </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)]
-        public RectangleSelector BackgroundImageBorderSelector
+        private StringSelector InternalTextSelector
         {
-            get
-            {
-                return buttonAttributes?.BackgroundImageAttributes?.Border;
-            }
+            get => buttonText?.TextSelector == null ? null : new StringSelector(buttonText.TextSelector);
             set
             {
-                if (value != null)
+                if (value == null || buttonText == null)
+                {
+                    throw new NullReferenceException("Button.TextSelector is null");
+                }
+                else
                 {
-                    CreateBackgroundAttributes();
-                    buttonAttributes.BackgroundImageAttributes.Border = value.Clone() as RectangleSelector;
-                    RelayoutRequest();
+                    buttonText.TextSelector = value;
                 }
             }
         }
+
         /// <summary>
-        /// Shadow image's resource url 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>
-        /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public StringSelector ShadowImageURLSelector
+        public StringSelector TranslatableTextSelector
         {
             get
             {
-                return buttonAttributes?.ShadowImageAttributes?.ResourceURL;
+                return GetValue(TranslatableTextSelectorProperty) as StringSelector;
+            }
+            set
+            {
+                SetValue(TranslatableTextSelectorProperty, value);
+                NotifyPropertyChanged();
             }
+        }
+        private StringSelector InternalTranslatableTextSelector
+        {
+            get => (buttonText?.TranslatableTextSelector == null) ? null : new StringSelector(buttonText.TranslatableTextSelector);
             set
             {
-                if (value != null)
+                if (value == null || buttonText == null)
                 {
-                    CreateShadowAttributes();
-                    buttonAttributes.ShadowImageAttributes.ResourceURL = value.Clone() as StringSelector;
-                    RelayoutRequest();
+                    throw new NullReferenceException("Button.TranslatableTextSelector is null");
+                }
+                else
+                {
+                    buttonText.TranslatableTextSelector = value;
                 }
             }
         }
+
         /// <summary>
-        /// Shadow image's border selector in Button.
+        /// 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>
-        /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public RectangleSelector ShadowImageBorderSelector
+        public ColorSelector TextColorSelector
         {
             get
             {
-                return buttonAttributes?.ShadowImageAttributes?.Border;
+                return GetValue(TextColorSelectorProperty) as ColorSelector;
             }
             set
             {
-                if (value != null)
-                {
-                    CreateShadowAttributes();
-                    buttonAttributes.ShadowImageAttributes.Border = value.Clone() as RectangleSelector;
-                    RelayoutRequest();
+                SetValue(TextColorSelectorProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private ColorSelector InternalTextColorSelector
+        {
+            get => buttonText?.TextColorSelector == null ? null : new ColorSelector(buttonText.TextColorSelector);
+            set
+            {
+                if (value == null || buttonText == null)
+                {
+                    throw new NullReferenceException("Button.TextColorSelectorProperty is null");
+                }
+                else
+                {
+                    buttonText.TextColorSelector = value;
                 }
             }
         }
+
         /// <summary>
-        /// Overlay image's resource url selector in Button.
+        /// 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>
-        /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public StringSelector OverlayImageURLSelector
+        public FloatSelector PointSizeSelector
         {
             get
             {
-                return buttonAttributes?.OverlayImageAttributes?.ResourceURL;
+                return GetValue(PointSizeSelectorProperty) as FloatSelector;
             }
             set
             {
-                if (value != null)
+                SetValue(PointSizeSelectorProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private FloatSelector InternalPointSizeSelector
+        {
+            get => buttonText?.PointSizeSelector == null ? null : new FloatSelector(buttonText.PointSizeSelector);
+            set
+            {
+                if (value == null || buttonText == null)
+                {
+                    throw new NullReferenceException("Button.PointSizeSelector is null");
+                }
+                else
                 {
-                    CreateOverlayAttributes();
-                    buttonAttributes.OverlayImageAttributes.ResourceURL = value.Clone() as StringSelector;
-                    RelayoutRequest();
+                    buttonText.PointSizeSelector = value;
                 }
             }
         }
+
         /// <summary>
-        /// Overlay image's border selector in Button.
+        /// 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>
-        /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public RectangleSelector OverlayImageBorderSelector
+        public StringSelector IconURLSelector
         {
             get
             {
-                return buttonAttributes?.OverlayImageAttributes?.Border;
+                return GetValue(IconURLSelectorProperty) as StringSelector;
             }
             set
             {
-                if (value != null)
+                SetValue(IconURLSelectorProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private StringSelector InternalIconURLSelector
+        {
+            get => buttonIcon?.ResourceUrlSelector == null ? null : new StringSelector(buttonIcon.ResourceUrlSelector);
+            set
+            {
+                if (value == null || buttonIcon == null)
+                {
+                    throw new NullReferenceException("Button.IconURLSelector is null");
+                }
+                else
                 {
-                    CreateOverlayAttributes();
-                    buttonAttributes.OverlayImageAttributes.Border = value.Clone() as RectangleSelector;
-                    RelayoutRequest();
+                    buttonIcon.ResourceUrlSelector = value;
                 }
             }
         }
+
         /// <summary>
         /// Flag to decide selected state in Button.
         /// </summary>
@@ -678,14 +765,14 @@ namespace Tizen.NUI.Components
         {
             get
             {
-                return isSelected;
+                return (bool)GetValue(IsSelectedProperty);
             }
             set
             {
-                isSelected = value;
-                UpdateState();
+                SetValue(IsSelectedProperty, value);
             }
         }
+
         /// <summary>
         /// Flag to decide enable or disable in Button.
         /// </summary>
@@ -694,138 +781,72 @@ namespace Tizen.NUI.Components
         {
             get
             {
-                return isEnabled;
+                return (bool)GetValue(IsEnabledProperty);
             }
             set
             {
-                isEnabled = value;
-                UpdateState();
+                SetValue(IsEnabledProperty, value);
             }
         }
 
         /// <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 buttonAttributes?.IconRelativeOrientation;
+                return (IconOrientation?)GetValue(IconRelativeOrientationProperty) ?? IconOrientation.Left;
             }
             set
             {
-                if(buttonAttributes != null && buttonAttributes.IconRelativeOrientation != value)
-                {
-                    buttonAttributes.IconRelativeOrientation = value;
-                    RelayoutRequest();
-                }
+                SetValue(IconRelativeOrientationProperty, value);
             }
         }
 
-        // <summary>
-        /// Icon padding in Button, work only when show icon and text.
+        /// <summary>
+        /// Icon padding in Button. It is shortcut of Icon.Padding.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
         public Extents IconPadding
         {
-            get
-            {
-                if (null == buttonAttributes || null == buttonAttributes.IconAttributes)
-                {
-                    return null;
-                }
-                else
-                {
-                    return new Extents((ushort)buttonAttributes.IconAttributes.PaddingLeft, (ushort)buttonAttributes.IconAttributes.PaddingRight, (ushort)buttonAttributes.IconAttributes.PaddingTop, (ushort)buttonAttributes.IconAttributes.PaddingBottom);
-                }
-            }
-            set
-            {
-                if (null != value)
-                {
-                    CreateIconAttributes();
-                    buttonAttributes.IconAttributes.PaddingLeft = value.Start;
-                    buttonAttributes.IconAttributes.PaddingRight = value.End;
-                    buttonAttributes.IconAttributes.PaddingTop = value.Top;
-                    buttonAttributes.IconAttributes.PaddingBottom = value.Bottom;
-                    RelayoutRequest();
-                }
-            }
+            get => (Extents)GetValue(IconPaddingProperty) ?? new Extents();
+            set => SetValue(IconPaddingProperty, value);
         }
 
-        // <summary>
-        /// Text padding in Button, work only when show icon and text.
+        /// <summary>
+        /// Text padding in Button. It is shortcut of TextLabel.Padding.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
         public Extents TextPadding
         {
-            get
-            {
-                if (null == buttonAttributes || null == buttonAttributes.TextAttributes)
-                {
-                    return null;
-                }
-                else
-                {
-                    return new Extents((ushort)buttonAttributes.TextAttributes.PaddingLeft, (ushort)buttonAttributes.TextAttributes.PaddingRight, (ushort)buttonAttributes.TextAttributes.PaddingTop, (ushort)buttonAttributes.TextAttributes.PaddingBottom);
-                }
-            }
-            set
-            {
-                if (null != value)
-                {
-                    CreateTextAttributes();
-                    buttonAttributes.TextAttributes.PaddingLeft = value.Start;
-                    buttonAttributes.TextAttributes.PaddingRight = value.End;
-                    buttonAttributes.TextAttributes.PaddingTop = value.Top;
-                    buttonAttributes.TextAttributes.PaddingBottom = value.Bottom;
-                    RelayoutRequest();
-                }
-            }
+            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)
+        /// <since_tizen> 9 </since_tizen>
+        public LinearLayout.Alignment ItemAlignment
         {
-            if (disposed)
-            {
-                return;
-            }
-
-            if (type == DisposeTypes.Explicit)
-            {
-                if (buttonIcon != null)
-                {
-                    buttonIcon.Relayout -= OnIconRelayout;
-                    Utility.Dispose(buttonIcon);
-                }
-                if (buttonText != null)
-                {
-                    Utility.Dispose(buttonText);
-                }
-                if (overlayImage != null)
-                {
-                    Utility.Dispose(overlayImage);
-                }
-                if (backgroundImage != null)
-                {
-                    Utility.Dispose(backgroundImage);
-                }
-                if (shadowImage != null)
-                {
-                    Utility.Dispose(shadowImage);
-                }
-            }
+            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>
+        /// <since_tizen> 9 </since_tizen>
+        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>
@@ -834,29 +855,41 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 6 </since_tizen>
         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();
-                    if(isEnabled)
-                    {
-                        ClickEventArgs eventArgs = new ClickEventArgs();
-                        OnClick(eventArgs);
-                    }
                 }
             }
             else if (key.State == Key.StateType.Up)
             {
                 if (key.KeyPressedName == "Return")
                 {
+                    bool clicked = isPressed && IsEnabled;
+
                     isPressed = false;
-                    if (buttonAttributes.IsSelectable != null && buttonAttributes.IsSelectable == true)
+
+                    if (IsSelectable)
                     {
-                        isSelected = !isSelected;
+                        IsSelected = !IsSelected;
+                    }
+                    else
+                    {
+                        UpdateState();
+                    }
+
+                    if (clicked)
+                    {
+                        ClickedEventArgs eventArgs = new ClickedEventArgs();
+                        OnClickedInternal(eventArgs);
                     }
-                    UpdateState();
                 }
             }
             return base.OnKey(key);
@@ -865,20 +898,17 @@ namespace Tizen.NUI.Components
         /// <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();
             UpdateState();
         }
+
         /// <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();
@@ -886,462 +916,99 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
-        /// Tap gesture event callback.
-        /// </summary>
-        /// <param name="source">Source which recieved touch event.</param>
-        /// <param name="e">Tap gesture event argument.</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 override void OnTapGestureDetected(object source, TapGestureDetector.DetectedEventArgs e)
-        {
-            if (isEnabled)
-            {
-                ClickEventArgs eventArgs = new ClickEventArgs();
-                OnClick(eventArgs);
-                base.OnTapGestureDetected(source, e);
-            }
-        }
-        /// <summary>
         /// Called after a touch event is received by the owning view.<br />
         /// CustomViewBehaviour.REQUIRES_TOUCH_EVENTS must be enabled during construction. See CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour).<br />
         /// </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
         {
-            PointStateType state = touch.GetState(0);
-      
-            switch(state)
-            {
-                case PointStateType.Down:
-                    isPressed = true;
-                    UpdateState();
-                    return true;
-                case PointStateType.Interrupted:
-                    isPressed = false;
-                    UpdateState();
-                    return true;
-                case PointStateType.Up:
-                    isPressed = false;
-                    if (buttonAttributes.IsSelectable != null && buttonAttributes.IsSelectable == true)
-                    {
-                        isSelected = !isSelected;
-                    }
-                    UpdateState();
-                    return true;
-                default:
-                    break;
-            }
             return base.OnTouch(touch);
         }
+
         /// <summary>
-        /// Get Button attribues.
-        /// </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 override Attributes GetAttributes()
-        {
-            return new ButtonAttributes();
-        }
-        /// <summary>
-        /// Update Button by attributes.
+        /// Apply style to button.
         /// </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 override void OnUpdate()
+        /// <param name="viewStyle">The style to apply.</param>
+        /// <since_tizen> 8 </since_tizen>
+        public override void ApplyStyle(ViewStyle viewStyle)
         {
-            if (buttonAttributes.ShadowImageAttributes != null)
-            {
-                if(shadowImage == null)
-                {
-                    shadowImage = new ImageView()
-                    {
-                        WidthResizePolicy = ResizePolicyType.FillToParent,
-                        HeightResizePolicy = ResizePolicyType.FillToParent
-                    };
-                    this.Add(shadowImage);
-                }
-                ApplyAttributes(shadowImage, buttonAttributes.ShadowImageAttributes);
-            }
+            Debug.Assert(buttonIcon != null && buttonText != null);
 
-            if (buttonAttributes.BackgroundImageAttributes != null)
-            {
-                if(backgroundImage == null)
-                {
-                    backgroundImage = new ImageView()
-                    {
-                        WidthResizePolicy = ResizePolicyType.FillToParent,
-                        HeightResizePolicy = ResizePolicyType.FillToParent
-                    };
-                    this.Add(backgroundImage);
-                }
-                ApplyAttributes(backgroundImage, buttonAttributes.BackgroundImageAttributes);
-            }
+            styleApplied = false;
 
-            if (buttonAttributes.OverlayImageAttributes != null)
-            {
-                if(overlayImage == null)
-                {
-                    overlayImage = new ImageView()
-                    {
-                        WidthResizePolicy = ResizePolicyType.FillToParent,
-                        HeightResizePolicy = ResizePolicyType.FillToParent
-                    };
-                    this.Add(overlayImage);
-                }
-                ApplyAttributes(overlayImage, buttonAttributes.OverlayImageAttributes);
-            }
+            base.ApplyStyle(viewStyle);
 
-            if (buttonAttributes.TextAttributes != null)
+            if (viewStyle is ButtonStyle buttonStyle)
             {
-                if(buttonText == null)
-                {
-                    buttonText = new TextLabel();
-                    this.Add(buttonText);
-                }
-                ApplyAttributes(buttonText, buttonAttributes.TextAttributes);
-            }
+                Extension = buttonStyle.CreateExtension();
 
-            if (buttonAttributes.IconAttributes != null)
-            {
-                if(buttonIcon == null)
+                if (buttonStyle.Overlay != null)
                 {
-                    buttonIcon = new ImageView();
-                    buttonIcon.Relayout += OnIconRelayout;
-                    this.Add(buttonIcon);
+                    OverlayImage?.ApplyStyle(buttonStyle.Overlay);
                 }
-                ApplyAttributes(buttonIcon, buttonAttributes.IconAttributes);
-            }
-
-            MeasureText();
-            LayoutChild();
-
-            Sensitive = isEnabled ? true : false;
-        }
-
-        /// <summary>
-        /// Update Button State.
-        /// </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 void UpdateState()
-        {
-            ControlStates sourceState = State;
-            ControlStates targetState;
 
-            if(isEnabled)
-            {
-                targetState = isPressed ? ControlStates.Pressed : (IsFocused ? (IsSelected ? ControlStates.SelectedFocused : ControlStates.Focused) : (IsSelected ? ControlStates.Selected : ControlStates.Normal));
-            }
-            else
-            {
-                targetState = IsSelected ? ControlStates.DisabledSelected : (IsFocused ? ControlStates.DisabledFocused : ControlStates.Disabled);
-            }
-            if(sourceState != targetState)
-            {
-                State = targetState;
-
-                OnUpdate();
-
-                StateChangedEventArgs e = new StateChangedEventArgs
+                if (Extension != null)
                 {
-                    PreviousState = sourceState,
-                    CurrentState = targetState
-                };
-                stateChangeHander?.Invoke(this, e);
-            }
-        }
-        /// <summary>
-        /// It is hijack by using protected, attributes copy problem when class inherited from Button.
-        /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        private void Initialize()
-        {
-            buttonAttributes = attributes as ButtonAttributes;
-            if (buttonAttributes == null)
-            {
-                throw new Exception("Button attribute parse error.");
-            }
-
-            ApplyAttributes(this, buttonAttributes);
-            LayoutDirectionChanged += OnLayoutDirectionChanged;
-        }
-
-        /// <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 (buttonAttributes.IconRelativeOrientation == null || buttonIcon == null || buttonText == null)
-            {
-                return;
-            }
-            buttonText.WidthResizePolicy = ResizePolicyType.Fixed;
-            buttonText.HeightResizePolicy = ResizePolicyType.Fixed;
-            int textPaddingLeft = buttonAttributes.TextAttributes.PaddingLeft;
-            int textPaddingRight = buttonAttributes.TextAttributes.PaddingRight;
-            int textPaddingTop = buttonAttributes.TextAttributes.PaddingTop;
-            int textPaddingBottom = buttonAttributes.TextAttributes.PaddingBottom;
-
-            int iconPaddingLeft = buttonAttributes.IconAttributes.PaddingLeft;
-            int iconPaddingRight = buttonAttributes.IconAttributes.PaddingRight;
-            int iconPaddingTop = buttonAttributes.IconAttributes.PaddingTop;
-            int iconPaddingBottom = buttonAttributes.IconAttributes.PaddingBottom;
-
-            if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom)
-            {
-                buttonText.SizeWidth = SizeWidth - textPaddingLeft - textPaddingRight;
-                buttonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - buttonIcon.SizeHeight;
-            }
-            else
-            {
-                buttonText.SizeWidth = SizeWidth - textPaddingLeft - textPaddingRight - iconPaddingLeft - iconPaddingRight - 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 (buttonAttributes.IconRelativeOrientation == null || buttonIcon == null || buttonText == null)
-            {
-                return;
-            }
-
-            int textPaddingLeft = buttonAttributes.TextAttributes.PaddingLeft;
-            int textPaddingRight = buttonAttributes.TextAttributes.PaddingRight;
-            int textPaddingTop = buttonAttributes.TextAttributes.PaddingTop;
-            int textPaddingBottom = buttonAttributes.TextAttributes.PaddingBottom;
-
-            int iconPaddingLeft = buttonAttributes.IconAttributes.PaddingLeft;
-            int iconPaddingRight = buttonAttributes.IconAttributes.PaddingRight;
-            int iconPaddingTop = buttonAttributes.IconAttributes.PaddingTop;
-            int iconPaddingBottom = buttonAttributes.IconAttributes.PaddingBottom;
-
-            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(iconPaddingLeft, 0);
-
-                        buttonText.PositionUsesPivotPoint = true;
-                        buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
-                        buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
-                        buttonText.Position2D = new Position2D(-textPaddingRight, 0);
-                    }
-                    else
-                    {
-                        buttonIcon.PositionUsesPivotPoint = true;
-                        buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
-                        buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
-                        buttonIcon.Position2D = new Position2D(-iconPaddingLeft, 0);
-
-                        buttonText.PositionUsesPivotPoint = true;
-                        buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
-                        buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
-                        buttonText.Position2D = new Position2D(textPaddingRight, 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(iconPaddingRight, 0);
-
-                        buttonText.PositionUsesPivotPoint = true;
-                        buttonText.ParentOrigin = NUI.ParentOrigin.CenterRight;
-                        buttonText.PivotPoint = NUI.PivotPoint.CenterRight;
-                        buttonText.Position2D = new Position2D(-textPaddingLeft, 0);
-                    }
-                    else
-                    {
-                        buttonIcon.PositionUsesPivotPoint = true;
-                        buttonIcon.ParentOrigin = NUI.ParentOrigin.CenterRight;
-                        buttonIcon.PivotPoint = NUI.PivotPoint.CenterRight;
-                        buttonIcon.Position2D = new Position2D(-iconPaddingRight, 0);
-
-                        buttonText.PositionUsesPivotPoint = true;
-                        buttonText.ParentOrigin = NUI.ParentOrigin.CenterLeft;
-                        buttonText.PivotPoint = NUI.PivotPoint.CenterLeft;
-                        buttonText.Position2D = new Position2D(textPaddingLeft, 0);
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-        /// <summary>
-        /// Theme change callback when theme is changed, this callback will be trigger.
-        /// </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 override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
-        {
-            ButtonAttributes tempAttributes = StyleManager.Instance.GetAttributes(style) as ButtonAttributes;
-            if(tempAttributes != null)
-            {
-                attributes = buttonAttributes = tempAttributes;
-                RelayoutRequest();
-            }
-        }
-
-        private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
-        {
-            MeasureText();
-            LayoutChild();
-        }
+                    buttonIcon.Unparent();
+                    buttonIcon = Extension.OnCreateIcon(this, buttonIcon);
 
-        private void OnClick(ClickEventArgs eventArgs)
-        {
-            ClickEvent?.Invoke(this, eventArgs);
-        }
+                    buttonText.Unparent();
+                    buttonText = Extension.OnCreateText(this, buttonText);
 
-        private void OnIconRelayout(object sender, EventArgs e)
-        {
-            MeasureText();
-            LayoutChild();
-        }
+                    LayoutItems();
+                }
 
-        private void CreateBackgroundAttributes()
-        {
-            if (buttonAttributes.BackgroundImageAttributes == null)
-            {
-                buttonAttributes.BackgroundImageAttributes = new ImageAttributes()
+                if (buttonStyle.Text != null)
                 {
-                    PositionUsesPivotPoint = true,
-                    ParentOrigin = Tizen.NUI.ParentOrigin.Center,
-                    PivotPoint = Tizen.NUI.PivotPoint.Center,
-                    WidthResizePolicy = ResizePolicyType.FillToParent,
-                    HeightResizePolicy = ResizePolicyType.FillToParent
-                };
-            }
-        }
+                    buttonText.ThemeChangeSensitive = false;
+                    buttonText.ApplyStyle(buttonStyle.Text);
+                }
 
-        private void CreateShadowAttributes()
-        {
-            if (buttonAttributes.ShadowImageAttributes == null)
-            {
-                buttonAttributes.ShadowImageAttributes = new ImageAttributes()
+                if (buttonStyle.Icon != null)
                 {
-                    PositionUsesPivotPoint = true,
-                    ParentOrigin = Tizen.NUI.ParentOrigin.Center,
-                    PivotPoint = Tizen.NUI.PivotPoint.Center,
-                    WidthResizePolicy = ResizePolicyType.FillToParent,
-                    HeightResizePolicy = ResizePolicyType.FillToParent
-                };
-            }
-        }
-
-        private void CreateOverlayAttributes()
-        {
-            if (buttonAttributes.OverlayImageAttributes == null)
-            {
-                buttonAttributes.OverlayImageAttributes = new ImageAttributes()
-                {
-                    PositionUsesPivotPoint = true,
-                    ParentOrigin = Tizen.NUI.ParentOrigin.Center,
-                    PivotPoint = Tizen.NUI.PivotPoint.Center,
-                    WidthResizePolicy = ResizePolicyType.FillToParent,
-                    HeightResizePolicy = ResizePolicyType.FillToParent
-                };
+                    buttonIcon.ApplyStyle(buttonStyle.Icon);
+                }
             }
-        }
 
-        private void CreateTextAttributes()
-        {
-            if (buttonAttributes.TextAttributes == null)
-            {
-                buttonAttributes.TextAttributes = new TextAttributes()
-                {
-                    PositionUsesPivotPoint = true,
-                    ParentOrigin = Tizen.NUI.ParentOrigin.Center,
-                    PivotPoint = Tizen.NUI.PivotPoint.Center,
-                    WidthResizePolicy = ResizePolicyType.FillToParent,
-                    HeightResizePolicy = ResizePolicyType.FillToParent,
-                    HorizontalAlignment = HorizontalAlignment.Center,
-                    VerticalAlignment = VerticalAlignment.Center
-                };
-            }
+            styleApplied = true;
+            UpdateState();
         }
 
-        private void CreateIconAttributes()
-        {
-            if (buttonAttributes.IconAttributes == null)
-            {
-                buttonAttributes.IconAttributes = new ImageAttributes()
-                {
-                    PositionUsesPivotPoint = true,
-                    ParentOrigin = Tizen.NUI.ParentOrigin.Center,
-                    PivotPoint = Tizen.NUI.PivotPoint.Center,
-                    WidthResizePolicy = ResizePolicyType.UseNaturalSize,
-                    HeightResizePolicy = ResizePolicyType.UseNaturalSize,
-                };
-            }
-        }
         /// <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;
         }
-
     }
 }