[NUI] Add TabButtonStyle class with the latest TabButton UX (#2780)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / TabButton.cs
index 77ab394..0555e29 100755 (executable)
@@ -28,13 +28,71 @@ namespace Tizen.NUI.Components
     {
         private bool selectedAgain = false;
 
+        private TabButtonStyle tabButtonStyle = null;
+
+        private bool styleApplied = false;
+
+        private View topLine = null;
+        private View bottomLine = null; // Visible only if TabButton is selected or pressed.
+
         /// <summary>
         /// Creates a new instance of TabButton.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public TabButton()
         {
-            GridLayout.SetHorizontalStretch(this, GridLayout.StretchFlags.ExpandAndFill);
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of TabButton.
+        /// </summary>
+        /// <param name="style">Creates TabButton by special style defined in UX.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TabButton(string style) : base(style)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of TabButton.
+        /// </summary>
+        /// <param name="tabButtonStyle">Creates TabButton by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TabButton(TabButtonStyle tabButtonStyle) : base(tabButtonStyle)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Applies style to TabButton.
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void ApplyStyle(ViewStyle viewStyle)
+        {
+            styleApplied = false;
+
+            base.ApplyStyle(viewStyle);
+
+            tabButtonStyle = viewStyle as TabButtonStyle;
+
+            //Apply TopLine style.
+            if (tabButtonStyle?.TopLine != null)
+            {
+                topLine?.ApplyStyle(tabButtonStyle.TopLine);
+            }
+
+            //Apply BottomLine style.
+            if (tabButtonStyle?.BottomLine != null)
+            {
+                bottomLine?.ApplyStyle(tabButtonStyle.BottomLine);
+            }
+
+            styleApplied = true;
+
+            //Calculate children's sizes and positions based on padding sizes.
+            LayoutItems();
         }
 
         /// <inheritdoc/>
@@ -68,6 +126,44 @@ namespace Tizen.NUI.Components
             return ret;
         }
 
+        /// <summary>
+        /// Dispose TabButton and all children on it.
+        /// </summary>
+        /// <param name="type">Dispose type.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                if (topLine != null)
+                {
+                    Utility.Dispose(topLine);
+                }
+
+                if (bottomLine != null)
+                {
+                    Utility.Dispose(bottomLine);
+                }
+            }
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
+        /// Gets TabButton style.
+        /// </summary>
+        /// <returns>The default TabButton style.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override ViewStyle CreateViewStyle()
+        {
+            return new TabButtonStyle();
+        }
+
         /// <inheritdoc/>
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected override bool HandleControlStateOnTouch(Touch touch)
@@ -121,5 +217,138 @@ namespace Tizen.NUI.Components
                 base.OnControlStateChanged(controlStateChangedInfo);
             }
         }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void OnUpdate()
+        {
+            base.OnUpdate();
+            LayoutItems();
+        }
+
+        /// <inheritdoc/>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void LayoutItems()
+        {
+            if (styleApplied == false)
+            {
+                return;
+            }
+
+            if ((Icon == null) && (TextLabel == null))
+            {
+                return;
+            }
+
+            // Icon is added in Button.LayoutItems().
+            if ((Icon != null) && (Children.Contains(Icon) == false))
+            {
+                Add(Icon);
+            }
+
+            // TextLabel is added in Button.LayoutItems().
+            if ((TextLabel != null) && (Children.Contains(TextLabel) == false))
+            {
+                Add(TextLabel);
+            }
+
+            // FIXME: set Selector<Extents> to padding
+            var padding = new Extents(40, 40, 24, 24);
+            var iconPadding = IconPadding;
+            var textPadding = TextPadding;
+
+            // Calculate size of TextLabel.
+            if (TextLabel != null)
+            {
+                // TODO: Other orientation cases are not implemented yet.
+                if ((IconRelativeOrientation == IconOrientation.Left) || (IconRelativeOrientation == IconOrientation.Right))
+                {
+                    var naturalWidthSum = (ushort)padding?.Start + (ushort)padding?.End + iconPadding.Start + iconPadding.End + (float)Icon?.SizeWidth + TextLabel.GetNaturalSize().Width;
+                    var naturalWidthDiff = SizeWidth - naturalWidthSum;
+
+                    if (naturalWidthDiff > 0)
+                    {
+                        TextLabel.SizeWidth = TextLabel.GetNaturalSize().Width;
+                    }
+                    else
+                    {
+                        TextLabel.SizeWidth = SizeWidth - (ushort)padding?.Start - (ushort)padding?.End - iconPadding.Start - iconPadding.End - textPadding.Start - textPadding.End - (float)Icon?.SizeWidth;
+                    }
+                }
+            }
+
+            // Calculate positions of Icon and TextLabel.
+            switch (IconRelativeOrientation)
+            {
+                // TODO: Other orientation cases are not implemented yet.
+                case IconOrientation.Left:
+                    if (LayoutDirection == ViewLayoutDirectionType.LTR)
+                    {
+                        if (Icon != null)
+                        {
+                            float iconX = 0;
+                            float iconY = (ushort)padding?.Top + iconPadding.Top;
+
+                            if (string.IsNullOrEmpty(TextLabel?.Text))
+                            {
+                                iconX = (SizeWidth - Icon.SizeWidth) / 2;
+                            }
+                            else
+                            {
+                                var widthSum = (ushort)padding?.Start + (ushort)padding?.End + iconPadding.Start + iconPadding.End + textPadding.Start + textPadding.End + Icon.SizeWidth + (float)TextLabel?.SizeWidth;
+                                var widthDiff = SizeWidth - widthSum;
+
+                                if (widthDiff > 0)
+                                {
+                                    iconX = (ushort)padding?.Start + iconPadding.Start + (widthDiff / 2);
+                                }
+                                else
+                                {
+                                    iconX = (ushort)padding?.Start + iconPadding.Start;
+                                }
+                            }
+
+                            Icon.Position = new Position(iconX, iconY);
+                        }
+
+                        if (TextLabel != null)
+                        {
+                            TextLabel.HorizontalAlignment = HorizontalAlignment.Begin;
+
+                            float textX = 0;
+                            float textY = 0;
+
+                            if (string.IsNullOrEmpty(Icon?.ResourceUrl))
+                            {
+                                textX = (SizeWidth - TextLabel.SizeWidth) / 2;
+                                textY = (ushort)padding?.Top + textPadding.Top;
+                            }
+                            else
+                            {
+                                textX = (float)Icon?.PositionX + (float)Icon?.SizeWidth;
+                                textY = (ushort)padding?.Top + textPadding.Top + (((float)Icon?.SizeHeight - TextLabel.SizeHeight) / 2);
+                            }
+
+                            TextLabel.Position = new Position(textX, textY);
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+
+            padding?.Dispose();
+        }
+
+        private void Initialize()
+        {
+            Layout = new AbsoluteLayout();
+
+            topLine = new View(tabButtonStyle?.TopLine);
+            Add(topLine);
+
+            bottomLine = new View(tabButtonStyle?.BottomLine);
+            Add(bottomLine);
+        }
     }
 }