From d37615bea848e83ff19c9d4fd3904f8c677f48bf Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 2 Mar 2019 16:34:29 +0100 Subject: [PATCH 1/4] Added failing test for #1898. Plus a couple of other empty binding path tests. --- .../Data/BindingTests.cs | 33 +++++++++++++++++++ .../Parsers/ExpressionNodeBuilderTests.cs | 9 +++++ .../ExpressionNodeBuilderTests_Errors.cs | 7 ++++ 3 files changed, 49 insertions(+) diff --git a/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs b/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs index 82b57224f0..baa1bca76a 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/BindingTests.cs @@ -273,6 +273,39 @@ namespace Avalonia.Markup.UnitTests.Data Assert.Equal(42, target.Value); } + [Fact] + public void Null_Path_Should_Bind_To_DataContext() + { + var target = new TextBlock { DataContext = "foo" }; + var binding = new Binding(); + + target.Bind(TextBlock.TextProperty, binding); + + Assert.Equal("foo", target.Text); + } + + [Fact] + public void Empty_Path_Should_Bind_To_DataContext() + { + var target = new TextBlock { DataContext = "foo" }; + var binding = new Binding { Path = string.Empty }; + + target.Bind(TextBlock.TextProperty, binding); + + Assert.Equal("foo", target.Text); + } + + [Fact] + public void Dot_Path_Should_Bind_To_DataContext() + { + var target = new TextBlock { DataContext = "foo" }; + var binding = new Binding { Path = "." }; + + target.Bind(TextBlock.TextProperty, binding); + + Assert.Equal("foo", target.Text); + } + /// /// Tests a problem discovered with ListBox with selection. /// diff --git a/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests.cs b/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests.cs index 2d687ff4f7..7061915a52 100644 --- a/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests.cs @@ -36,6 +36,15 @@ namespace Avalonia.Markup.UnitTests.Parsers AssertIsProperty(result[0], "F0o"); } + [Fact] + public void Should_Build_Dot() + { + var result = ToList(ExpressionObserverBuilder.Parse(".")); + + Assert.Equal(1, result.Count); + Assert.IsType(result[0]); + } + [Fact] public void Should_Build_Property_Chain() { diff --git a/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests_Errors.cs b/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests_Errors.cs index 347fc0a744..ac385b4cab 100644 --- a/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests_Errors.cs +++ b/tests/Avalonia.Markup.UnitTests/Parsers/ExpressionNodeBuilderTests_Errors.cs @@ -30,6 +30,13 @@ namespace Avalonia.Markup.UnitTests.Parsers () => ExpressionObserverBuilder.Parse("Foo.Bar.")); } + [Fact] + public void Expression_Cannot_Start_With_Period_Then_Token() + { + Assert.Throws( + () => ExpressionObserverBuilder.Parse(".Bar")); + } + [Fact] public void Expression_Cannot_Have_Empty_Indexer() { From e486d7f8ea1b2e607732ee38df62f4b5bfcbcbee Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 2 Mar 2019 16:34:50 +0100 Subject: [PATCH 2/4] Allow `{Binding .}` syntax. Fixes #1898. --- .../Avalonia.Markup/Markup/Parsers/ExpressionParser.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs b/src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs index bf6ebe837b..a1350a8393 100644 --- a/src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs +++ b/src/Markup/Avalonia.Markup/Markup/Parsers/ExpressionParser.cs @@ -106,6 +106,11 @@ namespace Avalonia.Markup.Parsers { return State.Indexer; } + else if (ParseDot(ref r)) + { + nodes.Add(new EmptyExpressionNode()); + return State.End; + } else { var identifier = r.ParseIdentifier(); @@ -317,6 +322,11 @@ namespace Avalonia.Markup.Parsers return !r.End && r.TakeIf('#'); } + private static bool ParseDot(ref CharacterReader r) + { + return !r.End && r.TakeIf('.'); + } + private enum State { Start, From 82b3bbcc6b83646a4d26f42f9c0ccdbf28b70195 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 2 Mar 2019 17:56:46 +0100 Subject: [PATCH 3/4] Added failing test for #1558. --- .../MouseDeviceTests.cs | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/Avalonia.Input.UnitTests/MouseDeviceTests.cs b/tests/Avalonia.Input.UnitTests/MouseDeviceTests.cs index 5853d1e82b..af034f541b 100644 --- a/tests/Avalonia.Input.UnitTests/MouseDeviceTests.cs +++ b/tests/Avalonia.Input.UnitTests/MouseDeviceTests.cs @@ -1,6 +1,7 @@ using Avalonia.Controls; using Avalonia.Input.Raw; using Avalonia.Interactivity; +using Avalonia.Media; using Avalonia.Rendering; using Avalonia.UnitTests; using Avalonia.VisualTree; @@ -184,6 +185,33 @@ namespace Avalonia.Input.UnitTests } } + + [Fact] + public void GetPosition_Should_Respect_Control_RenderTransform() + { + var renderer = new Mock(); + + using (TestApplication(renderer.Object)) + { + var inputManager = InputManager.Instance; + + var root = new TestRoot + { + MouseDevice = new MouseDevice(), + Child = new Border + { + Background = Brushes.Black, + RenderTransform = new TranslateTransform(10, 0), + } + }; + + SendMouseMove(inputManager, root, new Point(11, 11)); + + var result = root.MouseDevice.GetPosition(root.Child); + Assert.Equal(new Point(1, 11), result); + } + } + private void AddEnterLeaveHandlers( EventHandler handler, params IControl[] controls) @@ -195,14 +223,14 @@ namespace Avalonia.Input.UnitTests } } - private void SendMouseMove(IInputManager inputManager, TestRoot root) + private void SendMouseMove(IInputManager inputManager, TestRoot root, Point p = new Point()) { inputManager.ProcessInput(new RawMouseEventArgs( root.MouseDevice, 0, root, RawMouseEventType.Move, - new Point(), + p, InputModifiers.None)); } From 12cd666dc7bd2484ea64140dd18eeefea43a8b54 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 2 Mar 2019 17:57:05 +0100 Subject: [PATCH 4/4] Respect RenderTransform in GetPosition. Fixes #1558. --- src/Avalonia.Input/MouseDevice.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Avalonia.Input/MouseDevice.cs b/src/Avalonia.Input/MouseDevice.cs index 7945ee8ee4..d3e62ece6f 100644 --- a/src/Avalonia.Input/MouseDevice.cs +++ b/src/Avalonia.Input/MouseDevice.cs @@ -84,18 +84,14 @@ namespace Avalonia.Input { Contract.Requires(relativeTo != null); - Point p = default(Point); - IVisual v = relativeTo; - IVisual root = null; - - while (v != null) + if (relativeTo.VisualRoot == null) { - p += v.Bounds.Position; - root = v; - v = v.VisualParent; + throw new InvalidOperationException("Control is not attached to visual tree."); } - return root.PointToClient(Position) - p; + var rootPoint = relativeTo.VisualRoot.PointToClient(Position); + var transform = relativeTo.VisualRoot.TransformToVisual(relativeTo); + return rootPoint * transform.Value; } public void ProcessRawEvent(RawInputEventArgs e)