[NUI] Check whether Accessibility is enabled intentionally
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Button.Internal.cs
index 2d108bd..e7aeb0e 100755 (executable)
@@ -2,6 +2,7 @@
 using System.ComponentModel;
 using Tizen.NUI.BaseComponents;
 using Tizen.NUI.Components.Extension;
+using Tizen.NUI.Accessibility; // To use AccessibilityManager
 
 namespace Tizen.NUI.Components
 {
@@ -11,24 +12,10 @@ namespace Tizen.NUI.Components
         private TextLabel buttonText;
         private ImageView buttonIcon;
 
-        private EventHandler<StateChangedEventArgs> stateChangeHander;
+        private EventHandler<StateChangedEventArgs> stateChangeHandler;
 
-        private bool isSelected = false;
-        private bool isEnabled = true;
         private bool isPressed = false;
-
-        private StringSelector textSelector = new StringSelector();
-        private StringSelector translatableTextSelector = new StringSelector();
-        private ColorSelector textColorSelector = new ColorSelector();
-        private FloatSelector pointSizeSelector = new FloatSelector();
-
-        private StringSelector iconURLSelector = new StringSelector();
-
-        /// <summary>
-        /// The last touch information triggering selected state change.
-        /// </summary>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        protected Touch SelectionChangedByTouch { get; set; }
+        private bool styleApplied = false;
 
         /// <summary>
         /// The ButtonExtension instance that is injected by ButtonStyle.
@@ -43,7 +30,16 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected virtual TextLabel CreateText()
         {
-            return new TextLabel();
+            return new TextLabel
+            {
+                PositionUsesPivotPoint = true,
+                ParentOrigin = NUI.ParentOrigin.Center,
+                PivotPoint = NUI.PivotPoint.Center,
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FillToParent,
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center
+            };
         }
 
         /// <summary>
@@ -53,7 +49,12 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected virtual ImageView CreateIcon()
         {
-            return new ImageView();
+            return new ImageView
+            {
+                PositionUsesPivotPoint = true,
+                ParentOrigin = NUI.ParentOrigin.Center,
+                PivotPoint = NUI.PivotPoint.Center
+            };
         }
 
         /// <summary>
@@ -63,7 +64,14 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected virtual ImageView CreateOverlayImage()
         {
-            return new ImageView();
+            return new ImageView
+            {
+                PositionUsesPivotPoint = true,
+                ParentOrigin = NUI.ParentOrigin.Center,
+                PivotPoint = NUI.PivotPoint.Center,
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FillToParent
+            };
         }
 
         /// <summary>
@@ -71,7 +79,7 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <param name="eventArgs">The click information.</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        protected virtual void OnClick(ClickEventArgs eventArgs)
+        protected virtual void OnClicked(ClickedEventArgs eventArgs)
         {
         }
 
@@ -95,58 +103,95 @@ namespace Tizen.NUI.Components
             Extension?.OnRelayout(this);
         }
 
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override bool HandleControlStateOnTouch(Touch touch)
+        {
+            if (!IsEnabled || null == touch)
+            {
+                return false;
+            }
+
+            PointStateType state = touch.GetState(0);
+
+            switch (state)
+            {
+                case PointStateType.Down:
+                    isPressed = true;
+                    Extension?.SetTouchInfo(touch);
+                    UpdateState();
+                    return true;
+                case PointStateType.Interrupted:
+                    isPressed = false;
+                    UpdateState();
+                    return true;
+                case PointStateType.Up:
+                    {
+                        bool clicked = isPressed && IsEnabled;
+
+                        isPressed = false;
+
+                        if (IsSelectable)
+                        {
+                            Extension?.SetTouchInfo(touch);
+                            IsSelected = !IsSelected;
+                        }
+                        else
+                        {
+                            Extension?.SetTouchInfo(touch);
+                            UpdateState();
+                        }
+
+                        if (clicked)
+                        {
+                            ClickedEventArgs eventArgs = new ClickedEventArgs();
+                            OnClickedInternal(eventArgs);
+                        }
+
+                        return true;
+                    }
+                default:
+                    break;
+            }
+            return base.HandleControlStateOnTouch(touch);
+        }
+
         /// <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()
         {
-            ControlStates sourceState = ControlState;
-            ControlStates targetState;
+            if (!styleApplied) return;
 
-            if (isEnabled)
-            {
-                if (isPressed)
-                {
-                    // Pressed
-                    targetState = ControlStates.Pressed;
-                }
-                else
-                {
-                    // Normal
-                    targetState = ControlStates.Normal;
+            ControlState sourceState = ControlState;
+            ControlState targetState;
 
-                    // Selected
-                    targetState |= (IsSelected ? ControlStates.Selected : 0);
+            // Normal, Disabled
+            targetState = IsEnabled ? ControlState.Normal : ControlState.Disabled;
 
-                    // Focused, SelectedFocused
-                    targetState |= (IsFocused ? ControlStates.Focused : 0);
-                }
-            }
-            else
-            {
-                // Disabled
-                targetState = ControlStates.Disabled;
+            // Selected, DisabledSelected
+            if (IsSelected) targetState += ControlState.Selected;
 
-                // DisabledSelected, DisabledFocused
-                targetState |= (IsSelected ? ControlStates.Selected : (IsFocused ? ControlStates.Focused : 0));
-            }
+            // Pressed, PressedSelected
+            if (isPressed) targetState += ControlState.Pressed;
+
+            // Focused, FocusedPressed, FocusedPressedSelected, DisabledFocused, DisabledSelectedFocused
+            if (IsFocused) targetState += ControlState.Focused;
 
             if (sourceState != targetState)
             {
                 ControlState = targetState;
-
                 OnUpdate();
 
                 StateChangedEventArgs e = new StateChangedEventArgs
                 {
-                    PreviousState = sourceState,
-                    CurrentState = targetState
+                    PreviousState = ControlStatesExtension.FromControlStateClass(sourceState),
+                    CurrentState = ControlStatesExtension.FromControlStateClass(targetState)
                 };
-                stateChangeHander?.Invoke(this, e);
+                stateChangeHandler?.Invoke(this, e);
 
                 Extension?.OnControlStateChanged(this, new ControlStateChangedEventArgs(sourceState, targetState));
             }
@@ -160,31 +205,34 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected virtual void MeasureText()
         {
-            if (Style.IconRelativeOrientation == null || Icon == null || TextLabel == null)
+            if (buttonIcon == null || buttonText == null)
             {
                 return;
             }
-            TextLabel.WidthResizePolicy = ResizePolicyType.Fixed;
-            TextLabel.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;
+            buttonText.WidthResizePolicy = ResizePolicyType.Fixed;
+            buttonText.HeightResizePolicy = ResizePolicyType.Fixed;
+
+            var textPadding = TextPadding;
+            int textPaddingStart = textPadding.Start;
+            int textPaddingEnd = textPadding.End;
+            int textPaddingTop = textPadding.Top;
+            int textPaddingBottom = textPadding.Bottom;
+
+            var iconPadding = IconPadding;
+            int iconPaddingStart = iconPadding.Start;
+            int iconPaddingEnd = iconPadding.End;
+            int iconPaddingTop = iconPadding.Top;
+            int iconPaddingBottom = iconPadding.Bottom;
 
             if (IconRelativeOrientation == IconOrientation.Top || IconRelativeOrientation == IconOrientation.Bottom)
             {
-                TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd;
-                TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - Icon.SizeHeight;
+                buttonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd;
+                buttonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom - iconPaddingTop - iconPaddingBottom - buttonIcon.SizeHeight;
             }
             else
             {
-                TextLabel.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - Icon.SizeWidth;
-                TextLabel.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom;
+                buttonText.SizeWidth = SizeWidth - textPaddingStart - textPaddingEnd - iconPaddingStart - iconPaddingEnd - buttonIcon.SizeWidth;
+                buttonText.SizeHeight = SizeHeight - textPaddingTop - textPaddingBottom;
             }
         }
 
@@ -196,23 +244,22 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected virtual void LayoutChild()
         {
-            if (Style.IconRelativeOrientation == null || Icon == null || TextLabel == null)
+            if (buttonIcon == null || buttonText == null)
             {
                 return;
             }
 
-            var buttonIcon = Icon;
-            var buttonText = TextLabel;
-
-            int textPaddingStart = Style.TextPadding.Start;
-            int textPaddingEnd = Style.TextPadding.End;
-            int textPaddingTop = Style.TextPadding.Top;
-            int textPaddingBottom = Style.TextPadding.Bottom;
+            var textPadding = TextPadding;
+            int textPaddingStart = textPadding.Start;
+            int textPaddingEnd = textPadding.End;
+            int textPaddingTop = textPadding.Top;
+            int textPaddingBottom = textPadding.Bottom;
 
-            int iconPaddingStart = Style.IconPadding.Start;
-            int iconPaddingEnd = Style.IconPadding.End;
-            int iconPaddingTop = Style.IconPadding.Top;
-            int iconPaddingBottom = Style.IconPadding.Bottom;
+            var iconPadding = IconPadding;
+            int iconPaddingStart = iconPadding.Start;
+            int iconPaddingEnd = iconPadding.End;
+            int iconPaddingTop = iconPadding.Top;
+            int iconPaddingBottom = iconPadding.Bottom;
 
             switch (IconRelativeOrientation)
             {
@@ -302,22 +349,6 @@ namespace Tizen.NUI.Components
         }
 
         /// <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>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
-        {
-            ButtonStyle buttonStyle = StyleManager.Instance.GetViewStyle(StyleName) as ButtonStyle;
-            if (buttonStyle != null)
-            {
-                Style.CopyFrom(buttonStyle);
-                UpdateUIContent();
-            }
-        }
-
-        /// <summary>
         /// Dispose Button and all children on it.
         /// </summary>
         /// <param name="type">Dispose type.</param>
@@ -331,19 +362,23 @@ namespace Tizen.NUI.Components
 
             if (type == DisposeTypes.Explicit)
             {
+                if (ThemeManager.CurrentProfile == ThemeManager.Profile.Mobile)
+                {
+                    AccessibilityManager.Instance.DeleteAccessibilityAttribute(this);
+                }
                 Extension?.OnDispose(this);
 
-                if (Icon != null)
+                if (buttonIcon != null)
                 {
-                    Utility.Dispose(Icon);
+                    Utility.Dispose(buttonIcon);
                 }
-                if (TextLabel != null)
+                if (buttonText != null)
                 {
-                    Utility.Dispose(TextLabel);
+                    Utility.Dispose(buttonText);
                 }
-                if (OverlayImage != null)
+                if (overlayImage != null)
                 {
-                    Utility.Dispose(OverlayImage);
+                    Utility.Dispose(overlayImage);
                 }
             }
 
@@ -356,21 +391,14 @@ namespace Tizen.NUI.Components
         {
             base.OnControlStateChanged(controlStateChangedInfo);
 
-            var stateEnabled = !((controlStateChangedInfo.CurrentState & ControlStates.Disabled) == ControlStates.Disabled);
-
-            if (isEnabled != stateEnabled)
-            {
-                isEnabled = stateEnabled;
-            }
-
-            var stateSelected = (controlStateChangedInfo.CurrentState & ControlStates.Selected) == ControlStates.Selected;
+            var stateEnabled = !controlStateChangedInfo.CurrentState.Contains(ControlState.Disabled);
 
-            if (isSelected != stateSelected)
+            if (IsEnabled != stateEnabled)
             {
-                isSelected = stateSelected;
+                IsEnabled = stateEnabled;
             }
 
-            var statePressed = (controlStateChangedInfo.CurrentState & ControlStates.Pressed) == ControlStates.Pressed;
+            var statePressed = controlStateChangedInfo.CurrentState.Contains(ControlState.Pressed);
 
             if (isPressed != statePressed)
             {
@@ -384,10 +412,15 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 6 </since_tizen>
         private void Initialize()
         {
-            var style = (ButtonStyle)Style;
             EnableControlStatePropagation = true;
             UpdateState();
             LayoutDirectionChanged += OnLayoutDirectionChanged;
+
+            if (ThemeManager.CurrentProfile == ThemeManager.Profile.Mobile)
+            {
+                AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "Button");
+                Feedback = true;
+            }
         }
 
         private void UpdateUIContent()
@@ -395,7 +428,7 @@ namespace Tizen.NUI.Components
             MeasureText();
             LayoutChild();
 
-            Sensitive = isEnabled;
+            Sensitive = IsEnabled;
         }
 
         private void OnLayoutDirectionChanged(object sender, LayoutDirectionChangedEventArgs e)
@@ -404,12 +437,15 @@ namespace Tizen.NUI.Components
             LayoutChild();
         }
 
-        private void OnClickInternal(ClickEventArgs eventArgs)
+        private void OnClickedInternal(ClickedEventArgs eventArgs)
         {
             Command?.Execute(CommandParameter);
-            OnClick(eventArgs);
-            Extension?.OnClick(this, eventArgs);
-            ClickEvent?.Invoke(this, eventArgs);
+            OnClicked(eventArgs);
+            Extension?.OnClicked(this, eventArgs);
+
+            ClickEventArgs nestedEventArgs = new ClickEventArgs();
+            ClickEvent?.Invoke(this, nestedEventArgs);
+            Clicked?.Invoke(this, eventArgs);
         }
 
         private void OnIconRelayout(object sender, EventArgs e)
@@ -418,5 +454,49 @@ namespace Tizen.NUI.Components
             LayoutChild();
         }
 
+        /// <summary>
+        /// This method is called when the control accessibility is activated.<br />
+        /// Derived classes should override this to perform custom accessibility activation.<br />
+        /// </summary>
+        /// <remarks>Hidden-API</remarks>
+        /// <returns>True if this control can perform accessibility activation.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override bool OnAccessibilityActivated()
+        {
+            if (!IsEnabled)
+            {
+                return false;
+            }
+
+            if (!AccessibilityManager.Instance.IsForcedEnable())
+            {
+                return false;
+            }
+
+            // Touch Down
+            isPressed = true;
+            UpdateState();
+
+            // Touch Up
+            bool clicked = isPressed && IsEnabled;
+            isPressed = false;
+
+            if (IsSelectable)
+            {
+                IsSelected = !IsSelected;
+            }
+            else
+            {
+                UpdateState();
+            }
+
+            if (clicked)
+            {
+                ClickedEventArgs eventArgs = new ClickedEventArgs();
+                OnClickedInternal(eventArgs);
+            }
+            return true;
+        }
+
     }
 }