From 78f7726289cf8a002c36f33ac49153e33407528b Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 28 May 2021 17:09:14 +0200 Subject: [PATCH 01/13] Don't activate window when extending client area. Fixes #5988 --- src/Windows/Avalonia.Win32/WindowImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 082aca1109..3a3342fd14 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -900,7 +900,7 @@ namespace Avalonia.Win32 IntPtr.Zero, rcWindow.left, rcWindow.top, rcClient.Width, rcClient.Height, - SetWindowPosFlags.SWP_FRAMECHANGED); + SetWindowPosFlags.SWP_FRAMECHANGED | SetWindowPosFlags.SWP_NOACTIVATE); if (_isClientAreaExtended && WindowState != WindowState.FullScreen) { From f2e93ecb87668f827f3ab03e91be44391fcc59fc Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Sun, 30 May 2021 00:59:05 +0200 Subject: [PATCH 02/13] Optimize shape rendering (pen creation mostly). --- src/Avalonia.Controls/Shapes/Shape.cs | 26 ++++- .../Media/Immutable/ImmutableDashStyle.cs | 12 +- .../Media/Immutable/ImmutablePen.cs | 2 +- .../Rendering/SceneGraph/SceneBuilder.cs | 2 + .../Rendering/SceneGraph/VisualNode.cs | 5 + .../NullDrawingContextImpl.cs | 103 ++++++++++++++++++ .../NullRenderingPlatform.cs | 4 +- .../Rendering/ShapeRendering.cs | 53 +++++++++ 8 files changed, 197 insertions(+), 10 deletions(-) create mode 100644 tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs create mode 100644 tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs diff --git a/src/Avalonia.Controls/Shapes/Shape.cs b/src/Avalonia.Controls/Shapes/Shape.cs index 0b7595ec9a..0d1d9e3ffe 100644 --- a/src/Avalonia.Controls/Shapes/Shape.cs +++ b/src/Avalonia.Controls/Shapes/Shape.cs @@ -1,6 +1,7 @@ using System; using Avalonia.Collections; using Avalonia.Media; +using Avalonia.Media.Immutable; #nullable enable @@ -199,8 +200,29 @@ namespace Avalonia.Controls.Shapes if (geometry != null) { - var pen = new Pen(Stroke, StrokeThickness, new DashStyle(StrokeDashArray, StrokeDashOffset), - StrokeLineCap, StrokeJoin); + var stroke = Stroke; + + ImmutablePen? pen = null; + + if (stroke != null) + { + var strokeDashArray = StrokeDashArray; + + ImmutableDashStyle? dashStyle = null; + + if (strokeDashArray != null && strokeDashArray.Count > 0) + { + dashStyle = new ImmutableDashStyle(strokeDashArray, StrokeDashOffset); + } + + pen = new ImmutablePen( + stroke.ToImmutable(), + StrokeThickness, + dashStyle, + StrokeLineCap, + StrokeJoin); + } + context.DrawGeometry(Fill, pen, geometry); } } diff --git a/src/Avalonia.Visuals/Media/Immutable/ImmutableDashStyle.cs b/src/Avalonia.Visuals/Media/Immutable/ImmutableDashStyle.cs index e9a52fe6ed..2dd188e0a9 100644 --- a/src/Avalonia.Visuals/Media/Immutable/ImmutableDashStyle.cs +++ b/src/Avalonia.Visuals/Media/Immutable/ImmutableDashStyle.cs @@ -10,6 +10,8 @@ namespace Avalonia.Media.Immutable /// public class ImmutableDashStyle : IDashStyle, IEquatable { + private readonly double[] _dashes; + /// /// Initializes a new instance of the class. /// @@ -17,12 +19,12 @@ namespace Avalonia.Media.Immutable /// The dash sequence offset. public ImmutableDashStyle(IEnumerable dashes, double offset) { - Dashes = (IReadOnlyList)dashes?.ToList() ?? Array.Empty(); + _dashes = dashes?.ToArray() ?? Array.Empty(); Offset = offset; } /// - public IReadOnlyList Dashes { get; } + public IReadOnlyList Dashes => _dashes; /// public double Offset { get; } @@ -56,9 +58,9 @@ namespace Avalonia.Media.Immutable var hashCode = 717868523; hashCode = hashCode * -1521134295 + Offset.GetHashCode(); - if (Dashes != null) + if (_dashes != null) { - foreach (var i in Dashes) + foreach (var i in _dashes) { hashCode = hashCode * -1521134295 + i.GetHashCode(); } @@ -69,7 +71,7 @@ namespace Avalonia.Media.Immutable private static bool SequenceEqual(IReadOnlyList left, IReadOnlyList right) { - if (left == right) + if (ReferenceEquals(left, right)) { return true; } diff --git a/src/Avalonia.Visuals/Media/Immutable/ImmutablePen.cs b/src/Avalonia.Visuals/Media/Immutable/ImmutablePen.cs index e586eaf3a9..32624fbf45 100644 --- a/src/Avalonia.Visuals/Media/Immutable/ImmutablePen.cs +++ b/src/Avalonia.Visuals/Media/Immutable/ImmutablePen.cs @@ -23,7 +23,7 @@ namespace Avalonia.Media.Immutable ImmutableDashStyle dashStyle = null, PenLineCap lineCap = PenLineCap.Flat, PenLineJoin lineJoin = PenLineJoin.Miter, - double miterLimit = 10.0) : this(new SolidColorBrush(color), thickness, dashStyle, lineCap, lineJoin, miterLimit) + double miterLimit = 10.0) : this(new ImmutableSolidColorBrush(color), thickness, dashStyle, lineCap, lineJoin, miterLimit) { } diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs index 56f05db04e..f2a09b815e 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs @@ -249,6 +249,8 @@ namespace Avalonia.Rendering.SceneGraph { var visualChildren = (IList) visual.VisualChildren; + node.TryPreallocateChildren(visualChildren.Count); + if (visualChildren.Count == 1) { var childNode = GetOrCreateChildNode(scene, visualChildren[0], node); diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs index d0439feed2..db6b606b41 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs @@ -358,6 +358,11 @@ namespace Avalonia.Rendering.SceneGraph internal void TryPreallocateChildren(int count) { + if (count == 0) + { + return; + } + EnsureChildrenCreated(count); } diff --git a/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs b/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs new file mode 100644 index 0000000000..7626be7760 --- /dev/null +++ b/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs @@ -0,0 +1,103 @@ +using Avalonia.Media; +using Avalonia.Platform; +using Avalonia.Rendering.SceneGraph; +using Avalonia.Utilities; +using Avalonia.Visuals.Media.Imaging; + +namespace Avalonia.Benchmarks +{ + internal class NullDrawingContextImpl : IDrawingContextImpl + { + public void Dispose() + { + } + + public Matrix Transform { get; set; } + + public void Clear(Color color) + { + } + + public void DrawBitmap(IRef source, double opacity, Rect sourceRect, Rect destRect, + BitmapInterpolationMode bitmapInterpolationMode = BitmapInterpolationMode.Default) + { + } + + public void DrawBitmap(IRef source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect) + { + } + + public void DrawLine(IPen pen, Point p1, Point p2) + { + } + + public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) + { + } + + public void DrawRectangle(IBrush brush, IPen pen, RoundedRect rect, BoxShadows boxShadows = default) + { + } + + public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text) + { + } + + public void DrawGlyphRun(IBrush foreground, GlyphRun glyphRun) + { + } + + public IDrawingContextLayerImpl CreateLayer(Size size) + { + return null; + } + + public void PushClip(Rect clip) + { + } + + public void PushClip(RoundedRect clip) + { + } + + public void PopClip() + { + } + + public void PushOpacity(double opacity) + { + } + + public void PopOpacity() + { + } + + public void PushOpacityMask(IBrush mask, Rect bounds) + { + } + + public void PopOpacityMask() + { + } + + public void PushGeometryClip(IGeometryImpl clip) + { + } + + public void PopGeometryClip() + { + } + + public void PushBitmapBlendMode(BitmapBlendingMode blendingMode) + { + } + + public void PopBitmapBlendMode() + { + } + + public void Custom(ICustomDrawOperation custom) + { + } + } +} diff --git a/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs b/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs index 8792cb5cb1..876a0de643 100644 --- a/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs +++ b/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs @@ -18,12 +18,12 @@ namespace Avalonia.Benchmarks public IGeometryImpl CreateEllipseGeometry(Rect rect) { - throw new NotImplementedException(); + return new MockStreamGeometryImpl(); } public IGeometryImpl CreateLineGeometry(Point p1, Point p2) { - throw new NotImplementedException(); + return new MockStreamGeometryImpl(); } public IGeometryImpl CreateRectangleGeometry(Rect rect) diff --git a/tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs b/tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs new file mode 100644 index 0000000000..b0db806afa --- /dev/null +++ b/tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs @@ -0,0 +1,53 @@ +using Avalonia.Controls.Shapes; +using Avalonia.Media; +using Avalonia.Platform; +using BenchmarkDotNet.Attributes; + +namespace Avalonia.Benchmarks.Rendering +{ + [MemoryDiagnoser] + public class ShapeRendering + { + private readonly DrawingContext _drawingContext; + private readonly Line _lineFill; + private readonly Line _lineFillAndStroke; + private readonly Line _lineNoBrushes; + private readonly Line _lineStroke; + + public ShapeRendering() + { + _lineNoBrushes = new Line(); + _lineStroke = new Line { Stroke = new SolidColorBrush() }; + _lineFill = new Line { Fill = new SolidColorBrush() }; + _lineFillAndStroke = new Line { Stroke = new SolidColorBrush(), Fill = new SolidColorBrush() }; + + _drawingContext = new DrawingContext(new NullDrawingContextImpl(), true); + + AvaloniaLocator.CurrentMutable.Bind().ToConstant(new NullRenderingPlatform()); + } + + [Benchmark] + public void Render_Line_NoBrushes() + { + _lineNoBrushes.Render(_drawingContext); + } + + [Benchmark] + public void Render_Line_WithStroke() + { + _lineStroke.Render(_drawingContext); + } + + [Benchmark] + public void Render_Line_WithFill() + { + _lineFill.Render(_drawingContext); + } + + [Benchmark] + public void Render_Line_WithFillAndStroke() + { + _lineFillAndStroke.Render(_drawingContext); + } + } +} From 86b9a60a4c2c037b32674a65cd01796cfab7727f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wies=C5=82aw=20=C5=A0olt=C3=A9s?= Date: Mon, 31 May 2021 09:41:49 -0700 Subject: [PATCH 03/13] Fix custom hit testing (#5968) * Fix custom hit testing * Use ICustomHitTest as it's intended to be used in defered renderer Co-authored-by: Dan Walmsley Co-authored-by: Steven Kirk Co-authored-by: Steven Kirk --- src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs | 3 +-- src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs index 1d655bb691..74d804f2bf 100644 --- a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs +++ b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs @@ -52,8 +52,7 @@ namespace Avalonia.Controls.Primitives { if (InputPassThroughElement is object) { - var p = point.Transform(this.TransformToVisual(VisualRoot)!.Value); - var hit = VisualRoot.GetVisualAt(p, x => x != this); + var hit = VisualRoot.GetVisualAt(point, x => x != this); if (hit is object) { diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs index 36aa08c2f9..d8e5baac97 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs @@ -257,7 +257,7 @@ namespace Avalonia.Rendering.SceneGraph if (childCount == 0 || wasVisited) { if ((wasVisited || FilterAndClip(node, ref clip)) && - (node.Visual is ICustomSimpleHitTest custom ? custom.HitTest(_point) : node.HitTest(_point))) + (node.Visual is ICustomHitTest custom ? custom.HitTest(_point) : node.HitTest(_point))) { _current = node.Visual; From 7d608a33eec1ef871345dbad579e031306676964 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 4 Jun 2021 10:28:44 +0200 Subject: [PATCH 04/13] Implemented ImageDrawing. --- src/Avalonia.Visuals/Media/ImageDrawing.cs | 53 +++++++++++ .../Media/ImageDrawingTests.cs | 84 ++++++++++++++++++ .../ImageDrawing_BottomRight.expected.png | Bin 0 -> 3526 bytes .../ImageDrawing_Fill.expected.png | Bin 0 -> 11529 bytes .../Media/ImageDrawing/github_icon.png | Bin 0 -> 17661 bytes .../ImageDrawing_BottomRight.expected.png | Bin 0 -> 3183 bytes .../ImageDrawing_Fill.expected.png | Bin 0 -> 6898 bytes .../Skia/Media/ImageDrawing/github_icon.png | Bin 0 -> 17661 bytes 8 files changed, 137 insertions(+) create mode 100644 src/Avalonia.Visuals/Media/ImageDrawing.cs create mode 100644 tests/Avalonia.RenderTests/Media/ImageDrawingTests.cs create mode 100644 tests/TestFiles/Direct2D1/Media/ImageDrawing/ImageDrawing_BottomRight.expected.png create mode 100644 tests/TestFiles/Direct2D1/Media/ImageDrawing/ImageDrawing_Fill.expected.png create mode 100644 tests/TestFiles/Direct2D1/Media/ImageDrawing/github_icon.png create mode 100644 tests/TestFiles/Skia/Media/ImageDrawing/ImageDrawing_BottomRight.expected.png create mode 100644 tests/TestFiles/Skia/Media/ImageDrawing/ImageDrawing_Fill.expected.png create mode 100644 tests/TestFiles/Skia/Media/ImageDrawing/github_icon.png diff --git a/src/Avalonia.Visuals/Media/ImageDrawing.cs b/src/Avalonia.Visuals/Media/ImageDrawing.cs new file mode 100644 index 0000000000..82f97b52b4 --- /dev/null +++ b/src/Avalonia.Visuals/Media/ImageDrawing.cs @@ -0,0 +1,53 @@ +#nullable enable + +namespace Avalonia.Media +{ + /// + /// Draws an image within a region defined by a . + /// + public class ImageDrawing : Drawing + { + /// + /// Defines the property. + /// + public static readonly StyledProperty ImageSourceProperty = + AvaloniaProperty.Register(nameof(ImageSource)); + + /// + /// Defines the property. + /// + public static readonly StyledProperty RectProperty = + AvaloniaProperty.Register(nameof(Rect)); + + /// + /// Gets or sets the source of the image. + /// + public IImage? ImageSource + { + get => GetValue(ImageSourceProperty); + set => SetValue(ImageSourceProperty, value); + } + + /// + /// Gets or sets region in which the image is drawn. + /// + public Rect Rect + { + get => GetValue(RectProperty); + set => SetValue(RectProperty, value); + } + + public override void Draw(DrawingContext context) + { + var imageSource = ImageSource; + var rect = Rect; + + if (imageSource is object && !rect.IsEmpty) + { + context.DrawImage(imageSource, rect); + } + } + + public override Rect GetBounds() => Rect; + } +} diff --git a/tests/Avalonia.RenderTests/Media/ImageDrawingTests.cs b/tests/Avalonia.RenderTests/Media/ImageDrawingTests.cs new file mode 100644 index 0000000000..5ca21a3535 --- /dev/null +++ b/tests/Avalonia.RenderTests/Media/ImageDrawingTests.cs @@ -0,0 +1,84 @@ +using System.Threading.Tasks; +using Avalonia.Controls; +using Avalonia.Media; +using Avalonia.Media.Imaging; +using Xunit; + +#if AVALONIA_SKIA +namespace Avalonia.Skia.RenderTests +#else +namespace Avalonia.Direct2D1.RenderTests.Media +#endif +{ + public class ImageDrawingTests : TestBase + { + public ImageDrawingTests() + : base(@"Media\ImageDrawing") + { + } + + private string BitmapPath + { + get { return System.IO.Path.Combine(OutputPath, "github_icon.png"); } + } + + [Fact] + public async Task ImageDrawing_Fill() + { + Decorator target = new Decorator + { + Width = 200, + Height = 200, + Child = new Image + { + Source = new DrawingImage + { + Drawing = new ImageDrawing + { + ImageSource = new Bitmap(BitmapPath), + Rect = new Rect(0, 0, 200, 200), + } + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + + [Fact] + public async Task ImageDrawing_BottomRight() + { + Decorator target = new Decorator + { + Width = 200, + Height = 200, + Child = new Image + { + Source = new DrawingImage + { + Drawing = new DrawingGroup + { + Children = + { + new GeometryDrawing + { + Geometry = StreamGeometry.Parse("m0,0 l200,200"), + Brush = Brushes.Black, + }, + new ImageDrawing + { + ImageSource = new Bitmap(BitmapPath), + Rect = new Rect(100, 100, 100, 100), + } + } + } + } + } + }; + + await RenderToFile(target); + CompareImages(); + } + } +} diff --git a/tests/TestFiles/Direct2D1/Media/ImageDrawing/ImageDrawing_BottomRight.expected.png b/tests/TestFiles/Direct2D1/Media/ImageDrawing/ImageDrawing_BottomRight.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..c6b7c2f3077c09d4cb50c05303f07b4c6f7c68de GIT binary patch literal 3526 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 ZZGCrrDbM_k!+&oO>V`R@#^_$`{{Ri>#kv3h literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Direct2D1/Media/ImageDrawing/ImageDrawing_Fill.expected.png b/tests/TestFiles/Direct2D1/Media/ImageDrawing/ImageDrawing_Fill.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..acc8532ff987e24923c908d4809d508e02e695ae GIT binary patch literal 11529 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 a*1@`ZA?>c!7F5m*BPXpaRViT_^#1{dpFcbR literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Direct2D1/Media/ImageDrawing/github_icon.png b/tests/TestFiles/Direct2D1/Media/ImageDrawing/github_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cd053c5fe1e742b21cffefd60111d8498a79dcee GIT binary patch literal 17661 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 literal 0 HcmV?d00001 diff --git a/tests/TestFiles/Skia/Media/ImageDrawing/ImageDrawing_BottomRight.expected.png b/tests/TestFiles/Skia/Media/ImageDrawing/ImageDrawing_BottomRight.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..f7a251055195f85996589719cd9e5fdec772c078 GIT binary patch literal 3183 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 literal 0 HcmV?d00001 From 4b2852f0e11e22f80a59b4e5182be5e0e090b2db Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Fri, 4 Jun 2021 14:08:30 +0200 Subject: [PATCH 05/13] Fix light dismiss overlay intercepting titlebar hit tests. --- src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs index d886b67241..8a340aac5e 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs @@ -117,7 +117,7 @@ namespace Avalonia.Win32 { var visual = window.Renderer.HitTestFirst(position, _owner as Window, x => { - if (x is IInputElement ie && !ie.IsHitTestVisible) + if (x is IInputElement ie && (!ie.IsHitTestVisible || !ie.IsVisible)) { return false; } From 471aa9c7779c6d0e29474d34dc1c885863799021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sun, 6 Jun 2021 15:06:49 +0200 Subject: [PATCH 06/13] fix xaml errors in filtertextbox --- .../Diagnostics/Controls/FilterTextBox.axaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Diagnostics/Diagnostics/Controls/FilterTextBox.axaml b/src/Avalonia.Diagnostics/Diagnostics/Controls/FilterTextBox.axaml index 52720e652f..b7995c38e3 100644 --- a/src/Avalonia.Diagnostics/Diagnostics/Controls/FilterTextBox.axaml +++ b/src/Avalonia.Diagnostics/Diagnostics/Controls/FilterTextBox.axaml @@ -27,7 +27,9 @@ - M7.495 9.052L8.386 11.402H9.477L6.237 3H5.217L2 11.402H3.095L3.933 9.052H7.495ZM5.811 4.453L5.855 4.588L7.173 8.162H4.255L5.562 4.588L5.606 4.453L5.644 4.297L5.676 4.145L5.697 4.019H5.72L5.744 4.145L5.773 4.297L5.811 4.453ZM13.795 10.464V11.4H14.755V7.498C14.755 6.779 14.575 6.226 14.216 5.837C13.857 5.448 13.327 5.254 12.628 5.254C12.429 5.254 12.227 5.273 12.022 5.31C11.817 5.347 11.622 5.394 11.439 5.451C11.256 5.508 11.091 5.569 10.944 5.636C10.797 5.703 10.683 5.765 10.601 5.824V6.808C10.867 6.578 11.167 6.397 11.505 6.268C11.843 6.139 12.194 6.075 12.557 6.075C12.745 6.075 12.915 6.103 13.07 6.16C13.225 6.217 13.357 6.306 13.466 6.427C13.575 6.548 13.659 6.706 13.718 6.899C13.777 7.092 13.806 7.326 13.806 7.599L11.995 7.851C11.651 7.898 11.355 7.977 11.107 8.088C10.859 8.199 10.654 8.339 10.492 8.507C10.33 8.675 10.21 8.868 10.132 9.087C10.054 9.306 10.015 9.546 10.015 9.808C10.015 10.054 10.057 10.283 10.139 10.496C10.221 10.709 10.342 10.893 10.502 11.047C10.662 11.201 10.862 11.323 11.1 11.413C11.338 11.503 11.613 11.548 11.926 11.548C12.328 11.548 12.686 11.456 13.001 11.27C13.316 11.084 13.573 10.816 13.772 10.464H13.795ZM11.667 8.721C11.843 8.657 12.068 8.607 12.341 8.572L13.806 8.367V8.976C13.806 9.222 13.765 9.451 13.683 9.664C13.601 9.877 13.486 10.063 13.34 10.221C13.194 10.379 13.019 10.503 12.816 10.593C12.613 10.683 12.39 10.728 12.148 10.728C11.961 10.728 11.795 10.703 11.653 10.652C11.511 10.601 11.392 10.53 11.296 10.441C11.2 10.352 11.127 10.247 11.076 10.125C11.025 10.003 11 9.873 11 9.732C11 9.568 11.018 9.421 11.055 9.292C11.092 9.163 11.16 9.051 11.257 8.958C11.354 8.865 11.491 8.785 11.667 8.721Z + + M7.495 9.052L8.386 11.402H9.477L6.237 3H5.217L2 11.402H3.095L3.933 9.052H7.495ZM5.811 4.453L5.855 4.588L7.173 8.162H4.255L5.562 4.588L5.606 4.453L5.644 4.297L5.676 4.145L5.697 4.019H5.72L5.744 4.145L5.773 4.297L5.811 4.453ZM13.795 10.464V11.4H14.755V7.498C14.755 6.779 14.575 6.226 14.216 5.837C13.857 5.448 13.327 5.254 12.628 5.254C12.429 5.254 12.227 5.273 12.022 5.31C11.817 5.347 11.622 5.394 11.439 5.451C11.256 5.508 11.091 5.569 10.944 5.636C10.797 5.703 10.683 5.765 10.601 5.824V6.808C10.867 6.578 11.167 6.397 11.505 6.268C11.843 6.139 12.194 6.075 12.557 6.075C12.745 6.075 12.915 6.103 13.07 6.16C13.225 6.217 13.357 6.306 13.466 6.427C13.575 6.548 13.659 6.706 13.718 6.899C13.777 7.092 13.806 7.326 13.806 7.599L11.995 7.851C11.651 7.898 11.355 7.977 11.107 8.088C10.859 8.199 10.654 8.339 10.492 8.507C10.33 8.675 10.21 8.868 10.132 9.087C10.054 9.306 10.015 9.546 10.015 9.808C10.015 10.054 10.057 10.283 10.139 10.496C10.221 10.709 10.342 10.893 10.502 11.047C10.662 11.201 10.862 11.323 11.1 11.413C11.338 11.503 11.613 11.548 11.926 11.548C12.328 11.548 12.686 11.456 13.001 11.27C13.316 11.084 13.573 10.816 13.772 10.464H13.795ZM11.667 8.721C11.843 8.657 12.068 8.607 12.341 8.572L13.806 8.367V8.976C13.806 9.222 13.765 9.451 13.683 9.664C13.601 9.877 13.486 10.063 13.34 10.221C13.194 10.379 13.019 10.503 12.816 10.593C12.613 10.683 12.39 10.728 12.148 10.728C11.961 10.728 11.795 10.703 11.653 10.652C11.511 10.601 11.392 10.53 11.296 10.441C11.2 10.352 11.127 10.247 11.076 10.125C11.025 10.003 11 9.873 11 9.732C11 9.568 11.018 9.421 11.055 9.292C11.092 9.163 11.16 9.051 11.257 8.958C11.354 8.865 11.491 8.785 11.667 8.721Z + @@ -38,7 +40,9 @@ - M1 2H15V3H1V2ZM14 4H13V12H14V4ZM11.272 8.387C11.194 8.088 11.073 7.825 10.912 7.601C10.751 7.377 10.547 7.2 10.303 7.071C10.059 6.942 9.769 6.878 9.437 6.878C9.239 6.878 9.057 6.902 8.89 6.951C8.725 7 8.574 7.068 8.437 7.156C8.301 7.244 8.18 7.35 8.072 7.474L7.893 7.732V4.578H7V12H7.893V11.425L8.019 11.6C8.106 11.702 8.208 11.79 8.323 11.869C8.44 11.947 8.572 12.009 8.721 12.055C8.87 12.101 9.035 12.123 9.219 12.123C9.572 12.123 9.885 12.052 10.156 11.911C10.428 11.768 10.655 11.573 10.838 11.325C11.021 11.075 11.159 10.782 11.252 10.446C11.345 10.108 11.392 9.743 11.392 9.349C11.391 9.007 11.352 8.686 11.272 8.387ZM9.793 7.78C9.944 7.851 10.075 7.956 10.183 8.094C10.292 8.234 10.377 8.407 10.438 8.611C10.489 8.785 10.52 8.982 10.527 9.198L10.52 9.323C10.52 9.65 10.487 9.943 10.42 10.192C10.353 10.438 10.259 10.645 10.142 10.806C10.025 10.968 9.882 11.091 9.721 11.172C9.399 11.334 8.961 11.338 8.652 11.187C8.499 11.112 8.366 11.012 8.259 10.891C8.174 10.795 8.103 10.675 8.041 10.524C8.041 10.524 7.862 10.077 7.862 9.577C7.862 9.077 8.041 8.575 8.041 8.575C8.103 8.398 8.177 8.257 8.265 8.145C8.379 8.002 8.521 7.886 8.689 7.8C8.857 7.714 9.054 7.671 9.276 7.671C9.466 7.671 9.64 7.708 9.793 7.78ZM15 13H1V14H15V13ZM2.813 10L2.085 12.031H1L1.025 11.959L3.466 4.87305H4.407L6.892 12.031H5.81L5.032 10H2.813ZM3.934 6.42205H3.912L3.007 9.17505H4.848L3.934 6.42205Z + + M1 2H15V3H1V2ZM14 4H13V12H14V4ZM11.272 8.387C11.194 8.088 11.073 7.825 10.912 7.601C10.751 7.377 10.547 7.2 10.303 7.071C10.059 6.942 9.769 6.878 9.437 6.878C9.239 6.878 9.057 6.902 8.89 6.951C8.725 7 8.574 7.068 8.437 7.156C8.301 7.244 8.18 7.35 8.072 7.474L7.893 7.732V4.578H7V12H7.893V11.425L8.019 11.6C8.106 11.702 8.208 11.79 8.323 11.869C8.44 11.947 8.572 12.009 8.721 12.055C8.87 12.101 9.035 12.123 9.219 12.123C9.572 12.123 9.885 12.052 10.156 11.911C10.428 11.768 10.655 11.573 10.838 11.325C11.021 11.075 11.159 10.782 11.252 10.446C11.345 10.108 11.392 9.743 11.392 9.349C11.391 9.007 11.352 8.686 11.272 8.387ZM9.793 7.78C9.944 7.851 10.075 7.956 10.183 8.094C10.292 8.234 10.377 8.407 10.438 8.611C10.489 8.785 10.52 8.982 10.527 9.198L10.52 9.323C10.52 9.65 10.487 9.943 10.42 10.192C10.353 10.438 10.259 10.645 10.142 10.806C10.025 10.968 9.882 11.091 9.721 11.172C9.399 11.334 8.961 11.338 8.652 11.187C8.499 11.112 8.366 11.012 8.259 10.891C8.174 10.795 8.103 10.675 8.041 10.524C8.041 10.524 7.862 10.077 7.862 9.577C7.862 9.077 8.041 8.575 8.041 8.575C8.103 8.398 8.177 8.257 8.265 8.145C8.379 8.002 8.521 7.886 8.689 7.8C8.857 7.714 9.054 7.671 9.276 7.671C9.466 7.671 9.64 7.708 9.793 7.78ZM15 13H1V14H15V13ZM2.813 10L2.085 12.031H1L1.025 11.959L3.466 4.87305H4.407L6.892 12.031H5.81L5.032 10H2.813ZM3.934 6.42205H3.912L3.007 9.17505H4.848L3.934 6.42205Z + @@ -49,7 +53,9 @@ - M10.0122 2H10.9879V5.11346L13.5489 3.55609L14.034 4.44095L11.4702 6L14.034 7.55905L13.5489 8.44391L10.9879 6.88654V10H10.0122V6.88654L7.45114 8.44391L6.96606 7.55905L9.5299 6L6.96606 4.44095L7.45114 3.55609L10.0122 5.11346V2ZM2 10H6V14H2V10Z + + M10.0122 2H10.9879V5.11346L13.5489 3.55609L14.034 4.44095L11.4702 6L14.034 7.55905L13.5489 8.44391L10.9879 6.88654V10H10.0122V6.88654L7.45114 8.44391L6.96606 7.55905L9.5299 6L6.96606 4.44095L7.45114 3.55609L10.0122 5.11346V2ZM2 10H6V14H2V10Z + From dbe9a2e2d17cbcd8ba5e1ea960b5e74a3564a31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Sun, 6 Jun 2021 15:07:13 +0200 Subject: [PATCH 07/13] fix xaml errors in controlcatalog sample --- samples/ControlCatalog/Pages/ContextFlyoutPage.axaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/ControlCatalog/Pages/ContextFlyoutPage.axaml b/samples/ControlCatalog/Pages/ContextFlyoutPage.axaml index e15637aa0f..f0e079ad91 100644 --- a/samples/ControlCatalog/Pages/ContextFlyoutPage.axaml +++ b/samples/ControlCatalog/Pages/ContextFlyoutPage.axaml @@ -84,13 +84,13 @@ - - - From 12c37270eeedb6fecf620f06a74e85b60514f3ac Mon Sep 17 00:00:00 2001 From: Deadpikle Date: Sun, 6 Jun 2021 12:27:14 -0400 Subject: [PATCH 08/13] SelectedDate and SelectedTime => TwoWay by default Fixes #3407 --- src/Avalonia.Controls/DateTimePickers/DatePicker.cs | 4 +++- src/Avalonia.Controls/DateTimePickers/TimePicker.cs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/DateTimePickers/DatePicker.cs b/src/Avalonia.Controls/DateTimePickers/DatePicker.cs index 8d893154eb..43bc7d1df9 100644 --- a/src/Avalonia.Controls/DateTimePickers/DatePicker.cs +++ b/src/Avalonia.Controls/DateTimePickers/DatePicker.cs @@ -2,6 +2,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Controls.Shapes; using Avalonia.Controls.Templates; +using Avalonia.Data; using Avalonia.Interactivity; using System; using System.Collections.Generic; @@ -88,7 +89,8 @@ namespace Avalonia.Controls /// public static readonly DirectProperty SelectedDateProperty = AvaloniaProperty.RegisterDirect(nameof(SelectedDate), - x => x.SelectedDate, (x, v) => x.SelectedDate = v); + x => x.SelectedDate, (x, v) => x.SelectedDate = v, + defaultBindingMode: BindingMode.TwoWay); // Template Items private Button _flyoutButton; diff --git a/src/Avalonia.Controls/DateTimePickers/TimePicker.cs b/src/Avalonia.Controls/DateTimePickers/TimePicker.cs index d0cf772c01..6b3f66912f 100644 --- a/src/Avalonia.Controls/DateTimePickers/TimePicker.cs +++ b/src/Avalonia.Controls/DateTimePickers/TimePicker.cs @@ -2,6 +2,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Controls.Shapes; using Avalonia.Controls.Templates; +using Avalonia.Data; using System; using System.Globalization; @@ -44,7 +45,8 @@ namespace Avalonia.Controls /// public static readonly DirectProperty SelectedTimeProperty = AvaloniaProperty.RegisterDirect(nameof(SelectedTime), - x => x.SelectedTime, (x, v) => x.SelectedTime = v); + x => x.SelectedTime, (x, v) => x.SelectedTime = v, + defaultBindingMode: BindingMode.TwoWay); // Template Items private TimePickerPresenter _presenter; From 6763337e25befce9c77e1a51da2cf57556fbfd0e Mon Sep 17 00:00:00 2001 From: Deadpikle Date: Sun, 6 Jun 2021 12:45:53 -0400 Subject: [PATCH 09/13] Add IsUndoEnabled to TextBox --- src/Avalonia.Controls/TextBox.cs | 87 +++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 3c221cbf27..e38531e540 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -119,9 +119,9 @@ namespace Avalonia.Controls AvaloniaProperty.Register(nameof(RevealPassword)); public static readonly DirectProperty CanCutProperty = - AvaloniaProperty.RegisterDirect( - nameof(CanCut), - o => o.CanCut); + AvaloniaProperty.RegisterDirect( + nameof(CanCut), + o => o.CanCut); public static readonly DirectProperty CanCopyProperty = AvaloniaProperty.RegisterDirect( @@ -129,9 +129,14 @@ namespace Avalonia.Controls o => o.CanCopy); public static readonly DirectProperty CanPasteProperty = - AvaloniaProperty.RegisterDirect( - nameof(CanPaste), - o => o.CanPaste); + AvaloniaProperty.RegisterDirect( + nameof(CanPaste), + o => o.CanPaste); + + public static readonly StyledProperty IsUndoEnabledProperty = + AvaloniaProperty.Register( + nameof(IsUndoEnabled), + defaultValue: true); struct UndoRedoState : IEquatable { @@ -218,7 +223,7 @@ namespace Avalonia.Controls value = CoerceCaretIndex(value); SetAndRaise(CaretIndexProperty, ref _caretIndex, value); UndoRedoState state; - if (_undoRedoHelper.TryGetLastState(out state) && state.Text == Text) + if (IsUndoEnabled && _undoRedoHelper.TryGetLastState(out state) && state.Text == Text) _undoRedoHelper.UpdateLastState(); } } @@ -316,7 +321,7 @@ namespace Avalonia.Controls SelectionEnd = CoerceCaretIndex(SelectionEnd, value); CaretIndex = CoerceCaretIndex(caretIndex, value); - if (SetAndRaise(TextProperty, ref _text, value) && !_isUndoingRedoing) + if (SetAndRaise(TextProperty, ref _text, value) && IsUndoEnabled && !_isUndoingRedoing) { _undoRedoHelper.Clear(); } @@ -329,7 +334,7 @@ namespace Avalonia.Controls get { return GetSelection(); } set { - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); if (string.IsNullOrEmpty(value)) { DeleteSelection(); @@ -338,7 +343,7 @@ namespace Avalonia.Controls { HandleTextInput(value); } - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); } } @@ -446,6 +451,27 @@ namespace Avalonia.Controls private set { SetAndRaise(CanPasteProperty, ref _canPaste, value); } } + /// + /// Property for determining whether undo/redo is enabled + /// + public bool IsUndoEnabled + { + get { return GetValue(IsUndoEnabledProperty); } + set + { + SetValue(IsUndoEnabledProperty, value); + if (value == false) + { + // from docs at + // https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled: + // "Setting this property to false clears the undo stack. + // Therefore, if you disable undo and then re-enable it, undo commands still do not work + // because the undo stack was emptied when you disabled undo." + _undoRedoHelper.Clear(); + } + } + } + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { _presenter = e.NameScope.Get("PART_TextPresenter"); @@ -551,7 +577,10 @@ namespace Avalonia.Controls SetTextInternal(text.Substring(0, caretIndex) + input + text.Substring(caretIndex)); CaretIndex += input.Length; ClearSelection(); - _undoRedoHelper.DiscardRedo(); + if (IsUndoEnabled) + { + _undoRedoHelper.DiscardRedo(); + } } } @@ -570,10 +599,10 @@ namespace Avalonia.Controls var text = GetSelection(); if (text is null) return; - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); Copy(); DeleteSelection(); - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); } public async void Copy() @@ -591,9 +620,9 @@ namespace Avalonia.Controls if (text is null) return; - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); HandleTextInput(text); - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); } protected override void OnKeyDown(KeyEventArgs e) @@ -638,7 +667,7 @@ namespace Avalonia.Controls Paste(); handled = true; } - else if (Match(keymap.Undo)) + else if (Match(keymap.Undo) && IsUndoEnabled) { try { @@ -652,7 +681,7 @@ namespace Avalonia.Controls handled = true; } - else if (Match(keymap.Redo)) + else if (Match(keymap.Redo) && IsUndoEnabled) { try { @@ -752,7 +781,7 @@ namespace Avalonia.Controls break; case Key.Back: - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); if (hasWholeWordModifiers && SelectionStart == SelectionEnd) { SetSelectionForControlBackspace(); @@ -776,13 +805,13 @@ namespace Avalonia.Controls CaretIndex -= removedCharacters; ClearSelection(); } - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); handled = true; break; case Key.Delete: - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); if (hasWholeWordModifiers && SelectionStart == SelectionEnd) { SetSelectionForControlDelete(); @@ -804,7 +833,7 @@ namespace Avalonia.Controls SetTextInternal(text.Substring(0, caretIndex) + text.Substring(caretIndex + removedCharacters)); } - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); handled = true; break; @@ -812,9 +841,9 @@ namespace Avalonia.Controls case Key.Enter: if (AcceptsReturn) { - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); HandleTextInput(NewLine); - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); handled = true; } @@ -823,9 +852,9 @@ namespace Avalonia.Controls case Key.Tab: if (AcceptsTab) { - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); HandleTextInput("\t"); - _undoRedoHelper.Snapshot(); + SnapshotUndoRedo(); handled = true; } else @@ -1251,5 +1280,13 @@ namespace Avalonia.Controls ClearSelection(); } } + + private void SnapshotUndoRedo() + { + if (IsUndoEnabled) + { + _undoRedoHelper.Snapshot(); + } + } } } From c6eb57c5350cf2e236f6c3c8bc26297b24d70ef7 Mon Sep 17 00:00:00 2001 From: Deadpikle Date: Sun, 6 Jun 2021 13:19:46 -0400 Subject: [PATCH 10/13] Add TextBox UndoLimit --- src/Avalonia.Controls/TextBox.cs | 20 +++++++++++++++++++ src/Avalonia.Controls/Utils/UndoRedoHelper.cs | 11 ++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index e38531e540..ffe0d39cab 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -138,6 +138,13 @@ namespace Avalonia.Controls nameof(IsUndoEnabled), defaultValue: true); + public static readonly DirectProperty UndoLimitProperty = + AvaloniaProperty.RegisterDirect( + nameof(UndoLimit), + o => o._undoRedoHelper.Limit, + (o, v) => o._undoRedoHelper.Limit = v, + unsetValue: -1); + struct UndoRedoState : IEquatable { public string Text { get; } @@ -472,6 +479,19 @@ namespace Avalonia.Controls } } + public int UndoLimit + { + get { return GetValue(UndoLimitProperty); } + set + { + SetValue(UndoLimitProperty, value); + // from docs at + // https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled: + // "Setting UndoLimit clears the undo queue." + _undoRedoHelper.Clear(); + } + } + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { _presenter = e.NameScope.Get("PART_TextPresenter"); diff --git a/src/Avalonia.Controls/Utils/UndoRedoHelper.cs b/src/Avalonia.Controls/Utils/UndoRedoHelper.cs index 17cf681f15..7374f20a0c 100644 --- a/src/Avalonia.Controls/Utils/UndoRedoHelper.cs +++ b/src/Avalonia.Controls/Utils/UndoRedoHelper.cs @@ -22,6 +22,10 @@ namespace Avalonia.Controls.Utils private LinkedListNode _currentNode; + /// + /// Maximum number of states this helper can store for undo/redo. + /// If -1, no limit is imposed. + /// public int Limit { get; set; } = 10; public UndoRedoHelper(IUndoRedoHost host) @@ -54,7 +58,10 @@ namespace Avalonia.Controls.Utils public bool HasState => _currentNode != null; public void UpdateLastState(TState state) { - _states.Last.Value = state; + if (_states.Last != null) + { + _states.Last.Value = state; + } } public void UpdateLastState() @@ -86,7 +93,7 @@ namespace Avalonia.Controls.Utils DiscardRedo(); _states.AddLast(current); _currentNode = _states.Last; - if (_states.Count > Limit) + if (Limit != -1 && _states.Count > Limit) _states.RemoveFirst(); } } From 4fe29b0f9e9568a85f0ced91e5041e80ee55d2c5 Mon Sep 17 00:00:00 2001 From: Deadpikle Date: Sun, 6 Jun 2021 21:27:47 -0400 Subject: [PATCH 11/13] UndoLimit now uses property properly --- src/Avalonia.Controls/TextBox.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index ffe0d39cab..06745bb3bc 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -141,8 +141,8 @@ namespace Avalonia.Controls public static readonly DirectProperty UndoLimitProperty = AvaloniaProperty.RegisterDirect( nameof(UndoLimit), - o => o._undoRedoHelper.Limit, - (o, v) => o._undoRedoHelper.Limit = v, + o => o.UndoLimit, + (o, v) => o.UndoLimit = v, unsetValue: -1); struct UndoRedoState : IEquatable @@ -481,10 +481,10 @@ namespace Avalonia.Controls public int UndoLimit { - get { return GetValue(UndoLimitProperty); } + get { return _undoRedoHelper.Limit; } set { - SetValue(UndoLimitProperty, value); + _undoRedoHelper.Limit = value; // from docs at // https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled: // "Setting UndoLimit clears the undo queue." From b5bb89348df5bdd201664c6e3ef71a5ed13400fe Mon Sep 17 00:00:00 2001 From: Deadpikle Date: Sun, 6 Jun 2021 21:38:50 -0400 Subject: [PATCH 12/13] Handle IsUndoEnabled in property changed --- src/Avalonia.Controls/TextBox.cs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 06745bb3bc..351d648afc 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -464,19 +464,7 @@ namespace Avalonia.Controls public bool IsUndoEnabled { get { return GetValue(IsUndoEnabledProperty); } - set - { - SetValue(IsUndoEnabledProperty, value); - if (value == false) - { - // from docs at - // https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled: - // "Setting this property to false clears the undo stack. - // Therefore, if you disable undo and then re-enable it, undo commands still do not work - // because the undo stack was emptied when you disabled undo." - _undoRedoHelper.Clear(); - } - } + set { SetValue(IsUndoEnabledProperty, value); } } public int UndoLimit @@ -511,6 +499,15 @@ namespace Avalonia.Controls UpdatePseudoclasses(); UpdateCommandStates(); } + else if (change.Property == IsUndoEnabledProperty && change.NewValue.GetValueOrDefault() == false) + { + // from docs at + // https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled: + // "Setting this property to false clears the undo stack. + // Therefore, if you disable undo and then re-enable it, undo commands still do not work + // because the undo stack was emptied when you disabled undo." + _undoRedoHelper.Clear(); + } } private void UpdateCommandStates() From 8ed27724793cd7315c9fd2cd73f804a9429ab1ae Mon Sep 17 00:00:00 2001 From: Deadpikle Date: Mon, 7 Jun 2021 07:56:35 -0400 Subject: [PATCH 13/13] Fix not raising property change on UndoLimit --- src/Avalonia.Controls/TextBox.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 351d648afc..1bee15bccd 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -472,7 +472,15 @@ namespace Avalonia.Controls get { return _undoRedoHelper.Limit; } set { - _undoRedoHelper.Limit = value; + if (_undoRedoHelper.Limit != value) + { + // can't use SetAndRaise due to using _undoRedoHelper.Limit + // (can't send a ref of a property to SetAndRaise), + // so use RaisePropertyChanged instead. + var oldValue = _undoRedoHelper.Limit; + _undoRedoHelper.Limit = value; + RaisePropertyChanged(UndoLimitProperty, oldValue, value); + } // from docs at // https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled: // "Setting UndoLimit clears the undo queue."