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

@ -64,6 +64,7 @@ impl text::Renderer for Null {
_paragraph: &Self::Paragraph, _paragraph: &Self::Paragraph,
_position: Point, _position: Point,
_color: Color, _color: Color,
_viewport: Rectangle,
) { ) {
} }
@ -72,6 +73,7 @@ impl text::Renderer for Null {
_editor: &Self::Editor, _editor: &Self::Editor,
_position: Point, _position: Point,
_color: Color, _color: Color,
_viewport: Rectangle,
) { ) {
} }
@ -80,6 +82,7 @@ impl text::Renderer for Null {
_paragraph: Text<'_, Self::Font>, _paragraph: Text<'_, Self::Font>,
_position: Point, _position: Point,
_color: Color, _color: Color,
_viewport: Rectangle,
) { ) {
} }
} }

View file

@ -9,7 +9,7 @@ pub use highlighter::Highlighter;
pub use paragraph::Paragraph; pub use paragraph::Paragraph;
use crate::alignment; use crate::alignment;
use crate::{Color, Pixels, Point, Size}; use crate::{Color, Pixels, Point, Rectangle, Size};
use std::borrow::Cow; use std::borrow::Cow;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
@ -202,6 +202,7 @@ pub trait Renderer: crate::Renderer {
text: &Self::Paragraph, text: &Self::Paragraph,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
); );
/// Draws the given [`Editor`] at the given position and with the given /// Draws the given [`Editor`] at the given position and with the given
@ -211,6 +212,7 @@ pub trait Renderer: crate::Renderer {
editor: &Self::Editor, editor: &Self::Editor,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
); );
/// Draws the given [`Text`] at the given position and with the given /// Draws the given [`Text`] at the given position and with the given
@ -220,5 +222,6 @@ pub trait Renderer: crate::Renderer {
text: Text<'_, Self::Font>, text: Text<'_, Self::Font>,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
); );
} }

View file

@ -172,7 +172,7 @@ where
style: &renderer::Style, style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
_cursor_position: mouse::Cursor, _cursor_position: mouse::Cursor,
_viewport: &Rectangle, viewport: &Rectangle,
) { ) {
let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>(); let state = tree.state.downcast_ref::<State<Renderer::Paragraph>>();
@ -182,6 +182,7 @@ where
layout, layout,
state, state,
theme.appearance(self.style.clone()), theme.appearance(self.style.clone()),
viewport,
); );
} }
} }
@ -244,6 +245,7 @@ pub fn draw<Renderer>(
layout: Layout<'_>, layout: Layout<'_>,
state: &State<Renderer::Paragraph>, state: &State<Renderer::Paragraph>,
appearance: Appearance, appearance: Appearance,
viewport: &Rectangle,
) where ) where
Renderer: text::Renderer, Renderer: text::Renderer,
{ {
@ -266,6 +268,7 @@ pub fn draw<Renderer>(
paragraph, paragraph,
Point::new(x, y), Point::new(x, y),
appearance.color.unwrap_or(style.text_color), appearance.color.unwrap_or(style.text_color),
*viewport,
); );
} }

View file

