From f5e219a253a5ff4f127794931791c57a04293b23 Mon Sep 17 00:00:00 2001 From: Jaehyun Cho <29364140+jaehyun0cho@users.noreply.github.com> Date: Tue, 5 Jan 2021 17:44:50 +0900 Subject: [PATCH] [NUI] Add AppBar class (#2435) AppBar shows title text and provides navigation and action functions on Page. Co-authored-by: Jaehyun Cho --- .../Controls/Navigation/AppBar.cs | 433 +++++++++++++++++++++ .../Controls/Navigation/Page.cs | 135 ++++++- .../Tizen.NUI.Samples/Samples/AppBarSample.cs | 98 +++++ 3 files changed, 655 insertions(+), 11 deletions(-) create mode 100755 src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs create mode 100755 test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AppBarSample.cs diff --git a/src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs b/src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs new file mode 100755 index 0000000..5014dbb --- /dev/null +++ b/src/Tizen.NUI.Components/Controls/Navigation/AppBar.cs @@ -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 +{ + /// + /// The AppBar class is a class which shows title text and provides navigation + /// and action functions on Page. + /// + [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; + + /// + /// Creates a new instance of a AppBar. + /// + [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); + } + } + + /// + /// Creates a new instance of a AppBar. + /// + /// The content to set to NavigationContent of AppBar. + /// The content to set to TitleContent of AppBar. + /// The content to set to ActionContent of AppBar. + [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; + } + } + + /// + /// Creates a new instance of a AppBar. + /// + /// The text string to set to TitleContent of AppBar. + /// The contents to add to ActionContent of AppBar. + [EditorBrowsable(EditorBrowsableState.Never)] + public AppBar(string title, params View[] actionContents) : this(null, title, actionContents) + { + } + + /// + /// Creates a new instance of a AppBar. + /// + /// The content to set to NavigationContent of AppBar. + /// The text string to set to TitleContent of AppBar. + /// The contents to add to ActionContent of AppBar. + [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; + } + } + + /// + /// Disposes AppBar and all children on it. + /// + /// Dispose type. + [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); + } + + /// + /// 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. + /// + [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(); + } + } + + /// + /// Title content of AppBar. TitleContent is added to Children automatically. + /// + [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(); + } + } + + /// + /// Action content of AppBar. ActionContent is added to Children automatically. + /// + [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(); + } + } + + /// + /// 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. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public bool AutoNavigationContent + { + get + { + return autoNavigationContent; + } + + set + { + if (autoNavigationContent == value) + { + return; + } + + autoNavigationContent = value; + + ResetContent(); + } + } + + /// + /// 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. + /// + [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); + } + } + } +} diff --git a/src/Tizen.NUI.Components/Controls/Navigation/Page.cs b/src/Tizen.NUI.Components/Controls/Navigation/Page.cs index 305a87c..298087e 100755 --- a/src/Tizen.NUI.Components/Controls/Navigation/Page.cs +++ b/src/Tizen.NUI.Components/Controls/Navigation/Page.cs @@ -45,6 +45,7 @@ namespace Tizen.NUI.Components [EditorBrowsable(EditorBrowsableState.Never)] public class Page : Control { + private AppBar _appBar = null; private View _content = null; /// @@ -52,12 +53,32 @@ namespace Tizen.NUI.Components /// /// The content to set to Content of Page. [EditorBrowsable(EditorBrowsableState.Never)] - public Page(View content = null) : base() + public Page(View content = null) : this(null, content) { + } + + /// + /// Creates a new instance of a Page. + /// + /// The content to set to AppBar of Page. + /// The content to set to Content of Page. + [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 } /// + /// Dispose Page and all children on it. + /// + /// Dispose type. + [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); + } + + /// + /// AppBar of Page. AppBar is added to Children automatically. + /// + [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(); + } + } + + /// /// Content of Page. Content is added to Children automatically. /// [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 index 0000000..7298042 --- /dev/null +++ b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/AppBarSample.cs @@ -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; + } + } +} -- 2.7.4