Scaffold the Ooui platform
This commit is contained in:
parent
f06b57f240
commit
3d148e7e9f
|
@ -4,7 +4,7 @@ using Ooui.Forms.Renderers;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Internals;
|
using Xamarin.Forms.Internals;
|
||||||
|
|
||||||
|
[assembly: Dependency (typeof (ResourcesProvider))]
|
||||||
[assembly: ExportRenderer (typeof (Button), typeof (ButtonRenderer))]
|
[assembly: ExportRenderer (typeof (Button), typeof (ButtonRenderer))]
|
||||||
|
|
||||||
namespace Ooui.Forms
|
namespace Ooui.Forms
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Ooui.Forms
|
||||||
|
{
|
||||||
|
public interface IVisualElementRenderer : IRegisterable, IDisposable
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +1,38 @@
|
||||||
using System;
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Ooui.Forms
|
namespace Xamarin.Forms
|
||||||
{
|
{
|
||||||
public static class PageExtensions
|
public static class PageExtensions
|
||||||
{
|
{
|
||||||
public static void Publish (this Xamarin.Forms.Page page, string path)
|
public static void Publish (this Xamarin.Forms.Page page, string path)
|
||||||
{
|
{
|
||||||
UI.Publish (path, () => page.CreateElement ());
|
Ooui.UI.Publish (path, () => page.CreateElement ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PublishShared (this Xamarin.Forms.Page page, string path)
|
public static void PublishShared (this Xamarin.Forms.Page page, string path)
|
||||||
{
|
{
|
||||||
var lazyPage = new Lazy<Element> ((() => page.CreateElement ()), true);
|
var lazyPage = new Lazy<Ooui.Element> ((() => page.CreateElement ()), true);
|
||||||
UI.Publish (path, () => lazyPage.Value);
|
Ooui.UI.Publish (path, () => lazyPage.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Element CreateElement (this Xamarin.Forms.Page page)
|
public static Ooui.Element CreateElement (this Xamarin.Forms.Page page)
|
||||||
{
|
{
|
||||||
if (!Xamarin.Forms.Forms.IsInitialized)
|
if (!Xamarin.Forms.Forms.IsInitialized)
|
||||||
throw new InvalidOperationException ("call Forms.Init() before this");
|
throw new InvalidOperationException ("call Forms.Init() before this");
|
||||||
|
|
||||||
throw new NotImplementedException ();
|
if (!(page.RealParent is Application)) {
|
||||||
|
var app = new DefaultApplication ();
|
||||||
|
app.MainPage = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new Ooui.Forms.Platform ();
|
||||||
|
result.SetPage (page);
|
||||||
|
return result.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DefaultApplication : Application
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,31 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ooui.Forms.Renderers;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Internals;
|
using Xamarin.Forms.Internals;
|
||||||
|
|
||||||
namespace Ooui.Forms
|
namespace Ooui.Forms
|
||||||
{
|
{
|
||||||
public class Platform : BindableObject, IPlatform, IDisposable
|
public class Platform : BindableObject, IPlatform, INavigation, IDisposable
|
||||||
{
|
{
|
||||||
bool _disposed;
|
bool _disposed;
|
||||||
|
|
||||||
|
public Element Element { get; private set; }
|
||||||
|
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
|
@ -19,9 +37,128 @@ namespace Ooui.Forms
|
||||||
MessagingCenter.Unsubscribe<Page, bool>(this, Page.BusySetSignalName);
|
MessagingCenter.Unsubscribe<Page, bool>(this, Page.BusySetSignalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 SizeRequest GetNativeSize(VisualElement view, double widthConstraint, double heightConstraint)
|
public SizeRequest GetNativeSize(VisualElement view, double widthConstraint, double heightConstraint)
|
||||||
{
|
{
|
||||||
return new SizeRequest(new Size(100, 100));
|
return new SizeRequest(new Size(100, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetPage (Page newRoot)
|
||||||
|
{
|
||||||
|
if (newRoot == null)
|
||||||
|
return;
|
||||||
|
if (Page != null)
|
||||||
|
throw new NotImplementedException ();
|
||||||
|
Page = newRoot;
|
||||||
|
|
||||||
|
Page.Platform = this;
|
||||||
|
AddChild (Page);
|
||||||
|
|
||||||
|
//Page.DescendantRemoved += HandleChildRemoved;
|
||||||
|
|
||||||
|
Application.Current.NavigationProxy.Inner = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddChild (VisualElement view)
|
||||||
|
{
|
||||||
|
if (!Application.IsApplicationOrNull (view.RealParent))
|
||||||
|
Console.Error.WriteLine ("Tried to add parented view to canvas directly");
|
||||||
|
|
||||||
|
if (GetRenderer (view) == null) {
|
||||||
|
var viewRenderer = CreateRenderer (view);
|
||||||
|
SetRenderer (view, viewRenderer);
|
||||||
|
|
||||||
|
//_renderer.View.AddSubview (viewRenderer.NativeView);
|
||||||
|
//if (viewRenderer.ViewController != null)
|
||||||
|
// _renderer.AddChildViewController (viewRenderer.ViewController);
|
||||||
|
//viewRenderer.NativeView.Frame = new RectangleF (0, 0, _renderer.View.Bounds.Width, _renderer.View.Bounds.Height);
|
||||||
|
//viewRenderer.SetElementSize (new Size (_renderer.View.Bounds.Width, _renderer.View.Bounds.Height));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Console.Error.WriteLine ("Potential view double add");
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Ooui.Forms.Renderers
|
||||||
|
{
|
||||||
|
public class DefaultRenderer : VisualElementRenderer<VisualElement>
|
||||||
|
{
|
||||||
|
public DefaultRenderer () : base ("div")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,40 @@ using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Ooui.Forms.Renderers
|
namespace Ooui.Forms.Renderers
|
||||||
{
|
{
|
||||||
public class ElementRenderer<TElement, TNativeElement> where TElement : View where TNativeElement : Ooui.Element
|
public class ElementRenderer<TElement, TNativeElement> : IVisualElementRenderer where TElement : View where TNativeElement : Ooui.Element
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#region IDisposable Support
|
||||||
|
private bool disposedValue = false; // To detect redundant calls
|
||||||
|
|
||||||
|
protected virtual void Dispose (bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue) {
|
||||||
|
if (disposing) {
|
||||||
|
// TODO: dispose managed state (managed objects).
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
|
||||||
|
// TODO: set large fields to null.
|
||||||
|
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
|
||||||
|
// ~ElementRenderer() {
|
||||||
|
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||||
|
// Dispose(false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// This code added to correctly implement the disposable pattern.
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||||
|
Dispose (true);
|
||||||
|
// TODO: uncomment the following line if the finalizer is overridden above.
|
||||||
|
// GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Xamarin.Forms.Internals;
|
||||||
|
|
||||||
|
namespace Ooui.Forms
|
||||||
|
{
|
||||||
|
public class ResourcesProvider : ISystemResourcesProvider
|
||||||
|
{
|
||||||
|
readonly Res res = new Res ();
|
||||||
|
|
||||||
|
public IResourceDictionary GetSystemResources ()
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Res : IResourceDictionary
|
||||||
|
{
|
||||||
|
readonly ConcurrentDictionary<string, object> values =
|
||||||
|
new ConcurrentDictionary<string, object> ();
|
||||||
|
|
||||||
|
public event EventHandler<ResourcesChangedEventArgs> ValuesChanged;
|
||||||
|
|
||||||
|
public bool TryGetValue (string key, out object value)
|
||||||
|
{
|
||||||
|
return values.TryGetValue (key, out value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<KeyValuePair<string, object>> GetEnumerator ()
|
||||||
|
{
|
||||||
|
return values.GetEnumerator ();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator ()
|
||||||
|
{
|
||||||
|
return values.GetEnumerator ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace Ooui.Forms
|
||||||
|
{
|
||||||
|
public class VisualElementRenderer<TElement> : Element, IVisualElementRenderer where TElement : VisualElement
|
||||||
|
{
|
||||||
|
public VisualElementRenderer (string tagName) : base (tagName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IDisposable Support
|
||||||
|
private bool disposedValue = false; // To detect redundant calls
|
||||||
|
|
||||||
|
protected virtual void Dispose (bool disposing)
|
||||||
|
{
|
||||||
|
if (!disposedValue) {
|
||||||
|
if (disposing) {
|
||||||
|
// TODO: dispose managed state (managed objects).
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
|
||||||
|
// TODO: set large fields to null.
|
||||||
|
|
||||||
|
disposedValue = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
|
||||||
|
// ~VisualElementRenderer() {
|
||||||
|
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||||
|
// Dispose(false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// This code added to correctly implement the disposable pattern.
|
||||||
|
public void Dispose ()
|
||||||
|
{
|
||||||
|
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||||
|
Dispose (true);
|
||||||
|
// TODO: uncomment the following line if the finalizer is overridden above.
|
||||||
|
// GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -402,6 +402,9 @@ namespace Ooui
|
||||||
Element element = null;
|
Element element = null;
|
||||||
try {
|
try {
|
||||||
element = elementHandler.GetElement ();
|
element = elementHandler.GetElement ();
|
||||||
|
|
||||||
|
if (element == null)
|
||||||
|
throw new Exception ("Handler returned a null element");
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
listenerContext.Response.StatusCode = 500;
|
listenerContext.Response.StatusCode = 500;
|
||||||
|
|
Loading…
Reference in New Issue