diff options
author | 2023-09-12 14:51:00 +0200 | |
---|---|---|
committer | 2023-09-12 14:51:00 +0200 | |
commit | 6448429103c9c82b90040ac5a5a097bdded23f82 (patch) | |
tree | 79582bde4a7d6df71df0abefe35146b06452409f /core | |
parent | 346af3f8b0baa418fd37b878bc2930ff0bd57cc0 (diff) | |
download | iced-6448429103c9c82b90040ac5a5a097bdded23f82.tar.gz iced-6448429103c9c82b90040ac5a5a097bdded23f82.tar.bz2 iced-6448429103c9c82b90040ac5a5a097bdded23f82.zip |
Draft `Editor` API and `TextEditor` widget
Diffstat (limited to 'core')
-rw-r--r-- | core/src/layout/limits.rs | 2 | ||||
-rw-r--r-- | core/src/lib.rs | 2 | ||||
-rw-r--r-- | core/src/renderer/null.rs | 38 | ||||
-rw-r--r-- | core/src/text.rs | 123 | ||||
-rw-r--r-- | core/src/text/editor.rs | 68 | ||||
-rw-r--r-- | core/src/text/paragraph.rs | 59 |
6 files changed, 209 insertions, 83 deletions
diff --git a/core/src/layout/limits.rs b/core/src/layout/limits.rs index 5d3c1556..39a3d98b 100644 --- a/core/src/layout/limits.rs +++ b/core/src/layout/limits.rs @@ -2,7 +2,7 @@ use crate::{Length, Padding, Size}; /// A set of size constraints for layouting. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Limits { min: Size, max: Size, diff --git a/core/src/lib.rs b/core/src/lib.rs index 1bfba7bd..13a9f06b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -12,7 +12,7 @@ #![forbid(unsafe_code, rust_2018_idioms)] #![deny( missing_debug_implementations, - missing_docs, + // missing_docs, unused_results, clippy::extra_unused_lifetimes, clippy::from_over_into, diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index 0ffd3649..adf75969 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -43,6 +43,7 @@ impl Renderer for Null { impl text::Renderer for Null { type Font = Font; type Paragraph = (); + type Editor = (); const ICON_FONT: Font = Font::DEFAULT; const CHECKMARK_ICON: char = '0'; @@ -66,6 +67,14 @@ impl text::Renderer for Null { ) { } + fn fill_editor( + &mut self, + _editor: &Self::Editor, + _position: Point, + _color: Color, + ) { + } + fn fill_text( &mut self, _paragraph: Text<'_, Self::Font>, @@ -106,3 +115,32 @@ impl text::Paragraph for () { None } } + +impl text::Editor for () { + type Font = Font; + + fn with_text(_text: &str) -> Self {} + + fn cursor(&self) -> text::editor::Cursor { + text::editor::Cursor::Caret(Point::ORIGIN) + } + + fn perform(&mut self, _action: text::editor::Action) {} + + fn bounds(&self) -> Size { + Size::ZERO + } + + fn min_bounds(&self) -> Size { + Size::ZERO + } + + fn update( + &mut self, + _new_bounds: Size, + _new_font: Self::Font, + _new_size: Pixels, + _new_line_height: text::LineHeight, + ) { + } +} diff --git a/core/src/text.rs b/core/src/text.rs index ff85696e..5aacbcc5 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -1,4 +1,11 @@ //! Draw and interact with text. +mod paragraph; + +pub mod editor; + +pub use editor::Editor; +pub use paragraph::Paragraph; + use crate::alignment; use crate::{Color, Pixels, Point, Size}; @@ -126,6 +133,31 @@ impl Hit { } } +/// The difference detected in some text. +/// +/// You will obtain a [`Difference`] when you [`compare`] a [`Paragraph`] with some +/// [`Text`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Difference { + /// No difference. + /// + /// The text can be reused as it is! + None, + + /// A bounds difference. + /// + /// This normally means a relayout is necessary, but the shape of the text can + /// be reused. + Bounds, + + /// A shape difference. + /// + /// The contents, alignment, sizes, fonts, or any other essential attributes + /// of the shape of the text have changed. A complete reshape and relayout of + /// the text is necessary. + Shape, +} + /// A renderer capable of measuring and drawing [`Text`]. pub trait Renderer: crate::Renderer { /// The font type used. @@ -134,6 +166,9 @@ pub trait Renderer: crate::Renderer { /// The [`Paragraph`] of this [`Renderer`]. type Paragraph: Paragraph<Font = Self::Font> + 'static; + /// The [`Editor`] of this [`Renderer`]. + type Editor: Editor<Font = Self::Font> + 'static; + /// The icon font of the backend. const ICON_FONT: Self::Font; @@ -165,6 +200,13 @@ pub trait Renderer: crate::Renderer { color: Color, ); + fn fill_editor( + &mut self, + editor: &Self::Editor, + position: Point, + color: Color, + ); + /// Draws the given [`Text`] at the given position and with the given /// [`Color`]. fn fill_text( @@ -174,84 +216,3 @@ pub trait Renderer: crate::Renderer { color: Color, ); } - -/// A text paragraph. -pub trait Paragraph: Sized + Default { - /// The font of this [`Paragraph`]. - type Font: Copy + PartialEq; - - /// Creates a new [`Paragraph`] laid out with the given [`Text`]. - fn with_text(text: Text<'_, Self::Font>) -> Self; - - /// Lays out the [`Paragraph`] with some new boundaries. - fn resize(&mut self, new_bounds: Size); - - /// Compares the [`Paragraph`] with some desired [`Text`] and returns the - /// [`Difference`]. - fn compare(&self, text: Text<'_, Self::Font>) -> Difference; - - /// Returns the horizontal alignment of the [`Paragraph`]. - fn horizontal_alignment(&self) -> alignment::Horizontal; - - /// Returns the vertical alignment of the [`Paragraph`]. - fn vertical_alignment(&self) -> alignment::Vertical; - - /// Returns the minimum boundaries that can fit the contents of the - /// [`Paragraph`]. - fn min_bounds(&self) -> Size; - - /// Tests whether the provided point is within the boundaries of the - /// [`Paragraph`], returning information about the nearest character. - fn hit_test(&self, point: Point) -> Option<Hit>; - - /// 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<'_, Self::Font>) { - match self.compare(text) { - Difference::None => {} - Difference::Bounds => { - self.resize(text.bounds); - } - Difference::Shape => { - *self = Self::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 minimum height that can fit the contents of the [`Paragraph`]. - fn min_height(&self) -> f32 { - self.min_bounds().height - } -} - -/// The difference detected in some text. -/// -/// You will obtain a [`Difference`] when you [`compare`] a [`Paragraph`] with some -/// [`Text`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Difference { - /// No difference. - /// - /// The text can be reused as it is! - None, - - /// A bounds difference. - /// - /// This normally means a relayout is necessary, but the shape of the text can - /// be reused. - Bounds, - - /// A shape difference. - /// - /// The contents, alignment, sizes, fonts, or any other essential attributes - /// of the shape of the text have changed. A complete reshape and relayout of - /// the text is necessary. - Shape, -} diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs new file mode 100644 index 00000000..a4fd0ec1 --- /dev/null +++ b/core/src/text/editor.rs @@ -0,0 +1,68 @@ +use crate::text::LineHeight; +use crate::{Pixels, Point, Rectangle, Size}; + +pub trait Editor: Sized + Default { + type Font: Copy + PartialEq + Default; + + /// Creates a new [`Editor`] laid out with the given text. + fn with_text(text: &str) -> Self; + + fn cursor(&self) -> Cursor; + + fn perform(&mut self, action: Action); + + /// Returns the current boundaries of the [`Editor`]. + fn bounds(&self) -> Size; + + /// Returns the minimum boundaries that can fit the contents of the + /// [`Editor`]. + fn min_bounds(&self) -> Size; + + /// Updates the [`Editor`] with some new attributes. + fn update( + &mut self, + new_bounds: Size, + new_font: Self::Font, + new_size: Pixels, + new_line_height: LineHeight, + ); + + /// Returns the minimum width that can fit the contents of the [`Editor`]. + fn min_width(&self) -> f32 { + self.min_bounds().width + } + + /// Returns the minimum height that can fit the contents of the [`Editor`]. + fn min_height(&self) -> f32 { + self.min_bounds().height + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Action { + MoveLeft, + MoveRight, + MoveUp, + MoveDown, + MoveLeftWord, + MoveRightWord, + MoveHome, + MoveEnd, + SelectWord, + SelectLine, + Insert(char), + Backspace, + Delete, + Click(Point), + Drag(Point), +} + +/// The cursor of an [`Editor`]. +#[derive(Debug, Clone)] +pub enum Cursor { + /// Cursor without a selection + Caret(Point), + + /// Cursor selecting a range of text + Selection(Vec<Rectangle>), +} diff --git a/core/src/text/paragraph.rs b/core/src/text/paragraph.rs new file mode 100644 index 00000000..de1fb74d --- /dev/null +++ b/core/src/text/paragraph.rs @@ -0,0 +1,59 @@ +use crate::alignment; +use crate::text::{Difference, Hit, Text}; +use crate::{Point, Size}; + +/// A text paragraph. +pub trait Paragraph: Sized + Default { + /// The font of this [`Paragraph`]. + type Font: Copy + PartialEq; + + /// Creates a new [`Paragraph`] laid out with the given [`Text`]. + fn with_text(text: Text<'_, Self::Font>) -> Self; + + /// Lays out the [`Paragraph`] with some new boundaries. + fn resize(&mut self, new_bounds: Size); + + /// Compares the [`Paragraph`] with some desired [`Text`] and returns the + /// [`Difference`]. + fn compare(&self, text: Text<'_, Self::Font>) -> Difference; + + /// Returns the horizontal alignment of the [`Paragraph`]. + fn horizontal_alignment(&self) -> alignment::Horizontal; + + /// Returns the vertical alignment of the [`Paragraph`]. + fn vertical_alignment(&self) -> alignment::Vertical; + + /// Returns the minimum boundaries that can fit the contents of the + /// [`Paragraph`]. + fn min_bounds(&self) -> Size; + + /// Tests whether the provided point is within the boundaries of the + /// [`Paragraph`], returning information about the nearest character. + fn hit_test(&self, point: Point) -> Option<Hit>; + + /// 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<'_, Self::Font>) { + match self.compare(text) { + Difference::None => {} + Difference::Bounds => { + self.resize(text.bounds); + } + Difference::Shape => { + *self = Self::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 minimum height that can fit the contents of the [`Paragraph`]. + fn min_height(&self) -> f32 { + self.min_bounds().height + } +} |