Clip text to viewport bounds instead of layout bounds

This commit is contained in:
Héctor Ramón Jiménez 2023-12-01 16:04:27 +01:00
parent 99899d49cc
commit 936d480267
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
23 changed files with 177 additions and 115 deletions

View file

@ -266,7 +266,7 @@ where
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let is_mouse_over = cursor.is_over(layout.bounds());
@ -315,6 +315,7 @@ where
},
bounds.center(),
custom_style.icon_color,
*viewport,
);
}
}
@ -330,6 +331,7 @@ where
crate::text::Appearance {
color: custom_style.text_color,
},
viewport,
);
}
}

View file

@ -224,15 +224,17 @@ where
cursor: mouse::Cursor,
viewport: &Rectangle,
) {
for ((child, state), layout) in self
.children
.iter()
.zip(&tree.children)
.zip(layout.children())
{
child
.as_widget()
.draw(state, renderer, theme, style, layout, cursor, viewport);
if let Some(viewport) = layout.bounds().intersection(viewport) {
for ((child, state), layout) in self
.children
.iter()
.zip(&tree.children)
.zip(layout.children())
{
child.as_widget().draw(
state, renderer, theme, style, layout, cursor, &viewport,
);
}
}
}

View file

@ -622,7 +622,7 @@ where
_style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let is_focused = {
let text_input_state = tree.children[0]
@ -645,6 +645,7 @@ where
layout,
cursor,
selection,
viewport,
);
}

View file

@ -252,21 +252,23 @@ where
) {
let style = theme.appearance(&self.style);
draw_background(renderer, &style, layout.bounds());
if let Some(viewport) = layout.bounds().intersection(viewport) {
draw_background(renderer, &style, layout.bounds());
self.content.as_widget().draw(
tree,
renderer,
theme,
&renderer::Style {
text_color: style
.text_color
.unwrap_or(renderer_style.text_color),
},
layout.children().next().unwrap(),
cursor,
viewport,
);
self.content.as_widget().draw(
tree,
renderer,
theme,
&renderer::Style {
text_color: style
.text_color
.unwrap_or(renderer_style.text_color),
},
layout.children().next().unwrap(),
cursor,
&viewport,
);
}
}
fn overlay<'b>(

View file

@ -544,6 +544,7 @@ where
} else {
appearance.text_color
},
*viewport,
);
}
}

View file

@ -235,7 +235,7 @@ where
_style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let font = self.font.unwrap_or_else(|| renderer.default_font());
draw(
@ -253,6 +253,7 @@ where
&self.handle,
&self.style,
|| tree.state.downcast_ref::<State<Renderer::Paragraph>>(),
viewport,
);
}
@ -631,6 +632,7 @@ pub fn draw<'a, T, Renderer>(
handle: &Handle<Renderer::Font>,
style: &<Renderer::Theme as StyleSheet>::Style,
state: impl FnOnce() -> &'a State<Renderer::Paragraph>,
viewport: &Rectangle,
) where
Renderer: text::Renderer,
Renderer::Theme: StyleSheet,
@ -715,6 +717,7 @@ pub fn draw<'a, T, Renderer>(
bounds.center_y(),
),
style.handle_color,
*viewport,
);
}
@ -743,6 +746,7 @@ pub fn draw<'a, T, Renderer>(
} else {
style.placeholder_color
},
*viewport,
);
}
}

View file

@ -291,7 +291,7 @@ where
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let is_mouse_over = cursor.is_over(layout.bounds());
@ -349,6 +349,7 @@ where
crate::text::Appearance {
color: custom_style.text_color,
},
viewport,
);
}
}

View file

@ -213,15 +213,17 @@ where
cursor: mouse::Cursor,
viewport: &Rectangle,
) {
for ((child, state), layout) in self
.children
.iter()
.zip(&tree.children)
.zip(layout.children())
{
child
.as_widget()
.draw(state, renderer, theme, style, layout, cursor, viewport);
if let Some(viewport) = layout.bounds().intersection(viewport) {
for ((child, state), layout) in self
.children
.iter()
.zip(&tree.children)
.zip(layout.children())
{
child.as_widget().draw(
state, renderer, theme, style, layout, cursor, &viewport,
);
}
}
}

View file

@ -429,7 +429,7 @@ where
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let bounds = layout.bounds();
@ -470,6 +470,7 @@ where
bounds.position()
+ Vector::new(self.padding.left, self.padding.top),
style.text_color,
*viewport,
);
let translation = Vector::new(

View file

@ -238,6 +238,7 @@ where
layout: Layout<'_>,
cursor: mouse::Cursor,
value: Option<&Value>,
viewport: &Rectangle,
) {
draw(
renderer,
@ -250,6 +251,7 @@ where
self.is_secure,
self.icon.as_ref(),
&self.style,
viewport,
);
}
}
@ -362,7 +364,7 @@ where
_style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
draw(
renderer,
@ -375,6 +377,7 @@ where
self.is_secure,
self.icon.as_ref(),
&self.style,
viewport,
);
}
@ -1055,6 +1058,7 @@ pub fn draw<Renderer>(
is_secure: bool,
icon: Option<&Icon<Renderer::Font>>,
style: &<Renderer::Theme as StyleSheet>::Style,
viewport: &Rectangle,
) where
Renderer: text::Renderer,
Renderer::Theme: StyleSheet,
@ -1096,6 +1100,7 @@ pub fn draw<Renderer>(
&state.icon,
icon_layout.bounds().center(),
appearance.icon_color,
*viewport,
);
}
@ -1189,39 +1194,31 @@ pub fn draw<Renderer>(
(None, 0.0)
};
let text_width = state.value.min_width();
let render = |renderer: &mut Renderer| {
if let Some((cursor, color)) = cursor {
renderer.fill_quad(cursor, color);
} else {
renderer.with_translation(Vector::ZERO, |_| {});
}
renderer.fill_paragraph(
if text.is_empty() {
&state.placeholder
} else {
&state.value
},
Point::new(text_bounds.x, text_bounds.center_y()),
if text.is_empty() {
theme.placeholder_color(style)
} else if is_disabled {
theme.disabled_color(style)
} else {
theme.value_color(style)
},
);
};
if text_width > text_bounds.width {
renderer.with_layer(text_bounds, |renderer| {
renderer.with_translation(Vector::new(-offset, 0.0), render);
if let Some((cursor, color)) = cursor {
renderer.with_translation(Vector::new(-offset, 0.0), |renderer| {
renderer.fill_quad(cursor, color)
});
} else {
render(renderer);
renderer.with_translation(Vector::ZERO, |_| {});
}
renderer.fill_paragraph(
if text.is_empty() {
&state.placeholder
} else {
&state.value
},
Point::new(text_bounds.x, text_bounds.center_y())
- Vector::new(offset, 0.0),
if text.is_empty() {
theme.placeholder_color(style)
} else if is_disabled {
theme.disabled_color(style)
} else {
theme.value_color(style)
},
text_bounds,
);
}
/// Computes the current [`mouse::Interaction`] of the [`TextInput`].

View file

@ -266,7 +266,7 @@ where
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
/// Makes sure that the border radius of the toggler looks good at every size.
const BORDER_RADIUS_RATIO: f32 = 32.0 / 13.0;
@ -287,6 +287,7 @@ where
label_layout,
tree.state.downcast_ref(),
crate::text::Appearance::default(),
viewport,
);
}