Skip to content
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
84 changes: 82 additions & 2 deletions src/Controls/src/Core/BoxView/BoxView.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#nullable disable
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Microsoft.Maui.Graphics;

Expand All @@ -11,12 +10,33 @@ namespace Microsoft.Maui.Controls
/// </summary>
public partial class BoxView : View, IColorElement, ICornerElement, IElementConfiguration<BoxView>, IShapeView, IShape
{
WeakBrushChangedProxy _fillProxy = null;
EventHandler _fillChanged;

/// <summary>Bindable property for <see cref="Color"/>.</summary>
public static readonly BindableProperty ColorProperty = ColorElement.ColorProperty;

/// <summary>Bindable property for <see cref="CornerRadius"/>.</summary>
public static readonly BindableProperty CornerRadiusProperty = CornerElement.CornerRadiusProperty;

/// <summary>Bindable property for <see cref="Fill"/>.</summary>
public static readonly BindableProperty FillProperty =
BindableProperty.Create(nameof(Fill), typeof(Brush), typeof(BoxView), null,
propertyChanging: (bindable, oldvalue, newvalue) =>
{
if (oldvalue != null)
{
(bindable as BoxView)?.StopNotifyingFillChanges();
}
},
propertyChanged: (bindable, oldvalue, newvalue) =>
{
if (newvalue != null)
{
(bindable as BoxView)?.NotifyFillChanges();
}
});

readonly Lazy<PlatformConfigurationRegistry<BoxView>> _platformConfigurationRegistry;

/// <summary>
Expand All @@ -27,6 +47,11 @@ public BoxView()
_platformConfigurationRegistry = new Lazy<PlatformConfigurationRegistry<BoxView>>(() => new PlatformConfigurationRegistry<BoxView>(this));
}

~BoxView()
{
_fillProxy?.Unsubscribe();
}

/// <summary>
/// Gets or sets the color which will fill the rectangle. This is a bindable property.
/// </summary>
Expand All @@ -37,6 +62,19 @@ public Color Color
set => SetValue(ColorElement.ColorProperty, value);
}

/// <summary>
/// Gets or sets the brush that fills the interior of the BoxView.
/// </summary>
/// <value>
/// A <see cref="Brush"/> object that describes how the BoxView's interior is painted.
/// The default value is <see langword="null"/>.
/// </value>
public Brush Fill
{
get => (Brush)GetValue(FillProperty);
set => SetValue(FillProperty, value);
}

/// <summary>
/// Gets or sets the corner radius for the box view.
/// </summary>
Expand Down Expand Up @@ -66,6 +104,45 @@ protected override SizeRequest OnMeasure(double widthConstraint, double heightCo
return new SizeRequest(new Size(40, 40));
}

void NotifyFillChanges()
{
var fill = Fill;

if (fill is ImmutableBrush)
{
return;
}

if (fill is not null)
{
SetInheritedBindingContext(fill, BindingContext);
_fillChanged ??= (sender, e) => OnPropertyChanged(nameof(Fill));
_fillProxy ??= new();
_fillProxy.Subscribe(fill, _fillChanged);

OnParentResourcesChanged(this.GetMergedResources());
((IElementDefinition)this).AddResourcesChangedListener(fill.OnParentResourcesChanged);
}
}

void StopNotifyingFillChanges()
{
var fill = Fill;

if (fill is ImmutableBrush)
{
return;
}

if (fill is not null)
{
((IElementDefinition)this).RemoveResourcesChangedListener(fill.OnParentResourcesChanged);

SetInheritedBindingContext(fill, null);
_fillProxy?.Unsubscribe();
}
}

#nullable enable
/// <inheritdoc/>
protected override void OnPropertyChanged([CallerMemberName] string? propertyName = null)
Expand All @@ -74,17 +151,20 @@ protected override void OnPropertyChanged([CallerMemberName] string? propertyNam

if (propertyName == BackgroundColorProperty.PropertyName ||
propertyName == ColorProperty.PropertyName ||
propertyName == FillProperty.PropertyName ||
propertyName == IsVisibleProperty.PropertyName ||
propertyName == BackgroundProperty.PropertyName ||
propertyName == CornerRadiusProperty.PropertyName)
{
Handler?.UpdateValue(nameof(IShapeView.Shape));
}
}

IShape? IShapeView.Shape => this;

PathAspect IShapeView.Aspect => PathAspect.None;

Paint? IShapeView.Fill => Color?.AsPaint();
Paint? IShapeView.Fill => Fill ?? Color?.AsPaint();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation allows both Color and Fill to be set simultaneously, with Fill taking priority. This requires updates in the documentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what happens when Fill is cleared?
<BoxView x:Name="box" Color="Red" Fill="{StaticResource MyGradient}" />

Later in code:

box.Fill = null;

Does Red color suddenly appear? Could we have a test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsuarezruiz , when fill is set to null , the color takes over. i have added test case to ensure this.


Paint? IStroke.Stroke => null;

Expand Down
44 changes: 44 additions & 0 deletions src/Controls/src/Core/Internals/WeakEventProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,48 @@ public override void Unsubscribe()
base.Unsubscribe();
}
}

