VisualExtensionsTests_GetVisualsAt.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System.Linq;
  4. using Avalonia.Controls;
  5. using Avalonia.Controls.Presenters;
  6. using Avalonia.Layout;
  7. using Avalonia.Media;
  8. using Avalonia.Rendering;
  9. using Avalonia.UnitTests;
  10. using Avalonia.VisualTree;
  11. using Moq;
  12. using Xunit;
  13. using System;
  14. using Avalonia.Controls.Shapes;
  15. namespace Avalonia.Visuals.UnitTests.VisualTree
  16. {
  17. public class VisualExtensionsTests_GetVisualsAt
  18. {
  19. [Fact]
  20. public void GetVisualsAt_Should_Find_Controls_At_Point()
  21. {
  22. using (TestApplication())
  23. {
  24. var container = new TestRoot
  25. {
  26. Width = 200,
  27. Height = 200,
  28. Child = new Border
  29. {
  30. Width = 100,
  31. Height = 100,
  32. Background = Brushes.Red,
  33. HorizontalAlignment = HorizontalAlignment.Center,
  34. VerticalAlignment = VerticalAlignment.Center
  35. }
  36. };
  37. container.Measure(Size.Infinity);
  38. container.Arrange(new Rect(container.DesiredSize));
  39. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  40. context.Render(container);
  41. var result = container.GetVisualsAt(new Point(100, 100));
  42. Assert.Equal(new[] { container.Child }, result);
  43. }
  44. }
  45. [Fact]
  46. public void GetVisualsAt_Should_Not_Find_Empty_Controls_At_Point()
  47. {
  48. using (TestApplication())
  49. {
  50. var container = new TestRoot
  51. {
  52. Width = 200,
  53. Height = 200,
  54. Child = new Border
  55. {
  56. Width = 100,
  57. Height = 100,
  58. HorizontalAlignment = HorizontalAlignment.Center,
  59. VerticalAlignment = VerticalAlignment.Center
  60. }
  61. };
  62. container.Measure(Size.Infinity);
  63. container.Arrange(new Rect(container.DesiredSize));
  64. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  65. context.Render(container);
  66. var result = container.GetVisualsAt(new Point(100, 100));
  67. Assert.Empty(result);
  68. }
  69. }
  70. [Fact]
  71. public void GetVisualsAt_Should_Not_Find_Invisible_Controls_At_Point()
  72. {
  73. using (TestApplication())
  74. {
  75. Border visible;
  76. var container = new TestRoot
  77. {
  78. Width = 200,
  79. Height = 200,
  80. Child = new Border
  81. {
  82. Width = 100,
  83. Height = 100,
  84. Background = Brushes.Red,
  85. HorizontalAlignment = HorizontalAlignment.Center,
  86. VerticalAlignment = VerticalAlignment.Center,
  87. IsVisible = false,
  88. Child = visible = new Border
  89. {
  90. Background = Brushes.Red,
  91. HorizontalAlignment = HorizontalAlignment.Stretch,
  92. VerticalAlignment = VerticalAlignment.Stretch,
  93. }
  94. }
  95. };
  96. container.Measure(Size.Infinity);
  97. container.Arrange(new Rect(container.DesiredSize));
  98. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  99. context.Render(container);
  100. var result = container.GetVisualsAt(new Point(100, 100));
  101. Assert.Empty(result);
  102. }
  103. }
  104. [Fact]
  105. public void GetVisualsAt_Should_Not_Find_Control_Outside_Point()
  106. {
  107. using (TestApplication())
  108. {
  109. var container = new TestRoot
  110. {
  111. Width = 200,
  112. Height = 200,
  113. Child = new Border
  114. {
  115. Width = 100,
  116. Height = 100,
  117. Background = Brushes.Red,
  118. HorizontalAlignment = HorizontalAlignment.Center,
  119. VerticalAlignment = VerticalAlignment.Center
  120. }
  121. };
  122. container.Measure(Size.Infinity);
  123. container.Arrange(new Rect(container.DesiredSize));
  124. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  125. context.Render(container);
  126. var result = container.GetVisualsAt(new Point(10, 10));
  127. Assert.Empty(result);
  128. }
  129. }
  130. [Fact]
  131. public void GetVisualsAt_Should_Return_Top_Controls_First()
  132. {
  133. using (TestApplication())
  134. {
  135. Panel container;
  136. var root = new TestRoot
  137. {
  138. Child = container = new Panel
  139. {
  140. Width = 200,
  141. Height = 200,
  142. Children = new Controls.Controls
  143. {
  144. new Border
  145. {
  146. Width = 100,
  147. Height = 100,
  148. Background = Brushes.Red,
  149. HorizontalAlignment = HorizontalAlignment.Center,
  150. VerticalAlignment = VerticalAlignment.Center
  151. },
  152. new Border
  153. {
  154. Width = 50,
  155. Height = 50,
  156. Background = Brushes.Red,
  157. HorizontalAlignment = HorizontalAlignment.Center,
  158. VerticalAlignment = VerticalAlignment.Center
  159. }
  160. }
  161. }
  162. };
  163. container.Measure(Size.Infinity);
  164. container.Arrange(new Rect(container.DesiredSize));
  165. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  166. context.Render(container);
  167. var result = container.GetVisualsAt(new Point(100, 100));
  168. Assert.Equal(new[] { container.Children[1], container.Children[0] }, result);
  169. }
  170. }
  171. [Fact]
  172. public void GetVisualsAt_Should_Return_Top_Controls_First_With_ZIndex()
  173. {
  174. using (TestApplication())
  175. {
  176. Panel container;
  177. var root = new TestRoot
  178. {
  179. Child = container = new Panel
  180. {
  181. Width = 200,
  182. Height = 200,
  183. Children = new Controls.Controls
  184. {
  185. new Border
  186. {
  187. Width = 100,
  188. Height = 100,
  189. ZIndex = 1,
  190. Background = Brushes.Red,
  191. HorizontalAlignment = HorizontalAlignment.Center,
  192. VerticalAlignment = VerticalAlignment.Center
  193. },
  194. new Border
  195. {
  196. Width = 50,
  197. Height = 50,
  198. Background = Brushes.Red,
  199. HorizontalAlignment = HorizontalAlignment.Center,
  200. VerticalAlignment = VerticalAlignment.Center
  201. },
  202. new Border
  203. {
  204. Width = 75,
  205. Height = 75,
  206. ZIndex = 2,
  207. Background = Brushes.Red,
  208. HorizontalAlignment = HorizontalAlignment.Center,
  209. VerticalAlignment = VerticalAlignment.Center
  210. }
  211. }
  212. }
  213. };
  214. container.Measure(Size.Infinity);
  215. container.Arrange(new Rect(container.DesiredSize));
  216. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  217. context.Render(container);
  218. var result = container.GetVisualsAt(new Point(100, 100));
  219. Assert.Equal(new[] { container.Children[2], container.Children[0], container.Children[1] }, result);
  220. }
  221. }
  222. [Fact]
  223. public void GetVisualsAt_Should_Find_Control_Translated_Outside_Parent_Bounds()
  224. {
  225. using (TestApplication())
  226. {
  227. Border target;
  228. Panel container;
  229. var root = new TestRoot
  230. {
  231. Child = container = new Panel
  232. {
  233. Width = 200,
  234. Height = 200,
  235. Background = Brushes.Red,
  236. ClipToBounds = false,
  237. Children = new Controls.Controls
  238. {
  239. new Border
  240. {
  241. Width = 100,
  242. Height = 100,
  243. ZIndex = 1,
  244. Background = Brushes.Red,
  245. HorizontalAlignment = HorizontalAlignment.Left,
  246. VerticalAlignment = VerticalAlignment.Top,
  247. Child = target = new Border
  248. {
  249. Width = 50,
  250. Height = 50,
  251. Background = Brushes.Red,
  252. HorizontalAlignment = HorizontalAlignment.Left,
  253. VerticalAlignment = VerticalAlignment.Top,
  254. RenderTransform = new TranslateTransform(110, 110),
  255. }
  256. },
  257. }
  258. }
  259. };
  260. container.Measure(Size.Infinity);
  261. container.Arrange(new Rect(container.DesiredSize));
  262. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  263. context.Render(container);
  264. var result = container.GetVisualsAt(new Point(120, 120));
  265. Assert.Equal(new IVisual[] { target, container }, result);
  266. }
  267. }
  268. [Fact]
  269. public void GetVisualsAt_Should_Not_Find_Control_Outside_Parent_Bounds_When_Clipped()
  270. {
  271. using (TestApplication())
  272. {
  273. Border target;
  274. Panel container;
  275. var root = new TestRoot
  276. {
  277. Child = container = new Panel
  278. {
  279. Width = 100,
  280. Height = 200,
  281. Background = Brushes.Red,
  282. Children = new Controls.Controls
  283. {
  284. new Panel()
  285. {
  286. Width = 100,
  287. Height = 100,
  288. Background = Brushes.Red,
  289. Margin = new Thickness(0, 100, 0, 0),
  290. ClipToBounds = true,
  291. Children = new Controls.Controls
  292. {
  293. (target = new Border()
  294. {
  295. Width = 100,
  296. Height = 100,
  297. Background = Brushes.Red,
  298. Margin = new Thickness(0, -100, 0, 0)
  299. })
  300. }
  301. }
  302. }
  303. }
  304. };
  305. container.Measure(Size.Infinity);
  306. container.Arrange(new Rect(container.DesiredSize));
  307. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  308. context.Render(container);
  309. var result = container.GetVisualsAt(new Point(50, 50));
  310. Assert.Equal(new[] { container }, result);
  311. }
  312. }
  313. [Fact]
  314. public void GetVisualsAt_Should_Not_Find_Control_Outside_Scroll_Viewport()
  315. {
  316. using (TestApplication())
  317. {
  318. Border target;
  319. Border item1;
  320. Border item2;
  321. ScrollContentPresenter scroll;
  322. Panel container;
  323. var root = new TestRoot
  324. {
  325. Child = container = new Panel
  326. {
  327. Width = 100,
  328. Height = 200,
  329. Background = Brushes.Red,
  330. Children = new Controls.Controls
  331. {
  332. (target = new Border()
  333. {
  334. Width = 100,
  335. Height = 100,
  336. Background = Brushes.Red,
  337. }),
  338. new Border()
  339. {
  340. Width = 100,
  341. Height = 100,
  342. Background = Brushes.Red,
  343. Margin = new Thickness(0, 100, 0, 0),
  344. Child = scroll = new ScrollContentPresenter()
  345. {
  346. Content = new StackPanel()
  347. {
  348. Children = new Controls.Controls
  349. {
  350. (item1 = new Border()
  351. {
  352. Width = 100,
  353. Height = 100,
  354. Background = Brushes.Red,
  355. }),
  356. (item2 = new Border()
  357. {
  358. Width = 100,
  359. Height = 100,
  360. Background = Brushes.Red,
  361. }),
  362. }
  363. }
  364. }
  365. }
  366. }
  367. }
  368. };
  369. scroll.UpdateChild();
  370. container.Measure(Size.Infinity);
  371. container.Arrange(new Rect(container.DesiredSize));
  372. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  373. context.Render(container);
  374. var result = container.GetVisualsAt(new Point(50, 150)).First();
  375. Assert.Equal(item1, result);
  376. result = container.GetVisualsAt(new Point(50, 50)).First();
  377. Assert.Equal(target, result);
  378. scroll.Offset = new Vector(0, 100);
  379. //we don't have setup LayoutManager so we will make it manually
  380. scroll.Parent.InvalidateArrange();
  381. container.InvalidateArrange();
  382. container.Arrange(new Rect(container.DesiredSize));
  383. context.Render(container);
  384. result = container.GetVisualsAt(new Point(50, 150)).First();
  385. Assert.Equal(item2, result);
  386. result = container.GetVisualsAt(new Point(50, 50)).First();
  387. Assert.NotEqual(item1, result);
  388. Assert.Equal(target, result);
  389. }
  390. }
  391. [Fact]
  392. public void GetVisualsAt_Should_Not_Find_Path_When_Outside_Fill()
  393. {
  394. using (TestApplication())
  395. {
  396. Path path;
  397. var container = new TestRoot
  398. {
  399. Width = 200,
  400. Height = 200,
  401. Child = path = new Path
  402. {
  403. Width = 200,
  404. Height = 200,
  405. Fill = Brushes.Red,
  406. Data = StreamGeometry.Parse("M100,0 L0,100 100,100")
  407. }
  408. };
  409. container.Measure(Size.Infinity);
  410. container.Arrange(new Rect(container.DesiredSize));
  411. var context = new DrawingContext(Mock.Of<IDrawingContextImpl>());
  412. context.Render(container);
  413. var result = container.GetVisualsAt(new Point(100, 100));
  414. Assert.Equal(new[] { path }, result);
  415. result = container.GetVisualsAt(new Point(10, 10));
  416. Assert.Empty(result);
  417. }
  418. }
  419. private IDisposable TestApplication()
  420. {
  421. return UnitTestApplication.Start(
  422. new TestServices(
  423. renderInterface: new MockRenderInterface(),
  424. renderLoop: Mock.Of<IRenderLoop>(),
  425. renderer: (root, loop) => new DeferredRenderer(root, loop)));
  426. }
  427. }
  428. }