Merge pull request #2526 from iced-rs/feature/rich-text-underline
Underline support for `rich_text`
This commit is contained in:
commit
ebc6c0eba8
2 changed files with 78 additions and 20 deletions
|
|
@ -245,6 +245,8 @@ pub struct Span<'a, Link = (), Font = crate::Font> {
|
||||||
///
|
///
|
||||||
/// Currently, it only affects the bounds of the [`Highlight`].
|
/// Currently, it only affects the bounds of the [`Highlight`].
|
||||||
pub padding: Padding,
|
pub padding: Padding,
|
||||||
|
/// Whether the [`Span`] should be underlined or not.
|
||||||
|
pub underline: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A text highlight.
|
/// A text highlight.
|
||||||
|
|
@ -268,6 +270,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
|
||||||
highlight: None,
|
highlight: None,
|
||||||
link: None,
|
link: None,
|
||||||
padding: Padding::ZERO,
|
padding: Padding::ZERO,
|
||||||
|
underline: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -386,6 +389,12 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets whether the [`Span`] shoud be underlined or not.
|
||||||
|
pub fn underline(mut self, underline: bool) -> Self {
|
||||||
|
self.underline = underline;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Turns the [`Span`] into a static one.
|
/// Turns the [`Span`] into a static one.
|
||||||
pub fn to_static(self) -> Span<'static, Link, Font> {
|
pub fn to_static(self) -> Span<'static, Link, Font> {
|
||||||
Span {
|
Span {
|
||||||
|
|
@ -397,6 +406,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
|
||||||
link: self.link,
|
link: self.link,
|
||||||
highlight: self.highlight,
|
highlight: self.highlight,
|
||||||
padding: self.padding,
|
padding: self.padding,
|
||||||
|
underline: self.underline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ where
|
||||||
theme: &Theme,
|
theme: &Theme,
|
||||||
defaults: &renderer::Style,
|
defaults: &renderer::Style,
|
||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
_cursor_position: mouse::Cursor,
|
cursor: mouse::Cursor,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) {
|
) {
|
||||||
let state = tree
|
let state = tree
|
||||||
|
|
@ -246,29 +246,77 @@ where
|
||||||
|
|
||||||
let style = theme.style(&self.class);
|
let style = theme.style(&self.class);
|
||||||
|
|
||||||
|
let hovered_span = cursor
|
||||||
|
.position_in(layout.bounds())
|
||||||
|
.and_then(|position| state.paragraph.hit_span(position));
|
||||||
|
|
||||||
for (index, span) in self.spans.iter().enumerate() {
|
for (index, span) in self.spans.iter().enumerate() {
|
||||||
if let Some(highlight) = span.highlight {
|
let is_hovered_link =
|
||||||
|
span.link.is_some() && Some(index) == hovered_span;
|
||||||
|
|
||||||
|
if span.highlight.is_some() || span.underline || is_hovered_link {
|
||||||
let translation = layout.position() - Point::ORIGIN;
|
let translation = layout.position() - Point::ORIGIN;
|
||||||
|
let regions = state.paragraph.span_bounds(index);
|
||||||
|
|
||||||
for bounds in state.paragraph.span_bounds(index) {
|
if let Some(highlight) = span.highlight {
|
||||||
let bounds = Rectangle::new(
|
for bounds in ®ions {
|
||||||
bounds.position()
|
let bounds = Rectangle::new(
|
||||||
- Vector::new(span.padding.left, span.padding.top),
|
bounds.position()
|
||||||
bounds.size()
|
- Vector::new(
|
||||||
+ Size::new(
|
span.padding.left,
|
||||||
span.padding.horizontal(),
|
span.padding.top,
|
||||||
span.padding.vertical(),
|
),
|
||||||
),
|
bounds.size()
|
||||||
);
|
+ Size::new(
|
||||||
|
span.padding.horizontal(),
|
||||||
|
span.padding.vertical(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
renderer.fill_quad(
|
renderer.fill_quad(
|
||||||
renderer::Quad {
|
renderer::Quad {
|
||||||
bounds: bounds + translation,
|
bounds: bounds + translation,
|
||||||
border: highlight.border,
|
border: highlight.border,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
highlight.background,
|
highlight.background,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if span.underline || is_hovered_link {
|
||||||
|
let size = span
|
||||||
|
.size
|
||||||
|
.or(self.size)
|
||||||
|
.unwrap_or(renderer.default_size());
|
||||||
|
|
||||||
|
let line_height = span
|
||||||
|
.line_height
|
||||||
|
.unwrap_or(self.line_height)
|
||||||
|
.to_absolute(size);
|
||||||
|
|
||||||
|
for bounds in regions {
|
||||||
|
renderer.fill_quad(
|
||||||
|
renderer::Quad {
|
||||||
|
bounds: Rectangle::new(
|
||||||
|
bounds.position()
|
||||||
|
+ translation
|
||||||
|
+ Vector::new(
|
||||||
|
0.0,
|
||||||
|
size.0
|
||||||
|
+ (line_height.0 - size.0)
|
||||||
|
/ 2.0
|
||||||
|
- size.0 * 0.08,
|
||||||
|
),
|
||||||
|
Size::new(bounds.width, 1.0),
|
||||||
|
),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
span.color
|
||||||
|
.or(style.color)
|
||||||
|
.unwrap_or(defaults.text_color),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue