#nullable enable using System; using Avalonia.Controls; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Rendering.Composition; using Avalonia.UnitTests; using Avalonia.VisualTree; using Moq; namespace Avalonia.Base.UnitTests.Input; public abstract class PointerTestsBase : ScopedTestBase { protected class TestPointer : Pointer { internal int PlatformCaptureCalled = 0; internal TestPointer(int id, PointerType type, bool isPrimary) : base(id, type, isPrimary) { } protected override void PlatformCapture(IInputElement? element) { PlatformCaptureCalled++; } } private protected static void SetHit(Mock renderer, Control? hit) { renderer.Setup(x => x.HitTest(It.IsAny(), It.IsAny(), It.IsAny>())) .Returns(hit is null ? Array.Empty() : new[] { hit }); renderer.Setup(x => x.HitTestFirst(It.IsAny(), It.IsAny(), It.IsAny>())) .Returns(hit); } protected static void SetMove(Mock deviceMock, IInputRoot root, IInputElement element) { deviceMock.Setup(d => d.ProcessRawEvent(It.IsAny())) .Callback(() => element.RaiseEvent(CreatePointerMovedArgs(root, element))); } private protected static Mock CreateTopLevelImplMock() { var impl = new Mock(); impl.DefaultValue = DefaultValue.Mock; impl.SetupAllProperties(); impl.SetupGet(r => r.RenderScaling).Returns(1); impl.Setup(r => r.TryGetFeature(It.IsAny())).Returns(null); impl.Setup(r => r.Compositor).Returns(RendererMocks.CreateDummyCompositor()); impl.Setup(r => r.PointToScreen(It.IsAny())).Returns(p => new PixelPoint((int)p.X, (int)p.Y)); impl.Setup(r => r.PointToClient(It.IsAny())).Returns(p => new Point(p.X, p.Y)); var screen1 = new Mock(1.75, new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 966)), true); var screens = new Mock(); screens.Setup(x => x.ScreenFromWindow(It.IsAny())).Returns(screen1.Object); impl.Setup(x => x.TryGetFeature(It.Is(t => t == typeof(IScreenImpl)))).Returns(screens.Object); return impl; } private protected static TopLevel CreateInputRoot(IWindowImpl impl, Control child, IHitTester hitTester) { var root = new Window(impl) { Width = 100, Height = 100, Content = child, Template = new FuncControlTemplate((w, _) => new ContentPresenter { Content = w.Content }), HitTesterOverride = hitTester }; root.Show(); return root; } protected static RawPointerEventArgs CreateRawPointerArgs( IPointerDevice pointerDevice, IInputRoot root, RawPointerEventType type, Point? position = default) { return new RawPointerEventArgs(pointerDevice, 0, root, type, position ?? default, default); } protected static RawPointerEventArgs CreateRawPointerMovedArgs( IPointerDevice pointerDevice, IInputRoot root, Point? position = null) { return new RawPointerEventArgs(pointerDevice, 0, root, RawPointerEventType.Move, position ?? default, default); } protected static PointerEventArgs CreatePointerMovedArgs( IInputRoot root, IInputElement? source, Point? position = null) { return new PointerEventArgs(InputElement.PointerMovedEvent, source, new Mock().Object, (Visual)root, position ?? default, default, PointerPointProperties.None, KeyModifiers.None); } protected static Mock CreatePointerDeviceMock( IPointer? pointer = null, PointerType pointerType = PointerType.Mouse) { if (pointer is null) { var pointerMock = new Mock(); pointerMock.SetupGet(p => p.Type).Returns(pointerType); pointer = pointerMock.Object; } var pointerDevice = new Mock(); pointerDevice.Setup(d => d.TryGetPointer(It.IsAny())) .Returns(pointer); return pointerDevice; } }