Skip to content

Commit 19ea747

Browse files
Merge pull request #104 from wieslawsoltes/HeadlessTests
Headless tests
2 parents 60d08c4 + 8f480b3 commit 19ea747

17 files changed

+4317
-37
lines changed

build/XUnit.props

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup>
4+
<PackageReference Include="Avalonia.Headless.XUnit" Version="11.3.0" />
5+
</ItemGroup>
36
<ItemGroup>
47
<PackageReference Include="xunit" Version="2.4.1" />
58
<PackageReference Include="xunit.abstractions" Version="2.0.3" />

src/PanAndZoom/ZoomBorder.cs

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
using System;
1+
using System;
22
using System.Diagnostics;
33
using Avalonia.Controls.Metadata;
44
using Avalonia.Input;
55
using Avalonia.Input.GestureRecognizers;
66
using Avalonia.Media;
77
using Avalonia.Media.Transformation;
88
using Avalonia.Reactive;
9+
using Avalonia.Styling;
910
using static System.Math;
1011

1112
namespace Avalonia.Controls.PanAndZoom;
@@ -86,7 +87,6 @@ public ZoomBorder()
8687

8788
this.GetObservable(ChildProperty).Subscribe(new AnonymousObserver<Control?>(ChildChanged));
8889
this.GetObservable(BoundsProperty).Subscribe(new AnonymousObserver<Rect>(BoundsChanged));
89-
Gestures.AddPointerTouchPadGestureMagnifyHandler(this, Border_Magnified);
9090

9191
// Initialize gesture recognizers
9292
_pinchGestureRecognizer = new PinchGestureRecognizer();
@@ -96,12 +96,6 @@ public ZoomBorder()
9696
CanVerticallyScroll = true
9797
};
9898

99-
// Add gesture event handlers
100-
AddHandler(Gestures.PinchEvent, Border_PinchGesture);
101-
AddHandler(Gestures.PinchEndedEvent, Border_PinchGestureEnded);
102-
AddHandler(Gestures.ScrollGestureEvent, Border_ScrollGesture);
103-
AddHandler(Gestures.ScrollGestureEndedEvent, Border_ScrollGestureEnded);
104-
10599
// Add gesture recognizers based on EnableGestures flag
106100
UpdateGestureRecognizers();
107101

@@ -141,12 +135,6 @@ private void UpdateGestureRecognizers()
141135
CanVerticallyScroll = true
142136
};
143137

144-
// Re-add event handlers to new recognizers
145-
AddHandler(Gestures.PinchEvent, Border_PinchGesture);
146-
AddHandler(Gestures.PinchEndedEvent, Border_PinchGestureEnded);
147-
AddHandler(Gestures.ScrollGestureEvent, Border_ScrollGesture);
148-
AddHandler(Gestures.ScrollGestureEndedEvent, Border_ScrollGestureEnded);
149-
150138
_gestureRecognizersAdded = false;
151139
}
152140
}
@@ -195,6 +183,22 @@ private void PanAndZoom_AttachedToVisualTree(object? sender, VisualTreeAttachmen
195183
Log($"[AttachedToVisualTree] {Name}");
196184
ChildChanged(Child);
197185

186+
// Add pointer event handlers
187+
PointerWheelChanged += Border_PointerWheelChanged;
188+
PointerPressed += Border_PointerPressed;
189+
PointerReleased += Border_PointerReleased;
190+
PointerMoved += Border_PointerMoved;
191+
PointerCaptureLost += Border_PointerCaptureLost;
192+
193+
// Add gesture event handlers
194+
AddHandler(Gestures.PinchEvent, Border_PinchGesture);
195+
AddHandler(Gestures.PinchEndedEvent, Border_PinchGestureEnded);
196+
AddHandler(Gestures.ScrollGestureEvent, Border_ScrollGesture);
197+
AddHandler(Gestures.ScrollGestureEndedEvent, Border_ScrollGestureEnded);
198+
199+
// Add touch pad gesture handler
200+
Gestures.AddPointerTouchPadGestureMagnifyHandler(this, Border_Magnified);
201+
198202
// Update gesture recognizers based on the new state
199203
UpdateGestureRecognizers();
200204

@@ -207,6 +211,22 @@ private void PanAndZoom_DetachedFromVisualTree(object? sender, VisualTreeAttachm
207211
{
208212
Log($"[DetachedFromVisualTree] {Name}");
209213
DetachElement();
214+
215+
// Remove pointer event handlers
216+
PointerWheelChanged -= Border_PointerWheelChanged;
217+
PointerPressed -= Border_PointerPressed;
218+
PointerReleased -= Border_PointerReleased;
219+
PointerMoved -= Border_PointerMoved;
220+
PointerCaptureLost -= Border_PointerCaptureLost;
221+
222+
// Remove gesture event handlers
223+
RemoveHandler(Gestures.PinchEvent, Border_PinchGesture);
224+
RemoveHandler(Gestures.PinchEndedEvent, Border_PinchGestureEnded);
225+
RemoveHandler(Gestures.ScrollGestureEvent, Border_ScrollGesture);
226+
RemoveHandler(Gestures.ScrollGestureEndedEvent, Border_ScrollGestureEnded);
227+
228+
// Remove touch pad gesture handler
229+
Gestures.RemovePointerTouchPadGestureMagnifyHandler(this, Border_Magnified);
210230
}
211231

212232
private void Border_Magnified(object? sender, PointerDeltaEventArgs e)
@@ -218,7 +238,7 @@ private void Border_Magnified(object? sender, PointerDeltaEventArgs e)
218238

219239
private void Border_PinchGesture(object? sender, PinchEventArgs e)
220240
{
221-
if (!EnableGestureZoom || _element == null)
241+
if (!EnableGestures || !EnableGestureZoom || _element == null)
222242
return;
223243

224244
Log($"[PinchGesture] {Name} Scale: {e.Scale}");
@@ -235,13 +255,16 @@ private void Border_PinchGesture(object? sender, PinchEventArgs e)
235255

236256
private void Border_PinchGestureEnded(object? sender, PinchEndedEventArgs e)
237257
{
258+
if (!EnableGestures)
259+
return;
260+
238261
Log($"[PinchGestureEnded] {Name}");
239262
e.Handled = true;
240263
}
241264

242265
private void Border_ScrollGesture(object? sender, ScrollGestureEventArgs e)
243266
{
244-
if (!EnableGestureTranslation)
267+
if (!EnableGestureTranslation || _element == null)
245268
return;
246269

247270
Log($"[ScrollGesture] {Name} Delta: {e.Delta}");
@@ -287,9 +310,10 @@ private void Border_PointerMoved(object? sender, PointerEventArgs e)
287310
Moved(e);
288311
}
289312

290-
private void Border_PointerCaptureLost(object sender, PointerCaptureLostEventArgs e)
313+
private void Border_PointerCaptureLost(object? sender, PointerCaptureLostEventArgs e)
291314
{
292315
CaptureLost();
316+
e.Handled = true;
293317
}
294318

295319
private void Element_PropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
@@ -330,11 +354,6 @@ private void AttachElement(Control? element)
330354

331355
_element = element;
332356
_element.PropertyChanged += Element_PropertyChanged;
333-
PointerCaptureLost += Border_PointerCaptureLost;
334-
PointerWheelChanged += Border_PointerWheelChanged;
335-
PointerPressed += Border_PointerPressed;
336-
PointerReleased += Border_PointerReleased;
337-
PointerMoved += Border_PointerMoved;
338357

339358
}
340359

@@ -345,11 +364,6 @@ private void DetachElement()
345364
return;
346365
}
347366

348-
PointerCaptureLost -= Border_PointerCaptureLost;
349-
PointerWheelChanged -= Border_PointerWheelChanged;
350-
PointerPressed -= Border_PointerPressed;
351-
PointerReleased -= Border_PointerReleased;
352-
PointerMoved -= Border_PointerMoved;
353367
_element.PropertyChanged -= Element_PropertyChanged;
354368
_element.RenderTransform = null;
355369
_element = null;
@@ -378,7 +392,7 @@ private void Pressed(PointerPressedEventArgs e)
378392
BeginPanTo(point.X, point.Y);
379393
_captured = true;
380394
_isPanning = true;
381-
SetPseudoClass(":isPanning", _isPanning);
395+
((IPseudoClasses)Classes).Set(":isPanning", _isPanning);
382396
}
383397
}
384398

@@ -399,7 +413,7 @@ private void PanningFinished()
399413
}
400414
_captured = false;
401415
_isPanning = false;
402-
SetPseudoClass(":isPanning", _isPanning);
416+
((IPseudoClasses)Classes).Set(":isPanning", _isPanning);
403417
}
404418

405419
private void Moved(PointerEventArgs e)
@@ -975,5 +989,5 @@ public void AutoFit(bool skipTransitions = false)
975989
AutoFit(Bounds.Width, Bounds.Height, _element.Bounds.Width, _element.Bounds.Height, skipTransitions);
976990
}
977991

978-
private void SetPseudoClass(string name, bool flag) => PseudoClasses.Set(name, flag);
992+
979993
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Application xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
x:Class="Avalonia.Controls.PanAndZoom.UnitTests.App">
4+
<Application.Styles>
5+
<FluentTheme />
6+
</Application.Styles>
7+
</Application>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Avalonia.Controls.ApplicationLifetimes;
2+
using Avalonia.Markup.Xaml;
3+
4+
namespace Avalonia.Controls.PanAndZoom.UnitTests;
5+
6+
public class App : Application
7+
{
8+
public override void Initialize()
9+
{
10+
AvaloniaXamlLoader.Load(this);
11+
}
12+
13+
public override void OnFrameworkInitializationCompleted()
14+
{
15+
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime)
16+
{
17+
// This is for headless testing, no main window needed
18+
}
19+
20+
base.OnFrameworkInitializationCompleted();
21+
}
22+
}

tests/Avalonia.Controls.PanAndZoom.UnitTests/Avalonia.Controls.PanAndZoom.UnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
<Import Project="..\..\build\Base.props" />
1111
<Import Project="..\..\build\Avalonia.props" />
12+
<Import Project="..\..\build\Avalonia.Themes.Fluent.props" />
1213
<Import Project="..\..\build\XUnit.props" />
1314

1415
<ItemGroup>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using Avalonia.Headless;
2+
3+
[assembly: AvaloniaTestApplication(typeof(Avalonia.Controls.PanAndZoom.UnitTests.TestAppBuilder))]
4+
5+
namespace Avalonia.Controls.PanAndZoom.UnitTests;
6+
7+
public class TestAppBuilder
8+
{
9+
public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure<App>()
10+
.UseHeadless(new AvaloniaHeadlessPlatformOptions());
11+
}

0 commit comments

Comments
 (0)