Skip to content

Commit

Permalink
Refactor the LayoutHandler (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
rookiejava committed Sep 7, 2021
1 parent e50f32d commit 9163400
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 60 deletions.
1 change: 1 addition & 0 deletions src/Compatibility/Core/src/Tizen/HandlerToRendererShim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public void SetElement(VisualElement element)

Element = element;
((IView)element).Handler = ViewHandler;
Platform.SetRenderer(element, this);

if (ViewHandler.VirtualView != element)
ViewHandler.SetVirtualView((IView)element);
Expand Down
1 change: 0 additions & 1 deletion src/Compatibility/Core/src/Tizen/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ internal static IVisualElementRenderer CreateRenderer(VisualElement element)
}
renderer = new HandlerToRendererShim(vh);
element.Handler = handler;
SetRenderer(element, renderer);
}
}
renderer.SetElement(element);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ void OnPromptRequested(Page sender, PromptArguments args)
var nativeView = layout.ToNative(MauiContext);

var request = layout.LayoutManager.Measure(sender.Width, sender.Height);
(layout.Handler as IRegisterLayoutUpdate)?.RegisterOnLayoutUpdated();
nativeView.MinimumHeight = request.Height.ToScaledPixel();
nativeView.MinimumWidth = request.Width.ToScaledPixel();

Expand Down
83 changes: 26 additions & 57 deletions src/Core/src/Handlers/Layout/LayoutHandler.Tizen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,8 @@

namespace Microsoft.Maui.Handlers
{
public interface IRegisterLayoutUpdate
public partial class LayoutHandler : ViewHandler<ILayout, LayoutCanvas>
{
void RegisterOnLayoutUpdated();
}

public partial class LayoutHandler : ViewHandler<ILayout, LayoutCanvas>, IRegisterLayoutUpdate
{
bool _layoutUpdatedRegistered;
Graphics.Rectangle _arrangeCache;

public override bool NeedsContainer =>
VirtualView?.Background != null ||
VirtualView?.Clip != null ||
Expand All @@ -37,7 +29,7 @@ protected override LayoutCanvas CreateNativeView()
throw new InvalidOperationException($"{nameof(NativeParent)} cannot be null");
}

var view = new LayoutCanvas(NativeParent)
var view = new LayoutCanvas(NativeParent, VirtualView)
{
CrossPlatformMeasure = VirtualView.LayoutManager.Measure,
CrossPlatformArrange = VirtualView.LayoutManager.ArrangeChildren
Expand Down Expand Up @@ -76,12 +68,10 @@ public void Add(IView child)
_ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class.");
_ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class.");

_arrangeCache = default(Graphics.Rectangle);

NativeView.Children.Add(child.ToNative(MauiContext));
if (child.Handler is INativeViewHandler thandler)
if (child.Handler is INativeViewHandler childHandler)
{
thandler?.SetParent(this);
childHandler?.SetParent(this);
}
}

Expand All @@ -90,64 +80,43 @@ public void Remove(IView child)
_ = NativeView ?? throw new InvalidOperationException($"{nameof(NativeView)} should have been set by base class.");
_ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class.");

_arrangeCache = default(Graphics.Rectangle);

if (child.Handler is INativeViewHandler thandler && thandler.NativeView is EvasObject nativeView)
if (child.Handler is INativeViewHandler thandler && thandler.NativeView is EvasObject childView)
{
NativeView.Children.Remove(nativeView);
NativeView.Children.Remove(childView);
thandler.Dispose();
}
}

protected override Graphics.Point ComputeAbsolutePoint(Graphics.Rectangle frame)
public void Clear()
{
if (_layoutUpdatedRegistered)
return frame.Location;
return base.ComputeAbsolutePoint(frame);
NativeView?.Clear();
}

protected override void ConnectHandler(LayoutCanvas nativeView)
public void Insert(int index, IView child)
{
base.ConnectHandler(nativeView);
nativeView.LayoutUpdated += OnLayoutUpdated;
}

protected override void DisconnectHandler(LayoutCanvas nativeView)
{
base.DisconnectHandler(nativeView);
nativeView.LayoutUpdated -= OnLayoutUpdated;
}
_ = NativeView ?? throw new InvalidOperationException($"{nameof(NativeView)} should have been set by base class.");
_ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class.");
_ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class.");

protected void OnLayoutUpdated(object? sender, LayoutEventArgs e)
{
if (VirtualView != null && NativeView != null)
NativeView.Children.Insert(index, child.ToNative(MauiContext));
if (child.Handler is INativeViewHandler childHandler)
{
var nativeGeometry = NativeView.Geometry.ToDP();
if (_arrangeCache == nativeGeometry)
return;

_arrangeCache = nativeGeometry;

if (nativeGeometry.Width > 0 && nativeGeometry.Height > 0)
{
VirtualView.InvalidateMeasure();
VirtualView.InvalidateArrange();

if (!_layoutUpdatedRegistered)
{
nativeGeometry.X = VirtualView.Frame.X;
nativeGeometry.Y = VirtualView.Frame.Y;
}

VirtualView.LayoutManager.Measure(nativeGeometry.Width, nativeGeometry.Height);
VirtualView.LayoutManager.ArrangeChildren(nativeGeometry);
}
childHandler?.SetParent(this);
}
}

public void RegisterOnLayoutUpdated()
public void Update(int index, IView child)
{
_layoutUpdatedRegistered = true;
_ = NativeView ?? throw new InvalidOperationException($"{nameof(NativeView)} should have been set by base class.");
_ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} should have been set by base class.");
_ = MauiContext ?? throw new InvalidOperationException($"{nameof(MauiContext)} should have been set by base class.");

NativeView.Children.RemoveAt(index);
NativeView.Children.Insert(index, child.ToNative(MauiContext));
if (child.Handler is INativeViewHandler childHandler)
{
childHandler?.SetParent(this);
}
}
}
}
26 changes: 25 additions & 1 deletion src/Core/src/Platform/Tizen/LayoutCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ namespace Microsoft.Maui
{
public class LayoutCanvas : Canvas, IMeasurable
{
public LayoutCanvas(EvasObject parent) : base(parent) { }
Rectangle _arrangeCache;
IView _virtualView;

public LayoutCanvas(EvasObject parent, IView view) : base(parent)
{
_arrangeCache = default(Rectangle);
_virtualView = view;
LayoutUpdated += OnLayoutUpdated;
}

public TSize Measure(double availableWidth, double availableHeight)
{
Expand All @@ -19,5 +27,21 @@ public TSize Measure(double availableWidth, double availableHeight)

internal Func<double, double, Size>? CrossPlatformMeasure { get; set; }
internal Func<Rectangle, Size>? CrossPlatformArrange { get; set; }

protected void OnLayoutUpdated(object? sender, LayoutEventArgs e)
{
var nativeGeometry = Geometry.ToDP();

if (_arrangeCache == nativeGeometry)
return;

if (nativeGeometry.Width > 0 && nativeGeometry.Height > 0)
{
nativeGeometry.X = _virtualView.Frame.X;
nativeGeometry.Y = _virtualView.Frame.Y;
CrossPlatformMeasure!(nativeGeometry.Width, nativeGeometry.Height);
CrossPlatformArrange!(nativeGeometry);
}
}
}
}

0 comments on commit 9163400

Please sign in to comment.