Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
5 changes: 4 additions & 1 deletion src/CommunityToolkit.Maui.UnitTests/BaseViewTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ static void InitializeServicesAndSetMockApplication(out IServiceProvider service
appBuilder.Services.AddTransientPopup<ShortLivedSelfClosingPopup, ShortLivedMockPageViewModel>();
appBuilder.Services.AddTransientPopup<GarbageCollectionHeavySelfClosingPopup, MockPageViewModel>();
appBuilder.Services.AddTransientPopup<SingleConstructionPopup, SingleConstructionViewModel>();

appBuilder.Services.AddTransientPopup<CustomButton>();

appBuilder.Services.AddTransientPopup<MockPopup>();
#endregion

Expand All @@ -82,4 +83,6 @@ static void InitializeServicesAndSetMockApplication(out IServiceProvider service

CreateViewHandler<MockPageHandler>(shell);
}

protected sealed class CustomButton : Button;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma warning disable CA1416
using CommunityToolkit.Maui.UnitTests.Services;
using CommunityToolkit.Maui.Views;
using Xunit;

namespace CommunityToolkit.Maui.UnitTests.Views;

#pragma warning disable CA1416
public class DefaultPopupSettingsTests : BaseTest
public class DefaultPopupSettingsTests : BaseViewTest
{
[Fact]
public void Popup_SetPopupDefaultsNotCalled_UsesPopupDefaults()
Expand Down Expand Up @@ -97,5 +98,103 @@ public void View_SetPopupDefaultsCalled_UsesDefaultPopupSettings()
Assert.Equal(defaultPopupSettings.VerticalOptions, popupBorder.VerticalOptions);
Assert.Equal(defaultPopupSettings.HorizontalOptions, popupBorder.HorizontalOptions);
}

[Fact(Timeout = (int)TestDuration.Medium)]
public void PopupService_View_SetPopupDefaultsCalled_UsesDefaultPopupSettings()
{
// Arrange
var defaultPopupSettings = new DefaultPopupSettings
{
CanBeDismissedByTappingOutsideOfPopup = false,
BackgroundColor = Colors.Orange,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Start,
Margin = 72,
Padding = 4
};

if (Application.Current?.Windows[0].Page is not Page page)
{
throw new InvalidOperationException("Page cannot be null");
}

var builder = MauiApp.CreateBuilder();
builder.UseMauiCommunityToolkit(options => { options.SetPopupDefaults(defaultPopupSettings); });

// Act
var popupService = ServiceProvider.GetRequiredService<IPopupService>();
popupService.ShowPopup<CustomButton>(page.Navigation);
Comment thread
TheCodeTraveler marked this conversation as resolved.

if (Application.Current.Windows[0].Page is not Shell { CurrentPage: PopupPage popupPage })
{
Assert.Fail("Popup page not found");
throw new InvalidOperationException("Popup page not found");
}
Comment thread
TheCodeTraveler marked this conversation as resolved.

var popupBorder = popupPage.Content.PopupBorder;
var popup = (Popup)(popupBorder.Content ?? throw new InvalidOperationException("PopupBorder Content cannot be null"));
var underlyingContentView = (ContentView)popup;

// Assert
Assert.Equal(defaultPopupSettings.BackgroundColor, popup.BackgroundColor);
Assert.Equal(defaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup, popup.CanBeDismissedByTappingOutsideOfPopup);
Assert.Equal(defaultPopupSettings.Margin, popupBorder.Margin);
Assert.Equal(defaultPopupSettings.VerticalOptions, popupBorder.VerticalOptions);
Assert.Equal(defaultPopupSettings.HorizontalOptions, popupBorder.HorizontalOptions);
Assert.Equal(defaultPopupSettings.Padding, popup.Padding);
Assert.Equal(defaultPopupSettings.Padding, underlyingContentView.Padding);
Assert.Equal(Thickness.Zero, underlyingContentView.Margin);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.HorizontalOptions);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.VerticalOptions);
}

