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

[Tizen] Added Fast Layout Opt-in #13221

Merged
merged 1 commit into from
Dec 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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