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

Add initial ConstrainedBox control for AspectRatio and Scaling #4104

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d996cb5
Add initial ConstrainedPresenter control for AspectRatio and simple S…
michael-hawker Jul 9, 2021
2fe411d
Add Viewbox to VisualTreeExtensions FindChild branches
michael-hawker Jul 15, 2021
39a95f2
Add implicit conversion operators to AspectRatio so it can be used in…
michael-hawker Jul 20, 2021
3b1518a
Rename ConstrainedPresenter to ConstrainedBox
michael-hawker Jul 22, 2021
4670e95
Fix trailing whitespace issue
michael-hawker Jul 28, 2021
4041c5c
Fix namespaces on Unit Tests for Controls
michael-hawker Jul 29, 2021
0fd2a37
Merge implementations of ConstrainedBox to handle all the scenarios
michael-hawker Jul 29, 2021
3a0f501
Split out properties into a separate file for ConstrainedBox
michael-hawker Jul 29, 2021
5283769
Tweak method for when we need to re-calculate ConstrainedBox
michael-hawker Jul 29, 2021
8ee8084
Add MultipleX and MultipleY to ConstrainedBox for floor snap to a mul…
michael-hawker Jul 30, 2021
b4fe600
Added another sample to the app, but it's a bit wonky still...
michael-hawker Jul 30, 2021
6057802
Add initial primitive test for each property in isolation
michael-hawker Jul 31, 2021
853a4a9
Apply suggestions from code review
michael-hawker Aug 2, 2021
52975a6
Update sample to show how to manipulate the image center
michael-hawker Jul 31, 2021
ee0e32e
Add extra mode to sample description
michael-hawker Aug 2, 2021
376c9f8
Update tolerance to be tighter and fix indentation/descriptions
michael-hawker Aug 2, 2021
a9cc874
Add a new combined test
michael-hawker Aug 2, 2021
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 @@ -15,7 +15,10 @@
AspectRatio="1:1"
MinWidth="64" MaxWidth="512">
<controls:ConstrainedBox.Background>
<!-- TODO: Should I make a DPI aware image? As otherwise scaling doesn't quite work at 150%? -->
<!-- TODO: TilesBrush doesn't support Dpi image loading for this scenario
This example is configured for 100% DPI at the moment.
See https://github.com/CommunityToolkit/WindowsCommunityToolkit/issues/4150
-->
<brushes:TilesBrush TextureUri="ms-appx:///Assets/checker.png"/>
</controls:ConstrainedBox.Background>
</controls:ConstrainedBox>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// 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.Linq;
using System.Threading.Tasks;
using Microsoft.Toolkit.Uwp;
using Microsoft.Toolkit.Uwp.UI;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;

namespace UnitTests.UWP.UI.Controls
{
[TestClass]
public partial class Test_ConstrainedBox : VisualUITestBase
{
[TestCategory("ConstrainedBox")]
[TestMethod]
public async Task Test_ConstrainedBox_Normal_AspectHorizontal()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
var treeRoot = XamlReader.Load(@"<Page
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<controls:ConstrainedBox x:Name=""ConstrainedBox"" AspectRatio=""2:1"" Width=""200"">
<Border HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"" Background=""Red""/>
</controls:ConstrainedBox>
</Page>") as FrameworkElement;

Assert.IsNotNull(treeRoot, "Could not load XAML tree.");

// Initialize Visual Tree
await SetTestContentAsync(treeRoot);

var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;

Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");

// Force Layout calculations
panel.UpdateLayout();

var child = panel.Content as Border;

Assert.IsNotNull(child, "Could not find inner Border");

// Check Size
Assert.AreEqual(child.ActualWidth, 200, "Width unexpected");
Assert.AreEqual(child.ActualHeight, 100, "Height unexpected");
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
});
}

