Replace set_clip_path with set_clips_contents method#1627
Replace set_clip_path with set_clips_contents method#1627PoignardAzur wants to merge 7 commits intolinebender:mainfrom
Conversation
| // pub(crate) clip_shape: Option<BezPath>, | ||
| // | ||
| /// Whether the widget and its children's scenes are clipped by the | ||
| /// [clip shape](crate::doc::masonry_concepts#clip-shape). |
There was a problem hiding this comment.
Should this say "clip shape" yet?
There was a problem hiding this comment.
Yeah, the documentation link is already valid.
| - If the widget is set to clip its contents, pointer events outside the clip shape won't affect the children either. | ||
| - If the widget is set to clip its contents, its scene and the children's scenes will be painted inside of the clip shape. | ||
|
|
||
| Currently, the clip shape is hardcoded to be the layout rect. |
There was a problem hiding this comment.
Maybe better to say "the widgets local rect, transformed for rendering" or something since we just say that a layout rect doesn't make sense above.
There was a problem hiding this comment.
True. I think I need to start a discussion about this on Zulip.
Builds on top of linebender#1627.
14c2596 to
3623059
Compare
This changes clipping behavior to a boolean flag, which better matches how it was used so far. A follow-up PR will add set_clip_shape to set arbitrary (even non-Rect) shapes.
3623059 to
b8b49d7
Compare
|
I've rebased on top of the box model rework. I'm not super happy with the result of the rebase (you can kinda tell the PR was meant for the previous coordinate system), and we need some kind of discussion about how to integrate clip shapes into the box model. We can do that before or after merging this PR. Note that one effect of this PR is that the Whether Label and Prose should clip to their border box is another discussion, one that will be tied to how clip shapes fit in the box model. |
xStrom
left a comment
There was a problem hiding this comment.
If you want to land this sooner than later, then I suggest making the bool mean border-box (matches the old behavior). I mention in an inline comment how to get that.
That will get the same old results for Prose and Label. It will (temporarily) regress TextInput but that would be ok.
More generally, I think we should provide easy clip support with more options. I think the three choices from CSS's overflow-clip-margin are all very useful.
- content-box
- padding-box
- border-box
Essentially I can imagine having:
enum Clip {
None,
ContentBox,
PaddingBox,
BorderBox,
Custom(Shape),
}Whether you think it should happen already in this PR I'll leave for you to decide.
I am also willing to implement the various pre-defined box clips myself, given I'm very familiar with the box conversions right now.
| let is_inside_clip_shape = ctx.content_box().contains(local_pos); | ||
|
|
||
| if ctx.clips_contents() && !is_inside_clip_shape { |
There was a problem hiding this comment.
A lot of widgets won't have ctx.clips_contents() as true, right? So we could avoid doing the content box fetching and position checking.
| let is_inside_clip_shape = ctx.content_box().contains(local_pos); | |
| if ctx.clips_contents() && !is_inside_clip_shape { | |
| if ctx.clips_contents() && !ctx.content_box().contains(local_pos) { |
| /// only the painting done in `Widget::paint` by this widget itself will be clipped. | ||
| /// The remaining painting done in `Widget::pre_paint` and `Widget::post_paint` will not be clipped. | ||
| /// - Pointer events must be inside that shape to reach the widget's children. | ||
| /// | ||
| /// This currently returns the border-box rect if `clips_contents` is true and `None` otherwise, but in the future we may want to support more complex clip shapes, in which case this method would need to be updated. | ||
| /// |
There was a problem hiding this comment.
I would prefer to keep these paint methods short and clickable links. Shortness also helps keep the line length under a 100 and links help keep docs fresh.
Similarly, let's break the long sentence into multiple lines so it's below 100.
| /// only the painting done in `Widget::paint` by this widget itself will be clipped. | |
| /// The remaining painting done in `Widget::pre_paint` and `Widget::post_paint` will not be clipped. | |
| /// - Pointer events must be inside that shape to reach the widget's children. | |
| /// | |
| /// This currently returns the border-box rect if `clips_contents` is true and `None` otherwise, but in the future we may want to support more complex clip shapes, in which case this method would need to be updated. | |
| /// | |
| /// only the painting done in [`paint`] by this widget itself will be clipped. | |
| /// The remaining painting done in [`pre_paint`] and [`post_paint`] will not be clipped. | |
| /// - Pointer events must be inside that shape to reach the widget's children. | |
| /// | |
| /// This currently returns the border-box rect if `clips_contents` is true and `None` otherwise, | |
| /// but in the future we may want to support more complex clip shapes, | |
| /// in which case this method would need to be updated. | |
| /// | |
| /// [`paint`]: crate::core::Widget::paint | |
| /// [`pre_paint`]: crate::core::Widget::pre_paint | |
| /// [`post_paint`]: crate::core::Widget::post_paint |
| /// | ||
| /// [clip shape]: crate::doc::masonry_concepts#clip-shape. | ||
| pub(crate) fn clip_shape(&self) -> Rect { | ||
| self.border_box_size().to_rect() - self.border_box_translation() |
There was a problem hiding this comment.
This is wrong, that translation means that it returns the border box rect in content-box coordinate space.
To return the border box rect in border-box coordinate space, you just do this:
| self.border_box_size().to_rect() - self.border_box_translation() | |
| self.border_box_size().to_rect() |
If instead you wanted to actually clip to the content-box rect, then it would be:
| self.border_box_size().to_rect() - self.border_box_translation() | |
| self.border_box_size().to_rect() - self.border_box_insets |
However, then a bunch of comments would need updating as well.
This changes clipping behavior to a boolean flag, which better matches how it was used so far.
A follow-up PR will add set_clip_shape to set arbitrary (even non-Rect) shapes.