Fix border inner rounded clip#20647
Fix border inner rounded clip#20647wieslawsoltes wants to merge 16 commits intoAvaloniaUI:masterfrom
Conversation
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
|
Awesome! Thanks so much for picking this up. Will definitely dig into the details for my own experience as well. |
src/Avalonia.Controls/Border.cs
Outdated
| bool IVisualWithChildClip.TryGetChildClip(out RoundedRect clip) | ||
| { | ||
| var bounds = new Rect(Bounds.Size); | ||
| var keypoints = GeometryBuilder.CalculateRoundedCornersRectangleWinUI( | ||
| bounds, | ||
| LayoutThickness, | ||
| CornerRadius, | ||
| BackgroundSizing.InnerBorderEdge); | ||
| clip = keypoints.ToRoundedRect(); | ||
| return true; | ||
| } |
There was a problem hiding this comment.
I know this is still draft so won't comment heavily. But should we try to support ALL geometries rather than just RoundedRect here? If someone creates a star-shaped control and needs to clip children this API won't work.
Note: The geometries can get crazy even in WinUI but I guess theoretically for a border are always some form of RoundedRect.
Note: We also need to support clipping in
ContentPresenter
There was a problem hiding this comment.
Also note WPF supports arbitrary geometry here as well: https://learn.microsoft.com/en-us/dotnet/api/system.windows.uielement.getlayoutclip
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
| } | ||
| } | ||
|
|
||
| public Thickness BorderThickness |
There was a problem hiding this comment.
Side comment: BackgroundSizing should be added too I think for border visuals to render the same. This is unrelated to the changes here though.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
| /// <summary> | ||
| /// Attempts to get a child-only clip. By default this uses <see cref="GetLayoutClip"/>. | ||
| /// </summary> | ||
| protected virtual bool TryGetChildClipCore(out RoundedRect clip, out Geometry? geometryClip) |
There was a problem hiding this comment.
If we look at GetLayoutClip based on WPF:
- There is no need for anything other than Geometry which covers all cases
- The return is nullable which means there isn't a need for true/false and Try semantics
I think these TryGetChildClip methods should be the same... just return an nullable Geometry. Is there really such a performance benefit to justify this non-ideal API?
If the method becomes protected virtual Geometry? GetChildClip() why have both it and the GetLayoutClip() method as well? They are actually redundant.
| } | ||
| } | ||
|
|
||
| public BackgroundSizing BackgroundSizing |
There was a problem hiding this comment.
Should all these inheritdoc ? I'm not sure the convention for visuals like this.
| protected override void RenderCore(ServerVisualRenderContext ctx, LtrbRect currentTransformedClip) | ||
| { | ||
| base.RenderCore(ctx, currentTransformedClip); | ||
| } |
There was a problem hiding this comment.
nit: missing newline separating methods
| { | ||
| private CornerRadius _cornerRadius; | ||
| private Thickness _borderThickness; | ||
| private BackgroundSizing _backgroundSizing; |
There was a problem hiding this comment.
nit: missing newline separating fields from method
|
Is there any chance the core avalonia team will have a chance to go over this? I'm worried it's going to miss 12.0. It's a pretty big flaw at this layer of the code though. |
PR Summary: Child-Only Layout Clipping, Composition Parity, and Samples
What
UIElement.GetLayoutClip.BorderandContentPresenterwhenClipToBoundsis enabled.BackgroundSizingonBorderandContentPresenter.ContentPresenterrounded clipping.BackgroundSizingparity.How
Visual.GetLayoutClip(Size layoutSlotSize)andTryGetChildClipCore(...)to provide child-only clips.Layoutable.Arrangeand used it when computing layout clips.BorderandContentPresenteroverrideTryGetChildClipCoreto return a rounded inner-edgeRoundedRectusingGeometryBuilder.CalculateRoundedCornersRectangleWinUIwithBackgroundSizing.InnerBorderEdge.ClipToBoundsand without clamping to visual bounds.BackgroundSizingto match immediate rendering.Why
GetLayoutClipbehavior should be based on layout slot size and independent fromClipToBounds.Behavioral Notes
GetLayoutClipaffects only children; the visual's own rendering is not clipped.ClipToBounds = trueonBorder/ContentPresenteryields rounded inner-edge child clipping.ClipToBounds = falsedoes not prevent layout clips provided byGetLayoutClip.Test Coverage
GeometryChildClip_Clips_ChildGeometryChildClip_Clips_When_ClipToBounds_FalseGeometryChildClip_Uses_LayoutSlotSizeContentPresenter_RoundedClip_Clips_ChildBorder_BackgroundSizing_OuterBorderEdgeContentPresenter_BackgroundSizing_OuterBorderEdgeSample Coverage
Border.ContentPresenter.ClipToBounds.Fixes #2105