Ooui-tws-port/Ooui.Forms/Platform.cs

251 lines
8.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Ooui.Forms.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Internals;
namespace Ooui.Forms
{
public class Platform : BindableObject, INavigation, IDisposable
#pragma warning disable CS0618 // Type or member is obsolete
, IPlatform
#pragma warning restore CS0618 // Type or member is obsolete
{
bool _disposed;
readonly PlatformRenderer _renderer;
public Ooui.Element Element => _renderer;
public Page Page { get; private set; }
IReadOnlyList<Page> INavigation.ModalStack => throw new NotImplementedException ();
IReadOnlyList<Page> INavigation.NavigationStack => throw new NotImplementedException ();
public static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached ("Renderer", typeof (IVisualElementRenderer), typeof (Platform), default (IVisualElementRenderer),
propertyChanged: (bindable, oldvalue, newvalue) => {
var view = bindable as VisualElement;
if (view != null)
view.IsPlatformEnabled = newvalue != null;
});
public Platform ()
{
_renderer = new PlatformRenderer (this);
_renderer.Style.PropertyChanged += HandleRendererStyle_PropertyChanged;
MessagingCenter.Subscribe (this, Page.AlertSignalName, (Page sender, AlertArguments arguments) => {
var alert = new DisplayAlert (arguments);
alert.Clicked += CloseAlert;
_renderer.AppendChild (alert.Element);
void CloseAlert (object s, EventArgs e)
{
_renderer.RemoveChild (alert.Element);
}
});
MessagingCenter.Subscribe(this, Page.ActionSheetSignalName, (Page sender, ActionSheetArguments arguments) =>
{
var sheet = new ActionSheet(arguments);
sheet.Clicked += CloseSheet;
_renderer.AppendChild(sheet.Element);
void CloseSheet (object s, EventArgs e)
{
_renderer.RemoveChild(sheet.Element);
}
});
}
void IDisposable.Dispose ()
{
if (_disposed)
return;
_disposed = true;
MessagingCenter.Unsubscribe<Page, ActionSheetArguments> (this, Page.ActionSheetSignalName);
MessagingCenter.Unsubscribe<Page, AlertArguments> (this, Page.AlertSignalName);
MessagingCenter.Unsubscribe<Page, bool> (this, Page.BusySetSignalName);
DisposeModelAndChildrenRenderers (Page);
//foreach (var modal in _modals)
//DisposeModelAndChildrenRenderers (modal);
}
public static IVisualElementRenderer CreateRenderer (VisualElement element)
{
var renderer = Registrar.Registered.GetHandler<IVisualElementRenderer> (element.GetType ()) ?? new DefaultRenderer ();
renderer.SetElement (element);
return renderer;
}
public static IVisualElementRenderer GetRenderer (VisualElement bindable)
{
return (IVisualElementRenderer)bindable.GetValue (RendererProperty);
}
public static void SetRenderer (VisualElement bindable, IVisualElementRenderer value)
{
bindable.SetValue (RendererProperty, value);
}
protected override void OnBindingContextChanged ()
{
SetInheritedBindingContext (Page, BindingContext);
base.OnBindingContextChanged ();
}
public static SizeRequest GetNativeSize (VisualElement view, double widthConstraint, double heightConstraint)
{
var renderView = GetRenderer (view);
if (renderView == null || renderView.NativeView == null)
return new SizeRequest (Size.Zero);
return renderView.GetDesiredSize (widthConstraint, heightConstraint);
}
public void SetPage (Page newRoot)
{
if (newRoot == null)
return;
if (Page != null)
throw new NotImplementedException ();
Page = newRoot;
#pragma warning disable CS0618 // Type or member is obsolete
// The Platform property is no longer necessary, but we have to set it because some third-party
// library might still be retrieving it and using it
Page.Platform = this;
#pragma warning restore CS0618 // Type or member is obsolete
AddChild(Page);
Page.DescendantRemoved += HandleChildRemoved;
Application.Current.NavigationProxy.Inner = this;
}
void HandleChildRemoved (object sender, ElementEventArgs e)
{
var view = e.Element;
DisposeModelAndChildrenRenderers (view);
}
void DisposeModelAndChildrenRenderers (Xamarin.Forms.Element view)
{
IVisualElementRenderer renderer;
foreach (VisualElement child in view.Descendants ()) {
renderer = GetRenderer (child);
child.ClearValue (RendererProperty);
if (renderer != null) {
//renderer.NativeView.RemoveFromSuperview ();
renderer.Dispose ();
}
}
renderer = GetRenderer ((VisualElement)view);
if (renderer != null) {
//renderer.NativeView.RemoveFromSuperview ();
renderer.Dispose ();
}
view.ClearValue (RendererProperty);
}
void AddChild (VisualElement view)
{
if (!Application.IsApplicationOrNull (view.RealParent))
System.Diagnostics.Debug.WriteLine ("Tried to add parented view to canvas directly");
if (GetRenderer (view) == null) {
var viewRenderer = CreateRenderer (view);
SetRenderer (view, viewRenderer);
_renderer.AppendChild (viewRenderer.NativeView);
viewRenderer.SetElementSize (new Size (640, 480));
}
else
System.Diagnostics.Debug.WriteLine ("Potential view double add");
}
void HandleRendererStyle_PropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var pageRenderer = GetRenderer (Page);
pageRenderer?.SetElementSize (Ooui.Forms.Extensions.ElementExtensions.GetSizeRequest (_renderer, double.PositiveInfinity, double.PositiveInfinity).Request);
}
void INavigation.InsertPageBefore (Page page, Page before)
{
throw new NotImplementedException ();
}
Task<Page> INavigation.PopAsync ()
{
throw new NotImplementedException ();
}
Task<Page> INavigation.PopAsync (bool animated)
{
throw new NotImplementedException ();
}
Task<Page> INavigation.PopModalAsync ()
{
throw new NotImplementedException ();
}
Task<Page> INavigation.PopModalAsync (bool animated)
{
throw new NotImplementedException ();
}
Task INavigation.PopToRootAsync ()
{
throw new NotImplementedException ();
}
Task INavigation.PopToRootAsync (bool animated)
{
throw new NotImplementedException ();
}
Task INavigation.PushAsync (Page page)
{
throw new NotImplementedException ();
}
Task INavigation.PushAsync (Page page, bool animated)
{
throw new NotImplementedException ();
}
Task INavigation.PushModalAsync (Page page)
{
throw new NotImplementedException ();
}
Task INavigation.PushModalAsync (Page page, bool animated)
{
throw new NotImplementedException ();
}
void INavigation.RemovePage (Page page)
{
throw new NotImplementedException ();
}
#region obsolete
SizeRequest IPlatform.GetNativeSize (VisualElement view, double widthConstraint, double heightConstraint)
{
return GetNativeSize(view, widthConstraint, heightConstraint);
}
#endregion
}
}