TextEdit: replace monomorphization with &mut dyn TextBuffer
This commit is contained in:
parent
8d854391df
commit
613c0b29f6
1 changed files with 31 additions and 31 deletions
|
@ -118,7 +118,7 @@ impl CCursorPair {
|
||||||
/// an underlying buffer.
|
/// an underlying buffer.
|
||||||
///
|
///
|
||||||
/// Most likely you will use a `String` which implements `TextBuffer`.
|
/// Most likely you will use a `String` which implements `TextBuffer`.
|
||||||
pub trait TextBuffer: AsRef<str> + Into<String> {
|
pub trait TextBuffer: AsRef<str> {
|
||||||
/// Can this text be edited?
|
/// Can this text be edited?
|
||||||
fn is_mutable(&self) -> bool;
|
fn is_mutable(&self) -> bool;
|
||||||
|
|
||||||
|
@ -253,8 +253,8 @@ impl<'a> TextBuffer for &'a str {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||||
pub struct TextEdit<'t, S: TextBuffer = String> {
|
pub struct TextEdit<'t> {
|
||||||
text: &'t mut S,
|
text: &'t mut dyn TextBuffer,
|
||||||
hint_text: String,
|
hint_text: String,
|
||||||
id: Option<Id>,
|
id: Option<Id>,
|
||||||
id_source: Option<Id>,
|
id_source: Option<Id>,
|
||||||
|
@ -271,18 +271,9 @@ pub struct TextEdit<'t, S: TextBuffer = String> {
|
||||||
cursor_at_end: bool,
|
cursor_at_end: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
impl<'t> TextEdit<'t> {
|
||||||
pub fn cursor(ui: &Ui, id: Id) -> Option<CursorPair> {
|
|
||||||
ui.memory()
|
|
||||||
.id_data
|
|
||||||
.get::<State>(&id)
|
|
||||||
.and_then(|state| state.cursorp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
|
||||||
/// No newlines (`\n`) allowed. Pressing enter key will result in the `TextEdit` losing focus (`response.lost_focus`).
|
/// No newlines (`\n`) allowed. Pressing enter key will result in the `TextEdit` losing focus (`response.lost_focus`).
|
||||||
pub fn singleline(text: &'t mut S) -> Self {
|
pub fn singleline(text: &'t mut dyn TextBuffer) -> Self {
|
||||||
Self {
|
Self {
|
||||||
desired_height_rows: 1,
|
desired_height_rows: 1,
|
||||||
multiline: false,
|
multiline: false,
|
||||||
|
@ -291,7 +282,7 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `TextEdit` for multiple lines. Pressing enter key will create a new line.
|
/// A `TextEdit` for multiple lines. Pressing enter key will create a new line.
|
||||||
pub fn multiline(text: &'t mut S) -> Self {
|
pub fn multiline(text: &'t mut dyn TextBuffer) -> Self {
|
||||||
Self {
|
Self {
|
||||||
text,
|
text,
|
||||||
hint_text: Default::default(),
|
hint_text: Default::default(),
|
||||||
|
@ -433,7 +424,16 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t, S: TextBuffer> Widget for TextEdit<'t, S> {
|
impl<'t> TextEdit<'t> {
|
||||||
|
pub fn cursor(ui: &Ui, id: Id) -> Option<CursorPair> {
|
||||||
|
ui.memory()
|
||||||
|
.id_data
|
||||||
|
.get::<State>(&id)
|
||||||
|
.and_then(|state| state.cursorp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'t> Widget for TextEdit<'t> {
|
||||||
fn ui(self, ui: &mut Ui) -> Response {
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
let is_mutable = self.text.is_mutable();
|
let is_mutable = self.text.is_mutable();
|
||||||
let frame = self.frame;
|
let frame = self.frame;
|
||||||
|
@ -507,7 +507,7 @@ fn mask_if_password(is_password: bool, text: &str) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
impl<'t> TextEdit<'t> {
|
||||||
fn content_ui(self, ui: &mut Ui) -> Response {
|
fn content_ui(self, ui: &mut Ui) -> Response {
|
||||||
let TextEdit {
|
let TextEdit {
|
||||||
text,
|
text,
|
||||||
|
@ -1038,18 +1038,18 @@ fn byte_index_from_char_index(s: &str, char_index: usize) -> usize {
|
||||||
s.len()
|
s.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_text<S: TextBuffer>(ccursor: &mut CCursor, text: &mut S, text_to_insert: &str) {
|
fn insert_text(ccursor: &mut CCursor, text: &mut dyn TextBuffer, text_to_insert: &str) {
|
||||||
ccursor.index += text.insert_text(text_to_insert, ccursor.index);
|
ccursor.index += text.insert_text(text_to_insert, ccursor.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
fn delete_selected<S: TextBuffer>(text: &mut S, cursorp: &CursorPair) -> CCursor {
|
fn delete_selected(text: &mut dyn TextBuffer, cursorp: &CursorPair) -> CCursor {
|
||||||
let [min, max] = cursorp.sorted();
|
let [min, max] = cursorp.sorted();
|
||||||
delete_selected_ccursor_range(text, [min.ccursor, max.ccursor])
|
delete_selected_ccursor_range(text, [min.ccursor, max.ccursor])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_selected_ccursor_range<S: TextBuffer>(text: &mut S, [min, max]: [CCursor; 2]) -> CCursor {
|
fn delete_selected_ccursor_range(text: &mut dyn TextBuffer, [min, max]: [CCursor; 2]) -> CCursor {
|
||||||
text.delete_char_range(min.index..max.index);
|
text.delete_char_range(min.index..max.index);
|
||||||
CCursor {
|
CCursor {
|
||||||
index: min.index,
|
index: min.index,
|
||||||
|
@ -1057,7 +1057,7 @@ fn delete_selected_ccursor_range<S: TextBuffer>(text: &mut S, [min, max]: [CCurs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_previous_char<S: TextBuffer>(text: &mut S, ccursor: CCursor) -> CCursor {
|
fn delete_previous_char(text: &mut dyn TextBuffer, ccursor: CCursor) -> CCursor {
|
||||||
if ccursor.index > 0 {
|
if ccursor.index > 0 {
|
||||||
let max_ccursor = ccursor;
|
let max_ccursor = ccursor;
|
||||||
let min_ccursor = max_ccursor - 1;
|
let min_ccursor = max_ccursor - 1;
|
||||||
|
@ -1067,22 +1067,22 @@ fn delete_previous_char<S: TextBuffer>(text: &mut S, ccursor: CCursor) -> CCurso
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_next_char<S: TextBuffer>(text: &mut S, ccursor: CCursor) -> CCursor {
|
fn delete_next_char(text: &mut dyn TextBuffer, ccursor: CCursor) -> CCursor {
|
||||||
delete_selected_ccursor_range(text, [ccursor, ccursor + 1])
|
delete_selected_ccursor_range(text, [ccursor, ccursor + 1])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_previous_word<S: TextBuffer>(text: &mut S, max_ccursor: CCursor) -> CCursor {
|
fn delete_previous_word(text: &mut dyn TextBuffer, max_ccursor: CCursor) -> CCursor {
|
||||||
let min_ccursor = ccursor_previous_word(text.as_ref(), max_ccursor);
|
let min_ccursor = ccursor_previous_word(text.as_ref(), max_ccursor);
|
||||||
delete_selected_ccursor_range(text, [min_ccursor, max_ccursor])
|
delete_selected_ccursor_range(text, [min_ccursor, max_ccursor])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_next_word<S: TextBuffer>(text: &mut S, min_ccursor: CCursor) -> CCursor {
|
fn delete_next_word(text: &mut dyn TextBuffer, min_ccursor: CCursor) -> CCursor {
|
||||||
let max_ccursor = ccursor_next_word(text.as_ref(), min_ccursor);
|
let max_ccursor = ccursor_next_word(text.as_ref(), min_ccursor);
|
||||||
delete_selected_ccursor_range(text, [min_ccursor, max_ccursor])
|
delete_selected_ccursor_range(text, [min_ccursor, max_ccursor])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_paragraph_before_cursor<S: TextBuffer>(
|
fn delete_paragraph_before_cursor(
|
||||||
text: &mut S,
|
text: &mut dyn TextBuffer,
|
||||||
galley: &Galley,
|
galley: &Galley,
|
||||||
cursorp: &CursorPair,
|
cursorp: &CursorPair,
|
||||||
) -> CCursor {
|
) -> CCursor {
|
||||||
|
@ -1099,8 +1099,8 @@ fn delete_paragraph_before_cursor<S: TextBuffer>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_paragraph_after_cursor<S: TextBuffer>(
|
fn delete_paragraph_after_cursor(
|
||||||
text: &mut S,
|
text: &mut dyn TextBuffer,
|
||||||
galley: &Galley,
|
galley: &Galley,
|
||||||
cursorp: &CursorPair,
|
cursorp: &CursorPair,
|
||||||
) -> CCursor {
|
) -> CCursor {
|
||||||
|
@ -1120,9 +1120,9 @@ fn delete_paragraph_after_cursor<S: TextBuffer>(
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Returns `Some(new_cursor)` if we did mutate `text`.
|
/// Returns `Some(new_cursor)` if we did mutate `text`.
|
||||||
fn on_key_press<S: TextBuffer>(
|
fn on_key_press(
|
||||||
cursorp: &mut CursorPair,
|
cursorp: &mut CursorPair,
|
||||||
text: &mut S,
|
text: &mut dyn TextBuffer,
|
||||||
galley: &Galley,
|
galley: &Galley,
|
||||||
key: Key,
|
key: Key,
|
||||||
modifiers: &Modifiers,
|
modifiers: &Modifiers,
|
||||||
|
@ -1365,7 +1365,7 @@ fn find_line_start(text: &str, current_index: CCursor) -> CCursor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrease_identation<S: TextBuffer>(ccursor: &mut CCursor, text: &mut S) {
|
fn decrease_identation(ccursor: &mut CCursor, text: &mut dyn TextBuffer) {
|
||||||
let line_start = find_line_start(text.as_ref(), *ccursor);
|
let line_start = find_line_start(text.as_ref(), *ccursor);
|
||||||
|
|
||||||
let remove_len = if text.as_ref()[line_start.index..].starts_with('\t') {
|
let remove_len = if text.as_ref()[line_start.index..].starts_with('\t') {
|
||||||
|
|
Loading…
Reference in a new issue