Add Link support to rich_text widget

This commit is contained in:
Héctor Ramón Jiménez 2024-07-21 12:45:05 +02:00
parent 4b44079f34
commit 9bfaf2840c
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
9 changed files with 287 additions and 71 deletions

View file

@ -77,8 +77,8 @@ impl text::Paragraph for () {
fn with_text(_text: Text<&str>) -> Self {}
fn with_spans(
_text: Text<&[text::Span<'_, Self::Font>], Self::Font>,
fn with_spans<Link>(
_text: Text<&[text::Span<'_, Link, Self::Font>], Self::Font>,
) -> Self {
}
@ -107,6 +107,10 @@ impl text::Paragraph for () {
fn hit_test(&self, _point: Point) -> Option<text::Hit> {
None
}
fn hit_span(&self, _point: Point) -> Option<usize> {
None
}
}
impl text::Editor for () {

View file

@ -223,8 +223,8 @@ pub trait Renderer: crate::Renderer {
}
/// A span of text.
#[derive(Debug, Clone, PartialEq)]
pub struct Span<'a, Font = crate::Font> {
#[derive(Debug, Clone)]
pub struct Span<'a, Link = (), Font = crate::Font> {
/// The [`Fragment`] of text.
pub text: Fragment<'a>,
/// The size of the [`Span`] in [`Pixels`].
@ -235,9 +235,11 @@ pub struct Span<'a, Font = crate::Font> {
pub font: Option<Font>,
/// The [`Color`] of the [`Span`].
pub color: Option<Color>,
/// The link of the [`Span`].
pub link: Option<Link>,
}
impl<'a, Font> Span<'a, Font> {
impl<'a, Link, Font> Span<'a, Link, Font> {
/// Creates a new [`Span`] of text with the given text fragment.
pub fn new(fragment: impl IntoFragment<'a>) -> Self {
Self {
@ -246,6 +248,7 @@ impl<'a, Font> Span<'a, Font> {
line_height: None,
font: None,
color: None,
link: None,
}
}
@ -285,14 +288,27 @@ impl<'a, Font> Span<'a, Font> {
self
}
/// Sets the link of the [`Span`].
pub fn link(mut self, link: impl Into<Link>) -> Self {
self.link = Some(link.into());
self
}
/// Sets the link of the [`Span`], if any.
pub fn link_maybe(mut self, link: Option<impl Into<Link>>) -> Self {
self.link = link.map(Into::into);
self
}
/// Turns the [`Span`] into a static one.
pub fn to_static(self) -> Span<'static, Font> {
pub fn to_static(self) -> Span<'static, Link, Font> {
Span {
text: Cow::Owned(self.text.into_owned()),
size: self.size,
line_height: self.line_height,
font: self.font,
color: self.color,
link: self.link,
}
}
}
@ -303,6 +319,16 @@ impl<'a, Font> From<&'a str> for Span<'a, Font> {
}
}
impl<'a, Link, Font: PartialEq> PartialEq for Span<'a, Link, Font> {
fn eq(&self, other: &Self) -> bool {
self.text == other.text
&& self.size == other.size
&& self.line_height == other.line_height
&& self.font == other.font
&& self.color == other.color
}
}
/// A fragment of [`Text`].
///
/// This is just an alias to a string that may be either

View file

@ -12,7 +12,9 @@ pub trait Paragraph: Sized + Default {
fn with_text(text: Text<&str, Self::Font>) -> Self;
/// Creates a new [`Paragraph`] laid out with the given [`Text`].
fn with_spans(text: Text<&[Span<'_, Self::Font>], Self::Font>) -> Self;
fn with_spans<Link>(
text: Text<&[Span<'_, Link, Self::Font>], Self::Font>,
) -> Self;
/// Lays out the [`Paragraph`] with some new boundaries.
fn resize(&mut self, new_bounds: Size);
@ -35,6 +37,11 @@ pub trait Paragraph: Sized + Default {
/// [`Paragraph`], returning information about the nearest character.
fn hit_test(&self, point: Point) -> Option<Hit>;
/// Tests whether the provided point is within the boundaries of a
/// [`Span`] in the [`Paragraph`], returning the index of the [`Span`]
/// that was hit.
fn hit_span(&self, point: Point) -> Option<usize>;
/// Returns the distance to the given grapheme index in the [`Paragraph`].
fn grapheme_position(&self, line: usize, index: usize) -> Option<Point>;