[TestCategory("ConstrainedBox")]
[TestMethod]
public async Task Test_ConstrainedBox_Normal_AspectVertical()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
var treeRoot = XamlReader.Load(@"<Page
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<controls:ConstrainedBox x:Name=""ConstrainedBox"" AspectRatio=""1:2"" Height=""200"">
<Border HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"" Background=""Red""/>
</controls:ConstrainedBox>
</Page>") as FrameworkElement;

Assert.IsNotNull(treeRoot, "Could not load XAML tree.");

// Initialize Visual Tree
await SetTestContentAsync(treeRoot);

var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;

Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");

// Force Layout calculations
panel.UpdateLayout();

var child = panel.Content as Border;

Assert.IsNotNull(child, "Could not find inner Border");

// Check Size
Assert.AreEqual(child.ActualWidth, 100, "Width unexpected");
Assert.AreEqual(child.ActualHeight, 200, "Height unexpected");
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
});
}
}
}
119 changes: 119 additions & 0 deletions UnitTests/UnitTests.UWP/UI/Controls/Test_ConstrainedBox.Multiple.cs
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.Linq;
using System.Threading.Tasks;
using Microsoft.Toolkit.Uwp;
using Microsoft.Toolkit.Uwp.UI;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;

namespace UnitTests.UWP.UI.Controls
{
public partial class Test_ConstrainedBox : VisualUITestBase
{
[TestCategory("ConstrainedBox")]
[TestMethod]
public async Task Test_ConstrainedBox_Normal_MultipleX()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
var treeRoot = XamlReader.Load(@"<Page
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<Grid x:Name=""ParentGrid"" Width=""200"" Height=""200"">
<controls:ConstrainedBox x:Name=""ConstrainedBox"" MultipleX=""32""
HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"">
<Border HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"" Background=""Red""/>
</controls:ConstrainedBox>
</Grid>
</Page>") as FrameworkElement;

Assert.IsNotNull(treeRoot, "Could not load XAML tree.");

// Initialize Visual Tree
await SetTestContentAsync(treeRoot);

var grid = treeRoot.FindChild("ParentGrid") as Grid;

var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;

Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");

// Force Layout calculations
panel.UpdateLayout();

var child = panel.Content as Border;

Assert.IsNotNull(child, "Could not find inner Border");

// Check Size
Assert.AreEqual(child.ActualWidth, 192);
Assert.AreEqual(child.ActualHeight, 200);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved

// Check inner Positioning, we do this from the Grid as the ConstainedBox also modifies its own size
// and is hugging the child.
var position = grid.CoordinatesTo(child);

Assert.AreEqual(position.X, 4);
Assert.AreEqual(position.Y, 0);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
});
}

