diff --git a/egui/src/widgets/text_edit.rs b/egui/src/widgets/text_edit.rs index 025eff02..7a8f8fca 100644 --- a/egui/src/widgets/text_edit.rs +++ b/egui/src/widgets/text_edit.rs @@ -118,7 +118,7 @@ impl CCursorPair { /// an underlying buffer. /// /// Most likely you will use a `String` which implements `TextBuffer`. -pub trait TextBuffer: AsRef + Into { +pub trait TextBuffer: AsRef { /// Can this text be edited? 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);`"] -pub struct TextEdit<'t, S: TextBuffer = String> { - text: &'t mut S, +pub struct TextEdit<'t> { + text: &'t mut dyn TextBuffer, hint_text: String, id: Option, id_source: Option, @@ -271,18 +271,9 @@ pub struct TextEdit<'t, S: TextBuffer = String> { cursor_at_end: bool, } -impl<'t, S: TextBuffer> TextEdit<'t, S> { - pub fn cursor(ui: &Ui, id: Id) -> Option { - ui.memory() - .id_data - .get::(&id) - .and_then(|state| state.cursorp) - } -} - -impl<'t, S: TextBuffer> TextEdit<'t, S> { +impl<'t> TextEdit<'t> { /// 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 { desired_height_rows: 1, 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. - pub fn multiline(text: &'t mut S) -> Self { + pub fn multiline(text: &'t mut dyn TextBuffer) -> Self { Self { text, 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 { + ui.memory() + .id_data + .get::(&id) + .and_then(|state| state.cursorp) + } +} + +impl<'t> Widget for TextEdit<'t> { fn ui(self, ui: &mut Ui) -> Response { let is_mutable = self.text.is_mutable(); 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 { let TextEdit { text, @@ -1038,18 +1038,18 @@ fn byte_index_from_char_index(s: &str, char_index: usize) -> usize { s.len() } -fn insert_text(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); } // ---------------------------------------------------------------------------- -fn delete_selected(text: &mut S, cursorp: &CursorPair) -> CCursor { +fn delete_selected(text: &mut dyn TextBuffer, cursorp: &CursorPair) -> CCursor { let [min, max] = cursorp.sorted(); delete_selected_ccursor_range(text, [min.ccursor, max.ccursor]) } -fn delete_selected_ccursor_range(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); CCursor { index: min.index, @@ -1057,7 +1057,7 @@ fn delete_selected_ccursor_range(text: &mut S, [min, max]: [CCurs } } -fn delete_previous_char(text: &mut S, ccursor: CCursor) -> CCursor { +fn delete_previous_char(text: &mut dyn TextBuffer, ccursor: CCursor) -> CCursor { if ccursor.index > 0 { let max_ccursor = ccursor; let min_ccursor = max_ccursor - 1; @@ -1067,22 +1067,22 @@ fn delete_previous_char(text: &mut S, ccursor: CCursor) -> CCurso } } -fn delete_next_char(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]) } -fn delete_previous_word(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); delete_selected_ccursor_range(text, [min_ccursor, max_ccursor]) } -fn delete_next_word(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); delete_selected_ccursor_range(text, [min_ccursor, max_ccursor]) } -fn delete_paragraph_before_cursor( - text: &mut S, +fn delete_paragraph_before_cursor( + text: &mut dyn TextBuffer, galley: &Galley, cursorp: &CursorPair, ) -> CCursor { @@ -1099,8 +1099,8 @@ fn delete_paragraph_before_cursor( } } -fn delete_paragraph_after_cursor( - text: &mut S, +fn delete_paragraph_after_cursor( + text: &mut dyn TextBuffer, galley: &Galley, cursorp: &CursorPair, ) -> CCursor { @@ -1120,9 +1120,9 @@ fn delete_paragraph_after_cursor( // ---------------------------------------------------------------------------- /// Returns `Some(new_cursor)` if we did mutate `text`. -fn on_key_press( +fn on_key_press( cursorp: &mut CursorPair, - text: &mut S, + text: &mut dyn TextBuffer, galley: &Galley, key: Key, modifiers: &Modifiers, @@ -1365,7 +1365,7 @@ fn find_line_start(text: &str, current_index: CCursor) -> CCursor { } } -fn decrease_identation(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 remove_len = if text.as_ref()[line_start.index..].starts_with('\t') {