private void AnchoringAtAlmostFarEdge(Orientation orientation) { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper()) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupDefaultAnchoringUI(orientation, scroller, scrollerLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); ChangeZoomFactor(scroller, 2.0f, 0.0f, 0.0f, ScrollerViewKind.Absolute, ScrollerViewChangeKind.DisableAnimation); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scroller.ExtentHeight * 2.0 - scroller.Height - 1.0; scroller.VerticalAnchorRatio = 1.0; } else { horizontalOffset = scroller.ExtentWidth * 2.0 - scroller.Width - 1.0; scroller.HorizontalAnchorRatio = 1.0; } }); ChangeOffsets(scroller, horizontalOffset, verticalOffset, ScrollerViewKind.Absolute, ScrollerViewChangeKind.DisableAnimation, ScrollerViewChangeSnapPointRespect.IgnoreSnapPoints, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { Log.Comment("Inserting child at far edge"); InsertStackPanelChild((scroller.Child as Border).Child as StackPanel, 1 /*operationCount*/, c_defaultAnchoringUIStackPanelChildrenCount /*newIndex*/, 1 /*newCount*/); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("No Scroller offset change expected"); if (orientation == Orientation.Vertical) { Verify.AreEqual(scroller.VerticalOffset, verticalOffset); } else { Verify.AreEqual(scroller.HorizontalOffset, horizontalOffset); } }); } }
private void AnchoringAtAlmostNearEdge(Orientation orientation) { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollerViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupDefaultAnchoringUI(orientation, scroller, scrollerLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); double horizontalOffset = orientation == Orientation.Vertical ? 0.0 : 1.0; double verticalOffset = orientation == Orientation.Vertical ? 1.0 : 0.0; ScrollTo(scroller, horizontalOffset, verticalOffset, AnimationMode.Disabled, SnapPointsMode.Ignore); RunOnUIThread.Execute(() => { scroller.ViewChanged += delegate(Scroller sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); scrollerViewChangedEvent.Set(); }; Log.Comment("Inserting child at near edge"); InsertStackPanelChild((scroller.Content as Border).Child as StackPanel, 1 /*operationCount*/, 0 /*newIndex*/, 1 /*newCount*/); }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("Scroller offset change expected"); if (orientation == Orientation.Vertical) { Verify.AreEqual(scroller.VerticalOffset, 127.0); } else { Verify.AreEqual(scroller.HorizontalOffset, 127.0); } }); } }
private void AnchoringAtNearEdge(Orientation orientation) { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupDefaultAnchoringUI(orientation, scroller, scrollerLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); RunOnUIThread.Execute(() => { Log.Comment("Inserting child at near edge"); InsertStackPanelChild((scroller.Content as Border).Child as StackPanel, 1 /*operationCount*/, 0 /*newIndex*/, 1 /*newCount*/); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("No Scroller offset change expected"); if (orientation == Orientation.Vertical) { Verify.AreEqual(scroller.VerticalOffset, 0); } else { Verify.AreEqual(scroller.HorizontalOffset, 0); } }); } }
public void AnchoringAtRepeaterMiddle() { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper()) { using (PrivateLoggingHelper privateLoggingHelper = new PrivateLoggingHelper("Scroller")) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollerViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupRepeaterAnchoringUI(scroller, scrollerLoadedEvent); scroller.HorizontalAnchorRatio = double.NaN; scroller.VerticalAnchorRatio = 0.5; }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); ChangeZoomFactor(scroller, 2.0f, 0.0f, 0.0f, ScrollerViewKind.Absolute, ScrollerViewChangeKind.AllowAnimation); ChangeOffsets(scroller, 0.0, 250.0, ScrollerViewKind.Absolute, ScrollerViewChangeKind.AllowAnimation, ScrollerViewChangeSnapPointRespect.IgnoreSnapPoints, false /*hookViewChanged*/); ItemsRepeater repeater = null; TestDataSource dataSource = null; RunOnUIThread.Execute(() => { repeater = (scroller.Child as Border).Child as ItemsRepeater; dataSource = repeater.ItemsSource as TestDataSource; scroller.ViewChanged += delegate(Scroller sender, object args) { scrollerViewChangedEvent.Set(); }; Log.Comment("Inserting items at the beginning"); dataSource.Insert(0 /*index*/, 2 /*count*/); }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); RunOnUIThread.Execute(() => { Log.Comment("Scroller offset change expected"); Verify.AreEqual(scroller.VerticalOffset, 520.0); }); RunOnUIThread.Execute(() => { scrollerViewChangedEvent.Reset(); Log.Comment("Removing items from the beginning"); dataSource.Remove(0 /*index*/, 2 /*count*/); }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); RunOnUIThread.Execute(() => { Log.Comment("Scroller offset change expected"); Verify.AreEqual(scroller.VerticalOffset, 250.0); }); } } }
private void AnchoringWithOffsetCoercion(bool reduceAnchorOffset) { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper()) { Scroller scroller = null; Border anchorElement = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollerViewChangedEvent = new AutoResetEvent(false); AutoResetEvent scrollerAnchorRequestedEvent = new AutoResetEvent(false); // This test validates that the Scroller accounts for maximum vertical offset (based on viewport and child extent) // when calculating the vertical offset shift for anchoring. The vertical offset cannot exceed child extent - viewport. RunOnUIThread.Execute(() => { Log.Comment("Visual tree setup"); anchorElement = new Border { Width = 100, Height = 100, Background = new SolidColorBrush(Colors.Red), Margin = new Thickness(0, 600, 0, 0), VerticalAlignment = VerticalAlignment.Top }; Grid grid = new Grid(); grid.Children.Add(anchorElement); grid.Width = 200; grid.Height = 1000; grid.Background = new SolidColorBrush(Colors.Gray); scroller = new Scroller { Child = grid, Width = 200, Height = 200 }; scroller.Loaded += (object sender, RoutedEventArgs e) => { Log.Comment("Scroller.Loaded event handler"); scrollerLoadedEvent.Set(); }; scroller.ViewChanged += delegate(Scroller sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); if ((reduceAnchorOffset && sender.VerticalOffset == 400) || (!reduceAnchorOffset && sender.VerticalOffset == 500)) { scrollerViewChangedEvent.Set(); } }; scroller.AnchorRequested += delegate(Scroller sender, ScrollerAnchorRequestedEventArgs args) { Log.Comment("Scroller.AnchorRequested event handler. Forcing the red Border to be the Scroller anchor."); args.AnchorElement = anchorElement; scrollerAnchorRequestedEvent.Set(); }; Log.Comment("Setting window content"); MUXControlsTestApp.App.TestContentRoot = scroller; }); WaitForEvent("Waiting for Scroller.Loaded event", scrollerLoadedEvent); IdleSynchronizer.Wait(); ChangeOffsets(scroller, 0.0, 600.0, ScrollerViewKind.Absolute, ScrollerViewChangeKind.DisableAnimation, ScrollerViewChangeSnapPointRespect.IgnoreSnapPoints); RunOnUIThread.Execute(() => { Verify.AreEqual(600, scroller.VerticalOffset); Log.Comment("Scroller.Child height is reduced by 300px. Scroller.VerticalOffset is expected to be reduced by 100px (600 -> 500)."); (scroller.Child as Grid).Height = 700; if (reduceAnchorOffset) { Log.Comment("Tracked element is shifted up by 200px within the Scroller.Child (600 -> 400). Anchoring is expected to reduce the VerticalOffset by half of that (500 -> 400)."); anchorElement.Margin = new Thickness(0, 400, 0, 0); } scrollerViewChangedEvent.Reset(); }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); WaitForEvent("Waiting for Scroller.AnchorRequested event", scrollerAnchorRequestedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Verify.AreEqual(reduceAnchorOffset ? 400 : 500, scroller.VerticalOffset); }); } }
private void AnchoringElementWithResizedViewport(Orientation orientation, double viewportSizeChange) { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper()) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollerViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupDefaultAnchoringUI(orientation, scroller, scrollerLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); ChangeZoomFactor(scroller, 2.0f, 0.0f, 0.0f, ScrollerViewKind.Absolute, ScrollerViewChangeKind.DisableAnimation); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = (scroller.ExtentHeight * 2.0 - scroller.Height) / 2.0; scroller.VerticalAnchorRatio = 0.5; } else { horizontalOffset = (scroller.ExtentWidth * 2.0 - scroller.Width) / 2.0; scroller.HorizontalAnchorRatio = 0.5; } }); ChangeOffsets(scroller, horizontalOffset, verticalOffset, ScrollerViewKind.Absolute, ScrollerViewChangeKind.DisableAnimation, ScrollerViewChangeSnapPointRespect.IgnoreSnapPoints, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { Log.Comment("Scroller view prior to viewport size change: HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", scroller.HorizontalOffset, scroller.VerticalOffset, scroller.ZoomFactor); scroller.ViewChanged += delegate(Scroller sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); scrollerViewChangedEvent.Set(); }; if (orientation == Orientation.Vertical) { Log.Comment("Changing viewport height"); scroller.Height += viewportSizeChange; } else { Log.Comment("Changing viewport width"); scroller.Width += viewportSizeChange; } }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("Scroller view after viewport size change: HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", scroller.HorizontalOffset, scroller.VerticalOffset, scroller.ZoomFactor); Log.Comment("Expecting offset change equal to half the viewport size change"); if (orientation == Orientation.Vertical) { Verify.AreEqual(scroller.VerticalOffset, verticalOffset - viewportSizeChange / 2.0); } else { Verify.AreEqual(scroller.HorizontalOffset, horizontalOffset - viewportSizeChange / 2.0); } }); } }
private void AnchoringAtFarEdgeWhileDecreasingViewport(Orientation orientation) { if (!PlatformConfiguration.IsOsVersionGreaterThanOrEqual(OSVersion.Redstone2)) { Log.Comment("Skipping test on RS1 where InteractionTracker's AdjustPositionXIfGreaterThanThreshold/AdjustPositionYIfGreaterThanThreshold are ineffective in this scenario."); return; } using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper()) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollerViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupDefaultAnchoringUI(orientation, scroller, scrollerLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); ChangeZoomFactor(scroller, 2.0f, 0.0f, 0.0f, ScrollerViewKind.Absolute, ScrollerViewChangeKind.DisableAnimation); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scroller.ExtentHeight * 2.0 - scroller.Height; scroller.VerticalAnchorRatio = 1.0; } else { horizontalOffset = scroller.ExtentWidth * 2.0 - scroller.Width; scroller.HorizontalAnchorRatio = 1.0; } }); ChangeOffsets(scroller, horizontalOffset, verticalOffset, ScrollerViewKind.Absolute, ScrollerViewChangeKind.DisableAnimation, ScrollerViewChangeSnapPointRespect.IgnoreSnapPoints, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { scroller.ViewChanged += delegate(Scroller sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); scrollerViewChangedEvent.Set(); }; if (orientation == Orientation.Vertical) { Log.Comment("Decreasing viewport height"); scroller.Height -= 100; } else { Log.Comment("Decreasing viewport width"); scroller.Width -= 100; } }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scroller.ExtentHeight * 2.0 - scroller.Height; } else { horizontalOffset = scroller.ExtentWidth * 2.0 - scroller.Width; } Log.Comment("Scroller offset change expected"); Verify.AreEqual(scroller.HorizontalOffset, horizontalOffset); Verify.AreEqual(scroller.VerticalOffset, verticalOffset); }); } }
private void AnchoringAtFarEdgeWhileIncreasingContent(Orientation orientation, double viewportSizeChange, double expectedFinalOffset) { if (!PlatformConfiguration.IsOsVersionGreaterThanOrEqual(OSVersion.Redstone2)) { Log.Comment("Skipping test on RS1 where InteractionTracker's AdjustPositionXIfGreaterThanThreshold/AdjustPositionYIfGreaterThanThreshold are ineffective in this scenario."); return; } using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper()) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollerViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupDefaultAnchoringUI(orientation, scroller, scrollerLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); ZoomTo(scroller, 2.0f, 0.0f, 0.0f, AnimationMode.Disabled, SnapPointsMode.Ignore); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scroller.ExtentHeight * 2.0 - scroller.Height; scroller.VerticalAnchorRatio = 1.0; } else { horizontalOffset = scroller.ExtentWidth * 2.0 - scroller.Width; scroller.HorizontalAnchorRatio = 1.0; } }); ScrollTo(scroller, horizontalOffset, verticalOffset, AnimationMode.Disabled, SnapPointsMode.Ignore, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { scroller.ViewChanged += delegate(Scroller sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); if ((orientation == Orientation.Vertical && expectedFinalOffset == sender.VerticalOffset) || (orientation == Orientation.Horizontal && expectedFinalOffset == sender.HorizontalOffset)) { scrollerViewChangedEvent.Set(); } }; Log.Comment("Inserting child at far edge"); InsertStackPanelChild((scroller.Content as Border).Child as StackPanel, 1 /*operationCount*/, c_defaultAnchoringUIStackPanelChildrenCount /*newIndex*/, 1 /*newCount*/); if (viewportSizeChange != 0) { if (orientation == Orientation.Vertical) { Log.Comment("Changing viewport height"); scroller.Height += viewportSizeChange; } else { Log.Comment("Changing viewport width"); scroller.Width += viewportSizeChange; } } }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scroller.ExtentHeight * 2.0 - scroller.Height; } else { horizontalOffset = scroller.ExtentWidth * 2.0 - scroller.Width; } Log.Comment("Scroller offset change expected"); Verify.AreEqual(scroller.HorizontalOffset, horizontalOffset); Verify.AreEqual(scroller.VerticalOffset, verticalOffset); }); } }
public void AnchoringAtRepeaterMiddle() { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { using (PrivateLoggingHelper privateLoggingHelper = new PrivateLoggingHelper("Scroller")) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollerViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupRepeaterAnchoringUI(scroller, scrollerLoadedEvent); scroller.HorizontalAnchorRatio = double.NaN; scroller.VerticalAnchorRatio = 0.5; }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); ZoomTo(scroller, 2.0f, 0.0f, 0.0f, AnimationMode.Enabled, SnapPointsMode.Ignore); ScrollTo(scroller, 0.0, 250.0, AnimationMode.Enabled, SnapPointsMode.Ignore, false /*hookViewChanged*/); ItemsRepeater repeater = null; TestDataSource dataSource = null; RunOnUIThread.Execute(() => { repeater = (scroller.Content as Border).Child as ItemsRepeater; dataSource = repeater.ItemsSource as TestDataSource; scroller.ViewChanged += delegate(Scroller sender, object args) { scrollerViewChangedEvent.Set(); }; Log.Comment("Inserting items at the beginning"); dataSource.Insert(0 /*index*/, 2 /*count*/); }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); RunOnUIThread.Execute(() => { Log.Comment("Scroller offset change expected"); Verify.AreEqual(scroller.VerticalOffset, 520.0); }); RunOnUIThread.Execute(() => { scrollerViewChangedEvent.Reset(); Log.Comment("Removing items from the beginning"); dataSource.Remove(0 /*index*/, 2 /*count*/); }); WaitForEvent("Waiting for Scroller.ViewChanged event", scrollerViewChangedEvent); RunOnUIThread.Execute(() => { Log.Comment("Scroller offset change expected"); Verify.AreEqual(scroller.VerticalOffset, 250.0); }); } } }
private void AnchoringAtAlmostFarEdge(Orientation orientation) { using (ScrollerTestHooksHelper scrollerTestHooksHelper = new ScrollerTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { Scroller scroller = null; AutoResetEvent scrollerLoadedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scroller = new Scroller(); SetupDefaultAnchoringUI(orientation, scroller, scrollerLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollerLoadedEvent); ZoomTo(scroller, 2.0f, 0.0f, 0.0f, AnimationMode.Disabled, SnapPointsMode.Ignore); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scroller.ExtentHeight * 2.0 - scroller.Height - 1.0; scroller.VerticalAnchorRatio = 1.0; } else { horizontalOffset = scroller.ExtentWidth * 2.0 - scroller.Width - 1.0; scroller.HorizontalAnchorRatio = 1.0; } }); ScrollTo(scroller, horizontalOffset, verticalOffset, AnimationMode.Disabled, SnapPointsMode.Ignore, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { Log.Comment("Inserting child at far edge"); InsertStackPanelChild((scroller.Content as Border).Child as StackPanel, 1 /*operationCount*/, c_defaultAnchoringUIStackPanelChildrenCount /*newIndex*/, 1 /*newCount*/); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("No Scroller offset change expected"); if (orientation == Orientation.Vertical) { Verify.AreEqual(scroller.VerticalOffset, verticalOffset); } else { Verify.AreEqual(scroller.HorizontalOffset, horizontalOffset); } }); } }