bezel

Patterns / Media

Selectable text

Markdown apps/gallery/src/patterns/selectable.rs

use markdown::selectable::{self, Pointer};

selectable::render(
    "message",
    &doc,
    &self.layouts,
    self.selection,
    self.dragging,
    window,
    cx,
    |view, pointer, cx| match pointer {
        Pointer::Down(cursor) => { view.selection = Some(Selection::at(cursor)); view.dragging = true }
        Pointer::Move(cursor) => view.selection = view.selection.map(|s| s.extend_to(cursor)),
        Pointer::Up => view.dragging = false,
    },
)

dragging is yours because a move must only extend a selection a press started — otherwise the pointer drags one just by crossing the text.

Copying

markdown::selectable::copied(&doc, selection)

Plain text, with a newline where each block ended. Not the editor's copy, which is slice then serialize and keeps the markup: a reader who selected the word inside **bold** selected the word.

API

// markdown::selectable

/// The release is answered twice, on the text and off it — a drag ending past
/// the edge of a paragraph is the ordinary way to select to the end of one.
pub fn render<V: 'static>(
    id: impl Into<ElementId>,
    doc: &Doc,
    layouts: &BlockLayouts,
    selection: Option<Selection>,
    dragging: bool,
    window: &mut Window,
    cx: &mut Context<V>,
    on_pointer: impl Fn(&mut V, Pointer, &mut Context<V>) + 'static,
) -> AnyElement;

pub enum Pointer { Down(Cursor), Move(Cursor), Up }

/// Plain text, with a newline where each block ended. `Doc::spans` answers in
/// parts, and joining them puts a multi-block selection back together.
pub fn copied(doc: &Doc, selection: Selection) -> String;

// ...

A screen with several documents on it keeps the selection keyed by item and hands each its own slice of the state — which item a press landed in is not something one block of text can know. caret_on is forced off, or a collapsed selection would blink an insertion point in text nobody can type into.

It lives in markdown rather than ui: it names Doc, Selection, Cursor and BlockLayouts, and ui depends on theme and motion alone.

Selectable text