[Fact(Timeout = (int)TestDuration.Medium)]
public void PopupService_Popup_SetPopupDefaultsCalled_UsesDefaultPopupSettings()
{
// Arrange
var defaultPopupSettings = new DefaultPopupSettings
{
CanBeDismissedByTappingOutsideOfPopup = true,
BackgroundColor = Colors.Orange,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Start,
Margin = 72,
Padding = 4
};

if (Application.Current?.Windows[0].Page is not Page page)
{
throw new InvalidOperationException("Page cannot be null");
}

var builder = MauiApp.CreateBuilder();
builder.UseMauiCommunityToolkit(options => { options.SetPopupDefaults(defaultPopupSettings); });

// Act
var popupService = ServiceProvider.GetRequiredService<IPopupService>();
popupService.ShowPopup<MockPopup>(page.Navigation);

Comment thread
TheCodeTraveler marked this conversation as resolved.
if (Application.Current.Windows[0].Page is not Shell { CurrentPage: PopupPage popupPage })
{
Assert.Fail("Popup page not found");
throw new InvalidOperationException("Popup page not found");
}
Comment thread
TheCodeTraveler marked this conversation as resolved.
Comment thread
TheCodeTraveler marked this conversation as resolved.

var popupBorder = popupPage.Content.PopupBorder;
var popup = (Popup)(popupBorder.Content ?? throw new InvalidOperationException("PopupBorder Content cannot be null"));
var underlyingContentView = (ContentView)popup;

// Assert
Assert.Equal(defaultPopupSettings.BackgroundColor, popup.BackgroundColor);
Assert.Equal(defaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup, popup.CanBeDismissedByTappingOutsideOfPopup);
Assert.Equal(defaultPopupSettings.Margin, popupBorder.Margin);
Assert.Equal(defaultPopupSettings.VerticalOptions, popupBorder.VerticalOptions);
Assert.Equal(defaultPopupSettings.HorizontalOptions, popupBorder.HorizontalOptions);
Assert.Equal(defaultPopupSettings.Padding, popup.Padding);
Assert.Equal(defaultPopupSettings.Padding, underlyingContentView.Padding);
Assert.Equal(Thickness.Zero, underlyingContentView.Margin);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.HorizontalOptions);
Assert.Equal(LayoutOptions.Fill, underlyingContentView.VerticalOptions);
}
}
#pragma warning restore CA1416
32 changes: 22 additions & 10 deletions src/CommunityToolkit.Maui/Views/Popup/Popup.shared.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

using System.Diagnostics.CodeAnalysis;
Comment thread
TheCodeTraveler marked this conversation as resolved.
Outdated
using CommunityToolkit.Maui.Extensions;

namespace CommunityToolkit.Maui.Views;
Expand All @@ -18,6 +19,7 @@ public Popup()
HorizontalOptions = Options.DefaultPopupSettings.HorizontalOptions;
VerticalOptions = Options.DefaultPopupSettings.VerticalOptions;
BackgroundColor = Options.DefaultPopupSettings.BackgroundColor;
CanBeDismissedByTappingOutsideOfPopup = Options.DefaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup;
}

/// <summary>
Expand All @@ -34,33 +36,43 @@ public Popup()
/// Gets or sets the margin between the <see cref="Popup"/> and the edge of the window.
/// </summary>
[BindableProperty]
public new partial Thickness Margin { get; set; } = Options.DefaultPopupSettings.Margin;

/// <summary>
/// Gets or sets the padding between the <see cref="Popup"/> border and the <see cref="Popup"/> content.
/// </summary>
[BindableProperty]
public new partial Thickness Padding { get; set; } = Options.DefaultPopupSettings.Padding;
public new partial Thickness? Margin { get; set; }

/// <summary>
/// Gets or sets the horizontal position of the <see cref="Popup"/> when displayed on screen.
/// </summary>
[BindableProperty]
public new partial LayoutOptions HorizontalOptions { get; set; } = Options.DefaultPopupSettings.HorizontalOptions;
public new partial LayoutOptions? HorizontalOptions { get; set; }

/// <summary>
/// Gets or sets the vertical position of the <see cref="Popup"/> when displayed on screen.
/// </summary>
[BindableProperty]
public new partial LayoutOptions VerticalOptions { get; set; } = Options.DefaultPopupSettings.VerticalOptions;
public new partial LayoutOptions? VerticalOptions { get; set; }

