SceneBuilderTests_Layers.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using System;
  2. using System.Linq;
  3. using Avalonia.Controls;
  4. using Avalonia.Media;
  5. using Avalonia.Rendering.SceneGraph;
  6. using Avalonia.UnitTests;
  7. using Avalonia.VisualTree;
  8. using Xunit;
  9. using Avalonia.Layout;
  10. using System.Reactive.Subjects;
  11. using Avalonia.Data;
  12. namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
  13. {
  14. public partial class SceneBuilderTests
  15. {
  16. [Fact]
  17. public void Control_With_Animated_Opacity_And_Children_Should_Start_New_Layer()
  18. {
  19. using (TestApplication())
  20. {
  21. Decorator decorator;
  22. Border border;
  23. Canvas canvas;
  24. var tree = new TestRoot
  25. {
  26. Padding = new Thickness(10),
  27. Width = 100,
  28. Height = 120,
  29. Child = decorator = new Decorator
  30. {
  31. Padding = new Thickness(11),
  32. Child = border = new Border
  33. {
  34. Background = Brushes.Red,
  35. Padding = new Thickness(12),
  36. Child = canvas = new Canvas()
  37. }
  38. }
  39. };
  40. var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
  41. layout.ExecuteInitialLayoutPass(tree);
  42. var animation = new BehaviorSubject<double>(0.5);
  43. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  44. var scene = new Scene(tree);
  45. var sceneBuilder = new SceneBuilder();
  46. sceneBuilder.UpdateAll(scene);
  47. var rootNode = (VisualNode)scene.Root;
  48. var borderNode = (VisualNode)scene.FindNode(border);
  49. var canvasNode = (VisualNode)scene.FindNode(canvas);
  50. Assert.Same(tree, rootNode.LayerRoot);
  51. Assert.Same(border, borderNode.LayerRoot);
  52. Assert.Same(border, canvasNode.LayerRoot);
  53. Assert.Equal(0.5, scene.Layers[border].Opacity);
  54. Assert.Equal(2, scene.Layers.Count());
  55. Assert.Empty(scene.Layers.Select(x => x.LayerRoot).Except(new IVisual[] { tree, border }));
  56. animation.OnCompleted();
  57. scene = scene.CloneScene();
  58. sceneBuilder.Update(scene, border);
  59. rootNode = (VisualNode)scene.Root;
  60. borderNode = (VisualNode)scene.FindNode(border);
  61. canvasNode = (VisualNode)scene.FindNode(canvas);
  62. Assert.Same(tree, rootNode.LayerRoot);
  63. Assert.Same(tree, borderNode.LayerRoot);
  64. Assert.Same(tree, canvasNode.LayerRoot);
  65. Assert.Single(scene.Layers);
  66. var rootDirty = scene.Layers[tree].Dirty;
  67. Assert.Single(rootDirty);
  68. Assert.Equal(new Rect(21, 21, 58, 78), rootDirty.Single());
  69. }
  70. }
  71. [Fact]
  72. public void Control_With_Animated_Opacity_And_No_Children_Should_Not_Start_New_Layer()
  73. {
  74. using (TestApplication())
  75. {
  76. Decorator decorator;
  77. Border border;
  78. var tree = new TestRoot
  79. {
  80. Padding = new Thickness(10),
  81. Width = 100,
  82. Height = 120,
  83. Child = decorator = new Decorator
  84. {
  85. Padding = new Thickness(11),
  86. Child = border = new Border
  87. {
  88. Background = Brushes.Red,
  89. }
  90. }
  91. };
  92. var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
  93. layout.ExecuteInitialLayoutPass(tree);
  94. var animation = new BehaviorSubject<double>(0.5);
  95. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  96. var scene = new Scene(tree);
  97. var sceneBuilder = new SceneBuilder();
  98. sceneBuilder.UpdateAll(scene);
  99. Assert.Single(scene.Layers);
  100. }
  101. }
  102. [Fact]
  103. public void Removing_Control_With_Animated_Opacity_Should_Remove_Layers()
  104. {
  105. using (TestApplication())
  106. {
  107. Decorator decorator;
  108. Border border;
  109. Canvas canvas;
  110. var tree = new TestRoot
  111. {
  112. Padding = new Thickness(10),
  113. Width = 100,
  114. Height = 120,
  115. Child = decorator = new Decorator
  116. {
  117. Padding = new Thickness(11),
  118. Child = border = new Border
  119. {
  120. Background = Brushes.Red,
  121. Padding = new Thickness(12),
  122. Child = canvas = new Canvas
  123. {
  124. Children = { new TextBlock() },
  125. }
  126. }
  127. }
  128. };
  129. var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
  130. layout.ExecuteInitialLayoutPass(tree);
  131. var animation = new BehaviorSubject<double>(0.5);
  132. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  133. canvas.Bind(Canvas.OpacityProperty, animation, BindingPriority.Animation);
  134. var scene = new Scene(tree);
  135. var sceneBuilder = new SceneBuilder();
  136. sceneBuilder.UpdateAll(scene);
  137. Assert.Equal(3, scene.Layers.Count);
  138. decorator.Child = null;
  139. scene = scene.CloneScene();
  140. sceneBuilder.Update(scene, border);
  141. Assert.Equal(1, scene.Layers.Count);
  142. }
  143. }
  144. [Fact]
  145. public void Hiding_Transparent_Control_Should_Remove_Layers()
  146. {
  147. using (TestApplication())
  148. {
  149. Decorator decorator;
  150. Border border;
  151. Canvas canvas;
  152. var tree = new TestRoot
  153. {
  154. Padding = new Thickness(10),
  155. Width = 100,
  156. Height = 120,
  157. Child = decorator = new Decorator
  158. {
  159. Padding = new Thickness(11),
  160. Child = border = new Border
  161. {
  162. Background = Brushes.Red,
  163. Padding = new Thickness(12),
  164. Child = canvas = new Canvas
  165. {
  166. Children = { new TextBlock() },
  167. }
  168. }
  169. }
  170. };
  171. var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
  172. layout.ExecuteInitialLayoutPass(tree);
  173. var animation = new BehaviorSubject<double>(0.5);
  174. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  175. canvas.Bind(Canvas.OpacityProperty, animation, BindingPriority.Animation);
  176. var scene = new Scene(tree);
  177. var sceneBuilder = new SceneBuilder();
  178. sceneBuilder.UpdateAll(scene);
  179. Assert.Equal(3, scene.Layers.Count);
  180. border.IsVisible = false;
  181. scene = scene.CloneScene();
  182. sceneBuilder.Update(scene, border);
  183. Assert.Equal(1, scene.Layers.Count);
  184. }
  185. }
  186. [Fact]
  187. public void GeometryClip_Should_Affect_Child_Layers()
  188. {
  189. using (TestApplication())
  190. {
  191. var clip = StreamGeometry.Parse("M100,0 L0,100 100,100");
  192. Decorator decorator;
  193. Border border;
  194. var tree = new TestRoot
  195. {
  196. Child = decorator = new Decorator
  197. {
  198. Clip = clip,
  199. Margin = new Thickness(12, 16),
  200. Child = border = new Border
  201. {
  202. Opacity = 0.5,
  203. Child = new Canvas(),
  204. }
  205. }
  206. };
  207. var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
  208. layout.ExecuteInitialLayoutPass(tree);
  209. var animation = new BehaviorSubject<double>(0.5);
  210. border.Bind(Border.OpacityProperty, animation, BindingPriority.Animation);
  211. var scene = new Scene(tree);
  212. var sceneBuilder = new SceneBuilder();
  213. sceneBuilder.UpdateAll(scene);
  214. var borderLayer = scene.Layers[border];
  215. Assert.Equal(
  216. Matrix.CreateTranslation(12, 16),
  217. ((MockStreamGeometryImpl)borderLayer.GeometryClip).Transform);
  218. }
  219. }
  220. }
  221. }