summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-07-17 18:47:58 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-07-17 18:50:53 +0200
commitffb520fb3703ce4ece9fb6d5ee2c7aa0b846879f (patch)
tree2f840fba3f2bb72e3d255c2778f88dd324cc0f4e /core
parent616689ca54942a13aac3615e571ae995ad4571b6 (diff)
downloadiced-ffb520fb3703ce4ece9fb6d5ee2c7aa0b846879f.tar.gz
iced-ffb520fb3703ce4ece9fb6d5ee2c7aa0b846879f.tar.bz2
iced-ffb520fb3703ce4ece9fb6d5ee2c7aa0b846879f.zip
Decouple caching from `Paragraph` API
Diffstat (limited to '')
-rw-r--r--core/src/renderer/null.rs2
-rw-r--r--core/src/text.rs3
-rw-r--r--core/src/text/paragraph.rs86
-rw-r--r--core/src/widget/text.rs11
4 files changed, 83 insertions, 19 deletions
diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs
index e8709dbc..560b5b43 100644
--- a/core/src/renderer/null.rs
+++ b/core/src/renderer/null.rs
@@ -79,7 +79,7 @@ impl text::Paragraph for () {
fn resize(&mut self, _new_bounds: Size) {}
- fn compare(&self, _text: Text<&str>) -> text::Difference {
+ fn compare(&self, _text: Text<()>) -> text::Difference {
text::Difference::None
}
diff --git a/core/src/text.rs b/core/src/text.rs
index b30feae0..e437a635 100644
--- a/core/src/text.rs
+++ b/core/src/text.rs
@@ -1,8 +1,7 @@
//! Draw and interact with text.
-mod paragraph;
-
pub mod editor;
pub mod highlighter;
+pub mod paragraph;
pub use editor::Editor;
pub use highlighter::Highlighter;
diff --git a/core/src/text/paragraph.rs b/core/src/text/paragraph.rs
index 8ff04015..66cadb5c 100644
--- a/core/src/text/paragraph.rs
+++ b/core/src/text/paragraph.rs
@@ -1,3 +1,4 @@
+//! Draw paragraphs.
use crate::alignment;
use crate::text::{Difference, Hit, Text};
use crate::{Point, Size};
@@ -15,7 +16,7 @@ pub trait Paragraph: Sized + Default {
/// Compares the [`Paragraph`] with some desired [`Text`] and returns the
/// [`Difference`].
- fn compare(&self, text: Text<&str, Self::Font>) -> Difference;
+ fn compare(&self, text: Text<(), Self::Font>) -> Difference;
/// Returns the horizontal alignment of the [`Paragraph`].
fn horizontal_alignment(&self) -> alignment::Horizontal;
@@ -34,26 +35,87 @@ pub trait Paragraph: Sized + Default {
/// Returns the distance to the given grapheme index in the [`Paragraph`].
fn grapheme_position(&self, line: usize, index: usize) -> Option<Point>;
- /// Updates the [`Paragraph`] to match the given [`Text`], if needed.
- fn update(&mut self, text: Text<&str, Self::Font>) {
- match self.compare(text) {
+ /// Returns the minimum width that can fit the contents of the [`Paragraph`].
+ fn min_width(&self) -> f32 {
+ self.min_bounds().width
+ }
+
+ /// Returns the minimum height that can fit the contents of the [`Paragraph`].
+ fn min_height(&self) -> f32 {
+ self.min_bounds().height
+ }
+}
+
+/// A [`Paragraph`] of plain text.
+#[derive(Debug, Clone, Default)]
+pub struct Plain<P: Paragraph> {
+ raw: P,
+ content: String,
+}
+
+impl<P: Paragraph> Plain<P> {
+ /// Creates a new [`Plain`] paragraph.
+ pub fn new(text: Text<&str, P::Font>) -> Self {
+ let content = text.content.to_owned();
+
+ Self {
+ raw: P::with_text(text),
+ content,
+ }
+ }
+
+ /// Updates the plain [`Paragraph`] to match the given [`Text`], if needed.
+ pub fn update(&mut self, text: Text<&str, P::Font>) {
+ if self.content != text.content {
+ text.content.clone_into(&mut self.content);
+ self.raw = P::with_text(text);
+ return;
+ }
+
+ match self.raw.compare(Text {
+ content: (),
+ bounds: text.bounds,
+ size: text.size,
+ line_height: text.line_height,
+ font: text.font,
+ horizontal_alignment: text.horizontal_alignment,
+ vertical_alignment: text.vertical_alignment,
+ shaping: text.shaping,
+ }) {
Difference::None => {}
Difference::Bounds => {
- self.resize(text.bounds);
+ self.raw.resize(text.bounds);
}
Difference::Shape => {
- *self = Self::with_text(text);
+ self.raw = P::with_text(text);
}
}
}
- /// Returns the minimum width that can fit the contents of the [`Paragraph`].
- fn min_width(&self) -> f32 {
- self.min_bounds().width
+ /// Returns the horizontal alignment of the [`Paragraph`].
+ pub fn horizontal_alignment(&self) -> alignment::Horizontal {
+ self.raw.horizontal_alignment()
}
- /// Returns the minimum height that can fit the contents of the [`Paragraph`].
- fn min_height(&self) -> f32 {
- self.min_bounds().height
+ /// Returns the vertical alignment of the [`Paragraph`].
+ pub fn vertical_alignment(&self) -> alignment::Vertical {
+ self.raw.vertical_alignment()
+ }
+
+ /// Returns the minimum boundaries that can fit the contents of the
+ /// [`Paragraph`].
+ pub fn min_bounds(&self) -> Size {
+ self.raw.min_bounds()
+ }
+
+ /// Returns the minimum width that can fit the contents of the
+ /// [`Paragraph`].
+ pub fn min_width(&self) -> f32 {
+ self.raw.min_width()
+ }
+
+ /// Returns the cached [`Paragraph`].
+ pub fn raw(&self) -> &P {
+ &self.raw
}
}
diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs
index 91c9893d..2aeb0765 100644
--- a/core/src/widget/text.rs
+++ b/core/src/widget/text.rs
@@ -3,7 +3,8 @@ use crate::alignment;
use crate::layout;
use crate::mouse;
use crate::renderer;
-use crate::text::{self, Paragraph};
+use crate::text;
+use crate::text::paragraph::{self, Paragraph};
use crate::widget::tree::{self, Tree};
use crate::{
Color, Element, Layout, Length, Pixels, Point, Rectangle, Size, Theme,
@@ -155,7 +156,7 @@ where
/// The internal state of a [`Text`] widget.
#[derive(Debug, Default)]
-pub struct State<P: Paragraph>(P);
+pub struct State<P: Paragraph>(paragraph::Plain<P>);
impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
for Text<'a, Theme, Renderer>
@@ -168,7 +169,9 @@ where
}
fn state(&self) -> tree::State {
- tree::State::new(State(Renderer::Paragraph::default()))
+ tree::State::new(State::<Renderer::Paragraph>(
+ paragraph::Plain::default(),
+ ))
}
fn size(&self) -> Size<Length> {
@@ -294,7 +297,7 @@ pub fn draw<Renderer>(
};
renderer.fill_paragraph(
- paragraph,
+ paragraph.raw(),
Point::new(x, y),
appearance.color.unwrap_or(style.text_color),
*viewport,