[NUI] Add AppBarStyle class with the latest AppBar UX (#2718)
authorJaehyun Cho <29364140+jaehyun0cho@users.noreply.github.com>
Wed, 10 Mar 2021 05:16:01 +0000 (14:16 +0900)
committerEunki Hong <h.pichulia@gmail.com>
Wed, 17 Mar 2021 06:50:14 +0000 (15:50 +0900)
To apply the latest AppBar UX, AppBarStyle class is added.

AppBarStyle.BackButton is applied to AppBar.DefaultNavigationContent.
AppBarStyle.TitleTextLabel is applied to AppBar.DefaultTitleContent.
AppBarStyle.ActionView and ActionButton are applied to the children of
AppBar.DefaultActionContent added by AppBar.AddActions().

Co-authored-by: Jaehyun Cho <jae_hyun.cho@samsung.com>
src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs
src/Tizen.NUI.Components/Style/Navigation/AppBarStyle.cs [new file with mode: 0755]
src/Tizen.NUI.Components/Theme/DefaultTheme.cs
src/Tizen.NUI.Components/Theme/DefaultThemeCommon.cs
src/Tizen.NUI.Components/res/nui_component_default_back_button.png [new file with mode: 0755]
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AppBarSample.cs

index 231dff3a4b06baa237d9e68822d9d3fffada159e..edc17c5b0f84a196bbffbc59bb619efff580fd1f 100755 (executable)
@@ -29,9 +29,6 @@ namespace Tizen.NUI.Components
     [EditorBrowsable(EditorBrowsableState.Never)]
     public class AppBar : Control
     {
-        //TODO: This app bar height should be implemented in AppBar style.
-        private float appBarHeight = 72.0f;
-
         private bool autoNavigationContent = true;
 
         private View defaultNavigationContent = null;
@@ -42,6 +39,10 @@ namespace Tizen.NUI.Components
         private View appBarTitle = null;
         private View appBarAction = null;
 
+        private AppBarStyle appBarStyle => ViewStyle as AppBarStyle;
+
+        private bool styleApplied = false;
+
         /// <summary>
         /// Creates a new instance of AppBar.
         /// </summary>
@@ -51,6 +52,26 @@ namespace Tizen.NUI.Components
             Initialize();
         }
 
+        /// <summary>
+        /// Creates a new instance of AppBar.
+        /// </summary>
+        /// <param name="style">Creates AppBar by special style defined in UX.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBar(string style) : base(style)
+        {
+            Initialize();
+        }
+
+        /// <summary>
+        /// Creates a new instance of AppBar.
+        /// </summary>
+        /// <param name="appBarStyle">Creates AppBar by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBar(AppBarStyle appBarStyle) : base(appBarStyle)
+        {
+            Initialize();
+        }
+
         /// <summary>
         /// Disposes AppBar and all children on it.
         /// </summary>
@@ -200,6 +221,7 @@ namespace Tizen.NUI.Components
         /// Action content of AppBar. ActionContent is added to Children automatically.
         /// Action content can contain action views and action buttons by AddActions.
         /// If ActionContent is set by user, then AddActions does not add actions to the replaced ActionContent.
+        /// The Action and ActionButton styles of AppBarStyle are applied to actions only by AddActions.
         /// If ActionContent is set by user, then RemoveActions does not remove actions from the replaced ActionContent.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
@@ -325,6 +347,57 @@ namespace Tizen.NUI.Components
             }
         }
 
+        /// <summary>
+        /// Applies style to AppBar.
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void ApplyStyle(ViewStyle viewStyle)
+        {
+            styleApplied = false;
+
+            base.ApplyStyle(viewStyle);
+
+            //Apply Back Button style.
+            if ((appBarStyle?.BackButton != null) && (DefaultNavigationContent is Button))
+            {
+                ((Button)DefaultNavigationContent)?.ApplyStyle(appBarStyle.BackButton);
+            }
+
+            //Apply Title style.
+            if ((appBarStyle?.TitleTextLabel != null) && (DefaultTitleContent is TextLabel))
+            {
+                ((TextLabel)DefaultTitleContent)?.ApplyStyle(appBarStyle.TitleTextLabel);
+            }
+
+            //Apply ActionCellPadding style.
+            if (DefaultActionContent?.Layout is LinearLayout)
+            {
+                ((LinearLayout)DefaultActionContent?.Layout).CellPadding = new Size2D(appBarStyle?.ActionCellPadding?.Width ?? 0, appBarStyle?.ActionCellPadding?.Height ?? 0);
+            }
+
+            //Apply Action and ActionButton styles.
+            if (DefaultActionContent?.ChildCount > 0)
+            {
+                foreach (var action in DefaultActionContent?.Children)
+                {
+                    if ((action is Button) && (appBarStyle?.ActionButton != null))
+                    {
+                        ((Button)action)?.ApplyStyle(appBarStyle.ActionButton);
+                    }
+                    else if (appBarStyle?.ActionView != null)
+                    {
+                        action?.ApplyStyle(appBarStyle.ActionView);
+                    }
+                }
+            }
+
+            styleApplied = true;
+
+            //Calculate children's positions based on padding sizes.
+            CalculatePosition();
+        }
+
         /// <summary>
         /// Sets title text of AppBar.
         /// SetTitle sets title text to the default title content.
@@ -342,6 +415,7 @@ namespace Tizen.NUI.Components
 
         /// <summary>
         /// Adds actions to ActionContent of AppBar.
+        /// The Action and ActionButton styles of AppBarStyle are applied to the added actions.
         /// AddActions adds action views to the default action content.
         /// Therefore, if ActionContent is set by user, then AddActions does not add actions to the replaced ActionContent.
         /// </summary>
@@ -357,6 +431,16 @@ namespace Tizen.NUI.Components
 
             foreach (var action in actions)
             {
+                //Apply Action and ActionButton styles.
+                if ((action is Button) && (appBarStyle?.ActionButton != null))
+                {
+                    ((Button)action)?.ApplyStyle(appBarStyle.ActionButton);
+                }
+                else if (appBarStyle?.ActionView != null)
+                {
+                    action?.ApplyStyle(appBarStyle.ActionView);
+                }
+
                 DefaultActionContent.Add(action);
             }
         }
@@ -395,9 +479,6 @@ namespace Tizen.NUI.Components
 
             WidthSpecification = LayoutParamPolicies.MatchParent;
 
