Skip to content

Commit

Permalink
[Windows] Improve performance of ContentPanel.EnsureBorderPath (#22346
Browse files Browse the repository at this point in the history
)

* Code style

* is null

* Cache children
  • Loading branch information
MartyIX authored May 27, 2024
1 parent ba9034d commit 320bcb4
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions src/Core/src/Platform/Windows/ContentPanel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#nullable enable
using System;
using System;
using System.Numerics;
using Microsoft.Graphics.Canvas;
using Microsoft.Maui.Graphics;
Expand All @@ -8,7 +7,6 @@
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Hosting;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Shapes;

namespace Microsoft.Maui.Platform
Expand Down Expand Up @@ -50,38 +48,53 @@ internal FrameworkElement? Content
public ContentPanel()
{
_borderPath = new Path();
EnsureBorderPath();
EnsureBorderPath(containsCheck: false);

SizeChanged += ContentPanelSizeChanged;
}

void ContentPanelSizeChanged(object sender, UI.Xaml.SizeChangedEventArgs e)
void ContentPanelSizeChanged(object sender, SizeChangedEventArgs e)
{
if (_borderPath is null)
{
return;
}

var width = e.NewSize.Width;
var height = e.NewSize.Height;

if (width <= 0 || height <= 0)
{
return;
}

_borderPath.UpdatePath(_borderStroke?.Shape, width, height);
UpdateClip(_borderStroke?.Shape, width, height);
}

internal void EnsureBorderPath()
internal void EnsureBorderPath(bool containsCheck = true)
{
if (!Children.Contains(_borderPath))
if (containsCheck)
{
var children = Children;

if (!children.Contains(_borderPath))
{
children.Add(_borderPath);
}
}
else
{
Children.Add(_borderPath);
}
}

public void UpdateBackground(Paint? background)
{
if (_borderPath == null)
if (_borderPath is null)
{
return;
}

_borderPath.UpdateBackground(background);
}
Expand All @@ -95,61 +108,81 @@ public void UpdateBorderShape(IShape borderShape)
internal void UpdateBorderStroke(IBorderStroke borderStroke)
{
if (borderStroke is null)
{
return;
}

_borderStroke = borderStroke;

if (_borderStroke is null)
{
return;
}

UpdateBorder(_borderStroke.Shape);
}

void UpdateBorder(IShape? strokeShape)
{
if (strokeShape is null || _borderPath is null)
{
return;
}

_borderPath.UpdateBorderShape(strokeShape, ActualWidth, ActualHeight);

var width = ActualWidth;
var height = ActualHeight;

if (width <= 0 || height <= 0)
{
return;
}

UpdateClip(strokeShape, width, height);
}

void AddContent(FrameworkElement? content)
{
if (content == null)
if (content is null)
{
return;
}

if (!Children.Contains(_content))
Children.Add(_content);
var children = Children;

if (!children.Contains(_content))
{
children.Add(_content);
}
}

void UpdateClip(IShape? borderShape, double width, double height)
{
if (Content is null)
{
return;
}

if (height <= 0 && width <= 0)
{
return;
}

var clipGeometry = borderShape;

if (clipGeometry is null)
{
return;
}

var visual = ElementCompositionPreview.GetElementVisual(Content);
var compositor = visual.Compositor;

PathF? clipPath;
float strokeThickness = (float)(_borderPath?.StrokeThickness ?? 0);
// The path size should consider the space taken by the border (top and bottom, left and right)
var pathSize = new Graphics.Rect(0, 0, width - strokeThickness * 2, height - strokeThickness * 2);
var pathSize = new Rect(0, 0, width - strokeThickness * 2, height - strokeThickness * 2);

if (clipGeometry is IRoundRectangle roundedRectangle)
{
Expand Down

0 comments on commit 320bcb4

Please sign in to comment.