Skip to content

Commit

Permalink
feat(background_sizing): Added support for BackgroundSizing on Android
Browse files Browse the repository at this point in the history
  • Loading branch information
carldebilly committed Aug 25, 2021
1 parent c3f8315 commit 7a9b306
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 7 deletions.
10 changes: 10 additions & 0 deletions src/Uno.UI/Extensions/RectangleExtensions.Android.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Android.Graphics;

namespace Uno.UI
{
Expand All @@ -11,6 +12,15 @@ internal static Android.Graphics.RectF ToRectF(this Windows.Foundation.Rect rect
return new Android.Graphics.RectF((float)rect.X, (float)rect.Y, (float)(rect.X + rect.Width), (float)(rect.Y + rect.Height));
}

internal static Android.Graphics.Path ToPath(this Windows.Foundation.Rect rect)
{
var path = new Android.Graphics.Path();

path.AddRect(rect.ToRectF(), Path.Direction.Cw);

return path;
}

//Need this because the current implementation of Foundation.Rect's "IsEmpty"
// is not intended to convey information about the Rect's area.
internal static bool HasZeroArea(this Windows.Foundation.Rect rect)
Expand Down
7 changes: 7 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Border/Border.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ private void UpdateBorder(bool willUpdateMeasures)
_borderRenderer.UpdateLayer(
this,
Background,
BackgroundSizing,
BorderThickness,
BorderBrush,
CornerRadius,
Expand All @@ -93,6 +94,12 @@ protected override void OnBackgroundChanged(DependencyPropertyChangedEventArgs e
UpdateBorder();
}

private protected override void OnBackgroundSizingChanged(DependencyPropertyChangedEventArgs e)
{
// Don't call base: it's doing nothing
UpdateBorder();
}

partial void OnBorderThicknessChangedPartial(Thickness oldValue, Thickness newValue)
{
UpdateBorder();
Expand Down
26 changes: 20 additions & 6 deletions src/Uno.UI/UI/Xaml/Controls/Border/BorderLayerRenderer.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Uno.UI;
using AndroidX.AppCompat.View;
using System.Diagnostics;
using Rect = Windows.Foundation.Rect;

namespace Windows.UI.Xaml.Controls
{
Expand All @@ -33,13 +34,15 @@ internal class BorderLayerRenderer
/// </summary>
/// <param name="view">The view to which we should add the layers</param>
/// <param name="background">The background brush of the border</param>
/// <param name="backgroundSizing">The background sizing (if drawn under border or not)</param>
/// <param name="borderThickness">The border thickness</param>
/// <param name="borderBrush">The border brush</param>
/// <param name="cornerRadius">The corner radius</param>
/// <param name="padding">The padding to apply on the content</param>
public void UpdateLayer(
FrameworkElement view,
Brush background,
BackgroundSizing backgroundSizing,
Thickness borderThickness,
Brush borderBrush,
CornerRadius cornerRadius,
Expand Down Expand Up @@ -71,7 +74,7 @@ public void UpdateLayer(
}

Action onImageSet = null;
var disposable = InnerCreateLayers(view, drawArea, background, borderThickness, borderBrush, cornerRadius, () => onImageSet?.Invoke());
var disposable = InnerCreateLayers(view, drawArea, background, backgroundSizing, borderThickness, borderBrush, cornerRadius, () => onImageSet?.Invoke());

// Most of the time we immediately dispose the previous layer. In the case where we're using an ImageBrush,
// and the backing image hasn't changed, we dispose the previous layer at the moment the new background is applied,
Expand Down Expand Up @@ -108,17 +111,18 @@ internal void Clear()
}

private static IDisposable InnerCreateLayers(BindableView view,
Windows.Foundation.Rect drawArea,
Rect drawArea,
Brush background,
BackgroundSizing backgroundSizing,
Thickness borderThickness,
Brush borderBrush,
CornerRadius cornerRadius,
Action onImageSet
)
Action onImageSet)
{
var disposables = new CompositeDisposable();

var physicalBorderThickness = borderThickness.LogicalToPhysicalPixels();
var isInnerBorderSizing = backgroundSizing == BackgroundSizing.InnerBorderEdge;
if (cornerRadius != 0)
{
if (view is UIElement uiElement && uiElement.FrameRoundingAdjustment is { } fra)
Expand All @@ -127,7 +131,10 @@ Action onImageSet
drawArea.Width += fra.Width;
}

var adjustedArea = drawArea.DeflateBy(physicalBorderThickness);
var adjustedArea =
isInnerBorderSizing
? drawArea.DeflateBy(physicalBorderThickness)
: drawArea;

using (var backgroundPath = cornerRadius.GetOutlinePath(adjustedArea.ToRectF()))
{
Expand Down Expand Up @@ -182,6 +189,13 @@ Action onImageSet
//We only need to set a background if the drawArea is non-zero
if (!drawArea.HasZeroArea())
{
var adjustedArea =
isInnerBorderSizing
? drawArea.DeflateBy(physicalBorderThickness)
: drawArea;

var outlinePath = adjustedArea.ToPath();

if (background is ImageBrush imageBrushBackground)
{
var setBackground = DispatchSetImageBrushAsBackground(view, imageBrushBackground, drawArea, onImageSet);
Expand All @@ -195,7 +209,7 @@ Action onImageSet
else
{
var fillPaint = background?.GetFillPaint(drawArea) ?? new Paint() { Color = Android.Graphics.Color.Transparent };
ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(Brush.GetBackgroundDrawable(background, drawArea, fillPaint)));
ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(Brush.GetBackgroundDrawable(background, drawArea, fillPaint, outlinePath)));
}
disposables.Add(() => ExecuteWithNoRelayout(view, v => v.SetBackgroundDrawable(null)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ private void UpdateChrome()
borderBrush = selectedBrush;
}

_borderRenderer.UpdateLayer(this, background, borderThickness, borderBrush, cornerRadius, default);
_borderRenderer.UpdateLayer(this, background, BackgroundSizing.InnerBorderEdge, borderThickness, borderBrush, cornerRadius, default);
}

private bool IsClear(Brush brush)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ private void UpdateBorder(bool willUpdateMeasures)
_borderRenderer.UpdateLayer(
this,
Background,
BackgroundSizing,
BorderThickness,
BorderBrush,
CornerRadius,
Expand Down
1 change: 1 addition & 0 deletions src/Uno.UI/UI/Xaml/Controls/Page/Page.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ private void UpdateBorder(bool willUpdateMeasures)
_borderRenderer.UpdateLayer(
this,
Background,
BackgroundSizing,
Thickness.Empty,
null,
CornerRadius.None,
Expand Down
7 changes: 7 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Panel/Panel.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ private void UpdateBorder(bool willUpdateMeasures)
_borderRenderer.UpdateLayer(
this,
Background,
BackgroundSizing,
BorderThickness,
BorderBrush,
CornerRadius,
Expand Down Expand Up @@ -110,6 +111,12 @@ protected override void OnBackgroundChanged(DependencyPropertyChangedEventArgs e
UpdateBorder();
}

private protected override void OnBackgroundSizingChanged(DependencyPropertyChangedEventArgs e)
{
// Don't call base: there's nothing there.
UpdateBorder();
}

protected override void OnBeforeArrange()
{
base.OnBeforeArrange();
Expand Down

0 comments on commit 7a9b306

Please sign in to comment.