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

[Proposal] Add AbsoluteLayout Flags Extension Methods #215

Closed
8 tasks done
brminnick opened this issue Apr 22, 2023 · 4 comments · Fixed by #216
Closed
8 tasks done

[Proposal] Add AbsoluteLayout Flags Extension Methods #215

brminnick opened this issue Apr 22, 2023 · 4 comments · Fixed by #216
Assignees
Labels
approved champion A member of the .NET MAUI Toolkit core team has chosen to champion this feature documentation approved proposal A fully fleshed out proposal describing a new feature in syntactic and semantic detail

Comments

@brminnick
Copy link
Collaborator

brminnick commented Apr 22, 2023

Feature name

Update AbsoluteLayout Flags Extensions

Progress tracker

Summary

This Proposal adds two new APIs to AbsoluteLayoutExtensions and updates the functionality of the existing .LayoutFlags() API to add existing AbsoluteLayoutFlags instead of overwriting existing AbsoluteLayoutFlags.

public static TBindable ClearLayoutFlags<TBindable>(this TBindable bindable) where TBindable : BindableObject;

public static TBindable LayoutFlags<TBindable>(this TBindable bindable, params AbsoluteLayoutFlags[] flags) where TBindable : BindableObject;

Motivation

1. .ClearLayoutFlags()

public static TBindable ClearLayoutFlags<TBindable>(this TBindable bindable) where TBindable : BindableObject;

Adding .ClearLayoutFlags() allows developers to easily remove any existing AbsoluteLayoutFlags using fluent APIs.

2. .LayoutFlags()

public static TBindable LayoutFlags<TBindable>(this TBindable bindable, params AbsoluteLayoutFlags[] flags) where TBindable : BindableObject;

Allowing this new .LayoutFlags() API helps developers (especially new developers) who may be unfamiliar with using Bitwise OR operator. This new API allows developers to pass in multiple AbsoluteLayoutFlags by listing them sequentially which provides a more natural feel and may be what some developers expect, like so:

new Label()
  .LayoutFlags(AbsoluteLayoutFlags.XProportional, AbsoluteLayoutFlags.WidthProportional)

Detailed Design

/// <summary>
/// Removes all <see cref="AbsoluteLayoutFlags"/>, reverting to the default configuraion of <see cref="AbsoluteLayoutFlags.None"/>.
/// </summary>
/// <typeparam name="TBindable"></typeparam>
/// <param name="bindable"></param>
/// <returns></returns>
public static TBindable ClearLayoutFlags<TBindable>(this TBindable bindable) where TBindable : BindableObject
{
  AbsoluteLayout.SetLayoutFlags(bindable, AbsoluteLayoutFlags.None);
  return bindable;
}

/// <summary>
/// Set an <see cref="AbsoluteLayoutFlags"/> that indicates whether the layout bounds position and size values for a child are proportional to the size of the <see cref="AbsoluteLayout"/>.
/// </summary>
/// <typeparam name="TBindable"></typeparam>
/// <param name="bindable"></param>
/// <param name="flags"></param>
/// <returns></returns>
public static TBindable LayoutFlags<TBindable>(this TBindable bindable, params AbsoluteLayoutFlags[] flags) where TBindable : BindableObject
{
  var newFlags = AbsoluteLayoutFlags.None;
  
  foreach(var flag in flags)
  {
	  newFlags |= flag;
  }
  
  AbsoluteLayout.SetLayoutFlags(bindable, newFlags);

  return bindable;
}

Usage Syntax

using Microsoft.Maui.Layouts;

namespace CommunityToolkit.Maui.Markup.Sample.Pages;

