From e7797eea673ecac0da6463314c43ce5645a96064 Mon Sep 17 00:00:00 2001
From: ErrorCraft <51973682+ErrorCraft@users.noreply.github.com>
Date: Wed, 3 Aug 2022 20:51:10 +0200
Subject: [PATCH 1/7] Add Sector shape
---
src/Avalonia.Base/Utilities/MathUtilities.cs | 35 +++++++++++
src/Avalonia.Controls/Shapes/Sector.cs | 65 ++++++++++++++++++++
2 files changed, 100 insertions(+)
create mode 100644 src/Avalonia.Controls/Shapes/Sector.cs
diff --git a/src/Avalonia.Base/Utilities/MathUtilities.cs b/src/Avalonia.Base/Utilities/MathUtilities.cs
index d381979c1e..3c48c3469e 100644
--- a/src/Avalonia.Base/Utilities/MathUtilities.cs
+++ b/src/Avalonia.Base/Utilities/MathUtilities.cs
@@ -324,6 +324,41 @@ namespace Avalonia.Utilities
return angle * 2 * Math.PI;
}
+ ///
+ /// Calculates the point of an angle on an ellipse.
+ ///
+ /// The centre point of the ellipse.
+ /// The x radius of the ellipse.
+ /// The y radius of the ellipse.
+ /// The angle in radians.
+ /// A point on the ellipse.
+ public static Point GetEllipsePoint(Point centre, double radiusX, double radiusY, double angle)
+ {
+ return new Point(radiusX * Math.Cos(angle) + centre.X, radiusY * Math.Sin(angle) + centre.Y);
+ }
+
+ ///
+ /// Gets the minimum and maximum from the specified numbers.
+ ///
+ /// The first number.
+ /// The second number.
+ /// A tuple containing the minimum and maximum of the two specified numbers.
+ public static (double min, double max) GetMinMax(double a, double b)
+ {
+ return a < b ? (a, b) : (b, a);
+ }
+
+ ///
+ /// Gets the minimum and maximum from the specified number and the difference with that number.
+ ///
+ /// The initial value to use.
+ /// The difference for .
+ /// A tuple containing the minimum and maximum of the specified number and the difference with that number.
+ public static (double min, double max) GetMinMaxFromDelta(double initialValue, double delta)
+ {
+ return GetMinMax(initialValue, initialValue + delta);
+ }
+
private static void ThrowCannotBeGreaterThanException(T min, T max)
{
throw new ArgumentException($"{min} cannot be greater than {max}.");
diff --git a/src/Avalonia.Controls/Shapes/Sector.cs b/src/Avalonia.Controls/Shapes/Sector.cs
new file mode 100644
index 0000000000..5d2f6701a7
--- /dev/null
+++ b/src/Avalonia.Controls/Shapes/Sector.cs
@@ -0,0 +1,65 @@
+using System;
+using Avalonia.Media;
+using Avalonia.Utilities;
+
+namespace Avalonia.Controls.Shapes
+{
+ public class Sector : Shape
+ {
+ public static readonly StyledProperty StartAngleProperty = AvaloniaProperty.Register(nameof(StartAngle), 0.0d);
+ public static readonly StyledProperty AngleProperty = AvaloniaProperty.Register(nameof(Angle), 0.0d);
+
+ public double StartAngle
+ {
+ get => GetValue(StartAngleProperty);
+ set => SetValue(StartAngleProperty, value);
+ }
+
+ public double Angle
+ {
+ get => GetValue(AngleProperty);
+ set => SetValue(AngleProperty, value);
+ }
+
+ static Sector()
+ {
+ StrokeThicknessProperty.OverrideDefaultValue(1.0d);
+ AffectsGeometry(BoundsProperty, StrokeThicknessProperty, StartAngleProperty, AngleProperty);
+ }
+
+ protected override Geometry? CreateDefiningGeometry()
+ {
+ Rect rect = new Rect(Bounds.Size);
+ Rect deflatedRect = rect.Deflate(StrokeThickness * 0.5d);
+
+ if (Angle >= 360.0d || Angle <= -360.0d)
+ {
+ return new EllipseGeometry(deflatedRect);
+ }
+
+ if (Angle == 0.0d)
+ {
+ return new StreamGeometry();
+ }
+
+ (double startAngle, double endAngle) = MathUtilities.GetMinMaxFromDelta(MathUtilities.Deg2Rad(StartAngle), MathUtilities.Deg2Rad(Angle));
+
+ Point centre = new Point(rect.Width * 0.5d, rect.Height * 0.5d);
+ double radiusX = deflatedRect.Width * 0.5d;
+ double radiusY = deflatedRect.Height * 0.5d;
+ Point startCurvePoint = MathUtilities.GetEllipsePoint(centre, radiusX, radiusY, startAngle);
+ Point endCurvePoint = MathUtilities.GetEllipsePoint(centre, radiusX, radiusY, endAngle);
+ Size size = new Size(radiusX, radiusY);
+
+ StreamGeometry streamGeometry = new StreamGeometry();
+ using StreamGeometryContext streamGeometryContext = streamGeometry.Open();
+
+ streamGeometryContext.BeginFigure(startCurvePoint, false);
+ streamGeometryContext.ArcTo(endCurvePoint, size, 0.0d, Math.Abs(Angle) > 180.0d, SweepDirection.Clockwise);
+ streamGeometryContext.LineTo(centre);
+ streamGeometryContext.EndFigure(true);
+
+ return streamGeometry;
+ }
+ }
+}
From ed582a9fde3aef0a2cd9462cbe66c9dc1446076d Mon Sep 17 00:00:00 2001
From: aldelaro5
Date: Wed, 3 Aug 2022 22:39:40 -0400
Subject: [PATCH 2/7] Implement DataContext update notifications on the
DataGrid
This fixes #5661 by allowing the DataGrid to notify its cells that their DataContext is about to be changed.
---
src/Avalonia.Controls.DataGrid/DataGrid.cs | 32 ++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs
index d42468f47e..f4cd425c53 100644
--- a/src/Avalonia.Controls.DataGrid/DataGrid.cs
+++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs
@@ -2167,6 +2167,38 @@ namespace Avalonia.Controls
return desiredSize;
}
+
+ ///
+ protected override void OnDataContextBeginUpdate()
+ {
+ base.OnDataContextBeginUpdate();
+ foreach (DataGridRow row in GetAllRows())
+ {
+ foreach (DataGridCell cell in row.Cells)
+ {
+ if (cell.Content is StyledElement)
+ {
+ DataContextProperty.Notifying?.Invoke((IAvaloniaObject)cell.Content, true);
+ }
+ }
+ }
+ }
+
+ ///
+ protected override void OnDataContextEndUpdate()
+ {
+ base.OnDataContextEndUpdate();
+ foreach (DataGridRow row in GetAllRows())
+ {
+ foreach (DataGridCell cell in row.Cells)
+ {
+ if (cell.Content is StyledElement)
+ {
+ DataContextProperty.Notifying?.Invoke((IAvaloniaObject)cell.Content, false);
+ }
+ }
+ }
+ }
///
/// Raises the BeginningEdit event.
From ee662cecdd0c9b57f986d44e93afa26b5d524b3e Mon Sep 17 00:00:00 2001
From: ili
Date: Mon, 8 Aug 2022 20:13:47 +0500
Subject: [PATCH 3/7] Avoid lock in timers
---
.../AndroidThreadingInterface.cs | 45 +++++++----------
.../InternalPlatformThreadingInterface.cs | 4 +-
.../HeadlessPlatformThreadingInterface.cs | 48 +++++++++----------
3 files changed, 42 insertions(+), 55 deletions(-)
diff --git a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
index 42f75a27e1..de9149e9a1 100644
--- a/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
+++ b/src/Android/Avalonia.Android/AndroidThreadingInterface.cs
@@ -27,46 +27,33 @@ namespace Avalonia.Android
{
if (interval.TotalMilliseconds < 10)
interval = TimeSpan.FromMilliseconds(10);
- object l = new object();
+
var stopped = false;
Timer timer = null;
- var scheduled = false;
timer = new Timer(_ =>
{
- lock (l)
+ if (stopped)
+ return;
+
+ EnsureInvokeOnMainThread(() =>
{
- if (stopped)
+ try
{
- timer.Dispose();
- return;
+ tick();
}
- if (scheduled)
- return;
- scheduled = true;
- EnsureInvokeOnMainThread(() =>
+ finally
{
- try
- {
- tick();
- }
- finally
- {
- lock (l)
- {
- scheduled = false;
- }
- }
- });
- }
- }, null, TimeSpan.Zero, interval);
+ if (!stopped)
+ timer.Change(interval, Timeout.InfiniteTimeSpan);
+ }
+ });
+ },
+ null, interval, Timeout.InfiniteTimeSpan);
return Disposable.Create(() =>
{
- lock (l)
- {
- stopped = true;
- timer.Dispose();
- }
+ stopped = true;
+ timer.Dispose();
});
}
diff --git a/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs b/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
index 630d2d8efb..e1f6db9c60 100644
--- a/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
+++ b/src/Avalonia.Controls/Platform/InternalPlatformThreadingInterface.cs
@@ -43,7 +43,7 @@ namespace Avalonia.Controls.Platform
_priority = priority;
_interval = interval;
_tick = tick;
- _timer = new Timer(OnTimer, null, interval, TimeSpan.FromMilliseconds(-1));
+ _timer = new Timer(OnTimer, null, interval, Timeout.InfiniteTimeSpan);
_handle = GCHandle.Alloc(_timer);
}
@@ -57,7 +57,7 @@ namespace Avalonia.Controls.Platform
if (_timer == null)
return;
_tick();
- _timer?.Change(_interval, TimeSpan.FromMilliseconds(-1));
+ _timer?.Change(_interval, Timeout.InfiniteTimeSpan);
});
}
diff --git a/src/Avalonia.Headless/HeadlessPlatformThreadingInterface.cs b/src/Avalonia.Headless/HeadlessPlatformThreadingInterface.cs
index e42a7b1a71..b233b46dd0 100644
--- a/src/Avalonia.Headless/HeadlessPlatformThreadingInterface.cs
+++ b/src/Avalonia.Headless/HeadlessPlatformThreadingInterface.cs
@@ -36,35 +36,35 @@ namespace Avalonia.Headless
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
{
- var cancelled = false;
- var enqueued = false;
- var l = new object();
- var timer = new Timer(_ =>
+ if (interval.TotalMilliseconds < 10)
+ interval = TimeSpan.FromMilliseconds(10);
+
+ var stopped = false;
+ Timer timer = null;
+ timer = new Timer(_ =>
{
- lock (l)
+ if (stopped)
+ return;
+
+ Dispatcher.UIThread.Post(() =>
{
- if (cancelled || enqueued)
- return;
- enqueued = true;
- Dispatcher.UIThread.Post(() =>
+ try
{
- lock (l)
- {
- enqueued = false;
- if (cancelled)
- return;
- tick();
- }
- }, priority);
- }
- }, null, interval, interval);
+ tick();
+ }
+ finally
+ {
+ if (!stopped)
+ timer.Change(interval, Timeout.InfiniteTimeSpan);
+ }
+ });
+ },
+ null, interval, Timeout.InfiniteTimeSpan);
+
return Disposable.Create(() =>
{
- lock (l)
- {
- timer.Dispose();
- cancelled = true;
- }
+ stopped = true;
+ timer.Dispose();
});
}
From 6d5b59c33f785f39af64080897e336896940ec5e Mon Sep 17 00:00:00 2001
From: Max Katz
Date: Fri, 12 Aug 2022 20:34:39 -0400
Subject: [PATCH 4/7] Update SkiaSharp
---
build/HarfBuzzSharp.props | 6 +++---
build/SkiaSharp.props | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/build/HarfBuzzSharp.props b/build/HarfBuzzSharp.props
index 85e7a1f34d..620ec58ff3 100644
--- a/build/HarfBuzzSharp.props
+++ b/build/HarfBuzzSharp.props
@@ -1,7 +1,7 @@
-
-
-
+
+
+
diff --git a/build/SkiaSharp.props b/build/SkiaSharp.props
index d54cffba08..cc573825cd 100644
--- a/build/SkiaSharp.props
+++ b/build/SkiaSharp.props
@@ -1,7 +1,7 @@
-
-
-
+
+
+
From 3378201230dfcc846859426c31834ec26252ef51 Mon Sep 17 00:00:00 2001
From: Maruhl
Date: Sat, 13 Aug 2022 10:30:30 +0200
Subject: [PATCH 5/7] Code refactored for better maintainability (Code from
#8668)
---
src/Avalonia.Controls.DataGrid/DataGrid.cs | 40 ++++++++++------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs
index f4cd425c53..cacd5c5a16 100644
--- a/src/Avalonia.Controls.DataGrid/DataGrid.cs
+++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs
@@ -2172,34 +2172,18 @@ namespace Avalonia.Controls
protected override void OnDataContextBeginUpdate()
{
base.OnDataContextBeginUpdate();
- foreach (DataGridRow row in GetAllRows())
- {
- foreach (DataGridCell cell in row.Cells)
- {
- if (cell.Content is StyledElement)
- {
- DataContextProperty.Notifying?.Invoke((IAvaloniaObject)cell.Content, true);
- }
- }
- }
+
+ NotifyDataContextPropertyForAllRowCells(GetAllRows(), true);
}
///
protected override void OnDataContextEndUpdate()
{
base.OnDataContextEndUpdate();
- foreach (DataGridRow row in GetAllRows())
- {
- foreach (DataGridCell cell in row.Cells)
- {
- if (cell.Content is StyledElement)
- {
- DataContextProperty.Notifying?.Invoke((IAvaloniaObject)cell.Content, false);
- }
- }
- }
- }
+ NotifyDataContextPropertyForAllRowCells(GetAllRows(), false);
+ }
+
///
/// Raises the BeginningEdit event.
///
@@ -3197,6 +3181,20 @@ namespace Avalonia.Controls
}
}
+ private static void NotifyDataContextPropertyForAllRowCells(IEnumerable rowSource, bool arg2)
+ {
+ foreach (DataGridRow row in rowSource)
+ {
+ foreach (DataGridCell cell in row.Cells)
+ {
+ if (cell.Content is StyledElement cellContent)
+ {
+ DataContextProperty.Notifying?.Invoke(cellContent, arg2);
+ }
+ }
+ }
+ }
+
private void UpdateRowDetailsVisibilityMode(DataGridRowDetailsVisibilityMode newDetailsMode)
{
int itemCount = DataConnection.Count;
From a96b317e4656d3374b33d74f047f9803a4fbdcff Mon Sep 17 00:00:00 2001
From: robloo
Date: Sun, 14 Aug 2022 15:09:20 -0400
Subject: [PATCH 6/7] Comment and standardize Sector with Arc
---
src/Avalonia.Controls/Shapes/Arc.cs | 36 +++++++++------
src/Avalonia.Controls/Shapes/Sector.cs | 64 +++++++++++++++++++-------
2 files changed, 71 insertions(+), 29 deletions(-)
diff --git a/src/Avalonia.Controls/Shapes/Arc.cs b/src/Avalonia.Controls/Shapes/Arc.cs
index 5ebb321f9b..de3814f215 100644
--- a/src/Avalonia.Controls/Shapes/Arc.cs
+++ b/src/Avalonia.Controls/Shapes/Arc.cs
@@ -1,8 +1,12 @@
using System;
using Avalonia.Media;
+using Avalonia.Utilities;
namespace Avalonia.Controls.Shapes
{
+ ///
+ /// Represents a circular or elliptical arc (a segment of a curve).
+ ///
public class Arc : Shape
{
///
@@ -19,8 +23,12 @@ namespace Avalonia.Controls.Shapes
static Arc()
{
- StrokeThicknessProperty.OverrideDefaultValue(1);
- AffectsGeometry(BoundsProperty, StrokeThicknessProperty, StartAngleProperty, SweepAngleProperty);
+ StrokeThicknessProperty.OverrideDefaultValue(1.0d);
+ AffectsGeometry(
+ BoundsProperty,
+ StrokeThicknessProperty,
+ StartAngleProperty,
+ SweepAngleProperty);
}
///
@@ -42,10 +50,11 @@ namespace Avalonia.Controls.Shapes
set => SetValue(SweepAngleProperty, value);
}
+ ///
protected override Geometry CreateDefiningGeometry()
{
- var angle1 = DegreesToRad(StartAngle);
- var angle2 = angle1 + DegreesToRad(SweepAngle);
+ var angle1 = MathUtilities.Deg2Rad(StartAngle);
+ var angle2 = angle1 + MathUtilities.Deg2Rad(SweepAngle);
var startAngle = Math.Min(angle1, angle2);
var sweepAngle = Math.Max(angle1, angle2);
@@ -80,24 +89,25 @@ namespace Avalonia.Controls.Shapes
var arcGeometry = new StreamGeometry();
- using (var ctx = arcGeometry.Open())
+ using (StreamGeometryContext context = arcGeometry.Open())
{
- ctx.BeginFigure(startPoint, false);
- ctx.ArcTo(endPoint, new Size(radiusX, radiusY), angleGap, angleGap >= Math.PI,
+ context.BeginFigure(startPoint, false);
+ context.ArcTo(
+ endPoint,
+ new Size(radiusX, radiusY),
+ rotationAngle: angleGap,
+ isLargeArc: angleGap >= Math.PI,
SweepDirection.Clockwise);
- ctx.EndFigure(false);
+ context.EndFigure(false);
}
return arcGeometry;
}
}
- static double DegreesToRad(double inAngle) =>
- inAngle * Math.PI / 180;
+ private static double RadToNormRad(double inAngle) => ((inAngle % (Math.PI * 2)) + (Math.PI * 2)) % (Math.PI * 2);
- static double RadToNormRad(double inAngle) => ((inAngle % (Math.PI * 2)) + (Math.PI * 2)) % (Math.PI * 2);
-
- static Point GetRingPoint(double radiusX, double radiusY, double centerX, double centerY, double angle) =>
+ private static Point GetRingPoint(double radiusX, double radiusY, double centerX, double centerY, double angle) =>
new Point((radiusX * Math.Cos(angle)) + centerX, (radiusY * Math.Sin(angle)) + centerY);
}
}
diff --git a/src/Avalonia.Controls/Shapes/Sector.cs b/src/Avalonia.Controls/Shapes/Sector.cs
index 5d2f6701a7..a9b7e8939b 100644
--- a/src/Avalonia.Controls/Shapes/Sector.cs
+++ b/src/Avalonia.Controls/Shapes/Sector.cs
@@ -4,45 +4,71 @@ using Avalonia.Utilities;
namespace Avalonia.Controls.Shapes
{
+ ///
+ /// Represents a circular or elliptical sector (a pie-shaped closed region of a circle or ellipse).
+ ///
public class Sector : Shape
{
- public static readonly StyledProperty StartAngleProperty = AvaloniaProperty.Register(nameof(StartAngle), 0.0d);
- public static readonly StyledProperty AngleProperty = AvaloniaProperty.Register(nameof(Angle), 0.0d);
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty StartAngleProperty =
+ AvaloniaProperty.Register(nameof(StartAngle), 0.0d);
+ ///
+ /// Defines the property.
+ ///
+ public static readonly StyledProperty SweepAngleProperty =
+ AvaloniaProperty.Register(nameof(SweepAngle), 0.0d);
+
+ ///
+ /// Gets or sets the angle at which the sector's arc starts, in degrees.
+ ///
public double StartAngle
{
get => GetValue(StartAngleProperty);
set => SetValue(StartAngleProperty, value);
}
- public double Angle
+ ///
+ /// Gets or sets the angle, in degrees, added to the defining where the sector's arc ends.
+ /// A positive value is clockwise, negative is counter-clockwise.
+ ///
+ public double SweepAngle
{
- get => GetValue(AngleProperty);
- set => SetValue(AngleProperty, value);
+ get => GetValue(SweepAngleProperty);
+ set => SetValue(SweepAngleProperty, value);
}
static Sector()
{
StrokeThicknessProperty.OverrideDefaultValue(1.0d);
- AffectsGeometry(BoundsProperty, StrokeThicknessProperty, StartAngleProperty, AngleProperty);
+ AffectsGeometry(
+ BoundsProperty,
+ StrokeThicknessProperty,
+ StartAngleProperty,
+ SweepAngleProperty);
}
+ ///
protected override Geometry? CreateDefiningGeometry()
{
Rect rect = new Rect(Bounds.Size);
Rect deflatedRect = rect.Deflate(StrokeThickness * 0.5d);
- if (Angle >= 360.0d || Angle <= -360.0d)
+ if (SweepAngle >= 360.0d || SweepAngle <= -360.0d)
{
return new EllipseGeometry(deflatedRect);
}
- if (Angle == 0.0d)
+ if (SweepAngle == 0.0d)
{
return new StreamGeometry();
}
- (double startAngle, double endAngle) = MathUtilities.GetMinMaxFromDelta(MathUtilities.Deg2Rad(StartAngle), MathUtilities.Deg2Rad(Angle));
+ (double startAngle, double endAngle) = MathUtilities.GetMinMaxFromDelta(
+ MathUtilities.Deg2Rad(StartAngle),
+ MathUtilities.Deg2Rad(SweepAngle));
Point centre = new Point(rect.Width * 0.5d, rect.Height * 0.5d);
double radiusX = deflatedRect.Width * 0.5d;
@@ -51,13 +77,19 @@ namespace Avalonia.Controls.Shapes
Point endCurvePoint = MathUtilities.GetEllipsePoint(centre, radiusX, radiusY, endAngle);
Size size = new Size(radiusX, radiusY);
- StreamGeometry streamGeometry = new StreamGeometry();
- using StreamGeometryContext streamGeometryContext = streamGeometry.Open();
-
- streamGeometryContext.BeginFigure(startCurvePoint, false);
- streamGeometryContext.ArcTo(endCurvePoint, size, 0.0d, Math.Abs(Angle) > 180.0d, SweepDirection.Clockwise);
- streamGeometryContext.LineTo(centre);
- streamGeometryContext.EndFigure(true);
+ var streamGeometry = new StreamGeometry();
+ using (StreamGeometryContext context = streamGeometry.Open())
+ {
+ context.BeginFigure(startCurvePoint, false);
+ context.ArcTo(
+ endCurvePoint,
+ size,
+ rotationAngle: 0.0d,
+ isLargeArc: Math.Abs(SweepAngle) > 180.0d,
+ SweepDirection.Clockwise);
+ context.LineTo(centre);
+ context.EndFigure(true);
+ }
return streamGeometry;
}
From 825fcfab31f8363c1e0d5755472355616987032b Mon Sep 17 00:00:00 2001
From: Takoooooo
Date: Mon, 15 Aug 2022 14:00:49 +0300
Subject: [PATCH 7/7] Remove obsolete members from Avalonia.Base namespace
---
src/Avalonia.Base/Animation/Animation.cs | 17 --
.../Animators/SolidColorBrushAnimator.cs | 13 --
src/Avalonia.Base/AvaloniaObjectExtensions.cs | 35 ----
src/Avalonia.Base/AvaloniaProperty`1.cs | 15 --
.../Collections/AvaloniaListExtensions.cs | 15 --
src/Avalonia.Base/DirectPropertyBase.cs | 15 --
src/Avalonia.Base/EnumExtensions.cs | 4 -
.../Interactivity/RoutedEvent.cs | 18 --
src/Avalonia.Base/Layout/ILayoutManager.cs | 11 -
src/Avalonia.Base/Layout/LayoutManager.cs | 11 -
src/Avalonia.Base/Layout/Layoutable.cs | 28 ---
src/Avalonia.Base/Media/Imaging/Bitmap.cs | 16 --
.../Media/Imaging/WriteableBitmap.cs | 14 +-
src/Avalonia.Base/Utilities/WeakObservable.cs | 25 ---
.../Utilities/WeakSubscriptionManager.cs | 193 ------------------
src/Avalonia.Base/Visual.cs | 16 --
.../VisualTree/IVisualTreeHost.cs | 19 --
src/Avalonia.Controls/Primitives/Popup.cs | 9 +-
src/Avalonia.Controls/Remote/RemoteWidget.cs | 2 -
src/Avalonia.X11/X11IconLoader.cs | 2 -
.../Collections/AvaloniaListExtenionsTests.cs | 155 --------------
.../WeakSubscriptionManagerTests.cs | 70 -------
.../Avalonia.RenderTests/Media/BitmapTests.cs | 2 -
23 files changed, 2 insertions(+), 703 deletions(-)
delete mode 100644 src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs
delete mode 100644 src/Avalonia.Base/VisualTree/IVisualTreeHost.cs
delete mode 100644 tests/Avalonia.Base.UnitTests/Collections/AvaloniaListExtenionsTests.cs
delete mode 100644 tests/Avalonia.Base.UnitTests/WeakSubscriptionManagerTests.cs
diff --git a/src/Avalonia.Base/Animation/Animation.cs b/src/Avalonia.Base/Animation/Animation.cs
index 03b2d17e44..6bb06367de 100644
--- a/src/Avalonia.Base/Animation/Animation.cs
+++ b/src/Avalonia.Base/Animation/Animation.cs
@@ -172,23 +172,6 @@ namespace Avalonia.Animation
set { SetAndRaise(SpeedRatioProperty, ref _speedRatio, value); }
}
- ///
- /// Obsolete: Do not use this property, use instead.
- ///
- ///
- [Obsolete("This property has been superceded by IterationCount.")]
- public string RepeatCount
- {
- get { return IterationCount.ToString(); }
- set
- {
- var val = value.ToUpper();
- val = val.Replace("LOOP", "INFINITE");
- val = val.Replace("NONE", "1");
- IterationCount = IterationCount.Parse(val);
- }
- }
-
///
/// Gets the children of the .
///
diff --git a/src/Avalonia.Base/Animation/Animators/SolidColorBrushAnimator.cs b/src/Avalonia.Base/Animation/Animators/SolidColorBrushAnimator.cs
index b87b2681d6..9256c7be5e 100644
--- a/src/Avalonia.Base/Animation/Animators/SolidColorBrushAnimator.cs
+++ b/src/Avalonia.Base/Animation/Animators/SolidColorBrushAnimator.cs
@@ -37,17 +37,4 @@ namespace Avalonia.Animation.Animators
}
}
- [Obsolete("Use ISolidColorBrushAnimator instead")]
- public class SolidColorBrushAnimator : Animator
- {
- public override SolidColorBrush? Interpolate(double progress, SolidColorBrush? oldValue, SolidColorBrush? newValue)
- {
- if (oldValue is null || newValue is null)
- {
- return progress >= 0.5 ? newValue : oldValue;
- }
-
- return new SolidColorBrush(ColorAnimator.InterpolateCore(progress, oldValue.Color, newValue.Color));
- }
- }
}
diff --git a/src/Avalonia.Base/AvaloniaObjectExtensions.cs b/src/Avalonia.Base/AvaloniaObjectExtensions.cs
index 134e3b2ac7..2d7bab6cd6 100644
--- a/src/Avalonia.Base/AvaloniaObjectExtensions.cs
+++ b/src/Avalonia.Base/AvaloniaObjectExtensions.cs
@@ -468,41 +468,6 @@ namespace Avalonia
});
}
- ///
- /// Subscribes to a property changed notifications for changes that originate from a
- /// .
- ///
- /// The type of the property change sender.
- /// The property changed observable.
- /// Given a TTarget, returns the handler.
- /// A disposable that can be used to terminate the subscription.
- [Obsolete("Use overload taking Action.")]
- public static IDisposable AddClassHandler(
- this IObservable observable,
- Func> handler)
- where TTarget : class
- {
- return observable.Subscribe(e => SubscribeAdapter(e, handler));
- }
-
- ///
- /// Observer method for .
- ///
- /// The sender type to accept.
- /// The event args.
- /// Given a TTarget, returns the handler.
- private static void SubscribeAdapter(
- AvaloniaPropertyChangedEventArgs e,
- Func> handler)
- where TTarget : class
- {
- if (e.Sender is TTarget target)
- {
- handler(target)(e);
- }
- }
-
private class BindingAdaptor : IBinding
{
private IObservable
public static class EnumExtensions
{
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [Obsolete("This method is obsolete. Use HasAllFlags instead.")]
- public static bool HasFlagCustom(this T value, T flag) where T : unmanaged, Enum
- => value.HasAllFlags(flag);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe bool HasAllFlags(this T value, T flags) where T : unmanaged, Enum
diff --git a/src/Avalonia.Base/Interactivity/RoutedEvent.cs b/src/Avalonia.Base/Interactivity/RoutedEvent.cs
index a9b7dc8c89..37edb24cc1 100644
--- a/src/Avalonia.Base/Interactivity/RoutedEvent.cs
+++ b/src/Avalonia.Base/Interactivity/RoutedEvent.cs
@@ -113,24 +113,6 @@ namespace Avalonia.Interactivity
{
}
- [Obsolete("Use overload taking Action.")]
- public IDisposable AddClassHandler(
- Func> handler,
- RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
- bool handledEventsToo = false)
- where TTarget : class, IInteractive
- {
- void Adapter(object? sender, RoutedEventArgs e)
- {
- if (sender is TTarget target && e is TEventArgs args)
- {
- handler(target)(args);
- }
- }
-
- return AddClassHandler(typeof(TTarget), Adapter, routes, handledEventsToo);
- }
-
public IDisposable AddClassHandler(
Action handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
diff --git a/src/Avalonia.Base/Layout/ILayoutManager.cs b/src/Avalonia.Base/Layout/ILayoutManager.cs
index 143ce13a1b..88d95c81fd 100644
--- a/src/Avalonia.Base/Layout/ILayoutManager.cs
+++ b/src/Avalonia.Base/Layout/ILayoutManager.cs
@@ -44,17 +44,6 @@ namespace Avalonia.Layout
///
void ExecuteInitialLayoutPass();
- ///
- /// Executes the initial layout pass on a layout root.
- ///
- /// The control to lay out.
- ///
- /// You should not usually need to call this method explictly, the layout root will call
- /// it to carry out the initial layout of the control.
- ///
- [Obsolete("Call ExecuteInitialLayoutPass without parameter")]
- void ExecuteInitialLayoutPass(ILayoutRoot root);
-
///
/// Registers a control as wanting to receive effective viewport notifications.
///
diff --git a/src/Avalonia.Base/Layout/LayoutManager.cs b/src/Avalonia.Base/Layout/LayoutManager.cs
index b9ca6bfbd7..826947c39a 100644
--- a/src/Avalonia.Base/Layout/LayoutManager.cs
+++ b/src/Avalonia.Base/Layout/LayoutManager.cs
@@ -196,17 +196,6 @@ namespace Avalonia.Layout
ExecuteLayoutPass();
}
- [Obsolete("Call ExecuteInitialLayoutPass without parameter")]
- public void ExecuteInitialLayoutPass(ILayoutRoot root)
- {
- if (root != _owner)
- {
- throw new ArgumentException("ExecuteInitialLayoutPass called with incorrect root.");
- }
-
- ExecuteInitialLayoutPass();
- }
-
public void Dispose()
{
_disposed = true;
diff --git a/src/Avalonia.Base/Layout/Layoutable.cs b/src/Avalonia.Base/Layout/Layoutable.cs
index 101e867d56..527b63292d 100644
--- a/src/Avalonia.Base/Layout/Layoutable.cs
+++ b/src/Avalonia.Base/Layout/Layoutable.cs
@@ -460,20 +460,6 @@ namespace Avalonia.Layout
_effectiveViewportChanged?.Invoke(this, e);
}
- ///
- /// Marks a property as affecting the control's measurement.
- ///
- /// The properties.
- ///
- /// After a call to this method in a control's static constructor, any change to the
- /// property will cause to be called on the element.
- ///
- [Obsolete("Use AffectsMeasure and specify the control type.")]
- protected static void AffectsMeasure(params AvaloniaProperty[] properties)
- {
- AffectsMeasure(properties);
- }
-
///
/// Marks a property as affecting the control's measurement.
///
@@ -497,20 +483,6 @@ namespace Avalonia.Layout
}
}
- ///
- /// Marks a property as affecting the control's arrangement.
- ///
- /// The properties.
- ///
- /// After a call to this method in a control's static constructor, any change to the
- /// property will cause to be called on the element.
- ///
- [Obsolete("Use AffectsArrange and specify the control type.")]
- protected static void AffectsArrange(params AvaloniaProperty[] properties)
- {
- AffectsArrange(properties);
- }
-
///
/// Marks a property as affecting the control's arrangement.
///
diff --git a/src/Avalonia.Base/Media/Imaging/Bitmap.cs b/src/Avalonia.Base/Media/Imaging/Bitmap.cs
index 5f1617d778..cf8a31c3e9 100644
--- a/src/Avalonia.Base/Media/Imaging/Bitmap.cs
+++ b/src/Avalonia.Base/Media/Imaging/Bitmap.cs
@@ -89,22 +89,6 @@ namespace Avalonia.Media.Imaging
PlatformImpl.Dispose();
}
- ///
- /// Initializes a new instance of the class.
- ///
- /// The pixel format.
- /// The pointer to the source bytes.
- /// The size of the bitmap in device pixels.
- /// The DPI of the bitmap.
- /// The number of bytes per row.
- [Obsolete("Use overload taking an AlphaFormat.")]
- public Bitmap(PixelFormat format, IntPtr data, PixelSize size, Vector dpi, int stride)
- {
- var ri = GetFactory();
- PlatformImpl = RefCountable.Create(ri
- .LoadBitmap(format, ri.DefaultAlphaFormat, data, size, dpi, stride));
- }
-
///
/// Initializes a new instance of the class.
///
diff --git a/src/Avalonia.Base/Media/Imaging/WriteableBitmap.cs b/src/Avalonia.Base/Media/Imaging/WriteableBitmap.cs
index 1f39b1344d..1aac8efac7 100644
--- a/src/Avalonia.Base/Media/Imaging/WriteableBitmap.cs
+++ b/src/Avalonia.Base/Media/Imaging/WriteableBitmap.cs
@@ -9,18 +9,6 @@ namespace Avalonia.Media.Imaging
///
public class WriteableBitmap : Bitmap
{
- ///
- /// Initializes a new instance of the class.
- ///
- /// The size of the bitmap in device pixels.
- /// The DPI of the bitmap.
- /// The pixel format (optional).
- /// An .
- [Obsolete("Use overload taking an AlphaFormat.")]
- public WriteableBitmap(PixelSize size, Vector dpi, PixelFormat? format = null)
- : base(CreatePlatformImpl(size, dpi, format, null))
- {
- }
///
/// Initializes a new instance of the class.
@@ -30,7 +18,7 @@ namespace Avalonia.Media.Imaging
/// The pixel format (optional).
/// The alpha format (optional).
/// An .
- public WriteableBitmap(PixelSize size, Vector dpi, PixelFormat format, AlphaFormat alphaFormat)
+ public WriteableBitmap(PixelSize size, Vector dpi, PixelFormat? format = null, AlphaFormat? alphaFormat = null)
: base(CreatePlatformImpl(size, dpi, format, alphaFormat))
{
}
diff --git a/src/Avalonia.Base/Utilities/WeakObservable.cs b/src/Avalonia.Base/Utilities/WeakObservable.cs
index 6bf1d4082f..e1c350d539 100644
--- a/src/Avalonia.Base/Utilities/WeakObservable.cs
+++ b/src/Avalonia.Base/Utilities/WeakObservable.cs
@@ -9,31 +9,6 @@ namespace Avalonia.Utilities
///
public static class WeakObservable
{
- ///
- /// Converts a .NET event conforming to the standard .NET event pattern into an observable
- /// sequence, subscribing weakly.
- ///
- /// The type of target.
- /// The type of the event args.
- /// Object instance that exposes the event to convert.
- /// Name of the event to convert.
- ///
- [Obsolete("Use WeakEvent-based overload")]
- public static IObservable> FromEventPattern(
- TTarget target,
- string eventName)
- where TEventArgs : EventArgs
- {
- _ = target ?? throw new ArgumentNullException(nameof(target));
- _ = eventName ?? throw new ArgumentNullException(nameof(eventName));
-
- return Observable.Create>(observer =>
- {
- var handler = new Handler(observer);
- WeakSubscriptionManager.Subscribe(target, eventName, handler);
- return () => WeakSubscriptionManager.Unsubscribe(target, eventName, handler);
- }).Publish().RefCount();
- }
private class Handler
: IWeakSubscriber,
diff --git a/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs b/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs
deleted file mode 100644
index dc9e86cc32..0000000000
--- a/src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs
+++ /dev/null
@@ -1,193 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-namespace Avalonia.Utilities
-{
- ///
- /// Manages subscriptions to events using weak listeners.
- ///
- public static class WeakSubscriptionManager
- {
- ///
- /// Subscribes to an event on an object using a weak subscription.
- ///
- /// The type of the target.
- /// The type of the event arguments.
- /// The event source.
- /// The name of the event.
- /// The subscriber.
- [Obsolete("Use WeakEvent")]
- public static void Subscribe(TTarget target, string eventName, IWeakSubscriber subscriber)
- where TEventArgs : EventArgs
- {
- _ = target ?? throw new ArgumentNullException(nameof(target));
-
- var dic = SubscriptionTypeStorage.Subscribers.GetOrCreateValue(target);
-
- if (!dic.TryGetValue(eventName, out var sub))
- {
- dic[eventName] = sub = new Subscription(dic, typeof(TTarget), target, eventName);
- }
-
- sub.Add(new WeakReference>(subscriber));
- }
-
- ///
- /// Unsubscribes from an event.
- ///
- /// The type of the event arguments.
- /// The event source.
- /// The name of the event.
- /// The subscriber.
- public static void Unsubscribe(object target, string eventName, IWeakSubscriber subscriber)
- where T : EventArgs
- {
- if (SubscriptionTypeStorage.Subscribers.TryGetValue(target, out var dic))
- {
- if (dic.TryGetValue(eventName, out var sub))
- {
- sub.Remove(subscriber);
- }
- }
- }
-
- private static class SubscriptionTypeStorage
- where T : EventArgs
- {
- public static readonly ConditionalWeakTable