-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial ConstrainedPresenter control for AspectRatio and simple S…
…ample. TODO: Tests and trying out more scenarios and better sample.
- Loading branch information
1 parent
0cb2ea6
commit 5dfb5c8
Showing
8 changed files
with
233 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Primitives/ConstrainedPresenter.bind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Page | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls" | ||
mc:Ignorable="d"> | ||
|
||
<Grid> | ||
<controls:ConstrainedPresenter AspectRatio="16:3" VerticalAlignment="Top"> | ||
<Image Source="/Assets/Photos/WestSeattleView.jpg" Stretch="UniformToFill"/> | ||
</controls:ConstrainedPresenter> | ||
</Grid> | ||
</Page> |
Binary file added
BIN
+825 Bytes
Microsoft.Toolkit.Uwp.SampleApp/SamplePages/Primitives/ConstrainedPresenter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
Microsoft.Toolkit.Uwp.UI.Controls.Primitives/ConstrainedPresenter/AspectRatio.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
|
||
namespace Microsoft.Toolkit.Uwp.UI.Controls | ||
{ | ||
/// <summary> | ||
/// The <see cref="AspectRatio"/> structure is used by the <see cref="ConstrainedPresenter"/> control to | ||
/// define a specific ratio to restrict its content. | ||
/// </summary> | ||
[Windows.Foundation.Metadata.CreateFromString(MethodName = "Microsoft.Toolkit.Uwp.UI.Controls.AspectRatio.ConvertToAspectRatio")] | ||
public readonly struct AspectRatio | ||
{ | ||
/// <summary> | ||
/// Gets the width component of the aspect ratio or the aspect ratio itself (and height will be 1). | ||
/// </summary> | ||
public double Width { get; } | ||
|
||
/// <summary> | ||
/// Gets the height component of the aspect ratio. | ||
/// </summary> | ||
public double Height { get; } | ||
|
||
/// <summary> | ||
/// Gets the raw numeriucal aspect ratio value itself (Width / Height). | ||
/// </summary> | ||
public double Value => Width / Height; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AspectRatio"/> struct with the provided width and height. | ||
/// </summary> | ||
/// <param name="width">Width side of the ratio.</param> | ||
/// <param name="height">Height side of the ratio.</param> | ||
public AspectRatio(double width, double height) | ||
{ | ||
Width = width; | ||
Height = height; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AspectRatio"/> struct with the specific numerical aspect ratio. | ||
/// </summary> | ||
/// <param name="ratio">Raw Aspect Ratio, Height will be 1.</param> | ||
public AspectRatio(double ratio) | ||
{ | ||
Width = ratio; | ||
Height = 1; | ||
} | ||
|
||
/// <summary> | ||
/// Converter to take a string aspect ration like "16:9" and convert it to an <see cref="AspectRatio"/> struct. | ||
/// Used automatically by XAML. | ||
/// </summary> | ||
/// <param name="rawString">The string to be converted in format "Width:Height" or a decimal value.</param> | ||
/// <returns>The <see cref="AspectRatio"/> struct representing that ratio.</returns> | ||
public static AspectRatio ConvertToAspectRatio(string rawString) | ||
{ | ||
string[] ratio = rawString.Split(":"); | ||
|
||
if (ratio.Length == 2) | ||
{ | ||
return new AspectRatio(Convert.ToDouble(ratio[0]), Convert.ToDouble(ratio[1])); | ||
} | ||
else if (ratio.Length == 1) | ||
{ | ||
return new AspectRatio(Convert.ToDouble(ratio[0])); | ||
} | ||
|
||
return new AspectRatio(1); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override string ToString() | ||
{ | ||
return Width + ":" + Height; | ||
} | ||
} | ||
} |
119 changes: 119 additions & 0 deletions
119
Microsoft.Toolkit.Uwp.UI.Controls.Primitives/ConstrainedPresenter/ConstrainedPresenter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
// See the LICENSE file in the project root for more information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Windows.Foundation; | ||
using Windows.UI.Xaml; | ||
using Windows.UI.Xaml.Controls; | ||
|
||
namespace Microsoft.Toolkit.Uwp.UI.Controls | ||
{ | ||
/// <summary> | ||
/// The <see cref="ConstrainedPresenter"/> is a <see cref="ContentPresenter"/> control which can restrict the | ||
/// available size for its content based on a scale factor and/or a specific <see cref="AspectRatio"/>. | ||
/// </summary> | ||
public class ConstrainedPresenter : ContentPresenter // TODO: Think it should be a Border? But it's sealed; hopefully can change in WinUI 3. | ||
{ | ||
/// <summary> | ||
/// Gets or sets aspect Ratio to use for the contents of the Panel (after scaling). | ||
/// </summary> | ||
public AspectRatio AspectRatio | ||
{ | ||
get { return (AspectRatio)GetValue(AspectRatioProperty); } | ||
set { SetValue(AspectRatioProperty, value); } | ||
} | ||
|
||
/// <summary> | ||
/// Identifies the <see cref="AspectRatio"/> property. | ||
/// </summary> | ||
public static readonly DependencyProperty AspectRatioProperty = | ||
DependencyProperty.Register(nameof(AspectRatio), typeof(AspectRatio), typeof(ConstrainedPresenter), new PropertyMetadata(null, AspectRatioPropertyChanged)); | ||
|
||
private static void AspectRatioPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
if (d is ConstrainedPresenter panel) | ||
{ | ||
panel.InvalidateMeasure(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the scale for the width of the panel. Should be a value between 0-1.0. Default is 1.0. | ||
/// </summary> | ||
public double ScaleX | ||
{ | ||
get { return (double)GetValue(ScaleXProperty); } | ||
set { SetValue(ScaleXProperty, value); } | ||
} | ||
|
||
/// <summary> | ||
/// Identifies the <see cref="ScaleX"/> property. | ||
/// </summary> | ||
public static readonly DependencyProperty ScaleXProperty = | ||
DependencyProperty.Register(nameof(ScaleX), typeof(double), typeof(ConstrainedPresenter), new PropertyMetadata(1.0, ScalePropertyChanged)); | ||
|
||
/// <summary> | ||
/// Gets or sets the scale for the height of the panel. Should be a value between 0-1.0. Default is 1.0. | ||
/// </summary> | ||
public double ScaleY | ||
{ | ||
get { return (double)GetValue(ScaleYProperty); } | ||
set { SetValue(ScaleYProperty, value); } | ||
} | ||
|
||
/// <summary> | ||
/// Identifies the <see cref="ScaleY"/> property. | ||
/// </summary> | ||
public static readonly DependencyProperty ScaleYProperty = | ||
DependencyProperty.Register(nameof(ScaleY), typeof(double), typeof(ConstrainedPresenter), new PropertyMetadata(1.0, ScalePropertyChanged)); | ||
|
||
private static void ScalePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | ||
{ | ||
if (d is ConstrainedPresenter panel) | ||
{ | ||
panel.InvalidateMeasure(); | ||
} | ||
} | ||
|
||
/// <inheritdoc/> | ||
protected override Size MeasureOverride(Size availableSize) | ||
{ | ||
return base.MeasureOverride(CalculateConstrainedSize(availableSize)); | ||
} | ||
|
||
/// <inheritdoc/> | ||
protected override Size ArrangeOverride(Size finalSize) | ||
{ | ||
return base.ArrangeOverride(CalculateConstrainedSize(finalSize)); | ||
} | ||
|
||
private Size CalculateConstrainedSize(Size initialSize) | ||
{ | ||
var availableSize = new Size(initialSize.Width * ScaleX, initialSize.Height * ScaleY); | ||
|
||
// If we don't have an Aspect Ratio, just return the scaled value. | ||
if (ReadLocalValue(AspectRatioProperty) == DependencyProperty.UnsetValue) | ||
{ | ||
return availableSize; | ||
} | ||
|
||
// Calculate the Aspect Ratio constraint based on the newly scaled size. | ||
var currentAspect = availableSize.Width / availableSize.Height; | ||
var desiredAspect = AspectRatio.Value; | ||
|
||
if (currentAspect >= desiredAspect) | ||
{ | ||
return new Size(availableSize.Height * desiredAspect, availableSize.Height); | ||
} | ||
else | ||
{ | ||
return new Size(availableSize.Width, availableSize.Width / desiredAspect); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters