[NUI] Add AppBar class (#2435)
authorJaehyun Cho <29364140+jaehyun0cho@users.noreply.github.com>
Tue, 5 Jan 2021 08:44:50 +0000 (17:44 +0900)
committerhuiyueun <35286162+huiyueun@users.noreply.github.com>
Mon, 11 Jan 2021 05:49:43 +0000 (14:49 +0900)
AppBar shows title text and provides navigation and action functions on
Page.

Co-authored-by: Jaehyun Cho <jae_hyun.cho@samsung.com>
src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs [new file with mode: 0755]
src/Tizen.NUI.Components/Controls/Navigation/Page.cs
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AppBarSample.cs [new file with mode: 0755]

diff --git a/src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs b/src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs
new file mode 100755 (executable)
index 0000000..5014dbb
--- /dev/null
@@ -0,0 +1,433 @@
+/*
+ * Copyright(c) 2020 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;
+using System.Collections.Generic;
+using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using System.Windows.Input;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// The AppBar class is a class which shows title text and provides navigation
+    /// and action functions on Page.
+    /// </summary>
+    [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;
+
+        private View appBarNavigation = null;
+        private View appBarTitle = null;
+        private View appBarAction = null;
+
+        /// <summary>
+        /// Creates a new instance of a AppBar.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBar() : base()
+        {
+            defaultNavigationContent = CreateDefaultNavigationContent();
+
+            //Navigation, Title and Action are located horizontally.
+            var linearLayout = new LinearLayout();
+            linearLayout.LinearOrientation = LinearLayout.Orientation.Horizontal;
+            Layout = linearLayout;
+
+            WidthSpecification = LayoutParamPolicies.MatchParent;
+
+            //TODO: This app bar height should be implemented in AppBar style.
+            SizeHeight = appBarHeight;
+
+            if ((AutoNavigationContent == true) && (DefaultNavigationContent != null))
+            {
+                Add(DefaultNavigationContent);
+            }
+        }
+
+        /// <summary>
+        /// Creates a new instance of a AppBar.
+        /// </summary>
+        /// <param name="navigationContent">The content to set to NavigationContent of AppBar.</param>
+        /// <param name="titleContent">The content to set to TitleContent of AppBar.</param>
+        /// <param name="actionContent">The content to set to ActionContent of AppBar.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBar(View navigationContent, View titleContent, View actionContent) : base()
+        {
+            defaultNavigationContent = CreateDefaultNavigationContent();
+
+            //Navigation, Title and Action are located horizontally.
+            var linearLayout = new LinearLayout();
+            linearLayout.LinearOrientation = LinearLayout.Orientation.Horizontal;
+            Layout = linearLayout;
+
+            WidthSpecification = LayoutParamPolicies.MatchParent;
+
+            //TODO: This app bar height should be implemented in AppBar style.
+            SizeHeight = appBarHeight;
+
+            if (navigationContent != null)
+            {
+                NavigationContent = navigationContent;
+            }
+            else if ((AutoNavigationContent == true) && (DefaultNavigationContent != null))
+            {
+                Add(DefaultNavigationContent);
+            }
+
+            if (titleContent != null)
+            {
+                TitleContent = titleContent;
+            }
+
+            if (actionContent != null)
+            {
+                ActionContent = actionContent;
+            }
+        }
+
+        /// <summary>
+        /// Creates a new instance of a AppBar.
+        /// </summary>
+        /// <param name="title">The text string to set to TitleContent of AppBar.</param>
+        /// <param name="actionContents">The contents to add to ActionContent of AppBar.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBar(string title, params View[] actionContents) : this(null, title, actionContents)
+        {
+        }
+
+        /// <summary>
+        /// Creates a new instance of a AppBar.
+        /// </summary>
+        /// <param name="navigationContent">The content to set to NavigationContent of AppBar.</param>
+        /// <param name="title">The text string to set to TitleContent of AppBar.</param>
+        /// <param name="actionContents">The contents to add to ActionContent of AppBar.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBar(View navigationContent, string title, params View[] actionContents) : base()
+        {
+            defaultNavigationContent = CreateDefaultNavigationContent();
+
+            //Navigation, Title and Action are located horizontally.
+            var linearLayout = new LinearLayout();
+            linearLayout.LinearOrientation = LinearLayout.Orientation.Horizontal;
+            Layout = linearLayout;
+
+            WidthSpecification = LayoutParamPolicies.MatchParent;
+
+            //TODO: This app bar height should be implemented in AppBar style.
+            SizeHeight = appBarHeight;
+
+            if (navigationContent != null)
+            {
+                navigationContent.HeightSpecification = LayoutParamPolicies.MatchParent;
+                navigationContent.Weight = 0.0f;
+
+                NavigationContent = navigationContent;
+            }
+            else if ((AutoNavigationContent == true) && (DefaultNavigationContent != null))
+            {
+                Add(DefaultNavigationContent);
+            }
+
+            if (title != null)
+            {
+                var titleContent = new TextLabel()
+                {
+                    Text = title,
+                    HeightSpecification = LayoutParamPolicies.MatchParent,
+                    VerticalAlignment = VerticalAlignment.Center,
+                    Weight = 1.0f,
+                    BackgroundColor = new Color(0.88f, 0.88f, 0.88f, 1.0f)
+                };
+
+                TitleContent = titleContent;
+            }
+
+            if (actionContents != null)
+            {
+                var actionContent = new Control()
+                {
+                    Layout = new LinearLayout()
+                    {
+                        LinearOrientation = LinearLayout.Orientation.Horizontal
+                    },
+                    HeightSpecification = LayoutParamPolicies.MatchParent,
+                    Weight = 0.0f
+                };
+
+                foreach (var actionView in actionContents)
+                {
+                    actionView.HeightSpecification = LayoutParamPolicies.MatchParent;
+
+                    actionContent.Add(actionView);
+                }
+
+                ActionContent = actionContent;
+            }
+        }
+
+        /// <summary>
+        /// Disposes AppBar 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 (appBarNavigation != null)
+                {
+                    Utility.Dispose(appBarNavigation);
+                }
+
+                if (appBarTitle != null)
+                {
+                    Utility.Dispose(appBarTitle);
+                }
+
+                if (appBarAction != null)
+                {
+                    Utility.Dispose(appBarAction);
+                }
+            }
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
+        /// Navigation content of AppBar. NavigationContent is added to Children automatically.
+        /// If AutoNavigationContent is set to be true and NavigationContent is not set,
+        /// then default navigation content is automatically displayed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View NavigationContent
+        {
+            get
+            {
+                return appBarNavigation;
+            }
+            set
+            {
+                if (appBarNavigation == value)
+                {
+                    return;
+                }
+
+                if (appBarNavigation != null)
+                {
+                    Remove(appBarNavigation);
+                }
+
+                appBarNavigation = value;
+                if (appBarNavigation == null)
+                {
+                    return;
+                }
+
+                ResetContent();
+            }
+        }
+
+        /// <summary>
+        /// Title content of AppBar. TitleContent is added to Children automatically.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View TitleContent
+        {
+            get
+            {
+                return appBarTitle;
+            }
+            set
+            {
+                if (appBarTitle == value)
+                {
+                    return;
+                }
+
+                if (appBarTitle != null)
+                {
+                    Remove(appBarTitle);
+                }
+
+                appBarTitle = value;
+                if (appBarTitle == null)
+                {
+                    return;
+                }
+
+                ResetContent();
+            }
+        }
+
+        /// <summary>
+        /// Action content of AppBar. ActionContent is added to Children automatically.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public View ActionContent
+        {
+            get
+            {
+                return appBarAction;
+            }
+            set
+            {
+                if (appBarAction == value)
+                {
+                    return;
+                }
+
+                if (appBarAction != null)
+                {
+                    Remove(appBarAction);
+                }
+
+                appBarAction = value;
+                if (appBarAction == null)
+                {
+                    return;
+                }
+
+                ResetContent();
+            }
+        }
+
+        /// <summary>
+        /// Flag to indicate if default navigation content is automatically set or not.
+        /// The default value is true.
+        /// If AutoNavigationContent is set to be true and NavigationContent is not set,
+        /// then default navigation content is automatically displayed.
+        /// If default navigation content is clicked, it calls navigator pop operation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public bool AutoNavigationContent
+        {
+            get
+            {
+                return autoNavigationContent;
+            }
+
+            set
+            {
+                if (autoNavigationContent == value)
+                {
+                    return;
+                }
+
+                autoNavigationContent = value;
+
+                ResetContent();
+            }
+        }
+
+        /// <summary>
+        /// Default navigation content of AppBar set automatically by default.
+        /// If AutoNavigationContent is set to be true and NavigationContent is not set,
+        /// then default navigation content is automatically displayed.
+        /// If default navigation content is clicked, it calls navigator pop operation.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected View DefaultNavigationContent
+        {
+            get
+            {
+                //TODO: Do not set default navigation content if there is no previous page.
+                return defaultNavigationContent;
+            }
+        }
+
+        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),
+            };
+
+            backButton.Clicked += (object sender, ClickedEventArgs args) =>
+            {
+                //The page of app bar is popped when default back button is clicked.
+                var page = GetParent() as Page;
+                if (page != null)
+                {
+                    var navigator = page.GetParent() as Navigator;
+                    if (navigator != null)
+                    {
+                        navigator.Pop();
+                    }
+                }
+            };
+
+            return backButton;
+        }
+
+        private void ResetContent()
+        {
+            //To keep the order of NavigationContent, TitleContent and ActionContent,
+            //the existing contents are removed and added again.
+            if ((appBarNavigation != null) && Children.Contains(appBarNavigation))
+            {
+                Remove(appBarNavigation);
+            }
+            else if ((DefaultNavigationContent != null) && Children.Contains(DefaultNavigationContent))
+            {
+                Remove(DefaultNavigationContent);
+            }
+
+            if ((appBarTitle != null) && Children.Contains(appBarTitle))
+            {
+                Remove(appBarTitle);
+            }
+
+            if ((appBarAction != null) && Children.Contains(appBarAction))
+            {
+                Remove(appBarAction);
+            }
+
+            if (appBarNavigation != null)
+            {
+                Add(appBarNavigation);
+            }
+            else if ((AutoNavigationContent == true) && (DefaultNavigationContent != null))
+            {
+                Add(DefaultNavigationContent);
+            }
+
+            if (appBarTitle != null)
+            {
+                Add(appBarTitle);
+            }
+
+            if (appBarAction != null)
+            {
+                Add(appBarAction);
+            }
+        }
+    }
+}
index 305a87c..298087e 100755 (executable)
@@ -45,6 +45,7 @@ namespace Tizen.NUI.Components
     [EditorBrowsable(EditorBrowsableState.Never)]
     public class Page : Control
     {
+        private AppBar _appBar = null;
         private View _content = null;
 
         /// <summary>
@@ -52,12 +53,32 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <param name="content">The content to set to Content of Page.</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public Page(View content = null) : base()
+        public Page(View content = null) : this(null, content)
         {
+        }
+
+        /// <summary>
+        /// Creates a new instance of a Page.
+        /// </summary>
+        /// <param name="appBar">The content to set to AppBar of Page.</param>
+        /// <param name="content">The content to set to Content of Page.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Page(AppBar appBar, View content = null) : base()
+        {
+            //AppBar and Content are located verically.
+            var linearLayout = new LinearLayout();
+            linearLayout.LinearOrientation = LinearLayout.Orientation.Vertical;
+            Layout = linearLayout;
+
             //Page fills to parent by default.
             WidthResizePolicy = ResizePolicyType.FillToParent;
             HeightResizePolicy = ResizePolicyType.FillToParent;
 
+            if (appBar)
+            {
+                AppBar = appBar;
+            }
+
             if (content)
             {
                 Content = content;
@@ -65,6 +86,68 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
+        /// Dispose Page 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 (_appBar != null)
+                {
+                    Utility.Dispose(_appBar);
+                }
+
+                if (_content != null)
+                {
+                    Utility.Dispose(_content);
+                }
+            }
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
+        /// AppBar of Page. AppBar is added to Children automatically.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public AppBar AppBar
+        {
+            get
+            {
+                return _appBar;
+            }
+            set
+            {
+                if (_appBar == value)
+                {
+                    return;
+                }
+
+                if (_appBar != null)
+                {
+                    Remove(_appBar);
+                }
+
+                _appBar = value;
+                if (_appBar == null)
+                {
+                    return;
+                }
+
+                _appBar.Weight = 0.0f;
+
+                ResetContent();
+            }
+        }
+
+        /// <summary>
         /// Content of Page. Content is added to Children automatically.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
@@ -76,20 +159,50 @@ namespace Tizen.NUI.Components
             }
             set
             {
-                if (_content)
+                if (_content == value)
                 {
-                    if (_content != value)
-                    {
-                        Remove(_content);
-                        _content = value;
-                        Add(value);
-                    }
+                    return;
                 }
-                else
+
+                if (_content != null)
                 {
-                    _content = value;
-                    Add(value);
+                    Remove(_content);
                 }
+
+                _content = value;
+                if (_content == null)
+                {
+                    return;
+                }
+
+                _content.Weight = 1.0f;
+
+                ResetContent();
+            }
+        }
+
+        private void ResetContent()
+        {
+            //To keep the order of AppBar and Content, the existing contents are
+            //removed and added again.
+            if ((_appBar != null) && Children.Contains(_appBar))
+            {
+                Remove(_appBar);
+            }
+
+            if ((_content != null) && Children.Contains(_content))
+            {
+                Remove(_content);
+            }
+
+            if (_appBar != null)
+            {
+                Add(_appBar);
+            }
+
+            if (_content != null)
+            {
+                Add(_content);
             }
         }
 
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AppBarSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AppBarSample.cs
new file mode 100755 (executable)
index 0000000..7298042
--- /dev/null
@@ -0,0 +1,98 @@
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace Tizen.NUI.Samples
+{
+    public class AppBarSample : IExample
+    {
+        private Page firstPage, secondPage;
+        private AppBar firstAppBar, secondAppBar;
+        private Button firstActionButton, secondActionButton;
+        private Button firstButton, secondButton;
+
+        public void Activate()
+        {
+            CreateFirstPage();
+        }
+
+        private void CreateFirstPage()
+        {
+            firstActionButton = new Button()
+            {
+                Text = "2",
+                Size = new Size(72.0f, 72.0f)
+            };
+            firstActionButton.Clicked += (object sender, ClickedEventArgs e) =>
+            {
+                CreateSecondPage();
+            };
+
+            firstAppBar = new AppBar("First Page", firstActionButton)
+            {
+                AutoNavigationContent = false
+            };
+
+            firstButton = new Button()
+            {
+                Text = "Click to next",
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+            };
+            firstButton.Clicked += (object sender, ClickedEventArgs e) =>
+            {
+                CreateSecondPage();
+            };
+
+            firstPage = new Page(firstAppBar, firstButton);
+
+            NUIApplication.GetDefaultWindow().GetDefaultNavigator().Push(firstPage);
+        }
+
+        private void CreateSecondPage()
+        {
+            secondActionButton = new Button()
+            {
+                Text = "1",
+                Size = new Size(72.0f, 72.0f)
+            };
+            secondActionButton.Clicked += (object sender, ClickedEventArgs e) =>
+            {
+                NUIApplication.GetDefaultWindow().GetDefaultNavigator().Pop();
+            };
+
+            secondAppBar = new AppBar("Second Page", secondActionButton);
+
+            secondButton = new Button()
+            {
+                Text = "Click to prev",
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+            };
+            secondButton.Clicked += (object sender, ClickedEventArgs e) =>
+            {
+                NUIApplication.GetDefaultWindow().GetDefaultNavigator().Pop();
+            };
+
+            secondPage = new Page(secondAppBar, secondButton);
+
+            NUIApplication.GetDefaultWindow().GetDefaultNavigator().Push(secondPage);
+        }
+
+        public void Deactivate()
+        {
+            NUIApplication.GetDefaultWindow().GetDefaultNavigator().Remove(secondPage);
+
+            secondPage = null;
+            secondAppBar = null;
+            secondActionButton = null;
+            secondButton = null;
+
+            NUIApplication.GetDefaultWindow().GetDefaultNavigator().Remove(firstPage);
+
+            firstPage = null;
+            firstAppBar = null;
+            firstActionButton = null;
+            firstButton = null;
+        }
+    }
+}