sealed class SettingsPage : BaseContentPage<SettingsViewModel>
{
	public SettingsPage(SettingsViewModel settingsViewModel) : base(settingsViewModel, "Settings")
	{
		Content = new AbsoluteLayout
		{
			Children =
			{
				new Image().Source("dotnet_bot.png").Opacity(0.25).IsOpaque(false).Aspect(Aspect.AspectFit)
					.ClearLayoutFlags()
					.LayoutFlags(AbsoluteLayoutFlags.SizeProportional | AbsoluteLayoutFlags.PositionProportional)
					.LayoutBounds(0.5, 0.5, 0.5, 0.5)
					.AutomationIsInAccessibleTree(false),

				new Label()
					.Text("Top Stories To Fetch")
					.AppThemeBinding(Label.TextColorProperty,AppStyles.BlackColor, AppStyles.PrimaryTextColorDark)
					.LayoutFlags(AbsoluteLayoutFlags.XProportional | AbsoluteLayoutFlags.WidthProportional)
					.LayoutBounds(0, 0, 1, 40)
					.TextCenterHorizontal()
					.TextBottom()
					.Assign(out Label topNewsStoriesToFetchLabel),

				new Entry { Keyboard = Keyboard.Numeric }
					.BackgroundColor(Colors.White)
					.Placeholder($"Provide a value between {SettingsService.MinimumStoriesToFetch} and {SettingsService.MaximumStoriesToFetch}", Colors.Grey)
					.LayoutFlags(AbsoluteLayoutFlags.XProportional, AbsoluteLayoutFlags.WidthProportional)
					.LayoutBounds(0.5, 45, 0.8, 40)
					.Behaviors(new NumericValidationBehavior
					{
						Flags = ValidationFlags.ValidateOnValueChanged,
						MinimumValue = SettingsService.MinimumStoriesToFetch,
						MaximumValue = SettingsService.MaximumStoriesToFetch,
						ValidStyle = AppStyles.ValidEntryNumericValidationBehaviorStyle,
						InvalidStyle = AppStyles.InvalidEntryNumericValidationBehaviorStyle,
					})
					.TextCenter()
					.SemanticDescription(topNewsStoriesToFetchLabel.Text)
					.Bind(Entry.TextProperty, static (SettingsViewModel vm) => vm.NumberOfTopStoriesToFetch, static (SettingsViewModel vm, int text) => vm.NumberOfTopStoriesToFetch = text),

				new Label()
					.Bind(
						Label.TextProperty,
						binding1: new Binding { Source = SettingsService.MinimumStoriesToFetch },
						binding2: new Binding { Source = SettingsService.MaximumStoriesToFetch },
						convert: ((int minimum, int maximum) values) => string.Format(CultureInfo.CurrentUICulture, $"The number must be between {values.minimum} and {values.maximum}."),
						mode: BindingMode.OneTime)
					.LayoutFlags(AbsoluteLayoutFlags.XProportional | AbsoluteLayoutFlags.WidthProportional)
					.LayoutBounds(0, 90, 1, 40)
					.TextCenter()
					.AppThemeColorBinding(Label.TextColorProperty,AppStyles.BlackColor, AppStyles.PrimaryTextColorDark)
					.Font(size: 12, italic: true)
					.SemanticHint($"The minimum and maximum possible values for the {topNewsStoriesToFetchLabel.Text} field above.")
			}
		};
	}
}

Drawbacks

None

Alternatives

To clear existing AbsoluteLayoutFlags, a developer can use the existing method:

.LayoutFlags(AbsoluteLayoutFlags.None)

To add multiple AbsoluteLayoutFlags, a developer can use the existing method:

.LayoutFlags(AbsoluteLayoutFlags.XProportional | AbsoluteLayoutFlags.WidthProportional)
@brminnick brminnick added proposal A fully fleshed out proposal describing a new feature in syntactic and semantic detail new labels Apr 22, 2023
@brminnick brminnick self-assigned this Apr 22, 2023
@ghost ghost added champion A member of the .NET MAUI Toolkit core team has chosen to champion this feature and removed new labels Apr 22, 2023
@brminnick brminnick added the needs discussion The team will aim to discuss this at the next monthly standup label Apr 22, 2023
@brminnick brminnick removed the needs discussion The team will aim to discuss this at the next monthly standup label May 9, 2023
@brminnick brminnick changed the title [Proposal] Update AbsoluteLayout Flags Extensions [Proposal] Add AbsoluteLayout Flags Extension Methods May 9, 2023
@VladislavAntonyuk
Copy link
Contributor

approve

@brminnick
Copy link
Collaborator Author

I approve this feature ✅

@bijington
Copy link
Contributor

Approve

@ghost ghost added approved help wanted This proposal has been approved and is ready to be implemented labels May 18, 2023
@brminnick brminnick removed the help wanted This proposal has been approved and is ready to be implemented label May 22, 2023
@ghost ghost reopened this May 24, 2023
@ghost
Copy link

ghost commented May 24, 2023

Reopening Proposal.

Only Proposals moved to the Closed Project Column and Completed Project Column can be closed.

@ghost ghost closed this as completed Jun 1, 2023
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved champion A member of the .NET MAUI Toolkit core team has chosen to champion this feature documentation approved proposal A fully fleshed out proposal describing a new feature in syntactic and semantic detail
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants