iced_core/text/editor.rs
1//! Edit text.
2use crate::text::highlighter::{self, Highlighter};
3use crate::text::{LineHeight, Wrapping};
4use crate::{Pixels, Point, Rectangle, Size};
5
6use std::sync::Arc;
7
8/// A component that can be used by widgets to edit multi-line text.
9pub trait Editor: Sized + Default {
10 /// The font of the [`Editor`].
11 type Font: Copy + PartialEq + Default;
12
13 /// Creates a new [`Editor`] laid out with the given text.
14 fn with_text(text: &str) -> Self;
15
16 /// Returns true if the [`Editor`] has no contents.
17 fn is_empty(&self) -> bool;
18
19 /// Returns the current [`Cursor`] of the [`Editor`].
20 fn cursor(&self) -> Cursor;
21
22 /// Returns the current cursor position of the [`Editor`].
23 ///
24 /// Line and column, respectively.
25 fn cursor_position(&self) -> (usize, usize);
26
27 /// Returns the current selected text of the [`Editor`].
28 fn selection(&self) -> Option<String>;
29
30 /// Returns the text of the given line in the [`Editor`], if it exists.
31 fn line(&self, index: usize) -> Option<&str>;
32
33 /// Returns the amount of lines in the [`Editor`].
34 fn line_count(&self) -> usize;
35
36 /// Performs an [`Action`] on the [`Editor`].
37 fn perform(&mut self, action: Action);
38
39 /// Returns the current boundaries of the [`Editor`].
40 fn bounds(&self) -> Size;
41
42 /// Returns the minimum boundaries to fit the current contents of
43 /// the [`Editor`].
44 fn min_bounds(&self) -> Size;
45
46 /// Updates the [`Editor`] with some new attributes.
47 fn update(
48 &mut self,
49 new_bounds: Size,
50 new_font: Self::Font,
51 new_size: Pixels,
52 new_line_height: LineHeight,
53 new_wrapping: Wrapping,
54 new_highlighter: &mut impl Highlighter,
55 );
56
57 /// Runs a text [`Highlighter`] in the [`Editor`].
58 fn highlight<H: Highlighter>(
59 &mut self,
60 font: Self::Font,
61 highlighter: &mut H,
62 format_highlight: impl Fn(&H::Highlight) -> highlighter::Format<Self::Font>,
63 );
64}
65
66/// An interaction with an [`Editor`].
67#[derive(Debug, Clone, PartialEq)]
68pub enum Action {
69 /// Apply a [`Motion`].
70 Move(Motion),
71 /// Select text with a given [`Motion`].
72 Select(Motion),
73 /// Select the word at the current cursor.
74 SelectWord,
75 /// Select the line at the current cursor.
76 SelectLine,
77 /// Select the entire buffer.
78 SelectAll,
79 /// Perform an [`Edit`].
80 Edit(Edit),
81 /// Click the [`Editor`] at the given [`Point`].
82 Click(Point),
83 /// Drag the mouse on the [`Editor`] to the given [`Point`].
84 Drag(Point),
85 /// Scroll the [`Editor`] a certain amount of lines.
86 Scroll {
87 /// The amount of lines to scroll.
88 lines: i32,
89 },
90}
91
92impl Action {
93 /// Returns whether the [`Action`] is an editing action.
94 pub fn is_edit(&self) -> bool {
95 matches!(self, Self::Edit(_))
96 }
97}
98
99/// An action that edits text.
100#[derive(Debug, Clone, PartialEq)]
101pub enum Edit {
102 /// Insert the given character.
103 Insert(char),
104 /// Paste the given text.
105 Paste(Arc<String>),
106 /// Break the current line.
107 Enter,
108 /// Delete the previous character.
109 Backspace,
110 /// Delete the next character.
111 Delete,
112}
113
114/// A cursor movement.
115#[derive(Debug, Clone, Copy, PartialEq)]
116pub enum Motion {
117 /// Move left.
118 Left,
119 /// Move right.
120 Right,
121 /// Move up.
122 Up,
123 /// Move down.
124 Down,
125 /// Move to the left boundary of a word.
126 WordLeft,
127 /// Move to the right boundary of a word.
128 WordRight,
129 /// Move to the start of the line.
130 Home,
131 /// Move to the end of the line.
132 End,
133 /// Move to the start of the previous window.
134 PageUp,
135 /// Move to the start of the next window.
136 PageDown,
137 /// Move to the start of the text.
138 DocumentStart,
139 /// Move to the end of the text.
140 DocumentEnd,
141}
142
143impl Motion {
144 /// Widens the [`Motion`], if possible.
145 pub fn widen(self) -> Self {
146 match self {
147 Self::Left => Self::WordLeft,
148 Self::Right => Self::WordRight,
149 Self::Home => Self::DocumentStart,
150 Self::End => Self::DocumentEnd,
151 _ => self,
152 }
153 }
154
155 /// Returns the [`Direction`] of the [`Motion`].
156 pub fn direction(&self) -> Direction {
157 match self {
158 Self::Left
159 | Self::Up
160 | Self::WordLeft
161 | Self::Home
162 | Self::PageUp
163 | Self::DocumentStart => Direction::Left,
164 Self::Right
165 | Self::Down
166 | Self::WordRight
167 | Self::End
168 | Self::PageDown
169 | Self::DocumentEnd => Direction::Right,
170 }
171 }
172}
173
174/// A direction in some text.
175#[derive(Debug, Clone, Copy, PartialEq, Eq)]
176pub enum Direction {
177 /// <-
178 Left,
179 /// ->
180 Right,
181}
182
183/// The cursor of an [`Editor`].
184#[derive(Debug, Clone)]
185pub enum Cursor {
186 /// Cursor without a selection
187 Caret(Point),
188
189 /// Cursor selecting a range of text
190 Selection(Vec<Rectangle>),
191}