183 lines
5.5 KiB
C#
183 lines
5.5 KiB
C#
using System;
|
|
using Xamarin.Forms;
|
|
|
|
namespace Ooui.Forms
|
|
{
|
|
public class VisualElementPackager : IDisposable
|
|
{
|
|
VisualElement _element;
|
|
|
|
bool _isDisposed;
|
|
|
|
IElementController ElementController => _element;
|
|
|
|
public VisualElementPackager (IVisualElementRenderer renderer) : this (renderer, null)
|
|
{
|
|
}
|
|
|
|
VisualElementPackager (IVisualElementRenderer renderer, VisualElement element)
|
|
{
|
|
if (renderer == null)
|
|
throw new ArgumentNullException (nameof (renderer));
|
|
|
|
Renderer = renderer;
|
|
renderer.ElementChanged += OnRendererElementChanged;
|
|
SetElement (null, element ?? renderer.Element);
|
|
}
|
|
|
|
protected IVisualElementRenderer Renderer { get; set; }
|
|
|
|
public void Dispose ()
|
|
{
|
|
Dispose (true);
|
|
}
|
|
|
|
public void Load ()
|
|
{
|
|
for (var i = 0; i < ElementController.LogicalChildren.Count; i++) {
|
|
var child = ElementController.LogicalChildren[i] as VisualElement;
|
|
if (child != null)
|
|
OnChildAdded (child);
|
|
}
|
|
}
|
|
|
|
protected virtual void Dispose (bool disposing)
|
|
{
|
|
if (_isDisposed)
|
|
return;
|
|
|
|
if (disposing) {
|
|
SetElement (_element, null);
|
|
if (Renderer != null) {
|
|
Renderer.ElementChanged -= OnRendererElementChanged;
|
|
Renderer = null;
|
|
}
|
|
}
|
|
|
|
_isDisposed = true;
|
|
}
|
|
|
|
protected virtual void OnChildAdded (VisualElement view)
|
|
{
|
|
if (_isDisposed)
|
|
return;
|
|
|
|
//if (CompressedLayout.GetIsHeadless (view)) {
|
|
// var packager = new VisualElementPackager (Renderer, view);
|
|
// view.IsPlatformEnabled = true;
|
|
// packager.Load ();
|
|
//}
|
|
//else {
|
|
var viewRenderer = Platform.CreateRenderer (view);
|
|
Platform.SetRenderer (view, viewRenderer);
|
|
|
|
var uiview = Renderer.NativeView;
|
|
uiview.AppendChild (viewRenderer.NativeView);
|
|
|
|
EnsureChildrenOrder ();
|
|
//}
|
|
}
|
|
|
|
protected virtual void OnChildRemoved (VisualElement view)
|
|
{
|
|
if (_element == null)
|
|
return;
|
|
|
|
var viewRenderer = Platform.GetRenderer (view);
|
|
if (viewRenderer == null || viewRenderer.NativeView == null)
|
|
return;
|
|
|
|
var parentRenderer = Platform.GetRenderer (_element);
|
|
if (parentRenderer == null || parentRenderer.NativeView == null)
|
|
return;
|
|
|
|
parentRenderer.NativeView.RemoveChild (viewRenderer.NativeView);
|
|
}
|
|
|
|
void EnsureChildrenOrder ()
|
|
{
|
|
if (ElementController.LogicalChildren.Count == 0)
|
|
return;
|
|
|
|
for (var z = 0; z < ElementController.LogicalChildren.Count; z++) {
|
|
var child = ElementController.LogicalChildren[z] as VisualElement;
|
|
if (child == null)
|
|
continue;
|
|
var childRenderer = Platform.GetRenderer (child);
|
|
|
|
if (childRenderer == null)
|
|
continue;
|
|
|
|
var nativeControl = childRenderer.NativeView;
|
|
#if __MOBILE__
|
|
Renderer.NativeView.BringSubviewToFront(nativeControl);
|
|
#endif
|
|
nativeControl.Style.ZIndex = z * 1000;
|
|
}
|
|
}
|
|
|
|
void OnChildAdded (object sender, ElementEventArgs e)
|
|
{
|
|
var view = e.Element as VisualElement;
|
|
if (view != null)
|
|
OnChildAdded (view);
|
|
}
|
|
|
|
void OnChildRemoved (object sender, ElementEventArgs e)
|
|
{
|
|
var view = e.Element as VisualElement;
|
|
if (view != null)
|
|
OnChildRemoved (view);
|
|
}
|
|
|
|
void OnRendererElementChanged (object sender, VisualElementChangedEventArgs args)
|
|
{
|
|
if (args.NewElement == _element)
|
|
return;
|
|
|
|
SetElement (_element, args.NewElement);
|
|
}
|
|
|
|
void SetElement (VisualElement oldElement, VisualElement newElement)
|
|
{
|
|
if (oldElement == newElement)
|
|
return;
|
|
|
|
if (oldElement != null) {
|
|
oldElement.ChildAdded -= OnChildAdded;
|
|
oldElement.ChildRemoved -= OnChildRemoved;
|
|
oldElement.ChildrenReordered -= UpdateChildrenOrder;
|
|
|
|
if (newElement != null) {
|
|
var pool = new RendererPool (Renderer, oldElement);
|
|
pool.UpdateNewElement (newElement);
|
|
|
|
EnsureChildrenOrder ();
|
|
}
|
|
else {
|
|
var elementController = ((IElementController)oldElement);
|
|
|
|
for (var i = 0; i < elementController.LogicalChildren.Count; i++) {
|
|
var child = elementController.LogicalChildren[i] as VisualElement;
|
|
if (child != null)
|
|
OnChildRemoved (child);
|
|
}
|
|
}
|
|
}
|
|
|
|
_element = newElement;
|
|
|
|
if (newElement != null) {
|
|
newElement.ChildAdded += OnChildAdded;
|
|
newElement.ChildRemoved += OnChildRemoved;
|
|
newElement.ChildrenReordered += UpdateChildrenOrder;
|
|
}
|
|
}
|
|
|
|
void UpdateChildrenOrder (object sender, EventArgs e)
|
|
{
|
|
EnsureChildrenOrder ();
|
|
}
|
|
}
|
|
}
|