Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge sr9 into net9 ga #25265

Merged
merged 22 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f91ee55
Revert "[X] do not apply Bindings if DataType doesnt match (#22056)" …
PureWeen Sep 12, 2024
d20d980
8.0.90 Release Branding (#24727)
PureWeen Sep 12, 2024
a249a31
[release/8.0.1xx-sr9] Add Padding for iOS Buttons in some scenarios (…
github-actions[bot] Sep 19, 2024
adcbc7d
[release/8.0.1xx-sr9] [C] fix specificity comparison (#24908)
github-actions[bot] Sep 24, 2024
0fce6c7
8.0.91 Release Branding (#24915)
PureWeen Sep 24, 2024
b2ab38e
[C] avoid NRE on null GesturRecognizer (#25029)
github-actions[bot] Oct 1, 2024
a8f9f60
[release/8.0.1xx-sr9] [iOS] Fix for the CollectionView to prevent dup…
github-actions[bot] Oct 1, 2024
1908429
[release/8.0.1xx-sr9] [X] allow namescope resolution before parenting…
github-actions[bot] Oct 4, 2024
011655f
[release/8.0.1xx-sr9] Revert #24222 and simply use `invalidate` inste…
github-actions[bot] Oct 8, 2024
ad27103
Preview SR9.2 branding (#25161)
PureWeen Oct 10, 2024
a800edb
[iOS] Text alignment in editor - improvements (#24859) (#25158)
PureWeen Oct 10, 2024
54268ce
[release/8.0.1xx-sr9] Fixed Microsoft.Maui.Controls 8.0.90 (Latest st…
PureWeen Oct 10, 2024
0294301
[release/8.0.1xx-sr9] Fix Regression with iOS button resizing with te…
tj-devel709 Oct 14, 2024
006fefb
[release/8.0.1xx-sr9] NullReferenceException when setting BarBackgrou…
PureWeen Oct 14, 2024
ed5a558
Merge remote-tracking branch 'origin/release/8.0.1xx-sr9' into merge_…
PureWeen Oct 14, 2024
57404b8
Update aar file
PureWeen Oct 14, 2024
a684dc3
Fix Missing IXamlDataTypeProvider.cs from Merge
PureWeen Oct 14, 2024
bece4b5
Merge branch 'release/9.0.1xx' into merge_sr9_into_net9_ga
PureWeen Oct 17, 2024
47d9623
Merge branch 'release/9.0.1xx' into merge_sr9_into_net9_ga
PureWeen Oct 18, 2024
af43d7e
Merge branch 'release/9.0.1xx' into merge_sr9_into_net9_ga
PureWeen Oct 18, 2024
676fcbb
Merge branch 'release/9.0.1xx' into merge_sr9_into_net9_ga
PureWeen Oct 18, 2024
11d68e2
Fix ScreenShots for New visual comparison code
PureWeen Oct 19, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ public void Visit(ElementNode node, INode parentNode)
}
if (setNameScope && Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Cache, Context.Body.Method.Module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "BindableObject"))))
SetNameScope(node, namescopeVarDef);
//workaround when VSM tries to apply state before parenting
else if (Context.Variables[node].VariableType.InheritsFromOrImplements(Context.Cache, Context.Body.Method.Module.ImportReference(Context.Cache, ("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Element"))))
{
var module = Context.Body.Method.Module;
var parameterTypes = new[] {
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "Element"),
("Microsoft.Maui.Controls", "Microsoft.Maui.Controls.Internals", "INameScope"),
};
Context.IL.Append(Context.Variables[node].LoadAs(Context.Cache, module.GetTypeDefinition(Context.Cache, parameterTypes[0]), module));
Context.IL.Append(namescopeVarDef.LoadAs(Context.Cache, module.GetTypeDefinition(Context.Cache, parameterTypes[1]), module));
Context.IL.Emit(OpCodes.Stfld, module.ImportFieldReference(Context.Cache, parameterTypes[0], nameof(Element.transientNamescope)));
}
Context.Scopes[node] = new Tuple<VariableDefinition, IList<string>>(namescopeVarDef, namesInNamescope);
}

Expand Down
71 changes: 32 additions & 39 deletions src/Controls/src/Core/Button/Button.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ namespace Microsoft.Maui.Controls
{
public partial class Button : ICrossPlatformLayout
{
// _originalImageSize and _originalImageSource are used to ensure we don't resize the image
// larger than the original image size and to ensure if a new image is loaded, we use that image's size for resizing.
CGSize _originalImageSize = CGSize.Empty;

// _isFirstMeasure is a flag to make sure we manually recalculate the titleRect when there are dynamic changes to the button.
// There are times the platformButton.TitleLabel is updated on dynamic changes and reacts to the change by truncating the label when we actually
// have space in our constraints. We provide the space to be used in our first measure of the titleRect and then use the newly laid out titleRect in later iterations.
bool _isFirstMeasure = true;
string _originalImageSource = string.Empty;

/// <summary>
/// Measure the desired size of the button based on the image and title size taking into account
Expand Down Expand Up @@ -86,8 +84,9 @@ Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double he
if (image is not null)
{
// Save the original image size for later image resizing
if (_originalImageSize == CGSize.Empty)
if (_originalImageSize == CGSize.Empty || _originalImageSource == string.Empty || _originalImageSource != button.ImageSource.ToString())
{
_originalImageSource = button.ImageSource.ToString();
_originalImageSize = image.Size;
}

Expand Down Expand Up @@ -144,11 +143,8 @@ Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double he
}
}

// if we are in a scenario with unlimited width and the image is on top or bottom,
// of if the horizontalOption is not fill and the image is on top or bottom,
// let's make sure the title is not cut off by ensuring we have enough padding for the image and title.
// if the image is on top or bottom, let's make sure the title is not cut off by ensuring we have enough padding for the image and title.
if (image is not null
&& (widthConstraint == double.PositiveInfinity || button.HorizontalOptions != LayoutOptions.Fill)
&& (layout.Position == ButtonContentLayout.ImagePosition.Top || layout.Position == ButtonContentLayout.ImagePosition.Bottom))
{
var maxTitleRect = ComputeTitleRect(platformButton, button, image, double.PositiveInfinity, double.PositiveInfinity, borderWidth, padding, true);
Expand All @@ -163,8 +159,6 @@ Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double he
var returnSize = new Size(Math.Min(buttonContentWidth, widthConstraint),
Math.Min(buttonContentHeight, heightConstraint));

_isFirstMeasure = false;

// Rounding the values up to the nearest whole number to match UIView.SizeThatFits
return new Size((int)Math.Ceiling(returnSize.Width), (int)Math.Ceiling(returnSize.Height));
}
Expand All @@ -183,8 +177,6 @@ Size ICrossPlatformLayout.CrossPlatformArrange(Rect bounds)
// Layout the image and title of the button
LayoutButton(platformButton, this, bounds);

_isFirstMeasure = true;

return new Size(bounds.Width, bounds.Height);
}

Expand Down Expand Up @@ -292,39 +284,40 @@ CGRect ComputeTitleRect (UIButton platformButton, Button button, UIImage image,
return CGRect.Empty;
}

// Use the current TitleLabel if it is set and valid
var titleRect = platformButton.TitleLabel.Bounds;
var titleWidthConstraint = widthConstraint - ((nfloat)borderWidth * 2);
var titleHeightConstraint = heightConstraint - ((nfloat)borderWidth * 2);

if ((isMeasuring && _isFirstMeasure) || titleRect.Height == 0 || titleRect.Width == 0)
if (image is not null && !string.IsNullOrEmpty(platformButton.CurrentTitle) && titleWidthConstraint != double.PositiveInfinity)
{
var titleWidthConstraint = widthConstraint - ((nfloat)borderWidth * 2);
var titleHeightConstraint = heightConstraint - ((nfloat)borderWidth * 2);
// In non-UIButtonConfiguration setups, the title will always be truncated by the image's width
// even when the image is on top or bottom.
titleWidthConstraint -= image.Size.Width;
}

if (image is not null && !string.IsNullOrEmpty(platformButton.CurrentTitle) && titleWidthConstraint != double.PositiveInfinity)
{
// In non-UIButtonConfiguration setups, the title will always be truncated by the image's width
// even when the image is on top or bottom.
titleWidthConstraint -= image.Size.Width;
}
if (image is not null && button.ContentLayout.Position == ButtonContentLayout.ImagePosition.Left || button.ContentLayout.Position == ButtonContentLayout.ImagePosition.Right)
{
titleWidthConstraint -= (nfloat)(button.ContentLayout.Spacing + padding.Left + padding.Right);
}

if (image is not null && button.ContentLayout.Position == ButtonContentLayout.ImagePosition.Left || button.ContentLayout.Position == ButtonContentLayout.ImagePosition.Right)
{
titleWidthConstraint -= (nfloat)(button.ContentLayout.Spacing + padding.Left + padding.Right);
}
else if (image is null)
{
titleWidthConstraint -= (nfloat)(padding.Left + padding.Right);
}

else if (image is null)
{
titleWidthConstraint -= (nfloat)(padding.Left + padding.Right);
}
var titleRect = platformButton.GetTitleBoundingRect(titleWidthConstraint, titleHeightConstraint);

titleRect = platformButton.GetTitleBoundingRect(titleWidthConstraint, titleHeightConstraint);
}
var currentTitleText = platformButton.CurrentTitle;

// Measure the width of the sample character string using the same font as the TitleLabel. If a character cannot fit in the titleRect, let's use a zero size.
var minimumCharacterWidth = new Foundation.NSString("A").GetSizeUsingAttributes(new UIStringAttributes { Font = platformButton.TitleLabel.Font });
if (double.IsNaN(titleRect.Width) || double.IsNaN(titleRect.Height) || titleRect.Width < minimumCharacterWidth.Width)
// We will only do this for buttons with image on left and right because the left and right padding are handled differently
// when the image is on the top or bottom
if (currentTitleText.Length > 0 && button.ContentLayout.Position == ButtonContentLayout.ImagePosition.Left || button.ContentLayout.Position == ButtonContentLayout.ImagePosition.Right)
{
titleRect = Rect.Zero;
// Measure the width of the first character in the string using the same font as the TitleLabel. If a character cannot fit in the titleRect, let's use a zero size.
var minimumCharacterWidth = new Foundation.NSString(currentTitleText.Substring(0,1)).GetSizeUsingAttributes(new UIStringAttributes { Font = platformButton.TitleLabel.Font });
if (double.IsNaN(titleRect.Width) || double.IsNaN(titleRect.Height) || titleRect.Width < minimumCharacterWidth.Width)
{
titleRect = Rect.Zero;
}
}

return titleRect;
Expand Down
8 changes: 7 additions & 1 deletion src/Controls/src/Core/Element/Element.cs
Original file line number Diff line number Diff line change
Expand Up @@ -502,13 +502,19 @@ public bool EffectIsAttached(string name)
return false;
}

