Browse Source

Implemented ElementComposition.SetElementChildVisual

pull/9544/head
Nikita Tsukanov 3 years ago
parent
commit
f19ba5507f
  1. 20
      src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
  2. 3
      src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs
  3. 21
      src/Avalonia.Base/Rendering/Composition/ElementCompositionPreview.cs
  4. 11
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionSolidColorVisual.cs
  5. 1
      src/Avalonia.Base/Visual.cs
  6. 3
      src/Avalonia.Base/composition-schema.xml

20
src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs

@ -146,8 +146,18 @@ public class CompositingRenderer : IRendererWithCompositor
return result == 0 ? lhs.index.CompareTo(rhs.index) : result;
});
}
if (compositionChildren.Count == visualChildren.Count)
var childVisual = v.ChildCompositionVisual;
// Check if the current visual somehow got migrated to another compositor
if (childVisual != null && childVisual.Compositor != v.CompositionVisual.Compositor)
childVisual = null;
var expectedCount = visualChildren.Count;
if (childVisual != null)
expectedCount++;
if (compositionChildren.Count == expectedCount)
{
bool mismatch = false;
if (sortedChildren != null)
@ -167,6 +177,9 @@ public class CompositingRenderer : IRendererWithCompositor
break;
}
if (childVisual != null &&
!ReferenceEquals(compositionChildren[compositionChildren.Count - 1], childVisual))
mismatch = true;
if (!mismatch)
{
@ -193,6 +206,9 @@ public class CompositingRenderer : IRendererWithCompositor
if (compositionChild != null)
compositionChildren.Add(compositionChild);
}
if (childVisual != null)
compositionChildren.Add(childVisual);
}
private void UpdateCore()

3
src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs

@ -29,4 +29,7 @@ public partial class Compositor
public ImplicitAnimationCollection CreateImplicitAnimationCollection() => new ImplicitAnimationCollection(this);
public CompositionAnimationGroup CreateAnimationGroup() => new CompositionAnimationGroup(this);
public CompositionSolidColorVisual CreateSolidColorVisual() =>
new(this, new ServerCompositionSolidColorVisual(Server));
}

21
src/Avalonia.Base/Rendering/Composition/ElementCompositionPreview.cs

@ -1,5 +1,8 @@
// Special license applies <see href="https://raw.githubusercontent.com/AvaloniaUI/Avalonia/master/src/Avalonia.Base/Rendering/Composition/License.md">License.md</see>
using System;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.Composition;
/// <summary>
@ -13,4 +16,22 @@ public static class ElementComposition
/// <param name="visual"></param>
/// <returns></returns>
public static CompositionVisual? GetElementVisual(Visual visual) => visual.CompositionVisual;
/// <summary>
/// Sets a custom <see cref="CompositionVisual"/> as the last child of the element’s visual tree.
/// </summary>
public static void SetElementChildVisual(Visual visual, CompositionVisual? compositionVisual)
{
if (compositionVisual != null && visual.CompositionVisual != null &&
compositionVisual.Compositor != visual.CompositionVisual.Compositor)
throw new InvalidOperationException("Composition visuals belong to different compositor instances");
visual.ChildCompositionVisual = compositionVisual;
visual.GetVisualRoot()?.Renderer.RecalculateChildren(visual);
}
/// <summary>
/// Retrieves a <see cref="CompositionVisual"/> object previously set by a call to <see cref="SetElementChildVisual" />.
/// </summary>
public static CompositionVisual? GetElementChildVisual(Visual visual) => visual.ChildCompositionVisual;
}

11
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionSolidColorVisual.cs

@ -0,0 +1,11 @@
using Avalonia.Media.Immutable;
namespace Avalonia.Rendering.Composition.Server;
internal partial class ServerCompositionSolidColorVisual
{
protected override void RenderCore(CompositorDrawingContextProxy canvas, Rect currentTransformedClip)
{
canvas.DrawRectangle(new ImmutableSolidColorBrush(Color), null, new Rect(0, 0, Size.X, Size.Y));
}
}

1
src/Avalonia.Base/Visual.cs

@ -292,6 +292,7 @@ namespace Avalonia
protected IRenderRoot? VisualRoot => _visualRoot ?? (this as IRenderRoot);
internal CompositionDrawListVisual? CompositionVisual { get; private set; }
internal CompositionVisual? ChildCompositionVisual { get; set; }
public bool HasNonUniformZIndexChildren { get; private set; }

3
src/Avalonia.Base/composition-schema.xml

@ -27,6 +27,9 @@
<Property Name="OpacityMaskBrush" Type="Avalonia.Media.IBrush?" Internal="true" />
</Object>
<Object Name="CompositionContainerVisual" Inherits="CompositionVisual"/>
<Object Name="CompositionSolidColorVisual" Inherits="CompositionContainerVisual">
<Property Name="Color" Type="Avalonia.Media.Color" Animated="true" />
</Object>
<List Name="CompositionVisualCollection" ItemType="CompositionVisual" CustomCtor="true"/>
<Object Name="CompositionTarget" CustomServerCtor="true">
<Property Name="Root" Type="CompositionVisual?"/>

Loading…
Cancel
Save