private void AnchoringAtAlmostNearEdge(Orientation orientation) { using (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { ScrollPresenter scrollPresenter = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollPresenterViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scrollPresenter = new ScrollPresenter(); SetupDefaultAnchoringUI(orientation, scrollPresenter, scrollPresenterLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollPresenterLoadedEvent); double horizontalOffset = orientation == Orientation.Vertical ? 0.0 : 1.0; double verticalOffset = orientation == Orientation.Vertical ? 1.0 : 0.0; ScrollTo(scrollPresenter, horizontalOffset, verticalOffset, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore); RunOnUIThread.Execute(() => { scrollPresenter.ViewChanged += delegate(ScrollPresenter sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); Log.Comment("ViewChanged - CurrentAnchor is " + (sender.CurrentAnchor == null ? "null" : "non-null")); scrollPresenterViewChangedEvent.Set(); }; Log.Comment("Inserting child at near edge"); InsertStackPanelChild((scrollPresenter.Content as Border).Child as StackPanel, 1 /*operationCount*/, 0 /*newIndex*/, 1 /*newCount*/); }); WaitForEvent("Waiting for ScrollPresenter.ViewChanged event", scrollPresenterViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("ScrollPresenter offset change expected"); if (orientation == Orientation.Vertical) { Verify.AreEqual(127.0, scrollPresenter.VerticalOffset); } else { Verify.AreEqual(127.0, scrollPresenter.HorizontalOffset); } Log.Comment("ScrollPresenter CurrentAnchor is " + (scrollPresenter.CurrentAnchor == null ? "null" : "non-null")); Verify.IsNotNull(scrollPresenter.CurrentAnchor); }); } }
private void AnchoringAtNearEdge(Orientation orientation) { using (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { ScrollPresenter scrollPresenter = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scrollPresenter = new ScrollPresenter(); SetupDefaultAnchoringUI(orientation, scrollPresenter, scrollPresenterLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollPresenterLoadedEvent); RunOnUIThread.Execute(() => { Log.Comment("Inserting child at near edge"); InsertStackPanelChild((scrollPresenter.Content as Border).Child as StackPanel, 1 /*operationCount*/, 0 /*newIndex*/, 1 /*newCount*/); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("No ScrollPresenter offset change expected"); if (orientation == Orientation.Vertical) { Verify.AreEqual(0, scrollPresenter.VerticalOffset); } else { Verify.AreEqual(0, scrollPresenter.HorizontalOffset); } }); } }
public void AnchoringAtRepeaterMiddle() { using (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { using (PrivateLoggingHelper privateLoggingHelper = new PrivateLoggingHelper("ScrollPresenter")) { ScrollPresenter scrollPresenter = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollPresenterViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scrollPresenter = new ScrollPresenter(); SetupRepeaterAnchoringUI(scrollPresenter, scrollPresenterLoadedEvent); scrollPresenter.HorizontalAnchorRatio = double.NaN; scrollPresenter.VerticalAnchorRatio = 0.5; }); WaitForEvent("Waiting for Loaded event", scrollPresenterLoadedEvent); ZoomTo(scrollPresenter, 2.0f, 0.0f, 0.0f, ScrollingAnimationMode.Enabled, ScrollingSnapPointsMode.Ignore); ScrollTo(scrollPresenter, 0.0, 250.0, ScrollingAnimationMode.Enabled, ScrollingSnapPointsMode.Ignore, false /*hookViewChanged*/); ItemsRepeater repeater = null; TestDataSource dataSource = null; RunOnUIThread.Execute(() => { repeater = (scrollPresenter.Content as Border).Child as ItemsRepeater; dataSource = repeater.ItemsSource as TestDataSource; scrollPresenter.ViewChanged += delegate(ScrollPresenter sender, object args) { scrollPresenterViewChangedEvent.Set(); }; Log.Comment("Inserting items at the beginning"); dataSource.Insert(0 /*index*/, 2 /*count*/); }); WaitForEvent("Waiting for ScrollPresenter.ViewChanged event", scrollPresenterViewChangedEvent); RunOnUIThread.Execute(() => { Log.Comment("ScrollPresenter offset change expected"); Verify.AreEqual(520.0, scrollPresenter.VerticalOffset); }); RunOnUIThread.Execute(() => { scrollPresenterViewChangedEvent.Reset(); Log.Comment("Removing items from the beginning"); dataSource.Remove(0 /*index*/, 2 /*count*/); }); WaitForEvent("Waiting for ScrollPresenter.ViewChanged event", scrollPresenterViewChangedEvent); RunOnUIThread.Execute(() => { Log.Comment("ScrollPresenter offset change expected"); Verify.AreEqual(250.0, scrollPresenter.VerticalOffset); Log.Comment("ScrollPresenter CurrentAnchor is " + (scrollPresenter.CurrentAnchor == null ? "null" : "non-null")); Verify.IsNotNull(scrollPresenter.CurrentAnchor); }); } } }
private void AnchoringWithOffsetCoercion(bool reduceAnchorOffset) { using (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { ScrollPresenter scrollPresenter = null; Border anchorElement = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollPresenterViewChangedEvent = new AutoResetEvent(false); AutoResetEvent scrollPresenterAnchorRequestedEvent = new AutoResetEvent(false); // This test validates that the ScrollPresenter accounts for maximum vertical offset (based on viewport and content extent) // when calculating the vertical offset shift for anchoring. The vertical offset cannot exceed content 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); scrollPresenter = new ScrollPresenter { Content = grid, Width = 200, Height = 200 }; scrollPresenter.Loaded += (object sender, RoutedEventArgs e) => { Log.Comment("ScrollPresenter.Loaded event handler"); scrollPresenterLoadedEvent.Set(); }; scrollPresenter.ViewChanged += delegate(ScrollPresenter sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); Log.Comment("ViewChanged - CurrentAnchor is " + (sender.CurrentAnchor == null ? "null" : "non-null")); if ((reduceAnchorOffset && sender.VerticalOffset == 400) || (!reduceAnchorOffset && sender.VerticalOffset == 500)) { scrollPresenterViewChangedEvent.Set(); } }; scrollPresenter.AnchorRequested += delegate(ScrollPresenter sender, ScrollingAnchorRequestedEventArgs args) { Log.Comment("AnchorRequested - Forcing the red Border to be the ScrollPresenter anchor."); args.AnchorElement = anchorElement; scrollPresenterAnchorRequestedEvent.Set(); }; Log.Comment("Setting window content"); Content = scrollPresenter; }); WaitForEvent("Waiting for ScrollPresenter.Loaded event", scrollPresenterLoadedEvent); IdleSynchronizer.Wait(); ScrollTo(scrollPresenter, 0.0, 600.0, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore); RunOnUIThread.Execute(() => { Verify.AreEqual(600, scrollPresenter.VerticalOffset); Log.Comment("ScrollPresenter.Content height is reduced by 300px. ScrollPresenter.VerticalOffset is expected to be reduced by 100px (600 -> 500)."); (scrollPresenter.Content as Grid).Height = 700; if (reduceAnchorOffset) { Log.Comment("Tracked element is shifted up by 200px within the ScrollPresenter.Content (600 -> 400). Anchoring is expected to reduce the VerticalOffset by half of that (500 -> 400)."); anchorElement.Margin = new Thickness(0, 400, 0, 0); } scrollPresenterViewChangedEvent.Reset(); }); WaitForEvent("Waiting for ScrollPresenter.ViewChanged event", scrollPresenterViewChangedEvent); WaitForEvent("Waiting for ScrollPresenter.AnchorRequested event", scrollPresenterAnchorRequestedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Verify.AreEqual(reduceAnchorOffset ? 400 : 500, scrollPresenter.VerticalOffset); Log.Comment("ScrollPresenter CurrentAnchor is " + (scrollPresenter.CurrentAnchor == null ? "null" : "non-null")); Verify.IsNotNull(scrollPresenter.CurrentAnchor); }); } }
private void AnchoringElementWithResizedViewport(Orientation orientation, double viewportSizeChange) { using (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { ScrollPresenter scrollPresenter = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollPresenterViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scrollPresenter = new ScrollPresenter(); SetupDefaultAnchoringUI(orientation, scrollPresenter, scrollPresenterLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollPresenterLoadedEvent); ZoomTo(scrollPresenter, 2.0f, 0.0f, 0.0f, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = (scrollPresenter.ExtentHeight * 2.0 - scrollPresenter.Height) / 2.0; scrollPresenter.VerticalAnchorRatio = 0.5; } else { horizontalOffset = (scrollPresenter.ExtentWidth * 2.0 - scrollPresenter.Width) / 2.0; scrollPresenter.HorizontalAnchorRatio = 0.5; } }); ScrollTo(scrollPresenter, horizontalOffset, verticalOffset, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { Log.Comment("ScrollPresenter view prior to viewport size change: HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", scrollPresenter.HorizontalOffset, scrollPresenter.VerticalOffset, scrollPresenter.ZoomFactor); scrollPresenter.ViewChanged += delegate(ScrollPresenter sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); Log.Comment("ViewChanged - CurrentAnchor is " + (sender.CurrentAnchor == null ? "null" : "non-null")); scrollPresenterViewChangedEvent.Set(); }; if (orientation == Orientation.Vertical) { Log.Comment("Changing viewport height"); scrollPresenter.Height += viewportSizeChange; } else { Log.Comment("Changing viewport width"); scrollPresenter.Width += viewportSizeChange; } }); WaitForEvent("Waiting for ScrollPresenter.ViewChanged event", scrollPresenterViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("ScrollPresenter view after viewport size change: HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", scrollPresenter.HorizontalOffset, scrollPresenter.VerticalOffset, scrollPresenter.ZoomFactor); Log.Comment("Expecting offset change equal to half the viewport size change"); if (orientation == Orientation.Vertical) { Verify.AreEqual(scrollPresenter.VerticalOffset, verticalOffset - viewportSizeChange / 2.0); } else { Verify.AreEqual(scrollPresenter.HorizontalOffset, horizontalOffset - viewportSizeChange / 2.0); } Log.Comment("ScrollPresenter CurrentAnchor is " + (scrollPresenter.CurrentAnchor == null ? "null" : "non-null")); Verify.IsNotNull(scrollPresenter.CurrentAnchor); }); } }
private void AnchoringAtAlmostFarEdge(Orientation orientation) { using (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { ScrollPresenter scrollPresenter = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scrollPresenter = new ScrollPresenter(); SetupDefaultAnchoringUI(orientation, scrollPresenter, scrollPresenterLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollPresenterLoadedEvent); ZoomTo(scrollPresenter, 2.0f, 0.0f, 0.0f, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scrollPresenter.ExtentHeight * 2.0 - scrollPresenter.Height - 1.0; scrollPresenter.VerticalAnchorRatio = 1.0; } else { horizontalOffset = scrollPresenter.ExtentWidth * 2.0 - scrollPresenter.Width - 1.0; scrollPresenter.HorizontalAnchorRatio = 1.0; } }); ScrollTo(scrollPresenter, horizontalOffset, verticalOffset, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { Log.Comment("Inserting child at far edge"); InsertStackPanelChild((scrollPresenter.Content as Border).Child as StackPanel, 1 /*operationCount*/, c_defaultAnchoringUIStackPanelChildrenCount /*newIndex*/, 1 /*newCount*/); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { Log.Comment("No ScrollPresenter offset change expected"); if (orientation == Orientation.Vertical) { Verify.AreEqual(scrollPresenter.VerticalOffset, verticalOffset); } else { Verify.AreEqual(scrollPresenter.HorizontalOffset, horizontalOffset); } Log.Comment("ScrollPresenter CurrentAnchor is " + (scrollPresenter.CurrentAnchor == null ? "null" : "non-null")); Verify.IsNotNull(scrollPresenter.CurrentAnchor); }); } }
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 (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { ScrollPresenter scrollPresenter = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollPresenterViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scrollPresenter = new ScrollPresenter(); SetupDefaultAnchoringUI(orientation, scrollPresenter, scrollPresenterLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollPresenterLoadedEvent); ZoomTo(scrollPresenter, 2.0f, 0.0f, 0.0f, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore); double horizontalOffset = 0.0; double verticalOffset = 0.0; RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scrollPresenter.ExtentHeight * 2.0 - scrollPresenter.Height; scrollPresenter.VerticalAnchorRatio = 1.0; } else { horizontalOffset = scrollPresenter.ExtentWidth * 2.0 - scrollPresenter.Width; scrollPresenter.HorizontalAnchorRatio = 1.0; } }); ScrollTo(scrollPresenter, horizontalOffset, verticalOffset, ScrollingAnimationMode.Disabled, ScrollingSnapPointsMode.Ignore, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { scrollPresenter.ViewChanged += delegate(ScrollPresenter sender, object args) { Log.Comment("ViewChanged - HorizontalOffset={0}, VerticalOffset={1}, ZoomFactor={2}", sender.HorizontalOffset, sender.VerticalOffset, sender.ZoomFactor); Log.Comment("ViewChanged - CurrentAnchor is " + (sender.CurrentAnchor == null ? "null" : "non-null")); scrollPresenterViewChangedEvent.Set(); }; scrollPresenter.AnchorRequested += delegate(ScrollPresenter sender, ScrollingAnchorRequestedEventArgs args) { Log.Comment("AnchorRequested - AnchorCandidates.Count={0}", args.AnchorCandidates.Count); }; if (orientation == Orientation.Vertical) { Log.Comment("Decreasing viewport height"); scrollPresenter.Height -= 100; } else { Log.Comment("Decreasing viewport width"); scrollPresenter.Width -= 100; } }); WaitForEvent("Waiting for ScrollPresenter.ViewChanged event", scrollPresenterViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scrollPresenter.ExtentHeight * 2.0 - scrollPresenter.Height; } else { horizontalOffset = scrollPresenter.ExtentWidth * 2.0 - scrollPresenter.Width; } Log.Comment("ScrollPresenter offset change expected"); Verify.AreEqual(scrollPresenter.HorizontalOffset, horizontalOffset); Verify.AreEqual(scrollPresenter.VerticalOffset, verticalOffset); Log.Comment("ScrollPresenter CurrentAnchor is " + (scrollPresenter.CurrentAnchor == null ? "null" : "non-null")); Verify.IsNull(scrollPresenter.CurrentAnchor); }); } }
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 (ScrollPresenterTestHooksHelper scrollPresenterTestHooksHelper = new ScrollPresenterTestHooksHelper( enableAnchorNotifications: true, enableInteractionSourcesNotifications: true, enableExpressionAnimationStatusNotifications: false)) { ScrollPresenter scrollPresenter = null; AutoResetEvent scrollPresenterLoadedEvent = new AutoResetEvent(false); AutoResetEvent scrollPresenterViewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { scrollPresenter = new ScrollPresenter(); SetupDefaultAnchoringUI(orientation, scrollPresenter, scrollPresenterLoadedEvent); }); WaitForEvent("Waiting for Loaded event", scrollPresenterLoadedEvent); ZoomTo(scrollPresenter, 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 = scrollPresenter.ExtentHeight * 2.0 - scrollPresenter.Height; scrollPresenter.VerticalAnchorRatio = 1.0; } else { horizontalOffset = scrollPresenter.ExtentWidth * 2.0 - scrollPresenter.Width; scrollPresenter.HorizontalAnchorRatio = 1.0; } }); ScrollTo(scrollPresenter, horizontalOffset, verticalOffset, AnimationMode.Disabled, SnapPointsMode.Ignore, false /*hookViewChanged*/); RunOnUIThread.Execute(() => { scrollPresenter.ViewChanged += delegate(ScrollPresenter 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)) { scrollPresenterViewChangedEvent.Set(); } }; Log.Comment("Inserting child at far edge"); InsertStackPanelChild((scrollPresenter.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"); scrollPresenter.Height += viewportSizeChange; } else { Log.Comment("Changing viewport width"); scrollPresenter.Width += viewportSizeChange; } } }); WaitForEvent("Waiting for ScrollPresenter.ViewChanged event", scrollPresenterViewChangedEvent); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { if (orientation == Orientation.Vertical) { verticalOffset = scrollPresenter.ExtentHeight * 2.0 - scrollPresenter.Height; } else { horizontalOffset = scrollPresenter.ExtentWidth * 2.0 - scrollPresenter.Width; } Log.Comment("ScrollPresenter offset change expected"); Verify.AreEqual(scrollPresenter.HorizontalOffset, horizontalOffset); Verify.AreEqual(scrollPresenter.VerticalOffset, verticalOffset); }); } }