diff options
-rwxr-xr-x | Xamarin.Forms.Platform.Tizen/Native/ListView.cs | 86 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.Tizen/Native/Window.cs | 106 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.Tizen/Platform.cs | 319 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.Tizen/Renderers/ListViewRenderer.cs | 2 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.Tizen/Renderers/TableViewRenderer.cs | 2 |
5 files changed, 207 insertions, 308 deletions
diff --git a/Xamarin.Forms.Platform.Tizen/Native/ListView.cs b/Xamarin.Forms.Platform.Tizen/Native/ListView.cs index c3146cfa..5b720d7d 100755 --- a/Xamarin.Forms.Platform.Tizen/Native/ListView.cs +++ b/Xamarin.Forms.Platform.Tizen/Native/ListView.cs @@ -128,48 +128,12 @@ namespace Xamarin.Forms.Platform.Tizen.Native } /// <summary> - /// Sets the size of the row. - /// </summary> - /// <param name="rowSize">Row size.</param> - public void SetRowSize(int rowSize) - { - foreach (var pair in _cellHandlers) - { - pair.Value.RowHeight = rowSize; - } - foreach (var pair in _groupCellHandlers) - { - pair.Value.RowHeight = rowSize; - } - - if (_headerElement != null) - { - _headerElement.MinimumHeightRequest = rowSize; - } - - if (_footerElement != null) - { - _footerElement.MinimumHeightRequest = rowSize; - } - - UpdateRealizedItems(); - } - - /// <summary> /// Sets the HasUnevenRows property. /// </summary> /// <param name="hasUnevenRows">If <c>true</c>, the list will allow uneven sizes for its rows.</param> public void SetHasUnevenRows(bool hasUnevenRows) { Homogeneous = !hasUnevenRows; - foreach (var pair in _cellHandlers) - { - pair.Value.HasUnevenRows = hasUnevenRows; - } - foreach (var pair in _groupCellHandlers) - { - pair.Value.HasUnevenRows = hasUnevenRows; - } UpdateRealizedItems(); } @@ -563,6 +527,7 @@ namespace Xamarin.Forms.Platform.Tizen.Native itemContext.Item.SelectionMode = GenListSelectionMode.Always; cell.PropertyChanged += OnCellPropertyChanged; + (cell as ICellController).ForceUpdateSizeRequested += OnForceUpdateSizeRequested; itemContext.Item.Deleted += ItemDeletedHandler; _itemContextList.Add(itemContext); } @@ -578,6 +543,7 @@ namespace Xamarin.Forms.Platform.Tizen.Native if (itemContext.Cell != null) { itemContext.Cell.PropertyChanged -= OnCellPropertyChanged; + (itemContext.Cell as ICellController).ForceUpdateSizeRequested -= OnForceUpdateSizeRequested; } _itemContextList.Remove(itemContext); } @@ -598,6 +564,14 @@ namespace Xamarin.Forms.Platform.Tizen.Native GetCellHandler(cell, context.IsGroupItem)?.HandlePropertyChanged(cell, context.Item, e.PropertyName); } + private void OnForceUpdateSizeRequested(object sender, EventArgs e) + { + var cell = sender as Cell; + var itemContext = GetItemContext(cell); + if (itemContext.Item != null) + itemContext.Item.Update(); + } + /// <summary> /// Gets the item class used for header and footer cells. /// </summary> @@ -652,16 +626,6 @@ namespace Xamarin.Forms.Platform.Tizen.Native } /// <summary> - /// The height of the row. - /// </summary> - public int RowHeight; - - /// <summary> - /// The flag indicating whether the cells may have non-uniform row heights. - /// </summary> - public bool HasUnevenRows; - - /// <summary> /// Initializes a new instance of the <see cref="Xamarin.Forms.Platform.Tizen.Native.ListView.CellHandler"/> class. /// </summary> /// <param name="style">A string specifying the style of a CellHandler.</param> @@ -674,9 +638,6 @@ namespace Xamarin.Forms.Platform.Tizen.Native GetContentHandler = (callType & CellCallType.Content) == CellCallType.Content ? OnGetContent : (GenItemClass.GetContentDelegate)null, DeleteHandler = OnDelete, }; - - RowHeight = -1; - HasUnevenRows = false; } /// <summary> @@ -760,25 +721,19 @@ namespace Xamarin.Forms.Platform.Tizen.Native /// <param name="cell">Cell whose row height is to be calculated.</param> protected int GetRowHeight(Cell cell) { - if (HasUnevenRows) + return cell.RenderHeight > 0 ? (int)cell.RenderHeight : FindCellContentHeight(cell); + } + + private int FindCellContentHeight(Cell cell) + { + if (cell is ViewCell) { - if (RowHeight > 0) - { - return RowHeight; - } - else if (RowHeight == -1) - { - return cell.Height > 0 ? (int)cell.Height : -1; - } - else - { - return -1; - } + var parentWidth = (cell.Parent as VisualElement).Width; + var view = (cell as ViewCell).View; + return (int)view.Measure(parentWidth, double.PositiveInfinity).Request.Height; } else - { - return RowHeight > 0 ? RowHeight : -1; - } + return -1; } /// <summary> @@ -880,7 +835,6 @@ namespace Xamarin.Forms.Platform.Tizen.Native var renderer = Platform.GetOrCreateRenderer(cell.View); renderer.NativeView.MinimumHeight = GetRowHeight(cell); - return renderer.NativeView; } return null; diff --git a/Xamarin.Forms.Platform.Tizen/Native/Window.cs b/Xamarin.Forms.Platform.Tizen/Native/Window.cs index aa43d892..87a54cd3 100644 --- a/Xamarin.Forms.Platform.Tizen/Native/Window.cs +++ b/Xamarin.Forms.Platform.Tizen/Native/Window.cs @@ -1,6 +1,4 @@ using System; -using System.Linq; -using System.Threading.Tasks; using ElmSharp; using EWindow = ElmSharp.Window; @@ -9,8 +7,6 @@ namespace Xamarin.Forms.Platform.Tizen.Native public class Window : EWindow { Conformant _conformant; - Naviframe _naviframe; - TaskCompletionSource<bool> _currentTaskSource = null; /// <summary> /// Initializes a new instance of the Window class. @@ -74,70 +70,12 @@ namespace Xamarin.Forms.Platform.Tizen.Native } /// <summary> - /// Sets the page to navigation stack. + /// Sets the main page of Window. /// </summary> - /// <param name="evasObject">ElmSharp.EvasObject type page to be set.</param> - public void SetPage(EvasObject evasObject) + /// <param name="content">ElmSharp.EvasObject type page to be set.</param> + public void SetMainPage(EvasObject content) { - NaviItem naviItem = null; - - if (_naviframe.NavigationStack.Count > 0) - _naviframe.NavigationStack[0].Delete(); - - if (_naviframe.NavigationStack.Count > 0) - naviItem = _naviframe.InsertBefore(_naviframe.NavigationStack[0], evasObject); - else - naviItem = _naviframe.Push(evasObject); - - naviItem.TitleBarVisible = false; - } - - /// <summary> - /// Pushes the modal page to the navigation stack asynchronously. - /// </summary> - /// <param name="evasObject">ElmSharp.EvasObject type modal page to be pushed.</param> - public async Task PushModalAsync(EvasObject evasObject, bool animated) - { - _currentTaskSource = new TaskCompletionSource<bool>(); - NaviItem naviItem = null; - if (animated) - { - naviItem = _naviframe.Push(evasObject); - if (_naviframe.NavigationStack.Count == 1) - { - CompleteCurrentNavigationTask(); - } - } - else - { - naviItem = _naviframe.InsertAfter(_naviframe.NavigationStack.Last(), evasObject); - CompleteCurrentNavigationTask(); - } - naviItem.TitleBarVisible = false; - if (CurrentPendingTask != null) - await CurrentPendingTask; - } - - /// <summary> - /// Pops the modal page from the navigation stack asynchronously. - /// </summary> - /// <param name="evasObject">ElmSharp.EvasObject type modal page to be popped.</param> - public async Task PopModalAsync(bool animated) - { - _currentTaskSource = new TaskCompletionSource<bool>(); - if (animated) - { - _naviframe.Pop(); - if (_naviframe.NavigationStack.Count == 0) - CompleteCurrentNavigationTask(); - } - else - { - _naviframe.NavigationStack.Last().Delete(); - CompleteCurrentNavigationTask(); - } - if (CurrentPendingTask != null) - await CurrentPendingTask; + _conformant.SetContent(content); } void Initialize() @@ -151,6 +89,10 @@ namespace Xamarin.Forms.Platform.Tizen.Native { Closed?.Invoke(this, EventArgs.Empty); }; + CloseRequested += (sender, e) => + { + Unrealize(); + }; KeyGrab(EvasKeyEventArgs.PlatformBackButtonName, false); KeyUp += (s, e) => @@ -161,9 +103,6 @@ namespace Xamarin.Forms.Platform.Tizen.Native } }; - // TODO: add background - - // show Active(); AutoDeletion = false; Show(); @@ -173,37 +112,8 @@ namespace Xamarin.Forms.Platform.Tizen.Native _conformant.SetWeight(1.0, 1.0); // expand _conformant.Show(); - _naviframe = new Naviframe(this); - _naviframe.PreserveContentOnPop = true; - _naviframe.DefaultBackButtonEnabled = true; - _naviframe.AnimationFinished += AnimationFinishedHandler; - _naviframe.SetAlignment(-1, -1); - _naviframe.SetWeight(1.0, 1.0); - _naviframe.Show(); - _conformant.SetContent(_naviframe, true); - AvailableOrientations = DisplayOrientations.Portrait | DisplayOrientations.Landscape | DisplayOrientations.PortraitFlipped | DisplayOrientations.LandscapeFlipped; } - - void AnimationFinishedHandler(object sender, EventArgs e) - { - CompleteCurrentNavigationTask(); - } - - Task CurrentPendingTask - { - get { return _currentTaskSource?.Task; } - } - - void CompleteCurrentNavigationTask() - { - if (_currentTaskSource != null) - { - var tmp = _currentTaskSource; - _currentTaskSource = null; - tmp.SetResult(true); - } - } DisplayOrientations GetDisplayOrientation() { switch (Rotation) diff --git a/Xamarin.Forms.Platform.Tizen/Platform.cs b/Xamarin.Forms.Platform.Tizen/Platform.cs index 3dea89b4..70e4e3c3 100644 --- a/Xamarin.Forms.Platform.Tizen/Platform.cs +++ b/Xamarin.Forms.Platform.Tizen/Platform.cs @@ -2,46 +2,72 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using ElmSharp; namespace Xamarin.Forms.Platform.Tizen { internal class Platform : BindableObject, IPlatform, INavigation, IDisposable { - public static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(IVisualElementRenderer), typeof(Platform), null, BindingMode.OneWay, null, delegate (BindableObject bindable, object oldvalue, object newvalue) - { - VisualElement visualElement = bindable as VisualElement; - if (visualElement != null) + internal static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(IVisualElementRenderer), typeof(Platform), default(IVisualElementRenderer), + propertyChanged: (bindable, oldvalue, newvalue) => { - visualElement.IsPlatformEnabled = (newvalue != null); - } - }, null, null, null); - - public static readonly BindableProperty PageContextProperty = BindableProperty.CreateAttached("PageContext", typeof(FormsApplication), typeof(Platform), null, BindingMode.OneWay, null, null, null, null, null); - - readonly List<Page> _modalStack; + var ve = bindable as VisualElement; + if (ve != null) + ve.IsPlatformEnabled = newvalue != null; + }); + internal static readonly BindableProperty PageContextProperty = BindableProperty.CreateAttached("PageContext", typeof(FormsApplication), typeof(Platform), null); + + Naviframe _naviframe; + NavigationModel _navModel = new NavigationModel(); bool _disposed; - public Page Page + internal Platform(FormsApplication context) { - get; - private set; + Forms.Context.MainWindow.BackButtonPressed += (o, e) => + { + bool handled = false; + if (_navModel.CurrentPage != null) + { + if (CurrentModalNavigationTask != null && !CurrentModalNavigationTask.IsCompleted) + { + handled = true; + } + else + { + handled = _navModel.CurrentPage.SendBackButtonPressed(); + } + } + if (!handled) + context.Exit(); + }; + _naviframe = new Naviframe(Forms.Context.MainWindow) + { + PreserveContentOnPop = true, + DefaultBackButtonEnabled = false, + }; + _naviframe.SetAlignment(-1, -1); + _naviframe.SetWeight(1.0, 1.0); + _naviframe.Show(); + _naviframe.AnimationFinished += NaviAnimationFinished; + Forms.Context.MainWindow.SetMainPage(_naviframe); } - public bool Supports3D + ~Platform() { - get - { - return true; - } + Dispose(false); } - public bool NavAnimationInProgress + public Page Page { get; - set; + private set; } Task CurrentModalNavigationTask { get; set; } + TaskCompletionSource<bool> CurrentTaskCompletionSource { get; set; } + IPageController CurrentPageController => _navModel.CurrentPage as IPageController; + IReadOnlyList<Page> INavigation.ModalStack => _navModel.Modals.ToList(); + IReadOnlyList<Page> INavigation.NavigationStack => new List<Page>(); public static FormsApplication GetPageContext(BindableObject bindable) { @@ -63,20 +89,6 @@ namespace Xamarin.Forms.Platform.Tizen bindable.SetValue(Platform.RendererProperty, value); } - static IVisualElementRenderer AttachRenderer(VisualElement view) - { - IVisualElementRenderer visualElementRenderer = Registrar.Registered.GetHandler<IVisualElementRenderer>(view.GetType()); - - if (null == visualElementRenderer) - { - throw new ArgumentException(String.Format("{0} doesn't have assigned renderer!", view.GetType())); - } - - visualElementRenderer.SetElement(view); - - return visualElementRenderer; - } - /// <summary> /// Gets the renderer associated with the <c>view</c>. If it doesn't exist, creates a new one. /// </summary> @@ -87,79 +99,45 @@ namespace Xamarin.Forms.Platform.Tizen return GetRenderer(view) ?? AttachRenderer(view); } - internal Platform(FormsApplication context) - { - _modalStack = new List<Page>(); - - Forms.Context.MainWindow.BackButtonPressed += (o, e) => - { - if (_modalStack.Count == 0 || !_modalStack.Last().SendBackButtonPressed()) - { - context.Exit(); - } - }; - } - - ~Platform() - { - Dispose(false); - } - public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } - protected virtual void Dispose(bool disposing) - { - if (_disposed) return; - if (disposing) - { - SetPage(null); - } - _disposed = true; - } - - bool HandleBackPressed(object sender, EventArgs e) - { - return false; - } - - public void SetPage(Page newRoot) { - if (newRoot == null || newRoot == Page) - { - return; - } - - IVisualElementRenderer oldPageRenderer = null; - if (Page != null) { - (Page as IPageController)?.SendDisappearing(); - _modalStack.Remove(Page); - oldPageRenderer = Platform.GetRenderer(Page); + var copyOfStack = new List<ElmSharp.NaviItem>(_naviframe.NavigationStack); + for (var i = 0; i < copyOfStack.Count; i++) + { + copyOfStack[i].Delete(); + } + foreach (Page page in _navModel.Roots) + { + var renderer = GetRenderer(page); + (page as IPageController)?.SendDisappearing(); + renderer?.Dispose(); + } + _navModel = new NavigationModel(); } - if (_modalStack.Count > 0) - _modalStack.Insert(0, newRoot); - else - _modalStack.Add(newRoot); + if (newRoot == null) + return; + + _navModel.Push(newRoot, null); Page = newRoot; Page.Platform = this; - ((Application)Page.RealParent).NavigationProxy.Inner = this; - Platform.SetPageContext(Page, Forms.Context); - IVisualElementRenderer visualElementRenderer = AttachRenderer(Page); - Forms.Context.MainWindow.SetPage(visualElementRenderer.NativeView); - // oldPageRenderer should be disposed after SetView - // because its NativeView is still used there - oldPageRenderer?.Dispose(); + Platform.SetPageContext(Page, Forms.Context); + IVisualElementRenderer pageRenderer = AttachRenderer(Page); + var naviItem = _naviframe.Push(pageRenderer.NativeView); + naviItem.TitleBarVisible = false; + ((Application)Page.RealParent).NavigationProxy.Inner = this; - (newRoot as IPageController)?.SendAppearing(); + CurrentPageController?.SendAppearing(); } public SizeRequest GetNativeSize(VisualElement view, double widthConstraint, double heightConstraint) @@ -173,25 +151,40 @@ namespace Xamarin.Forms.Platform.Tizen return GetRenderer(view).GetDesiredSize(width, height); } + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + if (disposing) + { + SetPage(null); + _naviframe.Unrealize(); + } + _disposed = true; + } + protected override void OnBindingContextChanged() { BindableObject.SetInheritedBindingContext(Page, base.BindingContext); base.OnBindingContextChanged(); } - void INavigation.InsertPageBefore(Page page, Page before) + static IVisualElementRenderer AttachRenderer(VisualElement view) { - throw new InvalidOperationException("InsertPageBefore is not supported globally on Tizen, please use a NavigationPage."); - } + IVisualElementRenderer visualElementRenderer = Registrar.Registered.GetHandler<IVisualElementRenderer>(view.GetType()); - IReadOnlyList<Page> INavigation.ModalStack - { - get { return _modalStack; } + if (null == visualElementRenderer) + { + throw new ArgumentException(String.Format("{0} doesn't have assigned renderer!", view.GetType())); + } + + visualElementRenderer.SetElement(view); + + return visualElementRenderer; } - IReadOnlyList<Page> INavigation.NavigationStack + void INavigation.InsertPageBefore(Page page, Page before) { - get { return new List<Page>(); } + throw new InvalidOperationException("InsertPageBefore is not supported globally on Tizen, please use a NavigationPage."); } Task<Page> INavigation.PopAsync() @@ -236,22 +229,17 @@ namespace Xamarin.Forms.Platform.Tizen async Task INavigation.PushModalAsync(Page modal, bool animated) { - if (CurrentModalNavigationTask != null && !CurrentModalNavigationTask.IsCompleted) - { - TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); - Task oldTask = CurrentModalNavigationTask; - CurrentModalNavigationTask = tcs.Task; - await oldTask; + CurrentPageController?.SendDisappearing(); - await Forms.Context.MainWindow.PushModalAsync(Platform.GetOrCreateRenderer(modal).NativeView, animated); - ModalPushInner(modal); - tcs.SetResult(true); - return; - } + _navModel.PushModal(modal); - CurrentModalNavigationTask = Forms.Context.MainWindow.PushModalAsync(Platform.GetOrCreateRenderer(modal).NativeView, animated); - ModalPushInner(modal); - await CurrentModalNavigationTask; + modal.Platform = this; + + await PushModalInternal(modal, animated); + + // Verify that the modal is still on the stack + if (_navModel.CurrentPage == modal) + CurrentPageController.SendAppearing(); } Task<Page> INavigation.PopModalAsync() @@ -261,50 +249,97 @@ namespace Xamarin.Forms.Platform.Tizen async Task<Page> INavigation.PopModalAsync(bool animated) { + Page modal = _navModel.PopModal(); + + ((IPageController)modal).SendDisappearing(); + + IVisualElementRenderer modalRenderer = GetRenderer(modal); + if (modalRenderer != null) + { + await PopModalInternal(animated); + } + Platform.GetRenderer(modal).Dispose(); + + CurrentPageController?.SendAppearing(); + return modal; + } + + async Task PushModalInternal(Page modal, bool animated) + { + TaskCompletionSource<bool> tcs = null; if (CurrentModalNavigationTask != null && !CurrentModalNavigationTask.IsCompleted) { - TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); - Task oldTask = CurrentModalNavigationTask; + var previousTask = CurrentModalNavigationTask; + tcs = new TaskCompletionSource<bool>(); CurrentModalNavigationTask = tcs.Task; - await oldTask; + await previousTask; + } - if (_modalStack.Count < 2) - { - tcs.SetResult(true); - return null; - } + var after = _naviframe.NavigationStack.LastOrDefault(); + NaviItem pushed = null; + if (animated || after == null) + { + pushed = _naviframe.Push(Platform.GetOrCreateRenderer(modal).NativeView, modal.Title); + } + else + { + pushed = _naviframe.InsertAfter(after, Platform.GetOrCreateRenderer(modal).NativeView, modal.Title); + } + pushed.TitleBarVisible = false; - await Forms.Context.MainWindow.PopModalAsync(animated); - tcs.SetResult(true); - return ModalPopInner(); + bool shouldWait = animated && after != null; + await WaitForCompletion(shouldWait, tcs); + } + + async Task PopModalInternal(bool animated) + { + TaskCompletionSource<bool> tcs = null; + if (CurrentModalNavigationTask != null && !CurrentModalNavigationTask.IsCompleted) + { + var previousTask = CurrentModalNavigationTask; + tcs = new TaskCompletionSource<bool>(); + CurrentModalNavigationTask = tcs.Task; + await previousTask; } - if (_modalStack.Count < 2) + + if (animated) + { + _naviframe.Pop(); + } + else { - return null; + _naviframe.NavigationStack.LastOrDefault()?.Delete(); } - Task result = Forms.Context.MainWindow.PopModalAsync(animated); - CurrentModalNavigationTask = result; - await result; - return ModalPopInner(); + bool shouldWait = animated && (_naviframe.NavigationStack.Count != 0); + await WaitForCompletion(shouldWait, tcs); } - void ModalPushInner(Page modal) + async Task WaitForCompletion(bool shouldWait, TaskCompletionSource<bool> tcs) { - (_modalStack.Last() as IPageController)?.SendDisappearing(); - _modalStack.Add(modal); - modal.Platform = this; - (modal as IPageController).SendAppearing(); + if (shouldWait) + { + tcs = tcs ?? new TaskCompletionSource<bool>(); + CurrentTaskCompletionSource = tcs; + if (CurrentModalNavigationTask == null || CurrentModalNavigationTask.IsCompleted) + { + CurrentModalNavigationTask = CurrentTaskCompletionSource.Task; + } + } + else + { + tcs?.SetResult(true); + } + + if (tcs != null) + await tcs.Task; } - Page ModalPopInner() + void NaviAnimationFinished(object sender, EventArgs e) { - Page popped = _modalStack.Last(); - (popped as IPageController).SendDisappearing(); - _modalStack.Remove(popped); - Platform.GetRenderer(popped).Dispose(); - (_modalStack.Last() as IPageController)?.SendAppearing(); - return popped; + var tcs = CurrentTaskCompletionSource; + CurrentTaskCompletionSource = null; + tcs?.SetResult(true); } } } diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/ListViewRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/ListViewRenderer.cs index c19a03d5..15a550d8 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/ListViewRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/ListViewRenderer.cs @@ -399,7 +399,7 @@ namespace Xamarin.Forms.Platform.Tizen /// </summary> void UpdateRowHeight() { - Control.SetRowSize(Element.RowHeight); + Control.UpdateRealizedItems(); } /// <summary> diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/TableViewRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/TableViewRenderer.cs index 43d3546f..59123549 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/TableViewRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/TableViewRenderer.cs @@ -72,7 +72,7 @@ namespace Xamarin.Forms.Platform.Tizen void UpdateRowHeight() { - Control.SetRowSize(Element.RowHeight); + Control.UpdateRealizedItems(); } } |