-            //TODO: This app bar height should be implemented in AppBar style.
-            SizeHeight = appBarHeight;
-
             if (AutoNavigationContent == true)
             {
                 NavigationContent = DefaultNavigationContent;
@@ -410,13 +491,7 @@ namespace Tizen.NUI.Components
 
         private View CreateDefaultNavigationContent()
         {
-            var backButton = new Button()
-            {
-                //FIXME: When back icon resource is added, replace this text to the icon resource.
-                Text = "<",
-                //TODO: This app bar height should be implemented in Appbar style.
-                Size = new Size(72.0f, 72.0f),
-            };
+            var backButton = new Button(appBarStyle?.BackButton ?? null);
 
             backButton.Clicked += (object sender, ClickedEventArgs args) =>
             {
@@ -437,7 +512,7 @@ namespace Tizen.NUI.Components
 
         private View CreateDefaultTitleContent()
         {
-            return new TextLabel()
+            return new TextLabel(appBarStyle?.TitleTextLabel ?? null)
             {
                 HeightSpecification = LayoutParamPolicies.MatchParent,
                 Weight = 1.0f,
@@ -451,6 +526,9 @@ namespace Tizen.NUI.Components
                 Layout = new LinearLayout()
                 {
                     LinearOrientation = LinearLayout.Orientation.Horizontal,
+
+                    //Apply ActionCellPadding style.
+                    CellPadding = new Size2D(appBarStyle?.ActionCellPadding?.Width ?? 0, appBarStyle?.ActionCellPadding?.Height ?? 0),
                 },
                 Weight = 0.0f,
             };
@@ -489,6 +567,45 @@ namespace Tizen.NUI.Components
             {
                 Add(appBarAction);
             }
+
+            //Calculate children's positions based on padding sizes.
+            CalculatePosition();
+        }
+
+        private void CalculatePosition()
+        {
+            if (styleApplied == false)
+            {
+                return;
+            }
+
+            //Apply NavigationPadding style.
+            if ((NavigationContent != null) && (appBarStyle?.NavigationPadding != null))
+            {
+                if (NavigationContent.Margin.NotEqualTo(appBarStyle.NavigationPadding))
+                {
+                    NavigationContent.Margin.CopyFrom(appBarStyle.NavigationPadding);
+                }
+            }
+
+            //Apply ActionPadding style.
+            if ((ActionContent != null) && (appBarStyle?.ActionPadding != null))
+            {
+                if (ActionContent.Margin.NotEqualTo(appBarStyle.ActionPadding))
+                {
+                    ActionContent.Margin.CopyFrom(appBarStyle.ActionPadding);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets AppBar style.
+        /// </summary>
+        /// <returns>The default AppBar style.</returns>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override ViewStyle CreateViewStyle()
+        {
+            return new AppBarStyle();
         }
     }
 }
diff --git a/src/Tizen.NUI.Components/Style/Navigation/AppBarStyle.cs b/src/Tizen.NUI.Components/Style/Navigation/AppBarStyle.cs
new file mode 100755 (executable)
index 0000000..994e97b
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// AppBarStyle is a class which saves AppBar's ux data.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class AppBarStyle : ControlStyle
+    {
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        static AppBarStyle() { }
+
+        /// <summary>
+        /// Creates a new instance of a AppBarStyle.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBarStyle() : base()
+        {
+        }
+
+        /// <summary>
+        /// Creates a new instance of a AppBarStyle with style.
+        /// </summary>
+        /// <param name="style">Creates AppBarStyle by style customized by user.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBarStyle(AppBarStyle style) : base(style)
+        {
+        }
+
+        /// <summary>
+        /// Gets or sets the AppBar Back Button style.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ButtonStyle BackButton { get; set; } = new ButtonStyle();
+
+        /// <summary>
+        /// Gets or sets the AppBar Title TextLabel style.
+        /// This style is applied if AppBar Title is a TextLabel.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public TextLabelStyle TitleTextLabel { get; set; } = new TextLabelStyle();
+
+        /// <summary>
+        /// Gets or sets the AppBar Action View style.
+        /// This style is applied if AppBar ActionContent's child is a View.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ViewStyle ActionView { get; set; } = new ViewStyle();
+
+        /// <summary>
+        /// Gets or sets the AppBar Action Button style.
+        /// This style is applied if AppBar ActionContent's child is a Button.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public ButtonStyle ActionButton { get; set; } = new ButtonStyle();
+
+        /// <summary>
+        /// Navigation padding in AppBar.
+        /// This works only when NavigationContent is visible.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Extents NavigationPadding { get; set; } = new Extents();
+
+        /// <summary>
+        /// Action padding in AppBar.
+        /// This works only when ActionContent is visible.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Extents ActionPadding { get; set; } = new Extents();
+
+        /// <summary>
+        /// Cell padding among Actions in AppBar.
+        /// This works only when ActionContent is visible.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Size2D ActionCellPadding { get; set; } = new Size2D();
+
+        /// <summary>
+        /// Style's clone function.
+        /// </summary>
+        /// <param name="bindableObject">The style that needs to copy.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void CopyFrom(BindableObject bindableObject)
+        {
+            base.CopyFrom(bindableObject);
+
+            if (bindableObject is AppBarStyle appBarStyle)
+            {
+                BackButton.CopyFrom(appBarStyle.BackButton);
+                TitleTextLabel.CopyFrom(appBarStyle.TitleTextLabel);
+                ActionView.CopyFrom(appBarStyle.ActionView);
+                ActionButton.CopyFrom(appBarStyle.ActionButton);
+                NavigationPadding = (appBarStyle.NavigationPadding == null) ? new Extents() : new Extents(appBarStyle.NavigationPadding);
+                ActionPadding = (appBarStyle.ActionPadding == null) ? new Extents() : new Extents(appBarStyle.ActionPadding);
+                ActionCellPadding = (appBarStyle.ActionCellPadding == null) ? new Size2D() : new Size2D(appBarStyle.ActionCellPadding.Width, appBarStyle.ActionCellPadding.Height);
+            }
+        }
+    }
+}
index 981ee35f93c8b2911d895c604874d4042cd43c1d..398032067c052643740b809c06a610c8d1ced7a7 100755 (executable)
@@ -102,6 +102,9 @@ namespace Tizen.NUI.Components
                 (new ExternalThemeKeyList(typeof(DefaultTitleItem), typeof(DefaultTitleItemStyle)))
                     .AddBackgroundSelector("/Background", SetBackgroundColor, SetBackgroundImage)
                     .Add<Rectangle>("/BackgroundImageBorder", SetBackgroundBorder),
+
+                // AppBar
+                (new ExternalThemeKeyList(typeof(AppBar), typeof(AppBarStyle))),
             };
 
             return actionSet;
index 53ccc234f702e8270e1a48fed4ac2467476b104e..ce27093638de45e10cd083b56c0e2149e3bfa628 100755 (executable)
@@ -346,6 +346,77 @@ namespace Tizen.NUI.Components
                 },
             });
 
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.AppBar", new AppBarStyle()
+            {
+                Size = new Size(-1, 120),
+                BackgroundColor = new Color("#EEEFF1FF"),
+                BackButton = new ButtonStyle()
+                {
+                    Size = new Size(48, 48),
+                    CornerRadius = 0,
+                    BackgroundColor = new Color(0, 0, 0, 0),
+                    Icon = new ImageViewStyle()
+                    {
+                        Size = new Size(48, 48),
+                        ResourceUrl = FrameworkInformation.ResourcePath + "nui_component_default_back_button.png",
+                        Color = new Selector<Color>()
+                        {
+                            Normal = new Color("#0A0E4AFF"),
+                            Focused = new Color("#00338BFF"),
+                            Pressed = new Color("#1B69CAFF"),
+                            Disabled = new Color("#C3CAD2FF"),
+                        },
+                    },
+                },
+                TitleTextLabel = new TextLabelStyle()
+                {
+                    PixelSize = 40,
+                    VerticalAlignment = VerticalAlignment.Center,
+                    TextColor = new Selector<Color>()
+                    {
+                        Normal = new Color("#000C2BFF"),
+                    }
+                },
+                ActionView = new ViewStyle()
+                {
+                    Size = new Size(-1, 48),
+                    CornerRadius = 0,
+                    BackgroundColor = new Color(0, 0, 0, 0),
+                },
+                ActionButton = new ButtonStyle()
+                {
+                    Size = new Size(-1, 48),
+                    CornerRadius = 0,
+                    BackgroundColor = new Color(0, 0, 0, 0),
+                    Text = new TextLabelStyle()
+                    {
+                        PixelSize = 26,
+                        TextColor = new Selector<Color>()
+                        {
+                            Normal = new Color("#0A0E4AFF"),
+                            Focused = new Color("#00338BFF"),
+                            Pressed = new Color("#1B69CAFF"),
+                            Disabled = new Color("#C3CAD2FF"),
+                        },
+                    },
+                    Icon = new ImageViewStyle()
+                    {
+                        Size = new Size(-1, 48),
+                        Color = new Selector<Color>()
+                        {
+                            Normal = new Color("#0A0E4AFF"),
+                            Focused = new Color("#00338BFF"),
+                            Pressed = new Color("#1B69CAFF"),
+                            Disabled = new Color("#C3CAD2FF"),
+                        },
+                    },
+                },
+                Padding = new Extents(64, 64, 0, 0),
+                NavigationPadding = new Extents(0, 24, 0, 0),
+                ActionPadding = new Extents(40, 0, 0, 0),
+                ActionCellPadding = new Size2D(40, 0),
+            });
+
             return theme;
         }
     }
diff --git a/src/Tizen.NUI.Components/res/nui_component_default_back_button.png b/src/Tizen.NUI.Components/res/nui_component_default_back_button.png
new file mode 100755 (executable)
index 0000000..19a101a
Binary files /dev/null and b/src/Tizen.NUI.Components/res/nui_component_default_back_button.png differ
index 70852e822fd38b5ae98b3bb9658d0dbf776f0d5b..e0584d9e30960c811f2289849e784a8f98dee208 100755 (executable)
@@ -19,8 +19,7 @@ namespace Tizen.NUI.Samples
         {
             firstActionButton = new Button()
             {
-                Text = "2",
-                Size = new Size(72.0f, 72.0f)
+                Text = "Page 2",
             };
             firstActionButton.Clicked += (object sender, ClickedEventArgs e) =>
             {
@@ -54,8 +53,7 @@ namespace Tizen.NUI.Samples
         {
             secondActionButton = new Button()
             {
-                Text = "1",
-                Size = new Size(72.0f, 72.0f)
+                Text = "Page 1",
             };
             secondActionButton.Clicked += (object sender, ClickedEventArgs e) =>
             {