Clip to the UI node's content box#15442
Conversation
…ourselves in each extraction function which is really complicated and fragile and has lead to a number of bugs. Adds an `Inset` type, a `border: Inset` field to `Node`, updates the border field in `ui_layout_system`, and removes the border calculations and extra queries from the extraction functions.
…der values instead.
Co-authored-by: UkoeHB <[email protected]>
Fixed `outline_radius` comment.
nicoburns
left a comment
There was a problem hiding this comment.
Generally looks good to me.
We could have another Overflow variant (probably called Overflow::Hidden) to that clips inside of the border box instead of the content box. Left it out here as I'm not certain about the naming or behaviour though. If this PR is adopted, it would be trivial to add a Hidden variant in a follow up.
In CSS, overflow: hidden also implies the creation of a "scrollable box" which is not scrollable by the user but is programatically scrollable. It also affects layout of things like flexbox items. For just controlling the clip region there is overflow-clip-margin which allows you to specify one of content-box, padding-box, or border-box and additionally a pixel offset from that box (which may be negative), which may be a better fit for Bevy?
Yeah that makes sense, I'll make an issue about a new api. |
e554e88 to
18ba0b1
Compare
|
I don't know why the CI is failing, the test gets cancelled? |
# Objective Limited implementation of the CSS property `overflow-clip-margin` https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-margin Allows you to control the visible area for clipped content when using overfllow-clip, -hidden, or -scroll and expand it with a margin. Based on #15442 Fixes #15468 ## Solution Adds a new field to Style: `overflow_clip_margin: OverflowClipMargin`. The field is ignored unless overflow-clip, -hidden or -scroll is set on at least one axis. `OverflowClipMargin` has these associated constructor functions: ``` pub const fn content_box() -> Self; pub const fn padding_box() -> Self; pub const fn border_box() -> Self; ``` You can also use the method `with_margin` to increases the size of the visible area: ``` commands .spawn(NodeBundle { style: Style { width: Val::Px(100.), height: Val::Px(100.), padding: UiRect::all(Val::Px(20.)), border: UiRect::all(Val::Px(5.)), overflow: Overflow::clip(), overflow_clip_margin: OverflowClipMargin::border_box().with_margin(25.), ..Default::default() }, border_color: Color::BLACK.into(), background_color: GRAY.into(), ..Default::default() }) ``` `with_margin` expects a length in logical pixels, negative values are clamped to zero. ## Notes * To keep this PR as simple as possible I omitted responsive margin values support. This could be added in a follow up if we want it. * CSS also supports a `margin-box` option but we don't have access to the margin values in `Node` so it's probably not feasible to implement atm. ## Testing ```cargo run --example overflow_clip_margin``` <img width="396" alt="overflow-clip-margin" src="https://github.com/user-attachments/assets/07b51cd6-a565-4451-87a0-fa079429b04b"> ## Migration Guide Style has a new field `OverflowClipMargin`. It allows users to set the visible area for clipped content when using overflow-clip, -hidden, or -scroll and expand it with a margin. There are three associated constructor functions `content_box`, `padding_box` and `border_box`: * `content_box`: elements painted outside of the content box area (the innermost part of the node excluding the padding and border) of the node are clipped. This is the new default behaviour. * `padding_box`: elements painted outside outside of the padding area of the node are clipped. * `border_box`: elements painted outside of the bounds of the node are clipped. This matches the behaviour from Bevy 0.14. There is also a `with_margin` method that increases the size of the visible area by the given number in logical pixels, negative margin values are clamped to zero. `OverflowClipMargin` is ignored unless overflow-clip, -hidden or -scroll is also set on at least one axis of the UI node. --------- Co-authored-by: UkoeHB <[email protected]>
Objective
Change UI clipping to respect borders and padding.
Fixes #15335
Solution
Based on #15163
paddingfield toNode.ui_layout_sizecopy the padding values from taffy toNode::padding.update_clippingperform the clipping intersection with the node's content box.Notes
Rectprobably needs some helper methods for working with insets but becauseRectandBorderRectare in different crates it's awkward to add them. Left for a follow up.Overflowvariant (probably calledOverflow::Hidden) to that clips inside of the border box instead of the content box. Left it out here as I'm not certain about the naming or behaviour though. If this PR is adopted, it would be trivial to add aHiddenvariant in a follow up.This is caused by existing bugs in
ui_layout_system's coordinates rounding and not anything to do with the changes in this PR.Testing
This PR also changes the
overflowexample to display borders on the overflow nodes so you can see how this works:main (The image is clipped at the edges of the node, overwriting the border).
this PR (The image is clipped at the edges of the node's border).
Migration Guide
Migration guide is on #15561