using System.Collections.Generic; using System.ComponentModel; using System.Linq; using ElmSharp; using EToolbarItem = ElmSharp.ToolbarItem; using EToolbarItemEventArgs = ElmSharp.ToolbarItemEventArgs; using Xamarin.Forms.PlatformConfiguration.TizenSpecific; using Xamarin.Forms.Internals; namespace Xamarin.Forms.Platform.Tizen { public class TabbedPageRenderer : VisualElementRenderer, IVisualElementRenderer { Box _outterLayout; Box _innerBox; Scroller _scroller; Toolbar _toolbar; Dictionary _itemToItemPage = new Dictionary(); IReadOnlyCollection Pages => (Element as IElementController).LogicalChildren; public TabbedPageRenderer() { //Register for title change property RegisterPropertyHandler(TabbedPage.TitleProperty, UpdateTitle); //Register for current page change property RegisterPropertyHandler("CurrentPage", CurrentPageChanged); } protected override void OnElementChanged(ElementChangedEventArgs e) { if (_toolbar == null) { //Create box that holds toolbar and selected content _outterLayout = new Box(Forms.Context.MainWindow) { AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1, IsHorizontal = false, }; _outterLayout.Show(); //Create toolbar that is placed inside the _outterLayout _toolbar = new Toolbar(Forms.Context.MainWindow) { AlignmentX = -1, WeightX = 1, SelectionMode = ToolbarSelectionMode.Always, Style = "tabbar_with_title" }; _toolbar.Show(); //Add callback for Toolbar item selection _toolbar.Selected += OnToolbarItemSelected; _outterLayout.PackEnd(_toolbar); _scroller = new Scroller(_outterLayout) { AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1, HorizontalPageScrollLimit = 1, ScrollBlock = ScrollBlock.Vertical, HorizontalScrollBarVisiblePolicy = ScrollBarVisiblePolicy.Invisible }; _scroller.SetPageSize(1.0, 1.0); _scroller.PageScrolled += OnItemPageScrolled; _scroller.Resized += OnScrollerResized; _innerBox = new Box(Forms.Context.MainWindow) { AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1, IsHorizontal = true, }; _scroller.SetContent(_innerBox); _scroller.Show(); _outterLayout.PackEnd(_scroller); SetNativeControl(_outterLayout); UpdateTitle(); } base.OnElementChanged(e); } void OnScrollerResized(object sender, System.EventArgs e) { foreach (var item in _itemToItemPage) { var nativeView = Platform.GetRenderer(item.Value).NativeView; nativeView.MinimumWidth = _scroller.Geometry.Width; nativeView.MinimumHeight = _scroller.Geometry.Height; } int index = Pages.IndexOf(_itemToItemPage[_toolbar.SelectedItem]); _scroller.ScrollTo(index, 0, true); } void OnItemPageScrolled(object sender, System.EventArgs e) { Page newPage = Element.GetPageByIndex(_scroller.HorizontalPageIndex); foreach (var pair in _itemToItemPage) { if (pair.Value == newPage) { pair.Key.IsSelected = true; return; } } } protected override void Dispose(bool disposing) { if (_outterLayout != null) { _outterLayout.Unrealize(); _outterLayout = null; } if (_toolbar != null) { _toolbar.Selected -= OnToolbarItemSelected; _scroller.PageScrolled -= OnItemPageScrolled; _toolbar.Unrealize(); _toolbar = null; } base.Dispose(disposing); } protected override void OnElementReady() { FillToolbarAndContents(); base.OnElementReady(); } protected override void UpdateThemeStyle() { var style = Element.OnThisPlatform().GetStyle(); if (!string.IsNullOrEmpty(style)) { _toolbar.Style = style; ((IVisualElementController)Element).NativeSizeChanged(); } } 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 FillToolbarAndContents() { //add items to toolbar foreach (Page child in Pages) { EToolbarItem toolbarItem = _toolbar.Append(child.Title, string.IsNullOrEmpty(child.Icon) ? null : ResourcePath.GetPath(child.Icon)); _itemToItemPage.Add(toolbarItem, child); var childContent = Platform.GetOrCreateRenderer(child).NativeView; _innerBox.PackEnd(childContent); if (Element.CurrentPage == child) { //select item on the toolbar and fill content toolbarItem.IsSelected = true; } child.PropertyChanged += OnPageTitleChanged; } } void OnToolbarItemSelected(object sender, EToolbarItemEventArgs e) { if (_toolbar.SelectedItem == null) return; var oldPage = Element.CurrentPage; var newPage = _itemToItemPage[_toolbar.SelectedItem]; if (oldPage == newPage) return; oldPage?.SendDisappearing(); Element.CurrentPage = newPage; newPage?.SendAppearing(); int index = MultiPage.GetIndex(newPage); _scroller.ScrollTo(index, 0, true); } void CurrentPageChanged() { foreach (var pair in _itemToItemPage) { if (pair.Value == Element.CurrentPage) { pair.Key.IsSelected = true; return; } } } } }