Add NavigationPage.HasBreadCrumbsBar Property
authorWonYoung Choi <wy80.choi@samsung.com>
Tue, 14 Feb 2017 05:59:13 +0000 (14:59 +0900)
committerKangho Hur <kangho.hur@samsung.com>
Mon, 10 Jul 2017 02:11:19 +0000 (11:11 +0900)
- RFC 19

Change-Id: I4db6c6b0615fb0b876f2ae56e123943077bcc463

Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/NavigationPage.cs [new file with mode: 0644]
Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/Page.cs [new file with mode: 0644]
Xamarin.Forms.Core/Xamarin.Forms.Core.csproj
Xamarin.Forms.Platform.Tizen/Extensions/PlatformConfigurationExtensions.cs [new file with mode: 0644]
Xamarin.Forms.Platform.Tizen/Renderers/NavigationPageRenderer.cs
Xamarin.Forms.Platform.Tizen/Xamarin.Forms.Platform.Tizen.csproj

diff --git a/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/NavigationPage.cs b/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/NavigationPage.cs
new file mode 100644 (file)
index 0000000..3522239
--- /dev/null
@@ -0,0 +1,33 @@
+namespace Xamarin.Forms.PlatformConfiguration.TizenSpecific
+{
+       using FormsElement = Forms.NavigationPage;
+
+       public static class NavigationPage
+       {
+               #region HasBreadCrumbsBar
+               public static readonly BindableProperty HasBreadCrumbsBarProperty
+                       = BindableProperty.CreateAttached("HasBreadCrumbsBar", typeof(bool), typeof(FormsElement), false);
+
+               public static bool GetHasBreadCrumbsBar(BindableObject element)
+               {
+                       return (bool)element.GetValue(HasBreadCrumbsBarProperty);
+               }
+
+               public static void SetHasBreadCrumbsBar(BindableObject element, bool value)
+               {
+                       element.SetValue(HasBreadCrumbsBarProperty, value);
+               }
+
+               public static bool HasBreadCrumbsBar(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+               {
+                       return GetHasBreadCrumbsBar(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetHasBreadCrumbsBar(this IPlatformElementConfiguration<Tizen, FormsElement> config, bool value)
+               {
+                       SetHasBreadCrumbsBar(config.Element, value);
+                       return config;
+               }
+               #endregion
+       }
+}
diff --git a/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/Page.cs b/Xamarin.Forms.Core/PlatformConfiguration/TizenSpecific/Page.cs
new file mode 100644 (file)
index 0000000..876bcd1
--- /dev/null
@@ -0,0 +1,33 @@
+namespace Xamarin.Forms.PlatformConfiguration.TizenSpecific
+{
+       using FormsElement = Forms.Page;
+
+       public static class Page
+       {
+               #region BreadCrumbName
+               public static readonly BindableProperty BreadCrumbProperty
+                       = BindableProperty.CreateAttached("BreadCrumb", typeof(string), typeof(FormsElement), default(string));
+
+               public static string GetBreadCrumb(BindableObject page)
+               {
+                       return (string)page.GetValue(BreadCrumbProperty);
+               }
+
+               public static void SetBreadCrumb(BindableObject page, string value)
+               {
+                       page.SetValue(BreadCrumbProperty, value);
+               }
+
+               public static string GetBreadCrumb(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+               {
+                       return GetBreadCrumb(config.Element);
+               }
+
+               public static IPlatformElementConfiguration<Tizen, FormsElement> SetBreadCrumb(this IPlatformElementConfiguration<Tizen, FormsElement> config, string value)
+               {
+                       SetBreadCrumb(config.Element, value);
+                       return config;
+               }
+               #endregion
+       }
+}
index ca43560..65e6871 100644 (file)
     <Compile Include="PlatformConfiguration\iOSSpecific\VisualElement.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\StyleValues.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\VisualElement.cs" />
+    <Compile Include="PlatformConfiguration\TizenSpecific\Page.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\Entry.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\Label.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\Image.cs" />
+    <Compile Include="PlatformConfiguration\TizenSpecific\NavigationPage.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\ProgressBar.cs" />
     <Compile Include="PlatformConfiguration\TizenSpecific\FontWeight.cs" />
     <Compile Include="PlatformConfiguration\WindowsSpecific\MasterDetailPage.cs" />
diff --git a/Xamarin.Forms.Platform.Tizen/Extensions/PlatformConfigurationExtensions.cs b/Xamarin.Forms.Platform.Tizen/Extensions/PlatformConfigurationExtensions.cs
new file mode 100644 (file)
index 0000000..5f60d86
--- /dev/null
@@ -0,0 +1,13 @@
+using CurrentPlatform = Xamarin.Forms.PlatformConfiguration.Tizen;
+
+namespace Xamarin.Forms.Platform.Tizen
+{
+       public static class PlatformConfigurationExtensions
+       {
+               public static IPlatformElementConfiguration<CurrentPlatform, T> OnThisPlatform<T>(this T element)
+                       where T : Element, IElementConfiguration<T>
+               {
+                       return (element).On<CurrentPlatform>();
+               }
+       }
+}
index c386d48..4953b6b 100644 (file)
@@ -3,25 +3,37 @@ using System.Linq;
 using System.Threading.Tasks;
 using System.Collections.Generic;
 using Xamarin.Forms.Internals;
+using Xamarin.Forms.PlatformConfiguration.TizenSpecific;
 using ElmSharp;
 using EButton = ElmSharp.Button;
+using EToolbar = ElmSharp.Toolbar;
+using EToolbarItem = ElmSharp.ToolbarItem;
 
 namespace Xamarin.Forms.Platform.Tizen
 {
        public class NavigationPageRenderer : VisualElementRenderer<NavigationPage>, IDisposable, IVisualElementRenderer
        {
+               enum ToolbarButtonPosition
+               {
+                       Left,
+                       Right
+               };
+
+               const string PartTitle = "default";
+               const string PartBackButton = "elm.swallow.prev_btn";
+               const string PartLeftToolbar = "title_left_btn";
+               const string PartRightToolbar = "title_right_btn";
+               const string PartNavigationBar = "navigationbar";
+               const string StyleLeftToolBarButton = "naviframe/title_left";
+               const string StyleRightToolbarButton = "naviframe/title_right";
+               const string StyleBackButton = "naviframe/back_btn/default";
+               const string StyleDefaultToolbarIcon = "naviframe/drawers";
+               const string StyleNavigationBar = "navigationbar";
+
+               readonly List<Widget> _naviItemContentPartList = new List<Widget>();
                Naviframe _naviFrame = null;
                Page _previousPage = null;
                TaskCompletionSource<bool> _currentTaskSource = null;
-               const string _partBackButton = "elm.swallow.prev_btn";
-               const string _leftToolbar = "title_left_btn";
-               const string _rightToolbar = "title_right_btn";
-               const string _leftToolBarButtonStyle = "naviframe/title_left";
-               const string _rightToolbarButtonStyle = "naviframe/title_right";
-               const string _defaultToolbarIcon = "naviframe/drawers";
-               const string _partTitle = "default";
-               const string _styleBackButton = "naviframe/back_btn/default";
-               readonly List<Widget> _naviItemContentPartList = new List<Widget>();
                ToolbarTracker _toolbarTracker = null;
 
                Page CurrentPage => Element.CurrentPage;
@@ -115,6 +127,8 @@ namespace Xamarin.Forms.Platform.Tizen
                        // Tizen does not support 'Tint', but only 'BarBackgroundColor'
                        else if (e.PropertyName == NavigationPage.BarBackgroundColorProperty.PropertyName)
                                UpdateBarBackgroundColor(CurrentNaviItem);
+                       else if (e.PropertyName == PlatformConfiguration.TizenSpecific.NavigationPage.HasBreadCrumbsBarProperty.PropertyName)
+                               UpdateBreadCrumbsBar(CurrentNaviItem);
                }
 
                void PageCollectionChangedHandler(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
@@ -142,6 +156,8 @@ namespace Xamarin.Forms.Platform.Tizen
                                UpdateHasBackButton(sender as Page);
                        else if (e.PropertyName == Page.TitleProperty.PropertyName)
                                UpdateTitle(sender as Page);
+                       else if (e.PropertyName == PlatformConfiguration.TizenSpecific.Page.BreadCrumbProperty.PropertyName)
+                               UpdateBreadCrumbsBar(GetNaviItemForPage(sender as Page));
                }
 
                void UpdateHasNavigationBar(Page page)
@@ -150,6 +166,7 @@ namespace Xamarin.Forms.Platform.Tizen
                        item.TitleBarVisible = (bool)page.GetValue(NavigationPage.HasNavigationBarProperty);
                        UpdateToolbarItem(page, item);
                        UpdateBarBackgroundColor(item);
+                       UpdateBreadCrumbsBar(item);
                }
 
                void UpdateToolbarItem(Page page, NaviItem item = null)
@@ -160,17 +177,17 @@ namespace Xamarin.Forms.Platform.Tizen
                        if (_naviFrame.NavigationStack.Count == 0 || item == null || item != _naviFrame.NavigationStack.Last())
                                return;
 
-                       item.SetPartContent(_leftToolbar, null, false);
-                       item.SetPartContent(_rightToolbar, null, false);
+                       item.SetPartContent(PartLeftToolbar, null, false);
+                       item.SetPartContent(PartRightToolbar, null, false);
 
-                       Native.Button rightButton = GetToolbarButtonIfExists(ToolbarItemOrder.Primary);
-                       item.SetPartContent(_rightToolbar, rightButton);
+                       Native.Button rightButton = GetToolbarButton(ToolbarButtonPosition.Right);
+                       item.SetPartContent(PartRightToolbar, rightButton);
 
-                       Native.Button leftButton = GetToolbarButtonIfExists(ToolbarItemOrder.Secondary);
+                       Native.Button leftButton = GetToolbarButton(ToolbarButtonPosition.Left);
                        if (leftButton == null)
                                UpdateHasBackButton(page, item);
                        else
-                               item.SetPartContent(_leftToolbar, leftButton);
+                               item.SetPartContent(PartLeftToolbar, leftButton);
                }
 
                void UpdateHasBackButton(Page page, NaviItem item = null)
@@ -182,7 +199,7 @@ namespace Xamarin.Forms.Platform.Tizen
 
                        if ((bool)page.GetValue(NavigationPage.HasBackButtonProperty))
                                button = CreateNavigationButton((string)page.GetValue(NavigationPage.BackButtonTitleProperty));
-                       item.SetPartContent(_partBackButton, button);
+                       item.SetPartContent(PartBackButton, button);
                }
 
                void UpdateTitle(Page page, NaviItem item = null)
@@ -190,7 +207,7 @@ namespace Xamarin.Forms.Platform.Tizen
                        if (item == null)
                                item = GetNaviItemForPage(page);
 
-                       item.SetPartText(_partTitle, SpanTitle(page.Title));
+                       item.SetPartText(PartTitle, SpanTitle(page.Title));
                }
 
                string SpanTitle(string Title)
@@ -218,6 +235,19 @@ namespace Xamarin.Forms.Platform.Tizen
                        UpdateBarBackgroundColor(item);
                }
 
