Skip to main content

Editor

Struct Editor 

Source
pub struct Editor { /* private fields */ }
Expand description

One text buffer bound to a signal, over any number of paragraphs.

The editor holds the text and the selection; the signal mirrors the text without any composing preedit. Every mutating method writes the signal, so Editor::text and the signal always agree. A write to the signal from outside is applied with Editor::set_text, which replaces the text and moves the caret to the end.

The editor lays out lazily and per paragraph: an edit drops the layouts of the paragraphs it touched, and the next call that needs geometry rebuilds them, alone. A document far larger than the screen costs an edit only the work its own lines take.

§Panics

Every method that edits the text, moves the caret or reads geometry can build layouts, so it runs the thread’s TextSystem and panics under the conditions of TextSystem::with, in particular when called from inside another with call on the same thread. No input text or edit sequence panics.

Implementations§

Source§

impl Editor

Source

pub fn new(value: RwSignal<String>) -> Editor

Creates an editor bound to value, starting empty.

The text the signal holds is not read: an editor starts empty and fills when its widget applies the signal’s current value. Binding value through a widget does that on mount.

Source

pub fn single_line(value: RwSignal<String>) -> Editor

Creates an editor of one line bound to value, starting empty.

The editor works as Editor::new makes it, except that every line break in text that reaches it becomes one space: typed or committed text, a paste and a write through Editor::set_text alike, with a carriage return and line feed pair counted as one break. The bound signal is written with the line the editor kept. A preedit an input method is composing is shown as the method sends it, since it is not the editor’s text until it commits.

use smudge_core::reactive::{RwSignal, prelude::*};
use smudge_text::{Editor, TextSystem};

TextSystem::bundled_only().install();
let value = RwSignal::new(String::new());
let editor = Editor::single_line(value.clone());
editor.paste("one\ntwo");
assert_eq!(value.get(), "one two");
Source

pub fn value(&self) -> RwSignal<String>

Returns the signal the text is bound to.

Source

pub fn set_style(&self, style: &TextStyle)

Applies style to the text the editor lays out.

The next layout rebuild picks the style up. Changing the font size changes what the editor measures, so a widget applies this before it measures.

Source

pub fn set_wrap_width(&self, width: Option<f32>)

Sets the width the editor wraps its lines to, in logical pixels, or None to lay each paragraph out as one unbroken line.

An editor starts unwrapped. The paragraphs already laid out break their lines again at the new width without shaping their text again, and the caret and selection geometry follow. The same width again does nothing.

Source

pub fn text(&self) -> String

Returns the text of the editor, without any composing preedit.

Source

pub fn is_empty(&self) -> bool

Returns whether the editor holds no text.

Source

pub fn has_text(&self, text: &str) -> bool

Returns whether the editor holds exactly text.

Source

pub fn raw_text(&self) -> String

Returns the text of the editor, including any composing preedit.

Source

pub fn selection(&self) -> Range<usize> ⓘ

Returns the byte range of the selection, into Editor::raw_text.

The range is empty and both ends equal when the caret is collapsed.

Source

pub fn is_composing(&self) -> bool

Returns whether an input method is composing text in the editor.

Source

pub fn ime_area(&self) -> Rect

Returns the area the input method should anchor to, in the editor’s own coordinates.

This bounds the preedit while one is being composed, and the selected part of the focused line otherwise, inflated a little so a candidate window does not jump while the user types.

Source

pub fn compose_geometry(&self) -> Vec<Rect>

Returns one rectangle per piece of the composing preedit, in the editor’s own coordinates, for the underline drawn beneath it.

The rectangles sit just below the baseline of each piece, in visual order, and the list is empty while no input method is composing.

Source

pub fn set_text(&self, text: &str)

Replaces the whole text and moves the caret to the end.

This is how an outside write to the bound signal reaches the editor: the user typed somewhere else, or the application replaced the value. The selection collapses at the end, because a selection into text the editor no longer has means nothing. The undo history is cleared, so undo never brings back text the application replaced, and any composition stops, because the text it was composing into is gone.

