diff options
author | 2024-07-21 12:45:05 +0200 | |
---|---|---|
committer | 2024-07-21 12:45:05 +0200 | |
commit | 9bfaf2840cffe35d689bd115a308d21961ab082a (patch) | |
tree | c9a7b4fc04607c3315dabe3ad2527251b0a3dff8 /graphics | |
parent | 4b44079f34aa9e01977a7974e5f49ae79ff6cd90 (diff) | |
download | iced-9bfaf2840cffe35d689bd115a308d21961ab082a.tar.gz iced-9bfaf2840cffe35d689bd115a308d21961ab082a.tar.bz2 iced-9bfaf2840cffe35d689bd115a308d21961ab082a.zip |
Add `Link` support to `rich_text` widget
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/src/text/paragraph.rs | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index 37fa97f2..b69110b2 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -100,8 +100,8 @@ impl core::text::Paragraph for Paragraph { })) } - fn with_spans(text: Text<&[Span<'_>]>) -> Self { - log::trace!("Allocating rich paragraph: {:?}", text.content); + fn with_spans<Link>(text: Text<&[Span<'_, Link>]>) -> Self { + log::trace!("Allocating rich paragraph: {} spans", text.content.len()); let mut font_system = text::font_system().write().expect("Write font system"); @@ -122,11 +122,9 @@ impl core::text::Paragraph for Paragraph { buffer.set_rich_text( font_system.raw(), - text.content.iter().map(|span| { - let attrs = cosmic_text::Attrs::new(); - + text.content.iter().enumerate().map(|(i, span)| { let attrs = if let Some(font) = span.font { - attrs + cosmic_text::Attrs::new() .family(text::to_family(font.family)) .weight(text::to_weight(font.weight)) .stretch(text::to_stretch(font.stretch)) @@ -156,7 +154,7 @@ impl core::text::Paragraph for Paragraph { attrs }; - (span.text.as_ref(), attrs) + (span.text.as_ref(), attrs.metadata(i)) }), text::to_attributes(text.font), text::to_shaping(text.shaping), @@ -231,6 +229,36 @@ impl core::text::Paragraph for Paragraph { Some(Hit::CharOffset(cursor.index)) } + fn hit_span(&self, point: Point) -> Option<usize> { + let internal = self.internal(); + + let cursor = internal.buffer.hit(point.x, point.y)?; + let line = internal.buffer.lines.get(cursor.line)?; + + let mut last_glyph = None; + let mut glyphs = line + .layout_opt() + .as_ref()? + .iter() + .flat_map(|line| line.glyphs.iter()) + .peekable(); + + while let Some(glyph) = glyphs.peek() { + if glyph.start <= cursor.index && cursor.index < glyph.end { + break; + } + + last_glyph = glyphs.next(); + } + + let glyph = match cursor.affinity { + cosmic_text::Affinity::Before => last_glyph, + cosmic_text::Affinity::After => glyphs.next(), + }?; + + Some(glyph.metadata) + } + fn grapheme_position(&self, line: usize, index: usize) -> Option<Point> { use unicode_segmentation::UnicodeSegmentation; |