Merge pull request #2252 from iced-rs/feature/clip-property

Add `clip` property to `Container`, `Column`, and `Row`
This commit is contained in:
Héctor Ramón 2024-02-15 01:48:36 +01:00 committed by GitHub
commit 5827023ccc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 75 additions and 8 deletions

View file

@ -47,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Support for generic `Element` in `Tooltip`. [#2228](https://github.com/iced-rs/iced/pull/2228) - Support for generic `Element` in `Tooltip`. [#2228](https://github.com/iced-rs/iced/pull/2228)
- Container and `gap` styling for `Scrollable`. [#2239](https://github.com/iced-rs/iced/pull/2239) - Container and `gap` styling for `Scrollable`. [#2239](https://github.com/iced-rs/iced/pull/2239)
- Use `Borrow` for both `options` and `selected` in PickList. [#2251](https://github.com/iced-rs/iced/pull/2251) - Use `Borrow` for both `options` and `selected` in PickList. [#2251](https://github.com/iced-rs/iced/pull/2251)
- `clip` property for `Container`, `Column`, `Row`, and `Button`. #[2252](https://github.com/iced-rs/iced/pull/2252)
### Changed ### Changed
- Enable WebGPU backend in `wgpu` by default instead of WebGL. [#2068](https://github.com/iced-rs/iced/pull/2068) - Enable WebGPU backend in `wgpu` by default instead of WebGL. [#2068](https://github.com/iced-rs/iced/pull/2068)

View file

@ -61,6 +61,7 @@ where
width: Length, width: Length,
height: Length, height: Length,
padding: Padding, padding: Padding,
clip: bool,
style: Theme::Style, style: Theme::Style,
} }
@ -82,6 +83,7 @@ where
width: size.width.fluid(), width: size.width.fluid(),
height: size.height.fluid(), height: size.height.fluid(),
padding: Padding::new(5.0), padding: Padding::new(5.0),
clip: false,
style: Theme::Style::default(), style: Theme::Style::default(),
} }
} }
@ -126,6 +128,13 @@ where
self.style = style.into(); self.style = style.into();
self self
} }
/// Sets whether the contents of the [`Button`] should be clipped on
/// overflow.
pub fn clip(mut self, clip: bool) -> Self {
self.clip = clip;
self
}
} }
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer> impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
@ -227,7 +236,7 @@ where
_style: &renderer::Style, _style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
_viewport: &Rectangle, viewport: &Rectangle,
) { ) {
let bounds = layout.bounds(); let bounds = layout.bounds();
let content_layout = layout.children().next().unwrap(); let content_layout = layout.children().next().unwrap();
@ -242,6 +251,12 @@ where
|| tree.state.downcast_ref::<State>(), || tree.state.downcast_ref::<State>(),
); );
let viewport = if self.clip {
bounds.intersection(viewport).unwrap_or(*viewport)
} else {
*viewport
};
self.content.as_widget().draw( self.content.as_widget().draw(
&tree.children[0], &tree.children[0],
renderer, renderer,
@ -251,7 +266,7 @@ where
}, },
content_layout, content_layout,
cursor, cursor,
&bounds, &viewport,
); );
} }

View file