Every carriage return and line feed pair, and every lone carriage return, becomes one line feed, or every line break one space in a single-line editor, and the bound signal is written with the text the editor kept.

Source

pub fn insert(&self, text: &str)

Inserts text at the caret, replacing the selection.

Typed characters group into one undo step until the caret moves, a different edit runs, or a whitespace character starts the next step, so undo removes text a word at a time. Inserting more than one character at once, as a paste does, is a step of its own. The text may hold line breaks, which cut the document into more paragraphs. A carriage return and line feed pair, or a lone carriage return, is inserted as one line feed. A single-line editor inserts every line break as one space instead.

Source

pub fn paste(&self, text: &str)

Inserts text from a clipboard, replacing the selection, as one undo step.

Line breaks in the text cut the document into more paragraphs, with a carriage return and line feed pair, or a lone carriage return, taken as one line feed. A single-line editor pastes every line break as one space instead, so a paste from a multi-line source lands on its one line. An empty paste inserts nothing.

Source

pub fn delete_selection(&self)

Deletes the selected text, or nothing when the caret is collapsed.

This is the deletion a cut pairs with the copy, and it is an undo step of its own.

Source

pub fn selected_text(&self) -> Option<String>

Returns the selected text, or None when the selection is collapsed.

Source

pub fn compose(&self, text: &str, cursor: Option<(usize, usize)>)

Shows, updates or clears the text an input method is composing.

Non-empty text becomes the preedit, which replaces the previous preedit, and cursor, the byte range of the input method’s cursor inside text, moves the caret into the preedit, or hides it when None. A composition that starts over a selection deletes the selection first, the way typing over it would, and that deletion is an undo step of its own. Empty text removes the preedit and leaves the caret where the preedit started.

The preedit is not the editor’s text: Editor::text leaves it out and the bound signal is not written, so a canceled or lost composition leaves the value as it was. Only Editor::commit makes composing text stick.

Cursor offsets past the end of text, or inside one of its characters, which a broken input method could report, are clamped or snapped to the text.

Source

pub fn commit(&self, text: &str)

Commits text from an input method, replacing any preedit with it.

A commit can arrive while the preedit is still showing, in which case the committed text takes its place, or after the platform already cleared it, in which case it is inserted at the caret. The committed text groups for undo like typed text: one character joins the word around it, and longer text is a step of its own. An empty commit only removes the preedit.

Source

pub fn backspace(&self)

Deletes one grapheme before the caret, or the selection.

A backspace before a combining mark takes the mark off first, and one after a line break joins the two lines. Repeated deletes group into one undo step until the caret moves or a different edit runs.

Source

pub fn backspace_word(&self)

Deletes one word before the caret, or the selection, as one undo step.

Source

pub fn delete(&self)

Deletes one grapheme after the caret, or the selection.

A delete before a line break joins the two lines. Repeated deletes group into one undo step until the caret moves or a different edit runs.

Source

pub fn delete_word(&self)

Deletes one word after the caret, or the selection, as one undo step.

Source

pub fn undo(&self)

Undoes the last undo step, restoring the text and the selection from before it, or does nothing when there is none.

Nothing is undone while an input method is composing, because the composition owns the text around the caret until it commits.

Source

pub fn redo(&self)

Redoes the last undone step, or does nothing when there is none.

Any edit after an undo discards the steps it could have redone.

Source

pub fn move_left(&self)

Moves the caret one grapheme to the left, in visual order.

Source

pub fn move_right(&self)

Moves the caret one grapheme to the right, in visual order.

Source

pub fn move_word_left(&self)

Moves the caret one word to the left, in visual order.

Source

pub fn move_word_right(&self)

Moves the caret one word to the right, in visual order.

Source

pub fn move_up(&self)

Moves the caret one visual line up, keeping its horizontal position.

Source

pub fn move_down(&self)

Moves the caret one visual line down, keeping its horizontal position.

Source

pub fn move_lines(&self, lines: isize)

Moves the caret lines visual lines down, or up when negative, keeping its horizontal position where the move can.

Source

pub fn move_to_start(&self)

Moves the caret to the start of the text.

Source

pub fn move_to_end(&self)

Moves the caret to the end of the text.

Source

pub fn move_to_line_start(&self)

Moves the caret to the start of the visual line it sits on.

A paragraph wrapped over several lines moves within the wrapped line, not to the start of the paragraph.

Source

pub fn move_to_line_end(&self)

Moves the caret to the end of the visual line it sits on.

The end of a wrapped line sits after the space the line broke at, on the same line.

Source

pub fn extend_left(&self)

Moves the selection focus one grapheme to the left.

Source

pub fn extend_right(&self)

Moves the selection focus one grapheme to the right.

Source

pub fn extend_word_left(&self)

Moves the selection focus one word to the left.

Source

pub fn extend_word_right(&self)

Moves the selection focus one word to the right.

Source

pub fn extend_up(&self)

Moves the selection focus one visual line up.

Source

pub fn extend_down(&self)

Moves the selection focus one visual line down.

Source

pub fn extend_lines(&self, lines: isize)

Moves the selection focus lines visual lines down, or up when negative.

Source

pub fn extend_to_start(&self)

Moves the selection focus to the start of the text.

Source

pub fn extend_to_end(&self)

Moves the selection focus to the end of the text.

Source

pub fn extend_to_line_start(&self)

Moves the selection focus to the start of the visual line it sits on.

Source

pub fn extend_to_line_end(&self)

Moves the selection focus to the end of the visual line it sits on.

Source

pub fn select_all(&self)

Selects the whole text.

Source

pub fn move_to_point(&self, x: f32, y: f32)

Places the caret at the point, in the editor’s own coordinates.

The coordinates are relative to the top left of the text, which a widget gets by subtracting where it draws the text from the pointer position. A point below the last line places the caret at the end of its paragraph, and one past a line’s end places it at that line’s end.

Source

pub fn extend_to_point(&self, x: f32, y: f32)

Moves the selection focus to the point, in the editor’s own coordinates, keeping the anchor where it was.

The extension follows the granularity a double or triple click left the selection at: by cluster after a plain drag, and by word after a double click.

Source

pub fn select_word_at_point(&self, x: f32, y: f32)

Selects the word under the point, in the editor’s own coordinates.

Source

pub fn cursor_geometry(&self, width: f32) -> Option<Rect>

Returns the rectangle of the caret, width logical pixels wide, in the editor’s own coordinates, or None when there is no caret.

A caret an input method hid, by composing without a cursor, is none.

Source

pub fn selection_geometry(&self) -> Vec<Rect>

Returns one rectangle per selected piece of a line, in the editor’s own coordinates.

A collapsed selection yields no rectangles.

Source

pub fn layout_size(&self) -> Size

Returns the width and height of the laid out text.

The width is the longest paragraph, and the height is the sum of every paragraph’s lines.

§Panics

Panics under the conditions of TextSystem::with.

Source

pub fn glyph_runs_at(&self, origin: Point, color: Color) -> Vec<GlyphRun>

Converts the laid out text into glyph runs at origin, in paint order, with every run in color.

origin is where the top left corner of the text box goes, in the caller’s paint coordinates. A widget that paints a large document walks Editor::paragraphs instead and builds the runs of the paragraphs it shows, so an edit elsewhere does not rebuild them.

§Panics

Panics under the conditions of TextSystem::with, in particular when called from inside another with call on the same thread.

Source

pub fn paragraphs(&self, f: impl FnMut(EditorParagraph<'_>))

Walks the editor’s laid out paragraphs, top to bottom, handing each to f.

A painter walks these to build its glyph runs one paragraph at a time: each paragraph carries a stamp that changes when its layout does, so a cache keyed on the stamp rebuilds only the paragraphs an edit touched, and a painter that shows part of the text builds the paragraphs it shows alone.

§Panics

Panics under the conditions of TextSystem::with.

Auto Trait Implementations§

§

impl !Freeze for Editor

§

impl !RefUnwindSafe for Editor

§

impl !Send for Editor

§

impl !Sync for Editor

§

impl !UnwindSafe for Editor

§

impl Forget for Editor

§

impl Move for Editor

§

impl Unpin for Editor

§

impl UnsafeUnpin for Editor

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.