Comment thread
TheCodeTraveler marked this conversation as resolved.
/// <inheritdoc cref="IPopupOptions.CanBeDismissedByTappingOutsideOfPopup"/> />
/// <remarks>
/// When true and the user taps outside the popup, it will dismiss.
/// On Android - when false the hardware back button is disabled.
/// </remarks>
[BindableProperty]
public partial bool CanBeDismissedByTappingOutsideOfPopup { get; set; } = Options.DefaultPopupSettings.CanBeDismissedByTappingOutsideOfPopup;
public partial bool CanBeDismissedByTappingOutsideOfPopup { get; set; }

/// <summary>
/// Gets or sets the padding between the <see cref="Popup"/> border and the <see cref="Popup"/> content.
/// </summary>
public new Thickness? Padding
{
get => field is not null ? base.Padding : field;
set
{
field = value;
if (value is not null)
{
base.Padding = value.Value;
}
Comment thread
TheCodeTraveler marked this conversation as resolved.
Outdated
}
}
Comment thread
TheCodeTraveler marked this conversation as resolved.

/// <summary>
/// Close the Popup.
Expand Down
18 changes: 9 additions & 9 deletions src/CommunityToolkit.Maui/Views/Popup/PopupPage.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -278,39 +278,39 @@ sealed partial class BorderStrokeConverter : BaseConverterOneWay<Shape?, Brush?>
public override Brush? ConvertFrom(Shape? value, CultureInfo? culture) => value?.Stroke;
}

sealed partial class HorizontalOptionsConverter : BaseConverterOneWay<LayoutOptions, LayoutOptions>
sealed partial class HorizontalOptionsConverter : BaseConverterOneWay<LayoutOptions?, LayoutOptions>
{
public override LayoutOptions DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.HorizontalOptions;

public override LayoutOptions ConvertFrom(LayoutOptions value, CultureInfo? culture) => value == LayoutOptions.Fill ? Options.DefaultPopupSettings.HorizontalOptions : value;
public override LayoutOptions ConvertFrom(LayoutOptions? value, CultureInfo? culture) => value ?? DefaultConvertReturnValue;
}

sealed partial class VerticalOptionsConverter : BaseConverterOneWay<LayoutOptions, LayoutOptions>
sealed partial class VerticalOptionsConverter : BaseConverterOneWay<LayoutOptions?, LayoutOptions>
{
public override LayoutOptions DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.VerticalOptions;

public override LayoutOptions ConvertFrom(LayoutOptions value, CultureInfo? culture) => value == LayoutOptions.Fill ? Options.DefaultPopupSettings.VerticalOptions : value;
public override LayoutOptions ConvertFrom(LayoutOptions? value, CultureInfo? culture) => value ?? DefaultConvertReturnValue;
}
Comment thread
TheCodeTraveler marked this conversation as resolved.
Outdated

sealed partial class BackgroundColorConverter : BaseConverterOneWay<Color?, Color>
{
public override Color DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.BackgroundColor;

public override Color ConvertFrom(Color? value, CultureInfo? culture) => value ?? Options.DefaultPopupSettings.BackgroundColor;
public override Color ConvertFrom(Color? value, CultureInfo? culture) => value ?? DefaultConvertReturnValue;
}
}

sealed partial class PaddingConverter : BaseConverterOneWay<Thickness, Thickness>
sealed partial class PaddingConverter : BaseConverterOneWay<Thickness?, Thickness>
{
public override Thickness DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.Padding;

public override Thickness ConvertFrom(Thickness value, CultureInfo? culture) => value == default ? Options.DefaultPopupSettings.Padding : value;
public override Thickness ConvertFrom(Thickness? value, CultureInfo? culture) => value ?? DefaultConvertReturnValue;
}

sealed partial class MarginConverter : BaseConverterOneWay<Thickness, Thickness>
sealed partial class MarginConverter : BaseConverterOneWay<Thickness?, Thickness>
{
public override Thickness DefaultConvertReturnValue { get; set; } = Options.DefaultPopupSettings.Margin;

public override Thickness ConvertFrom(Thickness value, CultureInfo? culture) => value == default ? Options.DefaultPopupSettings.Margin : value;
public override Thickness ConvertFrom(Thickness? value, CultureInfo? culture) => value ?? DefaultConvertReturnValue;
}
Comment thread
TheCodeTraveler marked this conversation as resolved.
Outdated
}
Loading