11using System ;
2+ using System . Collections . Generic ;
23using System . Diagnostics ;
4+ using System . Linq ;
35using System . Numerics ;
46using Avalonia ;
57using Avalonia . Animation ;
68using Avalonia . Animation . Easings ;
79using Avalonia . Controls ;
10+ using Avalonia . Controls . Shapes ;
811using Avalonia . Input ;
912using Avalonia . Media ;
1013using Avalonia . Rendering . Composition ;
@@ -15,6 +18,7 @@ namespace RenderDemo.Pages
1518{
1619 public class HitTestingPage : UserControl
1720 {
21+ private const int RegionSize = 80 ;
1822 private const int GroupColumns = 8 ;
1923 private const int GroupRows = 5 ;
2024 private const int CellsPerGroupSide = 10 ;
@@ -44,6 +48,9 @@ public class HitTestingPage : UserControl
4448 private bool _animationsStarted ;
4549 private Cell ? _lastHitCell ;
4650 private Cell ? _lastClickedCell ;
51+ private bool _regionSelection ;
52+ private Ellipse _region ;
53+ private List < Cell > _regionHits = new List < Cell > ( ) ;
4754
4855 public HitTestingPage ( )
4956 {
@@ -54,6 +61,9 @@ public HitTestingPage()
5461 Background = Brushes . Transparent
5562 } ;
5663
64+ _scene . PointerMoved += Scene_PointerMoved ;
65+ _scene . PointerPressed += Scene_PointerPressed ;
66+
5767 _stats = new TextBlock
5868 {
5969 HorizontalAlignment = Avalonia . Layout . HorizontalAlignment . Center ,
@@ -65,6 +75,31 @@ public HitTestingPage()
6575 IsHitTestVisible = false
6676 } ;
6777
78+ var regionSelection = new CheckBox ( )
79+ {
80+ Content = "Region Selection"
81+ } ;
82+
83+ _region = new Ellipse ( )
84+ {
85+ Width = RegionSize * 2 ,
86+ Height = RegionSize ,
87+ Fill = Brushes . Transparent ,
88+ StrokeThickness = 2 ,
89+ Stroke = Brushes . Green ,
90+ IsVisible = false ,
91+ IsHitTestVisible = false
92+ } ;
93+
94+ regionSelection . IsCheckedChanged += ( s , e ) =>
95+ {
96+ _regionSelection = ! _regionSelection ;
97+
98+ _region . IsVisible = _regionSelection ;
99+
100+ ClearRegionHighlights ( ) ;
101+ } ;
102+
68103 var numberOfHitTests = new NumericUpDown
69104 {
70105 Minimum = 0 ,
@@ -92,7 +127,8 @@ public HitTestingPage()
92127 Children =
93128 {
94129 new TextBlock { Text = "Hit tests per update:" } ,
95- numberOfHitTests
130+ numberOfHitTests ,
131+ regionSelection
96132 }
97133 } ;
98134
@@ -119,6 +155,57 @@ public HitTestingPage()
119155 ResetState ( ) ;
120156 }
121157
158+ private void ClearRegionHighlights ( )
159+ {
160+ _lastClickedCell ? . ClearHighlight ( ) ;
161+ _lastClickedCell = null ;
162+ foreach ( var cell in _regionHits )
163+ {
164+ cell . ClearHighlight ( ) ;
165+ }
166+ _regionHits . Clear ( ) ;
167+ }
168+
169+ private void Scene_PointerPressed ( object ? sender , PointerPressedEventArgs e )
170+ {
171+ if ( _regionSelection )
172+ {
173+ var bounds = _region . Bounds ;
174+
175+ ClearRegionHighlights ( ) ;
176+
177+ var geometry = new EllipseGeometry ( bounds ) ;
178+
179+ var cells = _scene . GetVisualsAt ( geometry ) ;
180+
181+ if ( cells == null )
182+ return ;
183+
184+ foreach ( var cell in cells )
185+ {
186+ if ( cell ? . VisualHit is Cell c )
187+ {
188+ c . IsLatestClick = true ;
189+ c . UpdateHighlight ( ) ;
190+ _regionHits . Add ( c ) ;
191+ }
192+ }
193+ }
194+ }
195+
196+ private void Scene_PointerMoved ( object ? sender , PointerEventArgs e )
197+ {
198+ if ( _regionSelection )
199+ {
200+ var point = e . GetPosition ( _scene ) ;
201+
202+ var rect = new Rect ( point , new Size ( ) ) . Inflate ( new Thickness ( _region . Bounds . Width / 2 , _region . Bounds . Height / 2 ) ) ;
203+
204+ Canvas . SetLeft ( _region , rect . X ) ;
205+ Canvas . SetTop ( _region , rect . Y ) ;
206+ }
207+ }
208+
122209 protected override void OnAttachedToVisualTree ( VisualTreeAttachmentEventArgs e )
123210 {
124211 base . OnAttachedToVisualTree ( e ) ;
@@ -177,6 +264,8 @@ private void BuildScene()
177264 }
178265 }
179266 }
267+
268+ _scene . Children . Add ( _region ) ;
180269 }
181270
182271 private void OnCompositionUpdate ( )
@@ -337,7 +426,7 @@ private void UpdateStats()
337426
338427 private void OnCellPointerPressed ( object ? sender , PointerPressedEventArgs e )
339428 {
340- if ( sender is not Cell cell )
429+ if ( sender is not Cell cell || _regionSelection )
341430 return ;
342431
343432 SetLastClickedCell ( cell ) ;
0 commit comments