CommunityToolkit / CommunityToolkit/Maui

[Proposal] OnScreenSize Markup

Open
#425 22 comments 2 reactions 1 assignee Claimed by @pictos View on GitHub
approved champion help wanted proposal
Dominant language
C#
Stars
2.7k
Forks
500
Avg merge
2d 14h
Merged PRs (30d)
7

Description

# OnScreenSize Markup

* [x] Proposed
* [x] Prototype: [Repo](https://github.com/carolzbnbr/OnScreenSizeMarkup) and [nuget](https://www.nuget.org/packages/OnScreenSizeMarkup.Forms)
* [x] Implementation: Works for Xamarin, I will port to Maui.
* [x] iOS Support
* [x] Android Support
* [ ] macOS Support
* [ ] Windows Support
* [ ] Unit Tests: Not Started
* [ ] Sample: Not Started
* [x] Documentation: Needs improvements

## Link to Discussion

Please link to the completed/approved [Discussion](https://github.com/CommunityToolkit/Maui/discussions/422)

## Summary
[summary]: #summary

OnScreenSize Markup: A Markup for controlling Views according to a category a screen size fits in (Small, Medium, Large, ExtraLarge, etc).

## Detailed Design
[design]: #detailed-design

**ScreenCategories.cs** enum:
Depending on the screen-size (Width/Heigh), or a device model is, a `ScreenCategories` enum is used.
```cs
public enum ScreenCategories
{
ExtraSmall = 1,
Small = 2,
Medium = 3,
Large = 4,
ExtraLarge = 5,
NotSet = 6,
}
}
```

**ICategoryFallbackHandler.cs**:
This interface is used to determine the category a device fits in, during first execution we attempt to execute `TryGetCategoryByDeviceModel` and wether it returns false, we attempt to execute `TryGetCategoryByPhysicalSize`
```cs
public interface ICategoryFallbackHandler
{
bool TryGetCategoryByDeviceModel(string deviceModel, out ScreenCategories category);

bool TryGetCategoryByPhysicalSize(double deviceWidth, double deviceHeight, out ScreenCategories category);
}
```

**OnScreenSize.cs**:

The markup itself.
1. During the first run, the methods `ICategoryFallbackHandler.TryGetCategoryByDeviceModel` and `ICategoryFallbackHandler.TryGetCategoryByPhysicalSize` are called to determine the `Device Category` a device fits in, and after that, its result is cached to optimize next runs.
2. Depending on the `Device Category` a device was categorized, a value will be obtained from it's corresponding Markup's property.
For instance: If device category was categorized a `Large`, the markup will attempt to get the value from property `OnScreenSize.Large`.
3. In case a markup property is not defined, it will attempt to use the value from the `OnScreenSize.DefaultSize`.

**Note:** Before returning, each markup property's value are attempted to be converted to its property-type, making it possible to have a batter user experience, but allowing values to be converted to `GridLength`, `Colors`, `Thinkness`, `RowDefinition`, `ColumnDefinition`, and etc.

```cs
public class OnScreenSize : IMarkupExtension
{
public OnScreenSize();
public object DefaultSize { get; set; }
public object ExtraSmall {get;set;}
public object Small {get;set;}
public object Medium {get;set;}
public object Large {get;set;}
public object ExtraLarge {get;set;}
public object ProvideValue(IServiceProvider serviceProvider);
}
```

## Usage Syntax
[usage]: #usage-syntax

### XAML Usage

```xml

```

```xml


<Setter Property="RowDefinitions">
<markups:OnScreenSize>
<markups:OnScreenSize.Small>0.25*, 0.13*, 0.08*, 230, *</markups:OnScreenSize.Small>
<markups:OnScreenSize.Large>0.15*, 0.1*, 0.01*, 290, *</markups:OnScreenSize.Large>
<markups:OnScreenSize.DefaultSize>0.15*, 0.1*, 0.01*, 290, *</markups:OnScreenSize.DefaultSize>
</markups:OnScreenSize>
</Setter>
<Setter Property="ColumnDefinitions">
<markups:OnScreenSize>
<markups:OnScreenSize.Small>*, 230, *</markups:OnScreenSize.Small>
<markups:OnScreenSize.Large>*, 290, *</markups:OnScreenSize.Large>
<markups:OnScreenSize.DefaultSize>*, 290, *</markups:OnScreenSize.DefaultSize>
</markups:OnScreenSize>
</Setter>


...

```
### C# Usage

There is no code-equivalent for instantiating a Markup, since `IServiceProvider` instance from `OnScreenSize.ProvideValue(IServiceProvider serviceProvider)` is only available via XAML.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.