//this is only used by XAMLC, not added to public API
[EditorBrowsable(EditorBrowsableState.Never)]
#pragma warning disable RS0016 // Add public types and members to the declared API
public INameScope transientNamescope;
#pragma warning restore RS0016 // Add public types and members to the declared API

/// <summary>Returns the element that has the specified name.</summary>
/// <param name="name">The name of the element to be found.</param>
/// <returns>The element that has the specified name.</returns>
/// <exception cref="InvalidOperationException">Thrown if the element's namescope couldn't be found.</exception>
public object FindByName(string name)
{
var namescope = GetNameScope();
var namescope = GetNameScope() ?? transientNamescope;
if (namescope == null)
throw new InvalidOperationException("this element is not in a namescope");
return namescope.FindByName(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public NavigationPageToolbar(Maui.IElement parent, Page rootPage) : base(parent)
_toolbarTracker.CollectionChanged += OnToolbarItemsChanged;
RootPage = rootPage;
_toolbarTracker.PageAppearing += OnPageAppearing;
_toolbarTracker.PagePropertyChanged += OnPagePropertyChanged;
_toolbarTracker.Target = RootPage;
}

Expand Down Expand Up @@ -71,6 +70,7 @@ void OnPageAppearing(object sender, EventArgs e)
if (sender is not ContentPage cp)
return;

_toolbarTracker.PagePropertyChanged -= OnPagePropertyChanged;
_currentPage = cp;
_currentNavigationPage = _currentPage.FindParentOfType<NavigationPage>();

Expand Down Expand Up @@ -112,6 +112,7 @@ void OnPageAppearing(object sender, EventArgs e)
_hasAppeared = true;

ApplyChanges(_currentNavigationPage);
_toolbarTracker.PagePropertyChanged += OnPagePropertyChanged;
}

// This is to catch scenarios where the user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ internal static CGRect GetTitleBoundingRect(this UIButton platformButton, double
NSStringDrawingOptions.UsesLineFragmentOrigin | NSStringDrawingOptions.UsesFontLeading | NSStringDrawingOptions.UsesDeviceMetrics,
null);

return new CGRect(boundingRectWithDeviceMetrics.Location, new CGSize(Math.Max(boundingRect.Width, boundingRectWithDeviceMetrics.Width), Math.Min(availableHeight, boundingRect.Height)));
return new CGRect(boundingRectWithDeviceMetrics.Location,
new CGSize(Math.Ceiling(Math.Max(boundingRect.Width, boundingRectWithDeviceMetrics.Width)),
Math.Ceiling(Math.Min(availableHeight, boundingRect.Height))));
}

return CGRect.Empty;
Expand Down
13 changes: 8 additions & 5 deletions src/Controls/src/Core/View/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,11 @@ void AddItems(IList newItems)
foreach (IElementDefinition item in newItems)
{
var gestureRecognizer = item as IGestureRecognizer;
ValidateGesture(gestureRecognizer);
item.Parent = this;
GestureController.CompositeGestureRecognizers.Add(gestureRecognizer);
if (ValidateGesture(gestureRecognizer))
{
item.Parent = this;
GestureController.CompositeGestureRecognizers.Add(gestureRecognizer);
}
}
}

