[NUI] Fix failed in TCT
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / Switch.cs
index f1747fe..b6e3b0d 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 Tizen.NUI.BaseComponents;
 using System.ComponentModel;
+using System.Diagnostics;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components.Extension;
 
 namespace Tizen.NUI.Components
 {
     /// <summary>
-    /// Switch is one kind of common component, it can be used as selector.
-    /// User can handle Navigation by adding/inserting/deleting NavigationItem.
+    /// Switch is a kind of <see cref="Button"/> component that uses icon part as a toggle shape.
+    /// The icon part consists of track and thumb.
     /// </summary>
     /// <since_tizen> 6 </since_tizen>
-    public class Switch : Button
+    public partial class Switch : Button
     {
-        private const int aniTime = 100; // will be defined in const file later
-        private ImageView trackImage;
-        private ImageView thumbImage;
-        private Animation handlerAni = null;
+        private ImageView thumb = null;
+
+        static Switch() { }
 
         /// <summary>
         /// Creates a new instance of a Switch.
@@ -38,84 +39,156 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 6 </since_tizen>
         public Switch() : base()
         {
-            Initialize();
         }
 
         /// <summary>
         /// Creates a new instance of a Switch with style.
         /// </summary>
         /// <param name="style">Create Switch 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 Switch(string style) : base(style)
         {
-            Initialize();
         }
 
         /// <summary>
         /// Creates a new instance of a Switch with style.
         /// </summary>
-        /// <param name="style">Create Switch by style customized by user.</param>
-        /// <since_tizen> 6 </since_tizen>
-        /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+        /// <param name="switchStyle">Create Switch by style customized by user.</param>
+        /// <since_tizen> 8 </since_tizen>
+        public Switch(SwitchStyle switchStyle) : base(switchStyle)
+        {
+        }
+
+        /// <summary>
+        /// Initialize AT-SPI object.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void OnInitialize()
+        {
+            base.OnInitialize();
+            SetAccessibilityConstructor(Role.ToggleButton);
+
+            IsSelectable = true;
+#if PROFILE_MOBILE
+            Feedback = true;
+#endif
+        }
+
+        /// <summary>
+        /// Informs AT-SPI bridge about the set of AT-SPI states associated with this object.
+        /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public Switch(SwitchStyle style) : base(style)
+        protected override AccessibilityStates AccessibilityCalculateStates(ulong states)
         {
-            Initialize();
+            var accessibilityStates = base.AccessibilityCalculateStates(states);
+            FlagSetter(ref accessibilityStates, AccessibilityStates.Checked, this.IsSelected);
+            return accessibilityStates;
         }
 
         /// <summary>
         /// An event for the item selected 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 SelectedChanged event instead.")]
         public event EventHandler<SelectEventArgs> SelectedEvent;
 
-        /// 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 new SwitchStyle Style => ViewStyle as SwitchStyle;
+        /// <summary>
+        /// An event for the item selected 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<SelectedChangedEventArgs> SelectedChanged;
 
         /// <summary>
-        /// Background image's resource url in Switch.
+        /// Return currently applied style.
         /// </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.
+        /// <remarks>
+        /// Modifying contents in style may cause unexpected behaviour.
+        /// </remarks>
+        /// <since_tizen> 8 </since_tizen>
+        public new SwitchStyle Style => (SwitchStyle)(ViewStyle as SwitchStyle)?.Clone();
+
+        /// <summary>
+        /// Apply style to switch.
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public string SwitchBackgroundImageURL
+        public override void ApplyStyle(ViewStyle viewStyle)
         {
-            get
+            if (viewStyle is SwitchStyle switchStyle)
             {
-                return Style.Track?.ResourceUrl?.All;
-            }
-            set
-            {
-                if (value != null)
+                if (Extension is SwitchExtension extension)
                 {
-                    if (Style.Track.ResourceUrl == null)
-                    {
-                        Style.Track.ResourceUrl = new StringSelector();
-                    }
-                    Style.Track.ResourceUrl.All = value;
+                    Icon.Unparent();
+                    thumb.Unparent();
+                    Icon = extension.OnCreateTrack(this, Icon);
+                    thumb = extension.OnCreateThumb(this, thumb);
+                    Icon.Add(thumb);
+                    LayoutItems();
+                }
+
+                if (switchStyle.Track != null)
+                {
+                    Track.ApplyStyle(switchStyle.Track);
+                }
+
+                if (switchStyle.Thumb != null)
+                {
+                    Thumb.ApplyStyle(switchStyle.Thumb);
                 }
             }
+
+            base.ApplyStyle(viewStyle);
         }
 
         /// <summary>
-        /// Background image's resource url selector in Switch.
+        /// Switch's track part.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public ImageView Track
+        {
+            get => Icon;
+            internal set
+            {
+                Icon = value;
+            }
+        }
+
+        /// <summary>
+        /// Switch's thumb part.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        public ImageView Thumb
+        {
+            get => thumb;
+            internal set
+            {
+                thumb = value;
+            }
+        }
+
+        /// <summary>
+        /// Switch's track part image url selector.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
         public StringSelector SwitchBackgroundImageURLSelector
         {
             get
             {
-                return (StringSelector)Style.Track?.ResourceUrl;
+                return GetValue(SwitchBackgroundImageURLSelectorProperty) as StringSelector;
             }
             set
             {
-                if (value != null)
-                {
-                    Style.Track.ResourceUrl = value.Clone() as StringSelector;
-                }
+                SetValue(SwitchBackgroundImageURLSelectorProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private StringSelector InternalSwitchBackgroundImageURLSelector
+        {
+            get => Icon?.ResourceUrlSelector == null ? null : new StringSelector(Icon.ResourceUrlSelector);
+            set
+            {
+                Debug.Assert(Icon != null);
+                Icon.ResourceUrlSelector = value;
             }
         }
 
@@ -127,37 +200,50 @@ namespace Tizen.NUI.Components
         {
             get
             {
-                return Style.Thumb?.ResourceUrl?.All;
+                return GetValue(SwitchHandlerImageURLProperty) as string;
             }
             set
             {
-                if (value != null)
-                {
-                    if (Style.Thumb.ResourceUrl == null)
-                    {
-                        Style.Thumb.ResourceUrl = new StringSelector();
-                    }
-                    Style.Thumb.ResourceUrl.All = value;
-                }
+                SetValue(SwitchHandlerImageURLProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private string InternalSwitchHandlerImageURL
+        {
+            get
+            {
+                return Thumb.ResourceUrl;
+            }
+            set
+            {
+                Thumb.ResourceUrl = value;
             }
         }
 
         /// <summary>
         /// Handler image's resource url selector in Switch.
+        /// Getter returns copied selector value if exist, null otherwise.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
         public StringSelector SwitchHandlerImageURLSelector
         {
             get
             {
-                return (StringSelector)Style.Thumb?.ResourceUrl;
+                return GetValue(SwitchHandlerImageURLSelectorProperty) as StringSelector;
             }
             set
             {
-                if (value != null)
-                {
-                    Style.Thumb.ResourceUrl = value.Clone() as StringSelector;
-                }
+                SetValue(SwitchHandlerImageURLSelectorProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private StringSelector InternalSwitchHandlerImageURLSelector
+        {
+            get => new StringSelector(thumb.ResourceUrlSelector);
+            set
+            {
+                Debug.Assert(thumb != null);
+                thumb.ResourceUrlSelector = value;
             }
         }
 
@@ -169,11 +255,23 @@ namespace Tizen.NUI.Components
         {
             get
             {
-                return Style.Thumb?.Size ?? new Size(0, 0);
+                return GetValue(SwitchHandlerImageSizeProperty) as Size;
             }
             set
             {
-                Style.Thumb.Size = value;
+                SetValue(SwitchHandlerImageSizeProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private Size InternalSwitchHandlerImageSize
+        {
+            get
+            {
+                return Thumb.Size;
+            }
+            set
+            {
+                Thumb.Size = value;
             }
         }
 
@@ -188,18 +286,7 @@ namespace Tizen.NUI.Components
 
             if (type == DisposeTypes.Explicit)
             {
-                if (null != handlerAni)
-                {
-                    if (handlerAni.State == Animation.States.Playing)
-                    {
-                        handlerAni.Stop();
-                    }
-                    handlerAni.Dispose();
-                    handlerAni = null;
-                }
-
-                Utility.Dispose(thumbImage);
-                Utility.Dispose(trackImage);
+                Utility.Dispose(thumb);
             }
 
             base.Dispose(type);
@@ -210,23 +297,10 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <param name="key">The key event.</param>
         /// <returns>True if the key 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>
         public override bool OnKey(Key key)
         {
-            if (!IsEnabled) return false;
-
-            bool ret = base.OnKey(key);
-            if (key.State == Key.StateType.Up)
-            {
-                if (key.KeyPressedName == "Return")
-                {
-                    OnSelect();
-                }
-            }
-
-            return ret;
+            return base.OnKey(key);
         }
 
         /// <summary>
@@ -235,90 +309,68 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <param name="touch">The touch event.</param>
         /// <returns>True if the event should be consumed.</returns>
-        /// <since_tizen> 6 </since_tizen>
-        /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
+        /// <since_tizen> 8 </since_tizen>
+        [Obsolete("Deprecated in API8; Will be removed in API10. Please use OnClicked instead.")]
+#pragma warning disable CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
         public override bool OnTouch(Touch touch)
+#pragma warning restore CS0809 // Obsolete member overrides non-obsolete member, It will be removed in API10
         {
-            if(!IsEnabled) return false;
-
-            PointStateType state = touch.GetState(0);
-            bool ret = base.OnTouch(touch);
-            switch (state)
-            {
-                case PointStateType.Up:
-                    OnSelect();
-                    break;
-                default:
-                    break;
-            }
-            return ret;
+            return base.OnTouch(touch);
         }
 
         /// <summary>
-        /// Get Switch attribues.
+        /// Get Switch style.
         /// </summary>
-        /// <since_tizen> 6 </since_tizen>
-        /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        protected override ViewStyle GetViewStyle()
+        /// <returns>The default switch style.</returns>
+        /// <since_tizen> 8 </since_tizen>
+        protected override ViewStyle CreateViewStyle()
         {
             return new SwitchStyle();
         }
 
-        private void Initialize()
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override ImageView CreateIcon()
         {
-            Style.IsSelectable = true;
-            handlerAni = new Animation(aniTime);
-            trackImage = new ImageView()
+            var icon = new ImageView()
             {
-                ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
-                PivotPoint = Tizen.NUI.PivotPoint.TopLeft,
-                PositionUsesPivotPoint = true,
-                WidthResizePolicy = ResizePolicyType.FillToParent,
-                HeightResizePolicy = ResizePolicyType.FillToParent,
-                Name = "SwitchBackgroundImage",
+                AccessibilityHighlightable = false,
+                EnableControlStatePropagation = true
             };
-            Add(trackImage);
-            trackImage.ApplyStyle(Style.Track);
 
-            thumbImage = new ImageView()
-            {
-                ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
-                PivotPoint = Tizen.NUI.PivotPoint.TopLeft,
-                PositionUsesPivotPoint = true,
-                Name = "SwitchHandlerImage",
-            };
-            trackImage.Add(thumbImage);
-            thumbImage.ApplyStyle(Style.Thumb);
+            thumb = new ImageView();
+            icon.Add(thumb);
+
+            return icon;
         }
 
-        /// <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.
+        /// <inheritdoc/>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
+        protected override void OnControlStateChanged(ControlStateChangedEventArgs controlStateChangedInfo)
         {
-            SwitchStyle tempAttributes = StyleManager.Instance.GetAttributes(style) as SwitchStyle;
-            if (null != tempAttributes)
+            base.OnControlStateChanged(controlStateChangedInfo);
+
+            if (!IsSelectable)
+            {
+                return;
+            }
+
+            bool previousSelected = controlStateChangedInfo.PreviousState.Contains(ControlState.Selected);
+
+            if (previousSelected != IsSelected)
             {
-                Style.CopyFrom(tempAttributes);
+                OnSelect();
             }
         }
 
         private void OnSelect()
         {
-            if (handlerAni.State == Animation.States.Playing)
+            if (Accessibility.Accessibility.Enabled && IsHighlighted)
             {
-                handlerAni.Stop();
+                EmitAccessibilityStatesChangedEvent(AccessibilityStates.Checked, IsSelected);
             }
-            handlerAni.Clear();
-            handlerAni.AnimateTo(thumbImage, "PositionX", Size2D.Width - thumbImage.Size2D.Width - thumbImage.Position2D.X);
-            trackImage.Opacity = 0.5f; ///////need defined by UX
-            handlerAni.AnimateTo(trackImage, "Opacity", 1);
-            handlerAni.Play();
+
+            ((SwitchExtension)Extension)?.OnSelectedChanged(this);
 
             if (SelectedEvent != null)
             {
@@ -326,12 +378,23 @@ namespace Tizen.NUI.Components
                 eventArgs.IsSelected = IsSelected;
                 SelectedEvent(this, eventArgs);
             }
+
+            if (SelectedChanged != null)
+            {
+                SelectedChangedEventArgs eventArgs = new SelectedChangedEventArgs();
+                eventArgs.IsSelected = IsSelected;
+                SelectedChanged(this, eventArgs);
+            }
         }
 
         /// <summary>
         /// SelectEventArgs is a class to record item selected arguments which will sent to user.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
+        /// It will be removed in API10
+        [Obsolete("Deprecated in API8; Will be removed in API10. Please use SelectedChangedEventArgs instead.")]
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:Do not declare visible instance fields")]
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
         public class SelectEventArgs : EventArgs
         {
             /// <summary> Select state of Switch </summary>