@ -14,24 +14,26 @@ use std::sync::Arc;
pub enum Primitive<T> { pub enum Primitive<T> {
/// A text primitive /// A text primitive
Text { Text {
/// The contents of the text /// The contents of the text.
content: String, content: String,
/// The bounds of the text /// The bounds of the text.
bounds: Rectangle, bounds: Rectangle,
/// The color of the text /// The color of the text.
color: Color, color: Color,
/// The size of the text in logical pixels /// The size of the text in logical pixels.
size: Pixels, size: Pixels,
/// The line height of the text /// The line height of the text.
line_height: text::LineHeight, line_height: text::LineHeight,
/// The font of the text /// The font of the text.
font: Font, font: Font,
/// The horizontal alignment of the text /// The horizontal alignment of the text.
horizontal_alignment: alignment::Horizontal, horizontal_alignment: alignment::Horizontal,
/// The vertical alignment of the text /// The vertical alignment of the text.
vertical_alignment: alignment::Vertical, vertical_alignment: alignment::Vertical,
/// The shaping strategy of the text. /// The shaping strategy of the text.
shaping: text::Shaping, shaping: text::Shaping,
/// The viewport of the text.
viewport: Rectangle,
}, },
/// A paragraph primitive /// A paragraph primitive
Paragraph { Paragraph {
@ -41,15 +43,19 @@ pub enum Primitive<T> {
position: Point, position: Point,
/// The color of the paragraph. /// The color of the paragraph.
color: Color, color: Color,
/// The viewport of the paragraph.
viewport: Rectangle,
}, },
/// An editor primitive /// An editor primitive
Editor { Editor {
/// The [`editor::Weak`] reference. /// The [`editor::Weak`] reference.
editor: editor::Weak, editor: editor::Weak,
/// The position of the paragraph. /// The position of the editor.
position: Point, position: Point,
/// The color of the paragraph. /// The color of the editor.
color: Color, color: Color,
/// The viewport of the editor.
viewport: Rectangle,
}, },
/// A quad primitive /// A quad primitive
Quad { Quad {

View file

@ -164,11 +164,13 @@ where
paragraph: &Self::Paragraph, paragraph: &Self::Paragraph,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
) { ) {
self.primitives.push(Primitive::Paragraph { self.primitives.push(Primitive::Paragraph {
paragraph: paragraph.downgrade(), paragraph: paragraph.downgrade(),
position, position,
color, color,
viewport,
}); });
} }
@ -177,11 +179,13 @@ where
editor: &Self::Editor, editor: &Self::Editor,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
) { ) {
self.primitives.push(Primitive::Editor { self.primitives.push(Primitive::Editor {
editor: editor.downgrade(), editor: editor.downgrade(),
position, position,
color, color,
viewport,
}); });
} }
@ -190,6 +194,7 @@ where
text: Text<'_, Self::Font>, text: Text<'_, Self::Font>,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
) { ) {
self.primitives.push(Primitive::Text { self.primitives.push(Primitive::Text {
content: text.content.to_string(), content: text.content.to_string(),
@ -201,6 +206,7 @@ where
horizontal_alignment: text.horizontal_alignment, horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment, vertical_alignment: text.vertical_alignment,
shaping: text.shaping, shaping: text.shaping,
viewport,
}); });
} }
} }

View file

@ -175,11 +175,12 @@ impl<T> text::Renderer for Renderer<T> {
paragraph: &Self::Paragraph, paragraph: &Self::Paragraph,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
) { ) {
delegate!( delegate!(
self, self,
renderer, renderer,
renderer.fill_paragraph(paragraph, position, color) renderer.fill_paragraph(paragraph, position, color, viewport)
); );
} }
@ -188,11 +189,12 @@ impl<T> text::Renderer for Renderer<T> {
editor: &Self::Editor, editor: &Self::Editor,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
) { ) {
delegate!( delegate!(
self, self,
renderer, renderer,
renderer.fill_editor(editor, position, color) renderer.fill_editor(editor, position, color, viewport)
); );
} }
@ -201,8 +203,13 @@ impl<T> text::Renderer for Renderer<T> {
text: Text<'_, Self::Font>, text: Text<'_, Self::Font>,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
) { ) {
delegate!(self, renderer, renderer.fill_text(text, position, color)); delegate!(
self,
renderer,
renderer.fill_text(text, position, color, viewport)
);
} }
} }

View file

@ -1,6 +1,6 @@
use crate::core::{Background, Color, Gradient, Rectangle, Vector}; use crate::core::{Background, Color, Gradient, Rectangle, Vector};
use crate::graphics::backend; use crate::graphics::backend;
use crate::graphics::{Damage, Viewport}; use crate::graphics::Viewport;
use crate::primitive::{self, Primitive}; use crate::primitive::{self, Primitive};
use std::borrow::Cow; use std::borrow::Cow;
@ -361,11 +361,9 @@ impl Backend {
paragraph, paragraph,
position, position,
color, color,
viewport,
} => { } => {
let physical_bounds = let physical_bounds = (*viewport + translation) * scale_factor;
(Rectangle::new(*position, paragraph.min_bounds)
+ translation)
* scale_factor;
if !clip_bounds.intersects(&physical_bounds) { if !clip_bounds.intersects(&physical_bounds) {
return; return;
@ -387,10 +385,9 @@ impl Backend {
editor, editor,
position, position,
color, color,
viewport,
} => { } => {
let physical_bounds = let physical_bounds = (*viewport + translation) * scale_factor;
(Rectangle::new(*position, editor.bounds) + translation)
* scale_factor;
if !clip_bounds.intersects(&physical_bounds) { if !clip_bounds.intersects(&physical_bounds) {
return; return;
@ -418,9 +415,9 @@ impl Backend {
horizontal_alignment, horizontal_alignment,
vertical_alignment, vertical_alignment,
shaping, shaping,
viewport,
} => { } => {
let physical_bounds = let physical_bounds = (*viewport + translation) * scale_factor;
(primitive.bounds() + translation) * scale_factor;
if !clip_bounds.intersects(&physical_bounds) { if !clip_bounds.intersects(&physical_bounds) {
return; return;

View file

@ -109,15 +109,17 @@ impl Frame {
Point::new(transformed[0].x, transformed[0].y) Point::new(transformed[0].x, transformed[0].y)
}; };
let bounds = Rectangle {
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
};
// TODO: Use vectorial text instead of primitive // TODO: Use vectorial text instead of primitive
self.primitives.push(Primitive::Text { self.primitives.push(Primitive::Text {
content: text.content, content: text.content,
bounds: Rectangle { bounds,
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
},
color: text.color, color: text.color,
size: text.size, size: text.size,
line_height: text.line_height, line_height: text.line_height,
@ -125,6 +127,7 @@ impl Frame {
horizontal_alignment: text.horizontal_alignment, horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment, vertical_alignment: text.vertical_alignment,
shaping: text.shaping, shaping: text.shaping,
viewport: bounds,
}); });
} }

View file

@ -328,15 +328,17 @@ impl Frame {
Point::new(transformed.x, transformed.y) Point::new(transformed.x, transformed.y)
}; };
let bounds = Rectangle {
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
};
// TODO: Use vectorial text instead of primitive // TODO: Use vectorial text instead of primitive
self.primitives.push(Primitive::Text { self.primitives.push(Primitive::Text {
content: text.content, content: text.content,
bounds: Rectangle { bounds,
x: position.x,
y: position.y,
width: f32::INFINITY,
height: f32::INFINITY,
},
color: text.color, color: text.color,
size: text.size, size: text.size,
line_height: text.line_height, line_height: text.line_height,
@ -344,6 +346,7 @@ impl Frame {
horizontal_alignment: text.horizontal_alignment, horizontal_alignment: text.horizontal_alignment,
vertical_alignment: text.vertical_alignment, vertical_alignment: text.vertical_alignment,
shaping: text.shaping, shaping: text.shaping,
viewport: bounds,
}); });
} }

View file

@ -75,6 +75,7 @@ impl<'a> Layer<'a> {
horizontal_alignment: alignment::Horizontal::Left, horizontal_alignment: alignment::Horizontal::Left,
vertical_alignment: alignment::Vertical::Top, vertical_alignment: alignment::Vertical::Top,
shaping: core::text::Shaping::Basic, shaping: core::text::Shaping::Basic,
viewport: Rectangle::with_size(Size::INFINITY),
}; };
overlay.text.push(Text::Cached(text.clone())); overlay.text.push(Text::Cached(text.clone()));
@ -123,6 +124,7 @@ impl<'a> Layer<'a> {
paragraph, paragraph,
position, position,
color, color,
viewport,
} => { } => {
let layer = &mut layers[current_layer]; let layer = &mut layers[current_layer];
@ -130,12 +132,14 @@ impl<'a> Layer<'a> {
paragraph: paragraph.clone(), paragraph: paragraph.clone(),
position: *position + translation, position: *position + translation,
color: *color, color: *color,
viewport: *viewport + translation,
}); });
} }
Primitive::Editor { Primitive::Editor {
editor, editor,
position, position,
color, color,
viewport,
} => { } => {
let layer = &mut layers[current_layer]; let layer = &mut layers[current_layer];
@ -143,6 +147,7 @@ impl<'a> Layer<'a> {
editor: editor.clone(), editor: editor.clone(),
position: *position + translation, position: *position + translation,
color: *color, color: *color,
viewport: *viewport + translation,
}); });
} }
Primitive::Text { Primitive::Text {
@ -155,6 +160,7 @@ impl<'a> Layer<'a> {
horizontal_alignment, horizontal_alignment,
vertical_alignment, vertical_alignment,
shaping, shaping,
viewport,
} => { } => {
let layer = &mut layers[current_layer]; let layer = &mut layers[current_layer];
@ -168,6 +174,7 @@ impl<'a> Layer<'a> {
horizontal_alignment: *horizontal_alignment, horizontal_alignment: *horizontal_alignment,
vertical_alignment: *vertical_alignment, vertical_alignment: *vertical_alignment,
shaping: *shaping, shaping: *shaping,
viewport: *viewport + translation,
})); }));
} }
Primitive::Quad { Primitive::Quad {

View file

@ -13,6 +13,7 @@ pub enum Text<'a> {
paragraph: paragraph::Weak, paragraph: paragraph::Weak,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
}, },
/// An editor. /// An editor.
#[allow(missing_docs)] #[allow(missing_docs)]
@ -20,6 +21,7 @@ pub enum Text<'a> {
editor: editor::Weak, editor: editor::Weak,
position: Point, position: Point,
color: Color, color: Color,
viewport: Rectangle,
}, },
/// A cached text. /// A cached text.
Cached(Cached<'a>), Cached(Cached<'a>),
@ -53,4 +55,7 @@ pub struct Cached<'a> {
/// The shaping strategy of the text. /// The shaping strategy of the text.
pub shaping: text::Shaping, pub shaping: text::Shaping,
/// The viewport of the text.
pub viewport: Rectangle,
} }

View file

@ -120,9 +120,13 @@ impl Pipeline {
horizontal_alignment, horizontal_alignment,
vertical_alignment, vertical_alignment,
color, color,
viewport,
) = match section { ) = match section {
Text::Paragraph { Text::Paragraph {
position, color, .. position,
color,
viewport,
..
} => { } => {
use crate::core::text::Paragraph as _; use crate::core::text::Paragraph as _;
@ -137,10 +141,14 @@ impl Pipeline {
paragraph.horizontal_alignment(), paragraph.horizontal_alignment(),
paragraph.vertical_alignment(), paragraph.vertical_alignment(),
*color, *color,
*viewport,
) )
} }
Text::Editor { Text::Editor {
position, color, .. position,
color,
viewport,
..
} => { } => {
use crate::core::text::Editor as _; use crate::core::text::Editor as _;
@ -155,6 +163,7 @@ impl Pipeline {
alignment::Horizontal::Left, alignment::Horizontal::Left,
alignment::Vertical::Top, alignment::Vertical::Top,
*color, *color,
*viewport,
) )
} }
Text::Cached(text) => { Text::Cached(text) => {
@ -173,6 +182,7 @@ impl Pipeline {
text.horizontal_alignment, text.horizontal_alignment,
text.vertical_alignment, text.vertical_alignment,
text.color, text.color,
text.viewport,
) )
} }
}; };
@ -195,13 +205,8 @@ impl Pipeline {
alignment::Vertical::Bottom => bounds.y - bounds.height, alignment::Vertical::Bottom => bounds.y - bounds.height,
}; };
let section_bounds = Rectangle { let clip_bounds =
x: left, layer_bounds.intersection(&(viewport * scale_factor))?;
y: top,
..bounds
};
let clip_bounds = layer_bounds.intersection(&section_bounds)?;
Some(glyphon::TextArea { Some(glyphon::TextArea {
buffer, buffer,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -429,7 +429,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();
@ -470,6 +470,7 @@ where
bounds.position() bounds.position()
+ Vector::new(self.padding.left, self.padding.top), + Vector::new(self.padding.left, self.padding.top),
style.text_color, style.text_color,
*viewport,
); );
let translation = Vector::new( let translation = Vector::new(

View file

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

View file

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