@ -20,6 +20,7 @@ pub struct Column<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
height: Length, height: Length,
max_width: f32, max_width: f32,
align_items: Alignment, align_items: Alignment,
clip: bool,
children: Vec<Element<'a, Message, Theme, Renderer>>, children: Vec<Element<'a, Message, Theme, Renderer>>,
} }
@ -36,6 +37,7 @@ where
height: Length::Shrink, height: Length::Shrink,
max_width: f32::INFINITY, max_width: f32::INFINITY,
align_items: Alignment::Start, align_items: Alignment::Start,
clip: false,
children: Vec::new(), children: Vec::new(),
} }
} }
@ -87,6 +89,13 @@ where
self self
} }
/// Sets whether the contents of the [`Column`] should be clipped on
/// overflow.
pub fn clip(mut self, clip: bool) -> Self {
self.clip = clip;
self
}
/// Adds an element to the [`Column`]. /// Adds an element to the [`Column`].
pub fn push( pub fn push(
mut self, mut self,
@ -240,7 +249,7 @@ where
cursor: mouse::Cursor, cursor: mouse::Cursor,
viewport: &Rectangle, viewport: &Rectangle,
) { ) {
if let Some(viewport) = layout.bounds().intersection(viewport) { if let Some(clipped_viewport) = layout.bounds().intersection(viewport) {
for ((child, state), layout) in self for ((child, state), layout) in self
.children .children
.iter() .iter()
@ -248,7 +257,17 @@ where
.zip(layout.children()) .zip(layout.children())
{ {
child.as_widget().draw( child.as_widget().draw(
state, renderer, theme, style, layout, cursor, &viewport, state,
renderer,
theme,
style,
layout,
cursor,
if self.clip {
&clipped_viewport
} else {
viewport
},
); );
} }
} }

View file

@ -37,6 +37,7 @@ pub struct Container<
horizontal_alignment: alignment::Horizontal, horizontal_alignment: alignment::Horizontal,
vertical_alignment: alignment::Vertical, vertical_alignment: alignment::Vertical,
style: Theme::Style, style: Theme::Style,
clip: bool,
content: Element<'a, Message, Theme, Renderer>, content: Element<'a, Message, Theme, Renderer>,
} }
@ -63,6 +64,7 @@ where
horizontal_alignment: alignment::Horizontal::Left, horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top, vertical_alignment: alignment::Vertical::Top,
style: Default::default(), style: Default::default(),
clip: false,
content, content,
} }
} }
@ -132,6 +134,13 @@ where
self.style = style.into(); self.style = style.into();
self self
} }
/// Sets whether the contents of the [`Container`] should be clipped on
/// overflow.
pub fn clip(mut self, clip: bool) -> Self {
self.clip = clip;
self
}
} }
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer> impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
@ -255,7 +264,7 @@ where
) { ) {
let style = theme.appearance(&self.style); let style = theme.appearance(&self.style);
if let Some(viewport) = layout.bounds().intersection(viewport) { if let Some(clipped_viewport) = layout.bounds().intersection(viewport) {
draw_background(renderer, &style, layout.bounds()); draw_background(renderer, &style, layout.bounds());
self.content.as_widget().draw( self.content.as_widget().draw(
@ -269,7 +278,11 @@ where
}, },
layout.children().next().unwrap(), layout.children().next().unwrap(),
cursor, cursor,
&viewport, if self.clip {
&clipped_viewport
} else {
viewport
},
); );
} }
} }

View file

@ -18,6 +18,7 @@ pub struct Row<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer> {
width: Length, width: Length,
height: Length, height: Length,
align_items: Alignment, align_items: Alignment,
clip: bool,
children: Vec<Element<'a, Message, Theme, Renderer>>, children: Vec<Element<'a, Message, Theme, Renderer>>,
} }
@ -33,6 +34,7 @@ where
width: Length::Shrink, width: Length::Shrink,
height: Length::Shrink, height: Length::Shrink,
align_items: Alignment::Start, align_items: Alignment::Start,
clip: false,
children: Vec::new(), children: Vec::new(),
} }
} }
@ -78,6 +80,13 @@ where
self self
} }
/// Sets whether the contents of the [`Row`] should be clipped on
/// overflow.
pub fn clip(mut self, clip: bool) -> Self {
self.clip = clip;
self
}
/// Adds an [`Element`] to the [`Row`]. /// Adds an [`Element`] to the [`Row`].
pub fn push( pub fn push(
mut self, mut self,
@ -229,7 +238,7 @@ where
cursor: mouse::Cursor, cursor: mouse::Cursor,
viewport: &Rectangle, viewport: &Rectangle,
) { ) {
if let Some(viewport) = layout.bounds().intersection(viewport) { if let Some(clipped_viewport) = layout.bounds().intersection(viewport) {
for ((child, state), layout) in self for ((child, state), layout) in self
.children .children
.iter() .iter()
@ -237,7 +246,17 @@ where
.zip(layout.children()) .zip(layout.children())
{ {
child.as_widget().draw( child.as_widget().draw(
state, renderer, theme, style, layout, cursor, &viewport, state,
renderer,
theme,
style,
layout,
cursor,
if self.clip {
&clipped_viewport
} else {
viewport
},
); );
} }
} }