diff --git a/src/Uno.UWP/UI/Composition/CompositionClip.cs b/src/Uno.UWP/UI/Composition/CompositionClip.cs index 7129bfef10c9..fc4e60e02b82 100644 --- a/src/Uno.UWP/UI/Composition/CompositionClip.cs +++ b/src/Uno.UWP/UI/Composition/CompositionClip.cs @@ -6,17 +6,59 @@ namespace Windows.UI.Composition { public partial class CompositionClip : CompositionObject { + private Matrix3x2 _transformMatrix = Matrix3x2.Identity; + private Vector2 _scale = new Vector2(1, 1); + private float _rotationAngleInDegrees; + private float _rotationAngle; + private Vector2 _offset = Vector2.Zero; + private Vector2 _centerPoint = Vector2.Zero; + private Vector2 _anchorPoint = Vector2.Zero; + internal CompositionClip(Compositor compositor) : base(compositor) { } - public Matrix3x2 TransformMatrix { get; set; } - public Vector2 Scale { get; set; } - public float RotationAngleInDegrees { get; set; } - public float RotationAngle { get; set; } - public Vector2 Offset { get; set; } - public Vector2 CenterPoint { get; set; } - public Vector2 AnchorPoint { get; set; } + public Matrix3x2 TransformMatrix + { + get => _transformMatrix; + set => SetProperty(ref _transformMatrix, value); + } + + public Vector2 Scale + { + get => _scale; + set => SetProperty(ref _scale, value); + } + + public float RotationAngleInDegrees + { + get => _rotationAngleInDegrees; + set => SetProperty(ref _rotationAngleInDegrees, value); + } + + public float RotationAngle + { + get => _rotationAngle; + set => SetProperty(ref _rotationAngle, value); + } + + public Vector2 Offset + { + get => _offset; + set => SetProperty(ref _offset, value); + } + + public Vector2 CenterPoint + { + get => _centerPoint; + set => SetProperty(ref _centerPoint, value); + } + + public Vector2 AnchorPoint + { + get => _anchorPoint; + set => SetProperty(ref _anchorPoint, value); + } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionColorBrush.cs b/src/Uno.UWP/UI/Composition/CompositionColorBrush.cs index 74f8c84141f3..7a18b8267e74 100644 --- a/src/Uno.UWP/UI/Composition/CompositionColorBrush.cs +++ b/src/Uno.UWP/UI/Composition/CompositionColorBrush.cs @@ -1,20 +1,14 @@ #nullable enable using System; -using System.Collections.Generic; -using Uno.Disposables; -using Windows.UI; namespace Windows.UI.Composition { public partial class CompositionColorBrush : CompositionBrush { - private List _colorChangedHandlers = new List(); private Color _color; - internal CompositionColorBrush() => throw new NotSupportedException(); - - public CompositionColorBrush(Compositor compositor) : base(compositor) + internal CompositionColorBrush(Compositor compositor) : base(compositor) { } @@ -22,22 +16,7 @@ public CompositionColorBrush(Compositor compositor) : base(compositor) public Color Color { get { return _color; } - set { _color = value; OnColorChanged(); } - } - - private void OnColorChanged() - { - foreach (var handler in _colorChangedHandlers) - { - handler(); - } - } - - internal IDisposable RegisterColorChanged(Action onColorChanged) - { - _colorChangedHandlers.Add(onColorChanged); - - return Disposable.Create(() => _colorChangedHandlers.Remove(onColorChanged)); + set { SetProperty(ref _color, value); } } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionGeometricClip.cs b/src/Uno.UWP/UI/Composition/CompositionGeometricClip.cs index dfa3e8e5d380..bba3e6dd535b 100644 --- a/src/Uno.UWP/UI/Composition/CompositionGeometricClip.cs +++ b/src/Uno.UWP/UI/Composition/CompositionGeometricClip.cs @@ -2,20 +2,26 @@ namespace Windows.UI.Composition { - public partial class CompositionGeometricClip : global::Windows.UI.Composition.CompositionClip + public partial class CompositionGeometricClip : CompositionClip { + private CompositionViewBox? _viewBox; + private CompositionGeometry? _geometry; + public CompositionGeometricClip(Compositor compositor) : base(compositor) { } + public CompositionViewBox? ViewBox { - get; set; + get => _viewBox; + set => SetProperty(ref _viewBox, value); } public CompositionGeometry? Geometry { - get; set; + get => _geometry; + set => SetProperty(ref _geometry, value); } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionObject.cs b/src/Uno.UWP/UI/Composition/CompositionObject.cs index 13c593b9b700..694de22630a6 100644 --- a/src/Uno.UWP/UI/Composition/CompositionObject.cs +++ b/src/Uno.UWP/UI/Composition/CompositionObject.cs @@ -1,14 +1,16 @@ #nullable enable using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; using Windows.Foundation.Metadata; using Windows.UI.Core; namespace Windows.UI.Composition { - public partial class CompositionObject : global::System.IDisposable + public partial class CompositionObject : IDisposable { - private object _gate = new object(); + private readonly ContextStore _contextStore = new ContextStore(); internal CompositionObject() { @@ -25,17 +27,184 @@ internal CompositionObject(Compositor compositor) public CoreDispatcher Dispatcher => CoreDispatcher.Main; + public string? Comment { get; set; } + public void StartAnimation(string propertyName, CompositionAnimation animation) { StartAnimationCore(propertyName, animation); } + public void StopAnimation(string propertyName) + { + + } + internal virtual void StartAnimationCore(string propertyName, CompositionAnimation animation) { } - public void StopAnimation(string propertyName) + internal void AddContext(CompositionObject context, string? propertyName) { + _contextStore.AddContext(context, propertyName); } - public string? Comment { get; set; } + internal void RemoveContext(CompositionObject context, string? propertyName) + { + _contextStore.RemoveContext(context, propertyName); + } + + private protected void SetProperty(ref T field, T value, [CallerMemberName] string? propertyName = null) + { + var fieldCO = field as CompositionObject; + var valueCO = value as CompositionObject; + if (fieldCO != null || value != null) + { + OnCompositionPropertyChanged(fieldCO, valueCO, propertyName); + } + + field = value; + + OnPropertyChanged(propertyName, false); + } + + private protected void OnChanged() => OnPropertyChanged(null, false); + + private protected void OnCompositionPropertyChanged(CompositionObject? oldValue, CompositionObject? newValue) => OnCompositionPropertyChanged(oldValue, newValue, null); + + private protected void OnCompositionPropertyChanged(CompositionObject? oldValue, CompositionObject? newValue, string? propertyName) + { + if (oldValue != null) + { + oldValue.RemoveContext(this, propertyName); + } + + if (newValue != null) + { + newValue.AddContext(this, propertyName); + } + } + + private protected void OnPropertyChanged(string? propertyName, bool isSubPropertyChange) + { + OnPropertyChangedCore(propertyName, isSubPropertyChange); + _contextStore.RaiseChanged(); + } + + private protected virtual void OnPropertyChangedCore(string? propertyName, bool isSubPropertyChange) + { + + } + + private class ContextStore + { + private readonly object _lock = new object(); + private List? _contextEntries = null; + + public ContextStore() + { + + } + + public void AddContext(CompositionObject context, string? propertyName) + { + lock (_lock) + { + AddContextImpl(context, propertyName); + } + } + + public void RemoveContext(CompositionObject context, string? propertyName) + { + lock (_lock) + { + RemoveContextImpl(context, propertyName); + } + } + + public void RaiseChanged() + { + lock (_lock) + { + RaiseChangedImpl(); + } + } + + private void AddContextImpl(CompositionObject newContext, string? propertyName) + { + var contextEntries = _contextEntries; + if (contextEntries == null) + { + contextEntries = new List(); + _contextEntries = contextEntries; + } + + contextEntries.Add(new ContextEntry(newContext, propertyName)); + } + + private void RemoveContextImpl(CompositionObject oldContext, string? propertyName) + { + var contextEntries = _contextEntries; + if (contextEntries == null) + { + return; + } + + for (int i = contextEntries.Count - 1; i >= 0; i--) + { + var contextEntry = contextEntries[i]; + + if (!contextEntry.Context.TryGetTarget(out CompositionObject? context)) + { + // Clean up dead references. + contextEntries.RemoveAt(i); + continue; + } + + if (context == oldContext && contextEntry.PropertyName == propertyName) + { + contextEntries.RemoveAt(i); + break; + } + } + + if (contextEntries.Count == 0) + { + _contextEntries = null; + } + } + + private void RaiseChangedImpl() + { + var contextEntries = _contextEntries; + if (contextEntries == null) + { + return; + } + + for (int i = contextEntries.Count - 1; i >= 0; i--) + { + var contextEntry = contextEntries[i]; + + if (!contextEntry.Context.TryGetTarget(out CompositionObject? context)) + { + // Clean up dead references. + contextEntries.RemoveAt(i); + continue; + } + + context!.OnPropertyChanged(contextEntry.PropertyName, true); + } + } + + private class ContextEntry + { + public ContextEntry(CompositionObject context, string? propertyName) + { + Context = new WeakReference(context); + PropertyName = propertyName; + } + + public WeakReference Context { get; } + public string? PropertyName { get; } + } + } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionShape.cs b/src/Uno.UWP/UI/Composition/CompositionShape.cs index e7f7d15a9e73..f7147c50365c 100644 --- a/src/Uno.UWP/UI/Composition/CompositionShape.cs +++ b/src/Uno.UWP/UI/Composition/CompositionShape.cs @@ -5,24 +5,55 @@ namespace Windows.UI.Composition { - public partial class CompositionShape : global::Windows.UI.Composition.CompositionObject + public partial class CompositionShape : CompositionObject { + private Matrix3x2 _transformMatrix = Matrix3x2.Identity; + private Vector2 _scale = new Vector2(1, 1); + private float _rotationAngleInDegrees; + private float _rotationAngle; + private Vector2 _offset; + private Vector2 _centerPoint; + internal CompositionShape() => throw new InvalidOperationException($"Use the Compositor ctor"); internal CompositionShape(Compositor compositor) : base(compositor) { } - public Matrix3x2 TransformMatrix { get; set; } = Matrix3x2.Identity; + public Matrix3x2 TransformMatrix + { + get => _transformMatrix; + set => SetProperty(ref _transformMatrix, value); + } - public Vector2 Scale { get; set; } = new Vector2(1, 1); + public Vector2 Scale + { + get => _scale; + set => SetProperty(ref _scale, value); + } - public float RotationAngleInDegrees { get; set; } + public float RotationAngleInDegrees + { + get => _rotationAngleInDegrees; + set => SetProperty(ref _rotationAngleInDegrees, value); + } - public float RotationAngle { get; set; } + public float RotationAngle + { + get => _rotationAngle; + set => SetProperty(ref _rotationAngle, value); + } - public Vector2 Offset { get; set; } + public Vector2 Offset + { + get => _offset; + set => SetProperty(ref _offset, value); + } - public Vector2 CenterPoint { get; set; } + public Vector2 CenterPoint + { + get => _centerPoint; + set => SetProperty(ref _centerPoint, value); + } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionShapeCollection.cs b/src/Uno.UWP/UI/Composition/CompositionShapeCollection.cs index 90811735c8bd..5e50e6a9ef89 100644 --- a/src/Uno.UWP/UI/Composition/CompositionShapeCollection.cs +++ b/src/Uno.UWP/UI/Composition/CompositionShapeCollection.cs @@ -1,17 +1,18 @@ #nullable enable +using System; using System.Collections; using System.Collections.Generic; namespace Windows.UI.Composition { - public partial class CompositionShapeCollection : CompositionObject, IList, IEnumerable + public partial class CompositionShapeCollection : CompositionObject, IList { - private List _shapes = new List(); - private ShapeVisual shapeVisual; + private readonly List _shapes = new List(); + private readonly ShapeVisual _shapeVisual; internal CompositionShapeCollection(Compositor compositor, ShapeVisual shapeVisual) : base(compositor) - => this.shapeVisual = shapeVisual; + => this._shapeVisual = shapeVisual; public int Count => _shapes.Count; @@ -19,22 +20,60 @@ public int IndexOf(CompositionShape item) => _shapes.IndexOf(item); public void Insert(int index, CompositionShape item) - => _shapes.Insert(index, item); + { + ThrowIfNull(item, nameof(item)); + + _shapes.Insert(index, item); + + OnCompositionPropertyChanged(null, item); + OnChanged(); + } public void RemoveAt(int index) - => _shapes.RemoveAt(index); + { + var shape = _shapes[index]; + + _shapes.RemoveAt(index); + + OnCompositionPropertyChanged(shape, null); + OnChanged(); + } public CompositionShape this[int index] { get => _shapes[index]; - set => _shapes[index] = value; + set + { + ThrowIfNull(value, nameof(value)); + + var oldShape = _shapes[index]; + + _shapes[index] = value; + + OnCompositionPropertyChanged(oldShape, value); + OnChanged(); + } } public void Add(CompositionShape item) - => _shapes.Add(item); + { + ThrowIfNull(item, nameof(item)); + _shapes.Add(item); + + OnCompositionPropertyChanged(null, item); + OnChanged(); + } public void Clear() - => _shapes.Clear(); + { + foreach (var shape in _shapes) + { + OnCompositionPropertyChanged(shape, null); + } + + _shapes.Clear(); + OnChanged(); + } public bool Contains(CompositionShape item) => _shapes.Contains(item); @@ -43,7 +82,22 @@ public void CopyTo(CompositionShape[] array, int arrayIndex) => _shapes.CopyTo(array, arrayIndex); public bool Remove(CompositionShape item) - => _shapes.Remove(item); + { + ThrowIfNull(item, nameof(item)); + + int index = _shapes.IndexOf(item); + if (index < 0) + { + return false; + } + + _shapes.RemoveAt(index); + + OnCompositionPropertyChanged(item, null); + OnChanged(); + + return true; + } public bool IsReadOnly => false; @@ -52,5 +106,13 @@ public IEnumerator GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => _shapes.GetEnumerator(); + + private void ThrowIfNull(T? item, string propertyName) where T : class + { + if (item == null) + { + throw new ArgumentNullException(propertyName); + } + } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionSpriteShape.cs b/src/Uno.UWP/UI/Composition/CompositionSpriteShape.cs index f35b94580923..4ddc2936c526 100644 --- a/src/Uno.UWP/UI/Composition/CompositionSpriteShape.cs +++ b/src/Uno.UWP/UI/Composition/CompositionSpriteShape.cs @@ -24,110 +24,74 @@ internal CompositionSpriteShape(Compositor compositor, CompositionGeometry? geom public float StrokeThickness { - get => _strokeThickness; set - { - _strokeThickness = value; - Compositor.InvalidateRender(); - } + get => _strokeThickness; + set => SetProperty(ref _strokeThickness, value); } public CompositionStrokeCap StrokeStartCap { - get => _strokeStartCap; set - { - _strokeStartCap = value; - Compositor.InvalidateRender(); - } + get => _strokeStartCap; + set => SetProperty(ref _strokeStartCap, value); } public float StrokeMiterLimit { - get => _strokeMiterLimit; set - { - _strokeMiterLimit = value; - Compositor.InvalidateRender(); - } + get => _strokeMiterLimit; + set => SetProperty(ref _strokeMiterLimit, value); } public CompositionStrokeLineJoin StrokeLineJoin { - get => _strokeLineJoin; set - { - _strokeLineJoin = value; - Compositor.InvalidateRender(); - } + get => _strokeLineJoin; + set => SetProperty(ref _strokeLineJoin, value); } public CompositionStrokeCap StrokeEndCap { - get => _strokeEndCap; set - { - _strokeEndCap = value; - Compositor.InvalidateRender(); - } + get => _strokeEndCap; + set => SetProperty(ref _strokeEndCap, value); } public float StrokeDashOffset { - get => _strokeDashOffset; set - { - _strokeDashOffset = value; - Compositor.InvalidateRender(); - } + get => _strokeDashOffset; + set => SetProperty(ref _strokeDashOffset, value); } public CompositionStrokeCap StrokeDashCap { - get => _strokeDashCap; set - { - _strokeDashCap = value; - Compositor.InvalidateRender(); - } + get => _strokeDashCap; + set => SetProperty(ref _strokeDashCap, value); } public CompositionBrush? StrokeBrush { - get => _strokeBrush; set - { - _strokeBrush = value; - Compositor.InvalidateRender(); - } + get => _strokeBrush; + set => SetProperty(ref _strokeBrush, value); } public bool IsStrokeNonScaling { - get => _isStrokeNonScaling; set - { - _isStrokeNonScaling = value; - Compositor.InvalidateRender(); - } + get => _isStrokeNonScaling; + set => SetProperty(ref _isStrokeNonScaling, value); } public CompositionGeometry? Geometry { - get => _geometry; set - { - _geometry = value; - Compositor.InvalidateRender(); - } + get => _geometry; + set => SetProperty(ref _geometry, value); } public CompositionBrush? FillBrush { - get => _fillBrush; set - { - _fillBrush = value; - Compositor.InvalidateRender(); - } + get => _fillBrush; + set => SetProperty(ref _fillBrush, value); } public CompositionStrokeDashArray? StrokeDashArray { - get => _strokeDashArray; set - { - _strokeDashArray = value; - Compositor.InvalidateRender(); - } + get => _strokeDashArray; + set => SetProperty(ref _strokeDashArray, value); } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionSurfaceBrush.cs b/src/Uno.UWP/UI/Composition/CompositionSurfaceBrush.cs index e326fc4a5a21..a25f04378c48 100644 --- a/src/Uno.UWP/UI/Composition/CompositionSurfaceBrush.cs +++ b/src/Uno.UWP/UI/Composition/CompositionSurfaceBrush.cs @@ -1,6 +1,5 @@ #nullable enable -using System; using System.Numerics; namespace Windows.UI.Composition @@ -19,134 +18,93 @@ public partial class CompositionSurfaceBrush : CompositionBrush private float _horizontalAlignmentRatio; private bool _snapToPixels; private float _verticalAlignmentRatio; - private CompositionBitmapInterpolationMode bitmapInterpolationMode; + private CompositionBitmapInterpolationMode _bitmapInterpolationMode; - internal event Action? PropertyChanged; - - public CompositionSurfaceBrush(Compositor compositor) : base(compositor) + internal CompositionSurfaceBrush(Compositor compositor) : base(compositor) { } - public CompositionSurfaceBrush(Compositor compositor, ICompositionSurface surface) : base(compositor) + internal CompositionSurfaceBrush(Compositor compositor, ICompositionSurface surface) : base(compositor) { Surface = surface; } public float VerticalAlignmentRatio { - get => _verticalAlignmentRatio; set - { - _verticalAlignmentRatio = value; - PropertyChanged?.Invoke(); - } + get => _verticalAlignmentRatio; + set => SetProperty(ref _verticalAlignmentRatio, value); } public ICompositionSurface? Surface { - get => _surface; set - { - _surface = value; - PropertyChanged?.Invoke(); - } + get => _surface; + set => SetProperty(ref _surface, value); } public CompositionStretch Stretch { - get => _stretch; set - { - _stretch = value; - PropertyChanged?.Invoke(); - } + get => _stretch; + set => SetProperty(ref _stretch, value); } public float HorizontalAlignmentRatio { - get => _horizontalAlignmentRatio; set - { - _horizontalAlignmentRatio = value; - PropertyChanged?.Invoke(); - } + get => _horizontalAlignmentRatio; + set => SetProperty(ref _horizontalAlignmentRatio, value); } public CompositionBitmapInterpolationMode BitmapInterpolationMode { - get => bitmapInterpolationMode; set - { - bitmapInterpolationMode = value; - PropertyChanged?.Invoke(); - } + get => _bitmapInterpolationMode; + set => SetProperty(ref _bitmapInterpolationMode, value); } public Matrix3x2 TransformMatrix { - get => _transformMatrix; set - { - _transformMatrix = value; - PropertyChanged?.Invoke(); - } + get => _transformMatrix; + set => SetProperty(ref _transformMatrix, value); } public Vector2 Scale { - get => _scale; set - { - _scale = value; - PropertyChanged?.Invoke(); - } + get => _scale; + set => SetProperty(ref _scale, value); } public float RotationAngleInDegrees { - get => _rotationAngleInDegrees; set - { - _rotationAngleInDegrees = value; - PropertyChanged?.Invoke(); - } + get => _rotationAngleInDegrees; + set => SetProperty(ref _rotationAngleInDegrees, value); } public float RotationAngle { - get => _rotationAngle; set - { - _rotationAngle = value; - PropertyChanged?.Invoke(); - } + get => _rotationAngle; + set => SetProperty(ref _rotationAngle, value); } public Vector2 Offset { - get => _offset; set - { - _offset = value; - PropertyChanged?.Invoke(); - } + get => _offset; + set => SetProperty(ref _offset, value); } public Vector2 CenterPoint { - get => _centerPoint; set - { - _centerPoint = value; - PropertyChanged?.Invoke(); - } + get => _centerPoint; + set => SetProperty(ref _centerPoint, value); } public Vector2 AnchorPoint { - get => _anchorPoint; set - { - _anchorPoint = value; - PropertyChanged?.Invoke(); - } + get => _anchorPoint; + set => SetProperty(ref _anchorPoint, value); } public bool SnapToPixels { - get => _snapToPixels; set - { - _snapToPixels = value; - PropertyChanged?.Invoke(); - } + get => _snapToPixels; + set => SetProperty(ref _snapToPixels, value); } } } diff --git a/src/Uno.UWP/UI/Composition/CompositionViewBox.cs b/src/Uno.UWP/UI/Composition/CompositionViewBox.cs index db9c5c4015c4..723d23ba62f6 100644 --- a/src/Uno.UWP/UI/Composition/CompositionViewBox.cs +++ b/src/Uno.UWP/UI/Composition/CompositionViewBox.cs @@ -6,10 +6,45 @@ namespace Windows.UI.Composition { public partial class CompositionViewBox : CompositionObject { - public float VerticalAlignmentRatio { get; set; } - public CompositionStretch Stretch { get; set; } - public Vector2 Size { get; set; } - public Vector2 Offset { get; set; } - public float HorizontalAlignmentRatio { get; set; } + private float _verticalAlignmentRatio; + private CompositionStretch _stretch; + private Vector2 _size; + private Vector2 _offset; + private float _horizontalAlignmentRatio; + + internal CompositionViewBox(Compositor compositor) : base (compositor) + { + + } + + public float VerticalAlignmentRatio + { + get => _verticalAlignmentRatio; + set => SetProperty(ref _verticalAlignmentRatio, value); + } + + public CompositionStretch Stretch + { + get => _stretch; + set => SetProperty(ref _stretch, value); + } + + public Vector2 Size + { + get => _size; + set => SetProperty(ref _size, value); + } + + public Vector2 Offset + { + get => _offset; + set => SetProperty(ref _offset, value); + } + + public float HorizontalAlignmentRatio + { + get => _horizontalAlignmentRatio; + set => SetProperty(ref _horizontalAlignmentRatio, value); + } } } diff --git a/src/Uno.UWP/UI/Composition/ContainerVisual.cs b/src/Uno.UWP/UI/Composition/ContainerVisual.cs index cc2bc43368b3..1fbc488fb298 100644 --- a/src/Uno.UWP/UI/Composition/ContainerVisual.cs +++ b/src/Uno.UWP/UI/Composition/ContainerVisual.cs @@ -4,7 +4,7 @@ namespace Windows.UI.Composition { - public partial class ContainerVisual : global::Windows.UI.Composition.Visual + public partial class ContainerVisual : Visual { internal ContainerVisual() : base(null!) => throw new NotSupportedException("Use the ctor with Compositor"); diff --git a/src/Uno.UWP/UI/Composition/InsetClip.cs b/src/Uno.UWP/UI/Composition/InsetClip.cs index d2b4ea80839d..f3dad8c53362 100644 --- a/src/Uno.UWP/UI/Composition/InsetClip.cs +++ b/src/Uno.UWP/UI/Composition/InsetClip.cs @@ -2,19 +2,40 @@ namespace Windows.UI.Composition { - public partial class InsetClip : CompositionClip + public partial class InsetClip : CompositionClip { - public InsetClip(Compositor compositor) : base(compositor) + private float _topInset; + private float _rightInset; + private float _leftInset; + private float _bottomInset; + + internal InsetClip(Compositor compositor) : base(compositor) { } - public float TopInset { get; set; } + public float TopInset + { + get => _topInset; + set => SetProperty(ref _topInset, value); + } - public float RightInset { get; set; } + public float RightInset + { + get => _rightInset; + set => SetProperty(ref _rightInset, value); + } - public float LeftInset { get; set; } + public float LeftInset + { + get => _leftInset; + set => SetProperty(ref _leftInset, value); + } - public float BottomInset { get; set; } + public float BottomInset + { + get => _bottomInset; + set => SetProperty(ref _bottomInset, value); + } } } diff --git a/src/Uno.UWP/UI/Composition/ShapeVisual.cs b/src/Uno.UWP/UI/Composition/ShapeVisual.cs index 505a4538aabc..d6b6c51239c6 100644 --- a/src/Uno.UWP/UI/Composition/ShapeVisual.cs +++ b/src/Uno.UWP/UI/Composition/ShapeVisual.cs @@ -2,15 +2,25 @@ namespace Windows.UI.Composition { - public partial class ShapeVisual : global::Windows.UI.Composition.ContainerVisual + public partial class ShapeVisual : ContainerVisual { + private CompositionViewBox? _viewBox; + public ShapeVisual(Compositor compositor) : base(compositor) { Shapes = new CompositionShapeCollection(compositor, this); + + // Add this as context for the shape collection so we get + // notified about changes in the shapes object graph. + OnCompositionPropertyChanged(null, Shapes, nameof(Shapes)); } - public CompositionViewBox? ViewBox { get; set; } + public CompositionViewBox? ViewBox + { + get => _viewBox; + set => SetProperty(ref _viewBox, value); + } public CompositionShapeCollection Shapes { get; } } diff --git a/src/Uno.UWP/UI/Composition/SpriteVisual.cs b/src/Uno.UWP/UI/Composition/SpriteVisual.cs index 19645a4e6224..9203fe95df97 100644 --- a/src/Uno.UWP/UI/Composition/SpriteVisual.cs +++ b/src/Uno.UWP/UI/Composition/SpriteVisual.cs @@ -1,7 +1,5 @@ #nullable enable -using System; - namespace Windows.UI.Composition { public partial class SpriteVisual : ContainerVisual @@ -15,18 +13,22 @@ public SpriteVisual(Compositor compositor) : base(compositor) public CompositionBrush? Brush { - get - { - return _brush; - } - set + get => _brush; + set => SetProperty(ref _brush, value); + } + + private protected override void OnPropertyChangedCore(string? propertyName, bool isSubPropertyChange) + { + // Call base implementation - Visual calls Compositor.InvalidateRender(). + base.OnPropertyChangedCore(propertyName, isSubPropertyChange); + + switch (propertyName) { - var previousBrush = _brush; - if (_brush != value) - { - _brush = value; - OnBrushChangedPartial(_brush); - } + case nameof(Brush): + OnBrushChangedPartial(Brush); + break; + default: + break; } } diff --git a/src/Uno.UWP/UI/Composition/Visual.cs b/src/Uno.UWP/UI/Composition/Visual.cs index 69fd6608d618..84c996ff57ac 100644 --- a/src/Uno.UWP/UI/Composition/Visual.cs +++ b/src/Uno.UWP/UI/Composition/Visual.cs @@ -1,12 +1,10 @@ #nullable enable -using System; using System.Numerics; -using Windows.UI.Core; namespace Windows.UI.Composition { - public partial class Visual : global::Windows.UI.Composition.CompositionObject + public partial class Visual : CompositionObject { private Vector2 _size; private Vector3 _offset; @@ -14,9 +12,10 @@ public partial class Visual : global::Windows.UI.Composition.CompositionObject private Vector3 _centerPoint; private float _rotationAngleInDegrees; private Vector3 _rotationAxis = new Vector3(0, 0, 1); - private Matrix4x4 transformMatrix = Matrix4x4.Identity; - private bool isVisible = true; - private float opacity = 1.0f; + private Matrix4x4 _transformMatrix = Matrix4x4.Identity; + private bool _isVisible = true; + private float _opacity = 1.0f; + private CompositionCompositeMode _compositeMode; internal Visual(Compositor compositor) : base(compositor) { @@ -27,59 +26,42 @@ internal Visual(Compositor compositor) : base(compositor) public Matrix4x4 TransformMatrix { - get => transformMatrix; - set - { - transformMatrix = value; - Compositor.InvalidateRender(); - } + get => _transformMatrix; + set => SetProperty(ref _transformMatrix, value); } + public Vector3 Offset { get => _offset; - set - { - _offset = value; - OnOffsetChanged(value); - Compositor.InvalidateRender(); - } + set { SetProperty(ref _offset, value); OnOffsetChanged(value); } } partial void OnOffsetChanged(Vector3 value); public bool IsVisible { - get => isVisible; - set - { - isVisible = value; - Compositor.InvalidateRender(); - } + get => _isVisible; + set => SetProperty(ref _isVisible, value); } - public CompositionCompositeMode CompositeMode { get; set; } + public CompositionCompositeMode CompositeMode + { + get => _compositeMode; + set => SetProperty(ref _compositeMode, value); + } public Vector3 CenterPoint { get => _centerPoint; - set - { - _centerPoint = value; OnCenterPointChanged(value); - Compositor.InvalidateRender(); - } + set { SetProperty(ref _centerPoint, value); OnCenterPointChanged(value); } } partial void OnCenterPointChanged(Vector3 value); - public global::System.Numerics.Vector3 Scale + public Vector3 Scale { get => _scale; - set - { - _scale = value; - OnScaleChanged(value); - Compositor.InvalidateRender(); - } + set { SetProperty(ref _scale, value); OnScaleChanged(value); } } partial void OnScaleChanged(Vector3 value); @@ -87,11 +69,7 @@ public Vector3 CenterPoint public float RotationAngleInDegrees { get => _rotationAngleInDegrees; - set - { - _rotationAngleInDegrees = value; OnRotationAngleInDegreesChanged(value); - Compositor.InvalidateRender(); - } + set { SetProperty(ref _rotationAngleInDegrees, value); OnRotationAngleInDegreesChanged(value); } } partial void OnRotationAngleInDegreesChanged(float value); @@ -99,35 +77,37 @@ public float RotationAngleInDegrees public Vector2 Size { get => _size; - set - { - _size = value; OnSizeChanged(value); - Compositor.InvalidateRender(); - } + set { SetProperty(ref _size, value); OnSizeChanged(value); } } partial void OnSizeChanged(Vector2 value); public float Opacity { - get => opacity; set - { - opacity = value; - Compositor.InvalidateRender(); - } + get => _opacity; + set => SetProperty(ref _opacity, value); } + public Vector3 RotationAxis { get => _rotationAxis; - set - { - _rotationAxis = value; OnRotationAxisChanged(value); - Compositor.InvalidateRender(); - } + set { SetProperty(ref _rotationAxis, value); OnRotationAxisChanged(value); } } partial void OnRotationAxisChanged(Vector3 value); public ContainerVisual? Parent { get; set; } + + private protected override void OnPropertyChangedCore(string? propertyName, bool isSubPropertyChange) + { + // TODO: Determine whether to invalidate renderer based on the fact whether we are attached to a CompositionTarget. + //bool isAttached = false; + //if (isAttached) + //{ + // Compositor.InvalidateRender(); + //} + + Compositor.InvalidateRender(); + } } }