+               void UpdateBreadCrumbsBar(NaviItem item)
+               {
+                       if (Element.OnThisPlatform().HasBreadCrumbsBar())
+                       {
+                               item.Style = StyleNavigationBar;
+                               item.SetPartContent(PartNavigationBar, GetBreadCrumbsBar());
+                       }
+                       else
+                       {
+                               item.SetPartContent(PartNavigationBar, null, false);
+                       }
+               }
+
                EButton CreateNavigationButton(string text)
                {
                        EButton button = new EButton(Forms.Context.MainWindow);
@@ -227,7 +257,7 @@ namespace Xamarin.Forms.Platform.Tizen
                                        Forms.Context.Exit();
                        };
 
-                       button.Style = _styleBackButton;
+                       button.Style = StyleBackButton;
                        button.Text = text;
 
                        _naviItemContentPartList.Add(button);
@@ -263,23 +293,16 @@ namespace Xamarin.Forms.Platform.Tizen
                        return item;
                }
 
-               Native.Button GetToolbarButtonIfExists(ToolbarItemOrder order)
+               Native.Button GetToolbarButton(ToolbarButtonPosition position)
                {
                        ToolbarItem item = _toolbarTracker.ToolbarItems.Where(
-                               (i => i.Order == order ||
-                               (order == ToolbarItemOrder.Primary && i.Order == ToolbarItemOrder.Default)))
-                               .OrderBy(i => i.Priority)
-                               .FirstOrDefault();
+                               i => (position == ToolbarButtonPosition.Right && i.Order <= ToolbarItemOrder.Primary)
+                               || (position == ToolbarButtonPosition.Left && i.Order == ToolbarItemOrder.Secondary))
+                               .OrderBy(i => i.Priority).FirstOrDefault();
 
