diff options
| author | 2024-07-17 18:47:58 +0200 | |
|---|---|---|
| committer | 2024-07-17 18:50:53 +0200 | |
| commit | ffb520fb3703ce4ece9fb6d5ee2c7aa0b846879f (patch) | |
| tree | 2f840fba3f2bb72e3d255c2778f88dd324cc0f4e /core | |
| parent | 616689ca54942a13aac3615e571ae995ad4571b6 (diff) | |
| download | iced-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.rs | 2 | ||||
| -rw-r--r-- | core/src/text.rs | 3 | ||||
| -rw-r--r-- | core/src/text/paragraph.rs | 86 | ||||
| -rw-r--r-- | core/src/widget/text.rs | 11 | 
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,  | 
