using System.Collections.Generic; using System.ComponentModel; using System.Linq; using ElmSharp; using EToolbarItem = ElmSharp.ToolbarItem; using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; using EColor = ElmSharp.Color; using Xamarin.Forms.PlatformConfiguration.TizenSpecific; namespace Xamarin.Forms.Platform.Tizen { public class TabbedPageRenderer : VisualElementRenderer, IVisualElementRenderer { Box _box; Toolbar _toolbar; EvasObject _content; Dictionary _itemToItemPage = new Dictionary(); public TabbedPageRenderer() { //Register for title change property RegisterPropertyHandler(TabbedPage.TitleProperty, UpdateTitle); //Register for current page change property RegisterPropertyHandler("CurrentPage", CurrentPageChanged); //TODO renderer should add item on EFL toolbar when new Page is added to TabbedPage RegisterPropertyHandler(TabbedPage.BarBackgroundColorProperty, UpdateBarBackgroundColor); } protected override void OnElementChanged(ElementChangedEventArgs e) { if (_toolbar == null) { //Create box that holds toolbar and selected content _box = new Box(Forms.Context.MainWindow) { AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1, IsHorizontal = false, }; _box.Show(); //Create toolbar that is placed inside the _box _toolbar = new Toolbar(Forms.Context.MainWindow) { AlignmentX = -1, WeightX = 1, SelectionMode = ToolbarSelectionMode.Always, }; if (Device.Idiom == TargetIdiom.Phone) { //Set ShrinkMode to Expand as default only for Mobile profile _toolbar.ShrinkMode = ToolbarShrinkMode.Expand; } else if (Device.Idiom == TargetIdiom.TV) { //According to TV UX Guideleine, toolbar style should be set to "tabbar_with_title" in case of TabbedPage _toolbar.Style = "tabbar_with_title"; } _toolbar.Show(); //Add callback for item selection _toolbar.Selected += OnCurrentPageChanged; _box.PackEnd(_toolbar); SetNativeControl(_box); UpdateTitle(); } base.OnElementChanged(e); } protected override void Dispose(bool disposing) { if (_box != null) { _box.Unrealize(); _box = null; } if (_toolbar != null) { _toolbar.Selected -= OnCurrentPageChanged; _toolbar.Unrealize(); _toolbar = null; } base.Dispose(disposing); } protected override void OnElementReady() { FillToolbar(); base.OnElementReady(); } protected override void UpdateThemeStyle() { var style = Element.OnThisPlatform().GetStyle(); if (!string.IsNullOrEmpty(style)) { _toolbar.Style = style; ((IVisualElementController)Element).NativeSizeChanged(); } } void UpdateBarBackgroundColor() { EColor bgColor = Element.BarBackgroundColor.ToNative(); _toolbar.BackgroundColor = bgColor; foreach (EToolbarItem item in _itemToItemPage.Keys) { if (Element.BarBackgroundColor == Color.Default) { item.DeletePartColor("bg"); } else { item.SetPartColor("bg", bgColor); } } } void UpdateTitle() { _toolbar.Text = Element.Title; } void UpdateTitle(Page page) { if (_itemToItemPage.ContainsValue(page)) { var pair = _itemToItemPage.FirstOrDefault(x => x.Value == page); pair.Key.SetPartText(null, pair.Value.Title); } } void OnPageTitleChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == Page.TitleProperty.PropertyName) { UpdateTitle(sender as Page); } } void FillToolbar() { var logicalChildren = (Element as IElementController).LogicalChildren; //add items to toolbar foreach (Page child in logicalChildren) { var childRenderer = Platform.GetRenderer(child); if (childRenderer != null) { childRenderer.NativeView.Hide(); } EToolbarItem toolbarItem = _toolbar.Append(child.Title, string.IsNullOrEmpty(child.Icon) ? null : ResourcePath.GetPath(child.Icon)); if (Element.BarBackgroundColor != Color.Default) { toolbarItem.SetPartColor("bg", _toolbar.BackgroundColor); } _itemToItemPage.Add(toolbarItem, child); if (Element.CurrentPage == child) { //select item on the toolbar and fill content toolbarItem.IsSelected = true; CreateNewPage(); } child.PropertyChanged += OnPageTitleChanged; } } void OnCurrentPageChanged(object sender, EToolbarItemEventArgs e) { if (_toolbar.SelectedItem == null) return; var selectedContent = Platform.GetRenderer(_itemToItemPage[e.Item]).NativeView; if (selectedContent == _content) return; //detach content from view without EvasObject changes if (_content != null) { //hide content that should not be visible _content.Hide(); //unpack content that is hiden an prepare for new content _box.UnPack(_content); Element.CurrentPage?.SendDisappearing(); } Element.CurrentPage = _itemToItemPage[_toolbar.SelectedItem]; CreateNewPage(); } void CreateNewPage() { //create EvasObject using renderer and remember to not destroy //it for better performance (create once) _content = Platform.GetOrCreateRenderer(Element.CurrentPage).NativeView; _content.SetAlignment(-1, -1); _content.SetWeight(1, 1); _content.Show(); _box.PackEnd(_content); Element.CurrentPage?.SendAppearing(); } void CurrentPageChanged() { foreach (KeyValuePair pair in _itemToItemPage) { if (pair.Value == Element.CurrentPage) { pair.Key.IsSelected = true; return; } } } } }