-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated RenderDataRectangleNode.HitTest to properly hit-test rounded …
…rectangles (#13797) * Updated RenderDataRectangleNode.HitTest to properly hit-test rounded rectangles. * Moved rounded rectangle contains logic to the RoundedRect struct, added unit tests, and refactored previous RenderDataRectangleNode changes. * Fixed a comment typo. * Added a private access modifier to a method.
- Loading branch information
Showing
3 changed files
with
119 additions
and
9 deletions.
There are no files selected for viewing
34 changes: 25 additions & 9 deletions
34
src/Avalonia.Base/Rendering/Composition/Drawing/Nodes/RenderDataRectangleNode.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,46 @@ | ||
using Avalonia.Media; | ||
using Avalonia.Platform; | ||
|
||
namespace Avalonia.Rendering.Composition.Drawing.Nodes; | ||
|
||
class RenderDataRectangleNode : RenderDataBrushAndPenNode | ||
{ | ||
public RoundedRect Rect { get; set; } | ||
public BoxShadows BoxShadows { get; set; } | ||
|
||
public override bool HitTest(Point p) | ||
{ | ||
if (ServerBrush != null) // it's safe to check for null | ||
var strokeThicknessAdjustment = (ClientPen?.Thickness / 2) ?? 0; | ||
|
||
if (Rect.IsRounded) | ||
{ | ||
var rect = Rect.Rect.Inflate((ClientPen?.Thickness / 2) ?? 0); | ||
return rect.ContainsExclusive(p); | ||
var outerRoundedRect = Rect.Inflate(strokeThicknessAdjustment, strokeThicknessAdjustment); | ||
if (outerRoundedRect.ContainsExclusive(p)) | ||
{ | ||
if (ServerBrush != null) // it's safe to check for null | ||
return true; | ||
|
||
var innerRoundedRect = Rect.Deflate(strokeThicknessAdjustment, strokeThicknessAdjustment); | ||
return !innerRoundedRect.ContainsExclusive(p); | ||
} | ||
} | ||
else | ||
{ | ||
var borderRect = Rect.Rect.Inflate((ClientPen?.Thickness / 2) ?? 0); | ||
var emptyRect = Rect.Rect.Deflate((ClientPen?.Thickness / 2) ?? 0); | ||
return borderRect.ContainsExclusive(p) && !emptyRect.ContainsExclusive(p); | ||
var outerRect = Rect.Rect.Inflate(strokeThicknessAdjustment); | ||
if (outerRect.ContainsExclusive(p)) | ||
{ | ||
if (ServerBrush != null) // it's safe to check for null | ||
return true; | ||
|
||
var innerRect = Rect.Rect.Deflate(strokeThicknessAdjustment); | ||
return !innerRect.ContainsExclusive(p); | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
public override void Invoke(ref RenderDataNodeRenderContext context) => | ||
context.Context.DrawRectangle(ServerBrush, ServerPen, Rect, BoxShadows); | ||
|
||
public override Rect? Bounds => BoxShadows.TransformBounds(Rect.Rect).Inflate((ServerPen?.Thickness ?? 0) / 2); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Xunit; | ||
|
||
namespace Avalonia.Base.UnitTests | ||
{ | ||
public class RoundedRectTests | ||
{ | ||
|
||
[Theory, | ||
// Corners | ||
InlineData(0, 0, false), | ||
InlineData(100, 0, false), | ||
InlineData(100, 100, false), | ||
InlineData(0, 100, false), | ||
// Indent 10px | ||
InlineData(10, 10, false), | ||
InlineData(90, 10, true), | ||
InlineData(90, 90, false), | ||
InlineData(10, 90, true), | ||
// Indent 17px | ||
InlineData(17, 17, false), | ||
InlineData(83, 17, true), | ||
InlineData(83, 83, true), | ||
InlineData(17, 83, true), | ||
// Center | ||
InlineData(50, 50, true), | ||
] | ||
public void ContainsExclusive_Should_Return_Expected_Result_For_Point(double x, double y, bool expectedResult) | ||
{ | ||
var rrect = new RoundedRect(new Rect(0, 0, 100, 100), new CornerRadius(60, 10, 50, 30)); | ||
|
||
Assert.Equal(expectedResult, rrect.ContainsExclusive(new Point(x, y))); | ||
} | ||
|
||
} | ||
} |