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
64 changes: 36 additions & 28 deletions src/Controls/src/Core/Brush/BrushTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel;
Expand Down Expand Up @@ -27,17 +26,17 @@ public class BrushTypeConverter : TypeConverter
/// <include file="../../docs/Microsoft.Maui.Controls/BrushTypeConverter.xml" path="//Member[@MemberName='Hsla']/Docs/*" />
public const string Hsla = "hsla";

readonly ColorTypeConverter _colorTypeConverter = new ColorTypeConverter();
readonly ColorTypeConverter _colorTypeConverter = new();

public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
=> sourceType == typeof(string)
|| sourceType == typeof(Color)
|| sourceType == typeof(Paint);

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
=> destinationType == typeof(Paint);

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is Color colorValue)
{
Expand All @@ -50,7 +49,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c

var strValue = value?.ToString();

if (strValue != null)
if (strValue is not null)
{
strValue = strValue.Trim();

Expand All @@ -59,29 +58,34 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c
var gradientBrushParser = new GradientBrushParser(_colorTypeConverter);
var brush = gradientBrushParser.Parse(strValue);

if (brush != null)
if (brush is not null)
{
return brush;
}
}

if (strValue.StartsWith(Rgb, StringComparison.InvariantCulture) || strValue.StartsWith(Rgba, StringComparison.InvariantCulture) || strValue.StartsWith(Hsl, StringComparison.InvariantCulture) || strValue.StartsWith(Hsla))
if (strValue.StartsWith(Rgb, StringComparison.InvariantCulture)
|| strValue.StartsWith(Rgba, StringComparison.InvariantCulture)
|| strValue.StartsWith(Hsl, StringComparison.InvariantCulture)
|| strValue.StartsWith(Hsla, StringComparison.InvariantCulture))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

StringComparison.InvariantCulture was missing for Hsla, so I added it.

{
var color = (Color)_colorTypeConverter.ConvertFromInvariantString(strValue);
var color = (Color?)_colorTypeConverter.ConvertFromInvariantString(strValue);
return new SolidColorBrush(color);
}
}

string[] parts = strValue.Split('.');
string[] parts = strValue.Split('.');

if (parts.Length == 1 || (parts.Length == 2 && parts[0] == "Color"))
{
var color = (Color)_colorTypeConverter.ConvertFromInvariantString(strValue);
return new SolidColorBrush(color);
if (parts.Length == 1 || (parts.Length == 2 && parts[0] == "Color"))
{
var color = (Color?)_colorTypeConverter.ConvertFromInvariantString(strValue);
return new SolidColorBrush(color);
}
}

return new SolidColorBrush(null);
}

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
{
if (value is Brush brush && destinationType == typeof(Paint))
{
Expand All @@ -94,26 +98,26 @@ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo cul
public class GradientBrushParser
{
readonly ColorTypeConverter _colorConverter;
GradientBrush _gradient;
string[] _parts;
GradientBrush? _gradient;
string[]? _parts;
int _position;

public GradientBrushParser(ColorTypeConverter colorConverter = null)
public GradientBrushParser(ColorTypeConverter? colorConverter = null)
{
_colorConverter = colorConverter ?? new ColorTypeConverter();
_colorConverter = colorConverter ?? new();
}

public GradientBrush Parse(string css)
public GradientBrush? Parse(string? css)
{
if (string.IsNullOrWhiteSpace(css))
{
return _gradient;
}

#if NETSTANDARD2_0
_parts = css.Replace("\r\n", "")
_parts = css!.Replace("\r\n", "")
#else
_parts = css.Replace("\r\n", "", StringComparison.Ordinal)
_parts = css!.Replace("\r\n", "", StringComparison.Ordinal)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For some reason string.IsNullOrWhiteSpace(css) is not enough for the analyzer to realize that css is not null at this point. (if (css is null || css = "") would be an alternative to avoid the ! operator.

#endif
.Split(new[] { '(', ')', ',' }, StringSplitOptions.RemoveEmptyEntries);

Expand All @@ -125,7 +129,7 @@ public GradientBrush Parse(string css)
if (part.StartsWith("#", StringComparison.Ordinal))
{
var parts = part.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var color = (Color)_colorConverter.ConvertFromInvariantString(parts[0]);
var color = (Color)_colorConverter.ConvertFromInvariantString(parts[0])!;

if (TryParseOffsets(parts, out var offsets))
AddGradientStops(color, offsets);
Expand All @@ -138,7 +142,7 @@ public GradientBrush Parse(string css)
if (colorParts[0].Equals("Color", StringComparison.Ordinal))
{
var parts = part.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var color = (Color)_colorConverter.ConvertFromInvariantString(parts[0]);
var color = (Color)_colorConverter.ConvertFromInvariantString(parts[0])!;

if (TryParseOffsets(parts, out var offsets))
AddGradientStops(color, offsets);
Expand Down Expand Up @@ -169,7 +173,7 @@ public GradientBrush Parse(string css)

colorString.Append(')');

var color = (Color)_colorConverter.ConvertFromInvariantString(colorString.ToString());
var color = (Color)_colorConverter.ConvertFromInvariantString(colorString.ToString())!;
var parts = GetNextPart().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

if (TryParseOffsets(parts, out var offsets))
Expand Down Expand Up @@ -211,7 +215,7 @@ public GradientBrush Parse(string css)

string GetPart()
{
if (!(_position < _parts.Length))
if (!(_position < _parts!.Length))
return string.Empty;

return _parts[_position];
Expand Down Expand Up @@ -259,13 +263,15 @@ void AddGradientStop(Color color, float? offset = null)
Offset = offset ?? -1
};

_gradient.GradientStops.Add(gradientStop);
_gradient!.GradientStops.Add(gradientStop);
}

void AddGradientStops(Color color, IEnumerable<float> offsets)
{
foreach (var offset in offsets)
{
AddGradientStop(color, offset);
}
}

Tuple<Point, Point> GetCoordinatesByAngle(double angle)
Expand Down Expand Up @@ -417,7 +423,9 @@ bool TryParseOffsets(string[] parts, out float[] result)
foreach (var part in parts)
{
if (TryParseOffset(part, out var offset))
{
offsets.Add(offset);
}
}

result = offsets.ToArray();
Expand Down
20 changes: 13 additions & 7 deletions src/Controls/src/Core/ColumnDefinitionCollectionTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#nullable disable
using System;
using System.ComponentModel;
using System.Globalization;
Expand All @@ -11,34 +10,41 @@ namespace Microsoft.Maui.Controls
[ProvideCompiled("Microsoft.Maui.Controls.XamlC.ColumnDefinitionCollectionTypeConverter")]
public class ColumnDefinitionCollectionTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
=> sourceType == typeof(string);

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
=> destinationType == typeof(string);

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
var strValue = value?.ToString();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In an ideal world, we would go with

Suggested change
var strValue = value?.ToString();
var strValue = value.ToString();

but that would change behavior. This approach is used even in other converters.


if (strValue != null)
if (strValue is not null)
{
var lengths = strValue.Split(',');
var converter = new GridLengthTypeConverter();
var definitions = new ColumnDefinition[lengths.Length];

for (var i = 0; i < lengths.Length; i++)
definitions[i] = new ColumnDefinition { Width = (GridLength)converter.ConvertFromInvariantString(lengths[i]) };
{
definitions[i] = new ColumnDefinition { Width = (GridLength)converter.ConvertFromInvariantString(lengths[i])! };
}

return new ColumnDefinitionCollection(definitions);
}

throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", strValue, typeof(ColumnDefinitionCollection)));
}


public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
{
if (value is not ColumnDefinitionCollection cdc)
{
throw new NotSupportedException();
}

var converter = new GridLengthTypeConverter();
return string.Join(", ", cdc.Select(cd => converter.ConvertToInvariantString(cd.Width)));
}
Expand Down
9 changes: 4 additions & 5 deletions src/Controls/src/Core/DecorableTextElement.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#nullable disable
using System;
using System.ComponentModel;
using System.Globalization;
Expand All @@ -14,13 +13,13 @@ static class DecorableTextElement
/// <include file="../../docs/Microsoft.Maui.Controls/TextDecorationConverter.xml" path="Type[@FullName='Microsoft.Maui.Controls.TextDecorationConverter']/Docs/*" />
public class TextDecorationConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
=> sourceType == typeof(string);

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
=> destinationType == typeof(string);

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
var strValue = value?.ToString();

Expand All @@ -46,7 +45,7 @@ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo c
return result;
}

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
{
if (value is not TextDecorations td)
throw new NotSupportedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,36 @@ override Microsoft.Maui.Controls.LayoutOptionsConverter.GetStandardValuesSupport
override Microsoft.Maui.Controls.LayoutOptionsConverter.GetStandardValuesExclusive(System.ComponentModel.ITypeDescriptorContext? context) -> bool
override Microsoft.Maui.Controls.LayoutOptionsConverter.GetStandardValues(System.ComponentModel.ITypeDescriptorContext? context) -> System.ComponentModel.TypeConverter.StandardValuesCollection!
Microsoft.Maui.Controls.IExtendedTypeConverter.ConvertFromInvariantString(string! value, System.IServiceProvider! serviceProvider) -> object?
override Microsoft.Maui.Controls.Shapes.PathGeometryConverter.CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type! sourceType) -> bool
override Microsoft.Maui.Controls.Shapes.PathGeometryConverter.CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) -> bool
override Microsoft.Maui.Controls.Shapes.PathGeometryConverter.ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object! value) -> object?
override Microsoft.Maui.Controls.Shapes.PathGeometryConverter.ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type! destinationType) -> object?
override Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type! sourceType) -> bool
override Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) -> bool
override Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object! value) -> object?
override Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type! destinationType) -> object?
override Microsoft.Maui.Controls.Shapes.MatrixTypeConverter.CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type! sourceType) -> bool
override Microsoft.Maui.Controls.Shapes.MatrixTypeConverter.CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) -> bool
override Microsoft.Maui.Controls.Shapes.MatrixTypeConverter.ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object! value) -> object?
override Microsoft.Maui.Controls.Shapes.MatrixTypeConverter.ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type! destinationType) -> object?
override Microsoft.Maui.Controls.TextDecorationConverter.CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type! sourceType) -> bool
override Microsoft.Maui.Controls.TextDecorationConverter.CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) -> bool
override Microsoft.Maui.Controls.TextDecorationConverter.ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object! value) -> object?
override Microsoft.Maui.Controls.TextDecorationConverter.ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type! destinationType) -> object?
override Microsoft.Maui.Controls.ColumnDefinitionCollectionTypeConverter.CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type! sourceType) -> bool
override Microsoft.Maui.Controls.ColumnDefinitionCollectionTypeConverter.CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) -> bool
override Microsoft.Maui.Controls.ColumnDefinitionCollectionTypeConverter.ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object! value) -> object?
override Microsoft.Maui.Controls.ColumnDefinitionCollectionTypeConverter.ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type! destinationType) -> object?
override Microsoft.Maui.Controls.BrushTypeConverter.CanConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Type! sourceType) -> bool
override Microsoft.Maui.Controls.BrushTypeConverter.CanConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Type? destinationType) -> bool
override Microsoft.Maui.Controls.BrushTypeConverter.ConvertFrom(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object! value) -> object?
override Microsoft.Maui.Controls.BrushTypeConverter.ConvertTo(System.ComponentModel.ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object? value, System.Type! destinationType) -> object?
const Microsoft.Maui.Controls.BrushTypeConverter.Hsl = "hsl" -> string!
const Microsoft.Maui.Controls.BrushTypeConverter.Hsla = "hsla" -> string!
const Microsoft.Maui.Controls.BrushTypeConverter.LinearGradient = "linear-gradient" -> string!
const Microsoft.Maui.Controls.BrushTypeConverter.RadialGradient = "radial-gradient" -> string!
const Microsoft.Maui.Controls.BrushTypeConverter.Rgb = "rgb" -> string!
const Microsoft.Maui.Controls.BrushTypeConverter.Rgba = "rgba" -> string!
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.GradientBrushParser(Microsoft.Maui.Graphics.Converters.ColorTypeConverter? colorConverter = null) -> void
Microsoft.Maui.Controls.BrushTypeConverter.GradientBrushParser.Parse(string? css) -> Microsoft.Maui.Controls.GradientBrush?
static Microsoft.Maui.Controls.Shapes.PathFigureCollectionConverter.ParseStringToPathFigureCollection(Microsoft.Maui.Controls.Shapes.PathFigureCollection! pathFigureCollection, string? pathString) -> void
Loading
Loading