Merge pull request #2528 from iced-rs/feature/rich-text-strikethrough
Strikethrough support for `rich_text`
This commit is contained in:
commit
7445b97df5
3 changed files with 73 additions and 28 deletions
|
|
@ -247,6 +247,8 @@ pub struct Span<'a, Link = (), Font = crate::Font> {
|
||||||
pub padding: Padding,
|
pub padding: Padding,
|
||||||
/// Whether the [`Span`] should be underlined or not.
|
/// Whether the [`Span`] should be underlined or not.
|
||||||
pub underline: bool,
|
pub underline: bool,
|
||||||
|
/// Whether the [`Span`] should be struck through or not.
|
||||||
|
pub strikethrough: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A text highlight.
|
/// A text highlight.
|
||||||
|
|
@ -271,6 +273,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
|
||||||
link: None,
|
link: None,
|
||||||
padding: Padding::ZERO,
|
padding: Padding::ZERO,
|
||||||
underline: false,
|
underline: false,
|
||||||
|
strikethrough: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -395,6 +398,12 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets whether the [`Span`] shoud be struck through or not.
|
||||||
|
pub fn strikethrough(mut self, strikethrough: bool) -> Self {
|
||||||
|
self.strikethrough = strikethrough;
|
||||||
|
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 {
|
||||||
|
|
@ -407,6 +416,7 @@ impl<'a, Link, Font> Span<'a, Link, Font> {
|
||||||
highlight: self.highlight,
|
highlight: self.highlight,
|
||||||
padding: self.padding,
|
padding: self.padding,
|
||||||
underline: self.underline,
|
underline: self.underline,
|
||||||
|
strikethrough: self.strikethrough,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ pub fn parse(
|
||||||
let mut spans = Vec::new();
|
let mut spans = Vec::new();
|
||||||
let mut strong = false;
|
let mut strong = false;
|
||||||
let mut emphasis = false;
|
let mut emphasis = false;
|
||||||
|
let mut strikethrough = false;
|
||||||
let mut metadata = false;
|
let mut metadata = false;
|
||||||
let mut table = false;
|
let mut table = false;
|
||||||
let mut link = None;
|
let mut link = None;
|
||||||
|
|
@ -59,7 +60,8 @@ pub fn parse(
|
||||||
markdown,
|
markdown,
|
||||||
pulldown_cmark::Options::ENABLE_YAML_STYLE_METADATA_BLOCKS
|
pulldown_cmark::Options::ENABLE_YAML_STYLE_METADATA_BLOCKS
|
||||||
| pulldown_cmark::Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS
|
| pulldown_cmark::Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS
|
||||||
| pulldown_cmark::Options::ENABLE_TABLES,
|
| pulldown_cmark::Options::ENABLE_TABLES
|
||||||
|
| pulldown_cmark::Options::ENABLE_STRIKETHROUGH,
|
||||||
);
|
);
|
||||||
|
|
||||||
let produce = |lists: &mut Vec<List>, item| {
|
let produce = |lists: &mut Vec<List>, item| {
|
||||||
|
|
@ -90,6 +92,10 @@ pub fn parse(
|
||||||
emphasis = true;
|
emphasis = true;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
pulldown_cmark::Tag::Strikethrough if !metadata && !table => {
|
||||||
|
strikethrough = true;
|
||||||
|
None
|
||||||
|
}
|
||||||
pulldown_cmark::Tag::Link { dest_url, .. }
|
pulldown_cmark::Tag::Link { dest_url, .. }
|
||||||
if !metadata && !table =>
|
if !metadata && !table =>
|
||||||
{
|
{
|
||||||
|
|
@ -155,12 +161,16 @@ pub fn parse(
|
||||||
Item::Heading(level, spans.drain(..).collect()),
|
Item::Heading(level, spans.drain(..).collect()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
pulldown_cmark::TagEnd::Strong if !metadata && !table => {
|
||||||
|
strong = false;
|
||||||
|
None
|
||||||
|
}
|
||||||
pulldown_cmark::TagEnd::Emphasis if !metadata && !table => {
|
pulldown_cmark::TagEnd::Emphasis if !metadata && !table => {
|
||||||
emphasis = false;
|
emphasis = false;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
pulldown_cmark::TagEnd::Strong if !metadata && !table => {
|
pulldown_cmark::TagEnd::Strikethrough if !metadata && !table => {
|
||||||
strong = false;
|
strikethrough = false;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
pulldown_cmark::TagEnd::Link if !metadata && !table => {
|
pulldown_cmark::TagEnd::Link if !metadata && !table => {
|
||||||
|
|
@ -227,7 +237,7 @@ pub fn parse(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = span(text.into_string());
|
let span = span(text.into_string()).strikethrough(strikethrough);
|
||||||
|
|
||||||
let span = if strong || emphasis {
|
let span = if strong || emphasis {
|
||||||
span.font(Font {
|
span.font(Font {
|
||||||
|
|
@ -263,7 +273,8 @@ pub fn parse(
|
||||||
.color(Color::WHITE)
|
.color(Color::WHITE)
|
||||||
.background(color!(0x111111))
|
.background(color!(0x111111))
|
||||||
.border(border::rounded(2))
|
.border(border::rounded(2))
|
||||||
.padding(padding::left(2).right(2));
|
.padding(padding::left(2).right(2))
|
||||||
|
.strikethrough(strikethrough);
|
||||||
|
|
||||||
let span = if let Some(link) = link.as_ref() {
|
let span = if let Some(link) = link.as_ref() {
|
||||||
span.color(palette.primary).link(link.clone())
|
span.color(palette.primary).link(link.clone())
|
||||||
|
|
@ -275,7 +286,7 @@ pub fn parse(
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
pulldown_cmark::Event::SoftBreak if !metadata && !table => {
|
pulldown_cmark::Event::SoftBreak if !metadata && !table => {
|
||||||
spans.push(span(" "));
|
spans.push(span(" ").strikethrough(strikethrough));
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
pulldown_cmark::Event::HardBreak if !metadata && !table => {
|
pulldown_cmark::Event::HardBreak if !metadata && !table => {
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,11 @@ where
|
||||||
let is_hovered_link =
|
let is_hovered_link =
|
||||||
span.link.is_some() && Some(index) == hovered_span;
|
span.link.is_some() && Some(index) == hovered_span;
|
||||||
|
|
||||||
if span.highlight.is_some() || span.underline || is_hovered_link {
|
if span.highlight.is_some()
|
||||||
|
|| span.underline
|
||||||
|
|| span.strikethrough
|
||||||
|
|| is_hovered_link
|
||||||
|
{
|
||||||
let translation = layout.position() - Point::ORIGIN;
|
let translation = layout.position() - Point::ORIGIN;
|
||||||
let regions = state.paragraph.span_bounds(index);
|
let regions = state.paragraph.span_bounds(index);
|
||||||
|
|
||||||
|
|
@ -284,7 +288,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if span.underline || is_hovered_link {
|
if span.underline || span.strikethrough || is_hovered_link {
|
||||||
let size = span
|
let size = span
|
||||||
.size
|
.size
|
||||||
.or(self.size)
|
.or(self.size)
|
||||||
|
|
@ -295,27 +299,47 @@ where
|
||||||
.unwrap_or(self.line_height)
|
.unwrap_or(self.line_height)
|
||||||
.to_absolute(size);
|
.to_absolute(size);
|
||||||
|
|
||||||
for bounds in regions {
|
let color = span
|
||||||
renderer.fill_quad(
|
.color
|
||||||
renderer::Quad {
|
.or(style.color)
|
||||||
bounds: Rectangle::new(
|
.unwrap_or(defaults.text_color);
|
||||||
bounds.position()
|
|
||||||
+ translation
|
let baseline = translation
|
||||||
+ Vector::new(
|
+ Vector::new(
|
||||||
0.0,
|
0.0,
|
||||||
size.0
|
size.0 + (line_height.0 - size.0) / 2.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),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if span.underline || is_hovered_link {
|
||||||
|
for bounds in ®ions {
|
||||||
|
renderer.fill_quad(
|
||||||
|
renderer::Quad {
|
||||||
|
bounds: Rectangle::new(
|
||||||
|
bounds.position() + baseline
|
||||||
|
- Vector::new(0.0, size.0 * 0.08),
|
||||||
|
Size::new(bounds.width, 1.0),
|
||||||
|
),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if span.strikethrough {
|
||||||
|
for bounds in ®ions {
|
||||||
|
renderer.fill_quad(
|
||||||
|
renderer::Quad {
|
||||||
|
bounds: Rectangle::new(
|
||||||
|
bounds.position() + baseline
|
||||||
|
- Vector::new(0.0, size.0 / 2.0),
|
||||||
|
Size::new(bounds.width, 1.0),
|
||||||
|
),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
color,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue