diff --git a/dev/ColorPicker/APITests/ColorPickerTests.cs b/dev/ColorPicker/APITests/ColorPickerTests.cs index 24ada1ae67..67053653d0 100644 --- a/dev/ColorPicker/APITests/ColorPickerTests.cs +++ b/dev/ColorPicker/APITests/ColorPickerTests.cs @@ -7,11 +7,14 @@ using System.Numerics; using System.Collections; using System.Linq; +using System.Threading; using Windows.Foundation; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Shapes; +using Windows.UI.Xaml.Media; using Common; #if USING_TAEF @@ -29,7 +32,7 @@ using ColorPicker = Microsoft.UI.Xaml.Controls.ColorPicker; using ColorChangedEventArgs = Microsoft.UI.Xaml.Controls.ColorChangedEventArgs; using ColorSpectrum = Microsoft.UI.Xaml.Controls.Primitives.ColorSpectrum; -using XamlControlsXamlMetaDataProvider = Microsoft.UI.Xaml.XamlTypeInfo.XamlControlsXamlMetaDataProvider; +using XamlControlsXamlMetaDataProvider = Microsoft.UI.Xaml.XamlTypeInfo.XamlControlsXamlMetaDataProvider; #endif namespace Windows.UI.Xaml.Tests.MUXControls.ApiTests @@ -37,6 +40,17 @@ namespace Windows.UI.Xaml.Tests.MUXControls.ApiTests [TestClass] public class ColorPickerTests { + [TestCleanup] + public void TestCleanup() + { + RunOnUIThread.Execute(() => + { + Log.Comment("TestCleanup: Restore TestContentRoot to null"); + // Put things back the way we found them. + MUXControlsTestApp.App.TestContentRoot = null; + }); + } + [TestMethod] public void ColorPickerTest() { @@ -232,6 +246,21 @@ public void ValidateHueRange() IdleSynchronizer.Wait(); } + [TestMethod] + public void ValidateFractionalWidthDoesNotCrash() + { + ColorSpectrum colorSpectrum = null; + + RunOnUIThread.Execute(() => + { + colorSpectrum = new ColorSpectrum(); + colorSpectrum.Width = 300.75; + colorSpectrum.Height = 300.75; + }); + + SetAsRootAndWaitForColorSpectrumFill(colorSpectrum); + } + // XamlControlsXamlMetaDataProvider does not exist in the OS repo, // so we can't execute this test as authored there. #if !BUILD_WINDOWS @@ -248,5 +277,31 @@ public void VerifyColorPropertyMetadata() }); } #endif + + // This takes a FrameworkElement parameter so you can pass in either a ColorPicker or a ColorSpectrum. + private void SetAsRootAndWaitForColorSpectrumFill(FrameworkElement element) + { + ManualResetEvent spectrumLoadedEvent = new ManualResetEvent(false); + + RunOnUIThread.Execute(() => + { + element.Loaded += (sender, args) => + { + var spectrumRectangle = VisualTreeUtils.FindVisualChildByName(element, "SpectrumRectangle") as Rectangle; + Verify.IsNotNull(spectrumRectangle); + + spectrumRectangle.RegisterPropertyChangedCallback(Shape.FillProperty, (o, dp) => + { + spectrumLoadedEvent.Set(); + }); + }; + + StackPanel root = new StackPanel(); + root.Children.Add(element); + MUXControlsTestApp.App.TestContentRoot = root; + }); + + spectrumLoadedEvent.WaitOne(); + } } } \ No newline at end of file diff --git a/dev/ColorPicker/ColorSpectrum.cpp b/dev/ColorPicker/ColorSpectrum.cpp index 2af44076be..ff42734a6f 100644 --- a/dev/ColorPicker/ColorSpectrum.cpp +++ b/dev/ColorPicker/ColorSpectrum.cpp @@ -886,20 +886,20 @@ void ColorSpectrum::CreateBitmapsAndColorMap() shared_ptr> bgraMaxPixelData = make_shared>(); shared_ptr> newHsvValues = make_shared>(); - bgraMinPixelData->reserve(static_cast(minDimension * minDimension * 4)); + bgraMinPixelData->reserve(static_cast(round(minDimension * minDimension * 4))); // We'll only save pixel data for the middle bitmaps if our third dimension is hue. if (components == winrt::ColorSpectrumComponents::ValueSaturation || components == winrt::ColorSpectrumComponents::SaturationValue) { - bgraMiddle1PixelData->reserve(static_cast(minDimension * minDimension * 4)); - bgraMiddle2PixelData->reserve(static_cast(minDimension * minDimension * 4)); - bgraMiddle3PixelData->reserve(static_cast(minDimension * minDimension * 4)); - bgraMiddle4PixelData->reserve(static_cast(minDimension * minDimension * 4)); + bgraMiddle1PixelData->reserve(static_cast(round(minDimension * minDimension * 4))); + bgraMiddle2PixelData->reserve(static_cast(round(minDimension * minDimension * 4))); + bgraMiddle3PixelData->reserve(static_cast(round(minDimension * minDimension * 4))); + bgraMiddle4PixelData->reserve(static_cast(round(minDimension * minDimension * 4))); } - bgraMaxPixelData->reserve(static_cast(minDimension * minDimension * 4)); - newHsvValues->reserve(static_cast(minDimension * minDimension)); + bgraMaxPixelData->reserve(static_cast(round(minDimension * minDimension * 4))); + newHsvValues->reserve(static_cast(round(minDimension * minDimension))); winrt::WorkItemHandler workItemHandler( [minDimension, hsv, minHue, maxHue, minSaturation, maxSaturation, minValue, maxValue, shape, components, @@ -1651,4 +1651,4 @@ bool ColorSpectrum::SelectionEllipseShouldBeLight() double bg = displayedColor.B <= 10 ? displayedColor.B / 3294.0 : pow(displayedColor.B / 269.0 + 0.0513, 2.4); return 0.2126 * rg + 0.7152 * gg + 0.0722 * bg <= 0.5; -} \ No newline at end of file +} diff --git a/test/MUXControlsTestApp/Utilities/VisualTreeUtils.cs b/test/MUXControlsTestApp/Utilities/VisualTreeUtils.cs index 4a2730c46c..3ecd83fec2 100644 --- a/test/MUXControlsTestApp/Utilities/VisualTreeUtils.cs +++ b/test/MUXControlsTestApp/Utilities/VisualTreeUtils.cs @@ -33,5 +33,32 @@ public static T FindElementOfTypeInSubtree(this DependencyObject element) return null; } + + public static DependencyObject FindVisualChildByName(FrameworkElement parent, string name) + { + if (parent.Name == name) + { + return parent; + } + + int childrenCount = VisualTreeHelper.GetChildrenCount(parent); + + for (int i = 0; i < childrenCount; i++) + { + FrameworkElement childAsFE = VisualTreeHelper.GetChild(parent, i) as FrameworkElement; + + if (childAsFE != null) + { + DependencyObject result = FindVisualChildByName(childAsFE, name); + + if (result != null) + { + return result; + } + } + } + + return null; + } } }