Expand Down Expand Up @@ -266,12 +268,13 @@ static void MarginPropertyChanged(BindableObject bindable, object oldValue, obje
((View)bindable).InvalidateMeasureInternal(InvalidationTrigger.MarginChanged);
}

void ValidateGesture(IGestureRecognizer gesture)
bool ValidateGesture(IGestureRecognizer gesture)
{
if (gesture == null)
return;
return false;
if (gesture is PinchGestureRecognizer && _gestureRecognizers.GetGesturesFor<PinchGestureRecognizer>().Count() > 1)
throw new InvalidOperationException($"Only one {nameof(PinchGestureRecognizer)} per view is allowed");
return true;
}

#nullable enable
Expand Down
5 changes: 5 additions & 0 deletions src/Controls/src/Xaml/CreateValuesVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ public void Visit(ElementNode node, INode parentNode)
if (value is BindableObject bindableValue && node.NameScopeRef != (parentNode as IElementNode)?.NameScopeRef)
NameScope.SetNameScope(bindableValue, node.NameScopeRef.NameScope);

//Workaround for when a VSM is applied before parenting
if (value is Element iElement)
iElement.transientNamescope = node.NameScopeRef.NameScope;


var assemblyName = (Context.RootAssembly ?? Context.RootElement?.GetType().Assembly)?.GetName().Name;
if (assemblyName != null && value != null && !value.GetType().IsValueType && XamlFilePathAttribute.GetFilePathForObject(Context.RootElement) is string path)
VisualDiagnostics.RegisterSourceInfo(value, new Uri($"{path};assembly={assemblyName}", UriKind.Relative), ((IXmlLineInfo)node).LineNumber, ((IXmlLineInfo)node).LinePosition);
Expand Down
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.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<MauiImage Update="Resources\Images\dotnet_bot.svg" Color="#FFFFFF" BaseSize="168,208" />
<MauiImage Update="Resources\Images\dotnet_bot_resized.svg" Color="#FFFFFF" BaseSize="20,20" />
<MauiImage Update="Resources\Images\dotnet_bot_resized2.svg" Color="#FFFFFF" BaseSize="40,40" />
<MauiImage Update="Resources\Images\dotnet_bot_resized3.svg" Color="#FFFFFF" BaseSize="70,70" />
<MauiImage Include="Resources\Images\dotnet_bot.svg" Link="Resources\Images\small_dotnet_bot.svg" Color="#FFFFFF" BaseSize="64,64" />
<MauiImage Include="Resources\AppIcons\appicon.svg" ForegroundFile="Resources\AppIcons\appicon_foreground.svg" IsAppIcon="true" />
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#FFFFFF" BaseSize="168,208" />
Expand Down
17 changes: 17 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue24583.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Maui.Controls.Sample.Issues;

