-
Notifications
You must be signed in to change notification settings - Fork 199
Replace set_clip_path with set_clips_contents method #1627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
29ff678
89d3404
b8b49d7
d244536
a01c659
00e961e
ea6697c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -119,14 +119,17 @@ pub(crate) struct WidgetState { | |||||||||||||||||||||||||||||||||||
| /// The pixel-snapped position of the baseline in the parent's border-box coordinate space. | ||||||||||||||||||||||||||||||||||||
| pub(crate) baseline_y: f64, | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // TODO - Use general Shape | ||||||||||||||||||||||||||||||||||||
| // Currently Kurbo doesn't really provide a type that lets us | ||||||||||||||||||||||||||||||||||||
| // efficiently hold an arbitrary shape. | ||||||||||||||||||||||||||||||||||||
| /// The widget's clip path in the widget's border-box coordinate space. | ||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||
| /// This clips the painting of `Widget::paint` and all the painting of children. | ||||||||||||||||||||||||||||||||||||
| /// It does not clip this widget's `Widget::pre_paint` nor `Widget::post_paint`. | ||||||||||||||||||||||||||||||||||||
| pub(crate) clip_path: Option<Rect>, | ||||||||||||||||||||||||||||||||||||
| // TODO - Add clip_shape | ||||||||||||||||||||||||||||||||||||
| // TODO - Use more efficient type and avoid allocating by default. | ||||||||||||||||||||||||||||||||||||
| // /// The widget's clip path in the widget's border-box coordinate space. | ||||||||||||||||||||||||||||||||||||
| // /// | ||||||||||||||||||||||||||||||||||||
| // /// This clips the painting of `Widget::paint` and all the painting of children. | ||||||||||||||||||||||||||||||||||||
| // /// It does not clip this widget's `Widget::pre_paint` nor `Widget::post_paint`. | ||||||||||||||||||||||||||||||||||||
| // pub(crate) clip_path: Option<Rect>, | ||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||
| /// Whether the widget and its children's scenes are clipped by the | ||||||||||||||||||||||||||||||||||||
| /// [clip shape](crate::doc::masonry_concepts#clip-shape). | ||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this say "clip shape" yet?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the documentation link is already valid. |
||||||||||||||||||||||||||||||||||||
| pub(crate) clips_contents: bool, | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /// Local transform used during the mapping of this widget's border-box coordinate space | ||||||||||||||||||||||||||||||||||||
| /// to the parent's border-box coordinate space. | ||||||||||||||||||||||||||||||||||||
|
|
@@ -275,7 +278,7 @@ impl WidgetState { | |||||||||||||||||||||||||||||||||||
| bounding_box: Rect::ZERO, | ||||||||||||||||||||||||||||||||||||
| layout_baseline_offset: 0.0, | ||||||||||||||||||||||||||||||||||||
| baseline_y: 0.0, | ||||||||||||||||||||||||||||||||||||
| clip_path: Option::default(), | ||||||||||||||||||||||||||||||||||||
| clips_contents: false, | ||||||||||||||||||||||||||||||||||||
| transform: options.transform, | ||||||||||||||||||||||||||||||||||||
| window_transform: Affine::IDENTITY, | ||||||||||||||||||||||||||||||||||||
| scroll_translation: Vec2::ZERO, | ||||||||||||||||||||||||||||||||||||
|
|
@@ -405,24 +408,45 @@ impl WidgetState { | |||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /// Returns the result of intersecting the widget's clip path (if any) with the given rect. | ||||||||||||||||||||||||||||||||||||
| /// Returns the portion of the given rect, if any, that is within the widget's "clip space". | ||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||
| /// Both the argument and the result are in window coordinates. | ||||||||||||||||||||||||||||||||||||
| /// If the widget doesn't clip its children, returns the input rect. | ||||||||||||||||||||||||||||||||||||
| /// If the clip path is a non-rectangle, uses the clip paths' bounding box. | ||||||||||||||||||||||||||||||||||||
| /// If the given rect doesn't intersect with the clipping box, returns `None`. | ||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||
| /// Returns `None` if the given rect is clipped out. | ||||||||||||||||||||||||||||||||||||
| pub(crate) fn clip_child(&self, child_rect: Rect) -> Option<Rect> { | ||||||||||||||||||||||||||||||||||||
| if let Some(clip_path) = self.clip_path { | ||||||||||||||||||||||||||||||||||||
| let clip_path_global = self.window_transform.transform_rect_bbox(clip_path); | ||||||||||||||||||||||||||||||||||||
| if clip_path_global.overlaps(child_rect) { | ||||||||||||||||||||||||||||||||||||
| Some(clip_path_global.intersect(child_rect)) | ||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| /// Both the argument and the result are in window coordinates. | ||||||||||||||||||||||||||||||||||||
| pub(crate) fn clipped_child_box(&self, child_box: Rect) -> Option<Rect> { | ||||||||||||||||||||||||||||||||||||
| if !self.clips_contents { | ||||||||||||||||||||||||||||||||||||
| return Some(child_box); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| let clip_rect = self.border_box_size().to_rect(); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| let bounding_box_global = self.window_transform.transform_rect_bbox(clip_rect); | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| if bounding_box_global.overlaps(child_box) { | ||||||||||||||||||||||||||||||||||||
| Some(bounding_box_global.intersect(child_box)) | ||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||
| Some(child_rect) | ||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| /// The [clip shape] in border-box space. | ||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||
| /// A widget's clip shape will have two effects: | ||||||||||||||||||||||||||||||||||||
| /// - It serves as a mask for painting operations of this widget and its children. | ||||||||||||||||||||||||||||||||||||
| /// Note that while all painting done by children will be clipped by this path, | ||||||||||||||||||||||||||||||||||||
| /// 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. | ||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+439
to
+444
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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.
Suggested change
|
||||||||||||||||||||||||||||||||||||
| /// [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() | ||||||||||||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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:
Suggested change
If instead you wanted to actually clip to the content-box rect, then it would be:
Suggested change
However, then a bunch of comments would need updating as well. |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| pub(crate) fn needs_rewrite_passes(&self) -> bool { | ||||||||||||||||||||||||||||||||||||
| self.needs_layout | ||||||||||||||||||||||||||||||||||||
| || self.needs_compose | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot of widgets won't have
ctx.clips_contents()astrue, right? So we could avoid doing the content box fetching and position checking.