class WeakBrushChangedProxy : WeakEventProxy<Brush, EventHandler>
{
void OnBrushChanged(object? sender, EventArgs e)
{
if (TryGetHandler(out var handler))
{
handler(sender, e);
}
else
{
Unsubscribe();
}
}

public override void Subscribe(Brush source, EventHandler handler)
{
if (TryGetSource(out var s))
{
s.PropertyChanged -= OnBrushChanged;

if (s is GradientBrush g)
g.InvalidateGradientBrushRequested -= OnBrushChanged;
}

source.PropertyChanged += OnBrushChanged;
if (source is GradientBrush gradientBrush)
gradientBrush.InvalidateGradientBrushRequested += OnBrushChanged;

base.Subscribe(source, handler);
}

public override void Unsubscribe()
{
if (TryGetSource(out var s))
{
s.PropertyChanged -= OnBrushChanged;

if (s is GradientBrush g)
g.InvalidateGradientBrushRequested -= OnBrushChanged;
}
base.Unsubscribe();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
*REMOVED*~static Microsoft.Maui.Controls.VisualStateManager.GetVisualStateGroups(Microsoft.Maui.Controls.VisualElement visualElement) -> System.Collections.Generic.IList<Microsoft.Maui.Controls.VisualStateGroup>
*REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultForegroundColor -> Microsoft.Maui.Graphics.Color
*REMOVED*~static readonly Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.DefaultTitleColor -> Microsoft.Maui.Graphics.Color
Expand Down Expand Up @@ -93,3 +93,7 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.set -> void
static Microsoft.Maui.Controls.Toolbar.MapBackButtonAccessibilityLabel(Microsoft.Maui.Handlers.IToolbarHandler! arg1, Microsoft.Maui.Controls.Toolbar! arg2) -> void
static Microsoft.Maui.Controls.Toolbar.MapBackButtonAccessibilityLabel(Microsoft.Maui.Handlers.ToolbarHandler! arg1, Microsoft.Maui.Controls.Toolbar! arg2) -> void
Microsoft.Maui.Controls.BoxView.~BoxView() -> void
~Microsoft.Maui.Controls.BoxView.Fill.get -> Microsoft.Maui.Controls.Brush
~Microsoft.Maui.Controls.BoxView.Fill.set -> void
~static readonly Microsoft.Maui.Controls.BoxView.FillProperty -> Microsoft.Maui.Controls.BindableProperty
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
*REMOVED*~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRootRenderer.TraitCollectionDidChange(UIKit.UITraitCollection previousTraitCollection) -> void
*REMOVED*~static Microsoft.Maui.Controls.VisualStateManager.GetVisualStateGroups(Microsoft.Maui.Controls.VisualElement visualElement) -> System.Collections.Generic.IList<Microsoft.Maui.Controls.VisualStateGroup>
Microsoft.Maui.Controls.AppThemeBinding
Expand Down Expand Up @@ -87,3 +87,7 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
~static readonly Microsoft.Maui.Controls.BackButtonBehavior.AccessibilityLabelProperty -> Microsoft.Maui.Controls.BindableProperty
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.get -> string
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.set -> void
Microsoft.Maui.Controls.BoxView.~BoxView() -> void
~Microsoft.Maui.Controls.BoxView.Fill.get -> Microsoft.Maui.Controls.Brush
~Microsoft.Maui.Controls.BoxView.Fill.set -> void
~static readonly Microsoft.Maui.Controls.BoxView.FillProperty -> Microsoft.Maui.Controls.BindableProperty
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
*REMOVED*~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRootRenderer.TraitCollectionDidChange(UIKit.UITraitCollection previousTraitCollection) -> void
*REMOVED*~static Microsoft.Maui.Controls.VisualStateManager.GetVisualStateGroups(Microsoft.Maui.Controls.VisualElement visualElement) -> System.Collections.Generic.IList<Microsoft.Maui.Controls.VisualStateGroup>
Microsoft.Maui.Controls.AppThemeBinding
Expand Down Expand Up @@ -87,3 +87,7 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
~static readonly Microsoft.Maui.Controls.BackButtonBehavior.AccessibilityLabelProperty -> Microsoft.Maui.Controls.BindableProperty
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.get -> string
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.set -> void
Microsoft.Maui.Controls.BoxView.~BoxView() -> void
~Microsoft.Maui.Controls.BoxView.Fill.get -> Microsoft.Maui.Controls.Brush
~Microsoft.Maui.Controls.BoxView.Fill.set -> void
~static readonly Microsoft.Maui.Controls.BoxView.FillProperty -> Microsoft.Maui.Controls.BindableProperty
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.set -> void
static Microsoft.Maui.Controls.Toolbar.MapBackButtonAccessibilityLabel(Microsoft.Maui.Handlers.IToolbarHandler! handler, Microsoft.Maui.Controls.Toolbar! toolbar) -> void
static Microsoft.Maui.Controls.Toolbar.MapBackButtonAccessibilityLabel(Microsoft.Maui.Handlers.ToolbarHandler! handler, Microsoft.Maui.Controls.Toolbar! toolbar) -> void
Microsoft.Maui.Controls.BoxView.~BoxView() -> void
~Microsoft.Maui.Controls.BoxView.Fill.get -> Microsoft.Maui.Controls.Brush
~Microsoft.Maui.Controls.BoxView.Fill.set -> void
~static readonly Microsoft.Maui.Controls.BoxView.FillProperty -> Microsoft.Maui.Controls.BindableProperty
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.set -> void
static Microsoft.Maui.Controls.Toolbar.MapBackButtonAccessibilityLabel(Microsoft.Maui.Handlers.IToolbarHandler! arg1, Microsoft.Maui.Controls.Toolbar! arg2) -> void
static Microsoft.Maui.Controls.Toolbar.MapBackButtonAccessibilityLabel(Microsoft.Maui.Handlers.ToolbarHandler! arg1, Microsoft.Maui.Controls.Toolbar! arg2) -> void
Microsoft.Maui.Controls.BoxView.~BoxView() -> void
~Microsoft.Maui.Controls.BoxView.Fill.get -> Microsoft.Maui.Controls.Brush
~Microsoft.Maui.Controls.BoxView.Fill.set -> void
~static readonly Microsoft.Maui.Controls.BoxView.FillProperty -> Microsoft.Maui.Controls.BindableProperty
6 changes: 5 additions & 1 deletion src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
*REMOVED*~static Microsoft.Maui.Controls.VisualStateManager.GetVisualStateGroups(Microsoft.Maui.Controls.VisualElement visualElement) -> System.Collections.Generic.IList<Microsoft.Maui.Controls.VisualStateGroup>
Microsoft.Maui.Controls.AppThemeBinding
Microsoft.Maui.Controls.AppThemeBinding.AppThemeBinding() -> void
Expand Down Expand Up @@ -81,3 +81,7 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
~static readonly Microsoft.Maui.Controls.BackButtonBehavior.AccessibilityLabelProperty -> Microsoft.Maui.Controls.BindableProperty
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.get -> string
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.set -> void
Microsoft.Maui.Controls.BoxView.~BoxView() -> void
~Microsoft.Maui.Controls.BoxView.Fill.get -> Microsoft.Maui.Controls.Brush
~Microsoft.Maui.Controls.BoxView.Fill.set -> void
~static readonly Microsoft.Maui.Controls.BoxView.FillProperty -> Microsoft.Maui.Controls.BindableProperty
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
*REMOVED*~static Microsoft.Maui.Controls.VisualStateManager.GetVisualStateGroups(Microsoft.Maui.Controls.VisualElement visualElement) -> System.Collections.Generic.IList<Microsoft.Maui.Controls.VisualStateGroup>
Microsoft.Maui.Controls.ImageSource.InvalidateStyle() -> void
Microsoft.Maui.Controls.LongPressGestureRecognizer
Expand Down Expand Up @@ -72,3 +72,7 @@ virtual Microsoft.Maui.Controls.LongPressingEventArgs.GetPosition(Microsoft.Maui
~static readonly Microsoft.Maui.Controls.BackButtonBehavior.AccessibilityLabelProperty -> Microsoft.Maui.Controls.BindableProperty
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.get -> string
~Microsoft.Maui.Controls.Toolbar.BackButtonAccessibilityLabel.set -> void
Microsoft.Maui.Controls.BoxView.~BoxView() -> void
~Microsoft.Maui.Controls.BoxView.Fill.get -> Microsoft.Maui.Controls.Brush
~Microsoft.Maui.Controls.BoxView.Fill.set -> void
~static readonly Microsoft.Maui.Controls.BoxView.FillProperty -> Microsoft.Maui.Controls.BindableProperty
44 changes: 0 additions & 44 deletions src/Controls/src/Core/Shapes/Shape.cs
Original file line number Diff line number Diff line change
Expand Up @@ -513,49 +513,5 @@ internal virtual double HeightForPathComputation
return height == -1 ? _fallbackHeight : height;
}
}

class WeakBrushChangedProxy : WeakEventProxy<Brush, EventHandler>
{
void OnBrushChanged(object? sender, EventArgs e)
{
if (TryGetHandler(out var handler))
{
handler(sender, e);
}
else
{
Unsubscribe();
}
}

public override void Subscribe(Brush source, EventHandler handler)
{
if (TryGetSource(out var s))
{
s.PropertyChanged -= OnBrushChanged;

if (s is GradientBrush g)
g.InvalidateGradientBrushRequested -= OnBrushChanged;
}

source.PropertyChanged += OnBrushChanged;
if (source is GradientBrush gradientBrush)
gradientBrush.InvalidateGradientBrushRequested += OnBrushChanged;

base.Subscribe(source, handler);
}

public override void Unsubscribe()
{
if (TryGetSource(out var s))
{
s.PropertyChanged -= OnBrushChanged;

if (s is GradientBrush g)
g.InvalidateGradientBrushRequested -= OnBrushChanged;
}
base.Unsubscribe();
}
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading