Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
[Tizen] Added Fast Layout Opt-in (#13221)
Browse files Browse the repository at this point in the history
  • Loading branch information
rookiejava committed Dec 27, 2020
1 parent 1d6d7bd commit 6ea5fa9
Show file tree
Hide file tree
Showing 7 changed files with 448 additions and 17 deletions.
7 changes: 7 additions & 0 deletions Xamarin.Forms.Platform.Tizen/Forms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class InitializationOptions
public StaticRegistrarStrategy StaticRegistarStrategy { get; set; }
public PlatformType PlatformType { get; set; }
public bool UseMessagingCenter { get; set; } = true;
public bool UseFastLayout { get; set; } = false;

public DisplayResolutionUnit DisplayResolutionUnit { get; set; }

Expand Down Expand Up @@ -271,6 +272,8 @@ public static bool IsInitialized

public static bool UseSkiaSharp { get; private set; }

public static bool UseFastLayout { get; private set; }

public static DisplayResolutionUnit DisplayResolutionUnit { get; private set; }

public static int ScreenDPI => s_dpi.Value;
Expand Down Expand Up @@ -480,6 +483,7 @@ static void SetupInit(CoreApplication application, InitializationOptions options
s_platformType = options.PlatformType;
s_useMessagingCenter = options.UseMessagingCenter;
UseSkiaSharp = options.UseSkiaSharp;
UseFastLayout = options.UseFastLayout;

if (options.Assemblies != null && options.Assemblies.Length > 0)
{
Expand Down Expand Up @@ -532,6 +536,9 @@ static void SetupInit(CoreApplication application, InitializationOptions options

if (UseSkiaSharp)
RegisterSkiaSharpRenderers();

if (UseFastLayout)
Registrar.Registered.Register(typeof(Layout), typeof(FastLayoutRenderer));
}
}

Expand Down
131 changes: 131 additions & 0 deletions Xamarin.Forms.Platform.Tizen/Native/EvasBox.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System;
using System.Runtime.InteropServices;
using ElmSharp;
using EColor = ElmSharp.Color;
using ERectangle = ElmSharp.Rectangle;

namespace Xamarin.Forms.Platform.Tizen.Native
{
public class EvasBox : Container
{
Interop.CanvasBoxLayoutCallback _layoutCallback;
Lazy<ERectangle> _rectangle;

public event EventHandler<LayoutEventArgs> LayoutUpdated;

public EvasBox(EvasObject parent) : base(parent)
{
_rectangle = new Lazy<ERectangle>(() =>
{
var rectangle = new ERectangle(this) { AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1 };
Interop.evas_object_box_insert_at(Handle, rectangle, 0);
rectangle.Lower();
rectangle.Show();
return rectangle;
});

SetLayoutCallback(() => { NotifyOnLayout(); });
}

public override EColor BackgroundColor
{
get
{
return _rectangle.Value.Color;
}
set
{
_rectangle.Value.Color = value.IsDefault ? EColor.Transparent : value;
}
}

public void PackEnd(EvasObject content)
{
Interop.evas_object_box_append(Handle, content);
AddChild(content);
}

public bool UnPack(EvasObject content)
{
var ret = Interop.evas_object_box_remove(Handle, content);
if (ret)
RemoveChild(content);
return ret;
}

public bool UnPackAll()
{
var ret = Interop.evas_object_box_remove_all(Handle, true);
if (ret)
{
ClearChildren();
if (_rectangle.IsValueCreated)
{
Interop.evas_object_box_append(Handle, _rectangle.Value);
}
}
return ret;
}

public void SetLayoutCallback(Action action)
{
_layoutCallback = (obj, priv, data) =>
{
if (_rectangle.IsValueCreated)
{
_rectangle.Value.Geometry = Geometry;
}
action();
};
Interop.evas_object_box_layout_set(Handle, _layoutCallback, IntPtr.Zero, null);
}

protected override IntPtr CreateHandle(EvasObject parent)
{
return Interop.evas_object_box_add(Interop.evas_object_evas_get(parent.Handle));
}

void NotifyOnLayout()
{
if (null != LayoutUpdated)
{
LayoutUpdated(this, new LayoutEventArgs() { Geometry = Geometry });
}
}

class Interop
{
public const string LibEvas = "libevas.so.1";

public delegate void CanvasBoxLayoutCallback(IntPtr obj, IntPtr priv, IntPtr userData);

public delegate void CanvasBoxDataFreeCallback(IntPtr data);

[DllImport(LibEvas)]
internal static extern IntPtr evas_object_box_add(IntPtr evas);

[DllImport(LibEvas)]
internal static extern IntPtr evas_object_evas_get(IntPtr obj);

[DllImport(LibEvas)]
internal static extern void evas_object_box_append(IntPtr obj, IntPtr child);

[DllImport(LibEvas)]
internal static extern void evas_object_box_insert_at(IntPtr obj, IntPtr child, int pos);

[DllImport(LibEvas)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool evas_object_box_remove(IntPtr obj, IntPtr child);

[DllImport(LibEvas)]
[return: MarshalAs(UnmanagedType.U1)]
internal static extern bool evas_object_box_remove_all(IntPtr obj, bool clear);

[DllImport(LibEvas)]
internal static extern void evas_object_box_layout_set(IntPtr obj, CanvasBoxLayoutCallback cb, IntPtr data, CanvasBoxDataFreeCallback dataFreeCb);

[DllImport(LibEvas)]
internal static extern void evas_object_box_layout_set(IntPtr obj, CanvasBoxLayoutCallback cb, IntPtr data, IntPtr dataFreeCb);
}
}
}
82 changes: 82 additions & 0 deletions Xamarin.Forms.Platform.Tizen/Native/EvasFormsCanvas.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using ElmSharp;

namespace Xamarin.Forms.Platform.Tizen.Native
{
public class EvasFormsCanvas : EvasBox, IContainable<EvasObject>
{
public EvasFormsCanvas(EvasObject parent) : base(parent)
{
Initilize();
}

readonly ObservableCollection<EvasObject> _children = new ObservableCollection<EvasObject>();

public new IList<EvasObject> Children
{
get
{
return _children;
}
}

protected override void OnUnrealize()
{
foreach (var child in _children)
{
child.Unrealize();
}

base.OnUnrealize();
}

void Initilize()
{
_children.CollectionChanged += (o, e) =>
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (var v in e.NewItems)
{
var view = v as EvasObject;
if (null != view)
{
OnAdd(view);
}
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (var v in e.OldItems)
{
var view = v as EvasObject;
if (null != view)
{
OnRemove(view);
}
}
}
else if (e.Action == NotifyCollectionChangedAction.Reset)
{
OnRemoveAll();
}
};
}

void OnAdd(EvasObject view)
{
PackEnd(view);
}

void OnRemove(EvasObject view)
{
UnPack(view);
}

void OnRemoveAll()
{
UnPackAll();
}
}
}
24 changes: 19 additions & 5 deletions Xamarin.Forms.Platform.Tizen/Native/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,29 @@ public class Page : Background, IContainable<EvasObject>
/// <summary>
/// Exposes the Children property, mapping it to the _canvas' Children property.
/// </summary>
public new IList<EvasObject> Children => _canvas.Children;
public new IList<EvasObject> Children => Forms.UseFastLayout ? EvasFormsCanvas?.Children : Canvas?.Children;

/// <summary>
/// The canvas, used as a container for other objects.
/// </summary>
/// <remarks>
/// The canvas holds all the Views that the ContentPage is composed of.
/// </remarks>
internal Canvas _canvas;
internal Container _canvas;

EvasFormsCanvas EvasFormsCanvas => _canvas as EvasFormsCanvas;

Canvas Canvas => _canvas as Canvas;

/// <summary>
/// Initializes a new instance of the ContentPage class.
/// </summary>
public Page(EvasObject parent) : base(parent)
{
_canvas = new Canvas(this);
if (Forms.UseFastLayout)
_canvas = new EvasFormsCanvas(this);
else
_canvas = new Canvas(this);
this.SetOverlayPart(_canvas);
}

Expand All @@ -44,11 +51,18 @@ public Page(EvasObject parent) : base(parent)
{
add
{
_canvas.LayoutUpdated += value;
if (Forms.UseFastLayout)
EvasFormsCanvas.LayoutUpdated += value;
else
Canvas.LayoutUpdated += value;

}
remove
{
_canvas.LayoutUpdated -= value;
if (Forms.UseFastLayout)
EvasFormsCanvas.LayoutUpdated -= value;
else
Canvas.LayoutUpdated -= value;
}
}

Expand Down
Loading

0 comments on commit 6ea5fa9

Please sign in to comment.