[XamlCompilation(XamlCompilationOptions.Compile)]
[Issue(IssueTracker.Github, 24583, "Text in the Editor control disappeared when reducing the Scale", PlatformAffected.iOS)]

public partial class Issue24583 : ContentPage
{
public Issue24583()
{
InitializeComponent();
}

private void Button_Clicked(object sender, EventArgs e)
{
editor1.Scale = editor2.Scale = editor3.Scale = 0.5;
}
}
32 changes: 32 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue24583.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue24583">
<StackLayout>
<Editor x:Name="editor1"
Text="1 2 3 4 5 6 7 8 9"
FontSize="50"
HeightRequest="200"
BackgroundColor="Red"
HorizontalOptions="Fill"
WidthRequest="300"/>
<Editor x:Name="editor2"
Text="1 2 3 4 5 6 7 8 9"
FontSize="50"
HeightRequest="200"
VerticalTextAlignment="Center"
BackgroundColor="Green"
HorizontalOptions="Fill"
WidthRequest="300"/>
<Editor x:Name="editor3"
Text="1 2 3 4 5 6 7 8 9"
FontSize="50"
HeightRequest="200"
VerticalTextAlignment="End"
BackgroundColor="Blue"
HorizontalOptions="Fill"
WidthRequest="300"/>
<Button Clicked="Button_Clicked"
AutomationId="button"/>
</StackLayout>
</ContentPage>
21 changes: 21 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25038.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Maui.Controls.Sample.Issues"
x:Class="Maui.Controls.Sample.Issues.Issue25038">

<StackLayout Padding="20">
<!-- First test case: Grid with entry having ClearButtonVisibility set to Never -->
<Grid x:Name="firstEntryGrid" IsVisible="False">
<Entry Text="Initial ClearButton Never Entry" x:Name="initialEntry" ClearButtonVisibility="Never" />
</Grid>

<!-- Second test case: Grid with entry where ClearButtonVisibility changes dynamically -->
<Grid x:Name="secondEntryGrid" IsVisible="False">
<Entry Text="Dynamic ClearButton Entry" x:Name="dynamicClearButtonEntry" ClearButtonVisibility="WhileEditing" />
</Grid>

<!-- Button to trigger the changes -->
<Button Text="Show Entries" AutomationId="button" Clicked="OnShowEntriesClicked"/>
</StackLayout>
</ContentPage>
27 changes: 27 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue25038.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.Maui.Controls.Internals;

namespace Maui.Controls.Sample.Issues
{
[XamlCompilation(XamlCompilationOptions.Compile)]
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 25038, "MAUI Entry in Windows always shows ClearButton if initially hidden and shown even if ClearButtonVisibility set to 'Never'", PlatformAffected.UWP)]
public partial class Issue25038 : ContentPage
{
public Issue25038()
{
InitializeComponent();
}

private void OnShowEntriesClicked(object sender, EventArgs e)
{
// Show the first Grid
firstEntryGrid.IsVisible = true;

// Show the second Grid
secondEntryGrid.IsVisible = true;

// Change ClearButtonVisibility of the second Entry to Never
dynamicClearButtonEntry.ClearButtonVisibility = ClearButtonVisibility.Never;
}
}
}
Loading
Loading