[TestCategory("ConstrainedBox")]
[TestMethod]
public async Task Test_ConstrainedBox_Normal_MultipleY()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
var treeRoot = XamlReader.Load(@"<Page
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<Grid x:Name=""ParentGrid"" Width=""200"" Height=""200"">
<controls:ConstrainedBox x:Name=""ConstrainedBox"" MultipleY=""32""
HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"">
<Border HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"" Background=""Red""/>
</controls:ConstrainedBox>
</Grid>
</Page>") as FrameworkElement;

Assert.IsNotNull(treeRoot, "Could not load XAML tree.");

// Initialize Visual Tree
await SetTestContentAsync(treeRoot);

var grid = treeRoot.FindChild("ParentGrid") as Grid;

var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;

Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");

// Force Layout calculations
panel.UpdateLayout();

var child = panel.Content as Border;

Assert.IsNotNull(child, "Could not find inner Border");

// Check Size
Assert.AreEqual(child.ActualWidth, 200);
Assert.AreEqual(child.ActualHeight, 192);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved

// Check inner Positioning, we do this from the Grid as the ConstainedBox also modifies its own size
// and is hugging the child.
var position = grid.CoordinatesTo(child);

Assert.AreEqual(position.X, 0);
Assert.AreEqual(position.Y, 4);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,33 @@

namespace UnitTests.UWP.UI.Controls
{
[TestClass]
public class Test_ConstrainedBox : VisualUITestBase
public partial class Test_ConstrainedBox : VisualUITestBase
{
[TestCategory("ConstrainedBox")]
[TestMethod]
public async Task Test_ConstrainedBox_Normal_Horizontal()
public async Task Test_ConstrainedBox_Normal_ScaleX()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
var treeRoot = XamlReader.Load(@"<Page
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<controls:ConstrainedBox x:Name=""ConstrainedBox"" AspectRatio=""2:1"" Width=""200"">
<Grid x:Name=""ParentGrid"" Width=""200"" Height=""200"">
<controls:ConstrainedBox x:Name=""ConstrainedBox"" ScaleX=""0.5""
HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"">
<Border HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"" Background=""Red""/>
</controls:ConstrainedBox>
</Grid>
</Page>") as FrameworkElement;

Assert.IsNotNull(treeRoot, "Could not load XAML tree.");

// Initialize Visual Tree
await SetTestContentAsync(treeRoot);

var grid = treeRoot.FindChild("ParentGrid") as Grid;

var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;

Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");
Expand All @@ -51,14 +55,21 @@ await App.DispatcherQueue.EnqueueAsync(async () =>
Assert.IsNotNull(child, "Could not find inner Border");

// Check Size
Assert.AreEqual(child.ActualWidth, 200, "Width unexpected");
Assert.AreEqual(child.ActualHeight, 100, "Height unexpected");
Assert.AreEqual(child.ActualWidth, 100);
Assert.AreEqual(child.ActualHeight, 200);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved

// Check inner Positioning, we do this from the Grid as the ConstainedBox also modifies its own size
// and is hugging the child.
var position = grid.CoordinatesTo(child);

Assert.AreEqual(position.X, 50);
Assert.AreEqual(position.Y, 0);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
});
}

[TestCategory("ConstrainedBox")]
[TestMethod]
public async Task Test_ConstrainedBox_Normal_ScaleX()
public async Task Test_ConstrainedBox_Normal_ScaleY()
{
await App.DispatcherQueue.EnqueueAsync(async () =>
{
Expand All @@ -67,7 +78,7 @@ await App.DispatcherQueue.EnqueueAsync(async () =>
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<Grid x:Name=""ParentGrid"" Width=""200"" Height=""200"">
<controls:ConstrainedBox x:Name=""ConstrainedBox"" ScaleX=""0.5""
<controls:ConstrainedBox x:Name=""ConstrainedBox"" ScaleY=""0.5""
HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"">
<Border HorizontalAlignment=""Stretch"" VerticalAlignment=""Stretch"" Background=""Red""/>
</controls:ConstrainedBox>
Expand All @@ -93,15 +104,15 @@ await App.DispatcherQueue.EnqueueAsync(async () =>
Assert.IsNotNull(child, "Could not find inner Border");

// Check Size
Assert.AreEqual(child.ActualWidth, 100);
Assert.AreEqual(child.ActualHeight, 200);
Assert.AreEqual(child.ActualWidth, 200);
Assert.AreEqual(child.ActualHeight, 100);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved

// Check inner Positioning, we do this from the Grid as the ConstainedBox also modifies its own size
// and is hugging the child.
var position = grid.CoordinatesTo(child);

Assert.AreEqual(position.X, 50);
Assert.AreEqual(position.Y, 0);
Assert.AreEqual(position.X, 0);
Assert.AreEqual(position.Y, 50);
michael-hawker marked this conversation as resolved.
Show resolved Hide resolved
});
}
}
Expand Down
4 changes: 3 additions & 1 deletion UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@
<Compile Include="UI\Collection\Test_IncrementalLoadingCollection.cs" />
<Compile Include="UI\Controls\Test_Carousel.cs" />
<Compile Include="UI\Controls\Test_BladeView.cs" />
<Compile Include="UI\Controls\Test_ConstrainedBox.AspectRatio.cs" />
<Compile Include="UI\Controls\Test_ConstrainedBox.Multiple.cs" />
<Compile Include="UI\Controls\Test_ImageEx.cs" />
<Compile Include="UI\Controls\Test_RadialGauge.cs" />
<Compile Include="UI\Controls\Test_TextToolbar_Localization.cs" />
Expand All @@ -231,7 +233,7 @@
<Compile Include="UI\Controls\Test_UniformGrid_FreeSpots.cs" />
<Compile Include="UI\Controls\Test_UniformGrid_Dimensions.cs" />
<Compile Include="UI\Controls\Test_RangeSelector.cs" />
<Compile Include="UI\Controls\Test_ConstrainedBox.cs" />
<Compile Include="UI\Controls\Test_ConstrainedBox.Scale.cs" />
<Compile Include="UI\Controls\Test_WrapPanel_Visibility.cs" />
<Compile Include="UI\Controls\Test_WrapPanel_BasicLayout.cs" />
<Compile Include="UI\Extensions\Test_VisualExtensions.cs" />
Expand Down