-                       if (item != default(ToolbarItem))
-                       {
-                               return GetToolbarButton(item);
-                       }
-                       return null;
-               }
+                       if (item == default(ToolbarItem))
+                               return null;
 
-               Native.Button GetToolbarButton(ToolbarItem item)
-               {
                        Native.Button button = new Native.Button(Forms.Context.MainWindow);
                        button.Clicked += (s, e) =>
                        {
@@ -294,19 +317,14 @@ namespace Xamarin.Forms.Platform.Tizen
                                if (string.IsNullOrEmpty(item.Text))
                                {
                                        // We assumed the default toolbar icon is "naviframe/drawer" if there are no icon and text.
-                                       button.Style = _defaultToolbarIcon;
+                                       button.Style = StyleDefaultToolbarIcon;
                                }
                                else
                                {
-                                       if (item.Order == ToolbarItemOrder.Secondary)
-                                       {
-                                               button.Style = _leftToolBarButtonStyle;
-                                       }
+                                       if (position == ToolbarButtonPosition.Right)
+                                               button.Style = StyleRightToolbarButton;
                                        else
-                                       {
-                                               // We assumed both primary or default order as right toolbar button
-                                               button.Style = _rightToolbarButtonStyle;
-                                       }
+                                               button.Style = StyleLeftToolBarButton;
                                }
                        }
                        else
@@ -319,6 +337,39 @@ namespace Xamarin.Forms.Platform.Tizen
                        return button;
                }
 
+               EToolbar GetBreadCrumbsBar()
+               {
+                       EToolbar toolbar = new EToolbar(Forms.Context.MainWindow)
+                       {
+                               Style = StyleNavigationBar,
+                               ItemAlignment = 0,
+                               Homogeneous = false,
+                               ShrinkMode = ToolbarShrinkMode.Scroll
+                       };
+
+                       foreach (var p in Element.Navigation.NavigationStack)
+                       {
+                               string breadCrumb = p.OnThisPlatform().GetBreadCrumb();
+                               if (!string.IsNullOrEmpty(breadCrumb))
+                               {
+                                       EToolbarItem toolbarItem = toolbar.Append(breadCrumb);
+                                       toolbarItem.Selected += (s, e) =>
+                                       {
+                                               var copyOfStack = Element.Navigation.NavigationStack.Reverse().Skip(1);
+                                               foreach (var lp in copyOfStack)
+                                               {
+                                                       if (lp == p) break;
+                                                       Element.Navigation.RemovePage(lp);
+                                               }
+                                               if (Element.Navigation.NavigationStack.Last() != p)
+                                                       Element.Navigation.PopAsync();
+                                       };
+                               }
+                       }
+
+                       return toolbar;
+               }
+
                void PopRequestedHandler(object sender, NavigationRequestedEventArgs nre)
                {
                        if ((Element as IPageController).InternalChildren.Count == _naviFrame.NavigationStack.Count)
index 6f8a65c..0096bc4 100644 (file)
@@ -48,6 +48,7 @@
     <Compile Include="ExportImageSourceHandlerAttribute.cs" />
     <Compile Include="ExportCellAttribute.cs" />
     <Compile Include="ExportRendererAttribute.cs" />
+    <Compile Include="Extensions\PlatformConfigurationExtensions.cs" />
     <Compile Include="Extensions\ColorExtensions.cs" />
     <Compile Include="Extensions\KeyboardExtensions.cs" />
     <Compile Include="Extensions\LayoutExtensions.cs" />