Remove dependency on AsRef trait for TextBuffer (#1824)

This commit is contained in:
Nicolas Musset 2022-08-02 20:35:37 +02:00 committed by GitHub
parent e39410c37f
commit e288ca86fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 24 deletions

View file

@ -378,7 +378,7 @@ impl<'t> TextEdit<'t> {
// .unwrap_or_else(|| ui.style().interact(&response).text_color()); // too bright // .unwrap_or_else(|| ui.style().interact(&response).text_color()); // too bright
.unwrap_or_else(|| ui.visuals().widgets.inactive.text_color()); .unwrap_or_else(|| ui.visuals().widgets.inactive.text_color());
let prev_text = text.as_ref().to_owned(); let prev_text = text.as_str().to_owned();
let font_id = font_selection.resolve(ui.style()); let font_id = font_selection.resolve(ui.style());
let row_height = ui.fonts().row_height(&font_id); let row_height = ui.fonts().row_height(&font_id);
@ -403,7 +403,7 @@ impl<'t> TextEdit<'t> {
let layouter = layouter.unwrap_or(&mut default_layouter); let layouter = layouter.unwrap_or(&mut default_layouter);
let mut galley = layouter(ui, text.as_ref(), wrap_width); let mut galley = layouter(ui, text.as_str(), wrap_width);
let desired_width = if multiline { let desired_width = if multiline {
galley.size().x.max(wrap_width) // always show everything in multiline galley.size().x.max(wrap_width) // always show everything in multiline
@ -473,7 +473,7 @@ impl<'t> TextEdit<'t> {
if response.double_clicked() { if response.double_clicked() {
// Select word: // Select word:
let center = cursor_at_pointer; let center = cursor_at_pointer;
let ccursor_range = select_word_at(text.as_ref(), center.ccursor); let ccursor_range = select_word_at(text.as_str(), center.ccursor);
state.set_cursor_range(Some(CursorRange { state.set_cursor_range(Some(CursorRange {
primary: galley.from_ccursor(ccursor_range.primary), primary: galley.from_ccursor(ccursor_range.primary),
secondary: galley.from_ccursor(ccursor_range.secondary), secondary: galley.from_ccursor(ccursor_range.secondary),
@ -481,7 +481,7 @@ impl<'t> TextEdit<'t> {
} else if response.triple_clicked() { } else if response.triple_clicked() {
// Select line: // Select line:
let center = cursor_at_pointer; let center = cursor_at_pointer;
let ccursor_range = select_line_at(text.as_ref(), center.ccursor); let ccursor_range = select_line_at(text.as_str(), center.ccursor);
state.set_cursor_range(Some(CursorRange { state.set_cursor_range(Some(CursorRange {
primary: galley.from_ccursor(ccursor_range.primary), primary: galley.from_ccursor(ccursor_range.primary),
secondary: galley.from_ccursor(ccursor_range.secondary), secondary: galley.from_ccursor(ccursor_range.secondary),
@ -584,7 +584,7 @@ impl<'t> TextEdit<'t> {
if ui.is_rect_visible(rect) { if ui.is_rect_visible(rect) {
painter.galley(text_draw_pos, galley.clone()); painter.galley(text_draw_pos, galley.clone());
if text.as_ref().is_empty() && !hint_text.is_empty() { if text.as_str().is_empty() && !hint_text.is_empty() {
let hint_text_color = ui.visuals().weak_text_color(); let hint_text_color = ui.visuals().weak_text_color();
let galley = if multiline { let galley = if multiline {
hint_text.into_galley(ui, Some(true), desired_size.x, font_id) hint_text.into_galley(ui, Some(true), desired_size.x, font_id)
@ -703,7 +703,7 @@ fn events(
// so that the undoer creates automatic saves even when there are no events for a while. // so that the undoer creates automatic saves even when there are no events for a while.
state.undoer.lock().feed_state( state.undoer.lock().feed_state(
ui.input().time, ui.input().time,
&(cursor_range.as_ccursor_range(), text.as_ref().to_owned()), &(cursor_range.as_ccursor_range(), text.as_str().to_owned()),
); );
let copy_if_not_password = |ui: &Ui, text: String| { let copy_if_not_password = |ui: &Ui, text: String| {
@ -719,7 +719,7 @@ fn events(
let did_mutate_text = match event { let did_mutate_text = match event {
Event::Copy => { Event::Copy => {
if cursor_range.is_empty() { if cursor_range.is_empty() {
copy_if_not_password(ui, text.as_ref().to_owned()); copy_if_not_password(ui, text.as_str().to_owned());
} else { } else {
copy_if_not_password(ui, selected_str(text, &cursor_range).to_owned()); copy_if_not_password(ui, selected_str(text, &cursor_range).to_owned());
} }
@ -795,7 +795,7 @@ fn events(
if let Some((undo_ccursor_range, undo_txt)) = state if let Some((undo_ccursor_range, undo_txt)) = state
.undoer .undoer
.lock() .lock()
.undo(&(cursor_range.as_ccursor_range(), text.as_ref().to_owned())) .undo(&(cursor_range.as_ccursor_range(), text.as_str().to_owned()))
{ {
text.replace(undo_txt); text.replace(undo_txt);
Some(*undo_ccursor_range) Some(*undo_ccursor_range)
@ -849,7 +849,7 @@ fn events(
any_change = true; any_change = true;
// Layout again to avoid frame delay, and to keep `text` and `galley` in sync. // Layout again to avoid frame delay, and to keep `text` and `galley` in sync.
*galley = layouter(ui, text.as_ref(), wrap_width); *galley = layouter(ui, text.as_str(), wrap_width);
// Set cursor_range using new galley: // Set cursor_range using new galley:
cursor_range = CursorRange { cursor_range = CursorRange {
@ -863,7 +863,7 @@ fn events(
state.undoer.lock().feed_state( state.undoer.lock().feed_state(
ui.input().time, ui.input().time,
&(cursor_range.as_ccursor_range(), text.as_ref().to_owned()), &(cursor_range.as_ccursor_range(), text.as_str().to_owned()),
); );
(any_change, cursor_range) (any_change, cursor_range)
@ -993,12 +993,12 @@ fn delete_next_char(text: &mut dyn TextBuffer, ccursor: CCursor) -> CCursor {
} }
fn delete_previous_word(text: &mut dyn TextBuffer, 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_str(), max_ccursor);
delete_selected_ccursor_range(text, [min_ccursor, max_ccursor]) delete_selected_ccursor_range(text, [min_ccursor, max_ccursor])
} }
fn delete_next_word(text: &mut dyn TextBuffer, 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_str(), min_ccursor);
delete_selected_ccursor_range(text, [min_ccursor, max_ccursor]) delete_selected_ccursor_range(text, [min_ccursor, max_ccursor])
} }
@ -1385,11 +1385,11 @@ fn find_line_start(text: &str, current_index: CCursor) -> CCursor {
} }
fn decrease_identation(ccursor: &mut CCursor, text: &mut dyn TextBuffer) { 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_str(), *ccursor);
let remove_len = if text.as_ref()[line_start.index..].starts_with('\t') { let remove_len = if text.as_str()[line_start.index..].starts_with('\t') {
Some(1) Some(1)
} else if text.as_ref()[line_start.index..] } else if text.as_str()[line_start.index..]
.chars() .chars()
.take(text::TAB_SIZE) .take(text::TAB_SIZE)
.all(|c| c == ' ') .all(|c| c == ' ')

View file

@ -4,17 +4,12 @@ use std::ops::Range;
/// 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> { pub trait TextBuffer {
/// Can this text be edited? /// Can this text be edited?
fn is_mutable(&self) -> bool; fn is_mutable(&self) -> bool;
/// Returns this buffer as a `str`. /// Returns this buffer as a `str`.
/// fn as_str(&self) -> &str;
/// This is an utility method, as it simply relies on the `AsRef<str>`
/// implementation.
fn as_str(&self) -> &str {
self.as_ref()
}
/// Reads the given character range. /// Reads the given character range.
fn char_range(&self, char_range: Range<usize>) -> &str { fn char_range(&self, char_range: Range<usize>) -> &str {
@ -45,7 +40,7 @@ pub trait TextBuffer: AsRef<str> {
/// Clears all characters in this buffer /// Clears all characters in this buffer
fn clear(&mut self) { fn clear(&mut self) {
self.delete_char_range(0..self.as_ref().len()); self.delete_char_range(0..self.as_str().len());
} }
/// Replaces all contents of this string with `text` /// Replaces all contents of this string with `text`
@ -56,7 +51,7 @@ pub trait TextBuffer: AsRef<str> {
/// Clears all characters in this buffer and returns a string of the contents. /// Clears all characters in this buffer and returns a string of the contents.
fn take(&mut self) -> String { fn take(&mut self) -> String {
let s = self.as_ref().to_owned(); let s = self.as_str().to_owned();
self.clear(); self.clear();
s s
} }
@ -67,6 +62,10 @@ impl TextBuffer for String {
true true
} }
fn as_str(&self) -> &str {
self.as_ref()
}
fn insert_text(&mut self, text: &str, char_index: usize) -> usize { fn insert_text(&mut self, text: &str, char_index: usize) -> usize {
// Get the byte index from the character index // Get the byte index from the character index
let byte_idx = self.byte_index_from_char_index(char_index); let byte_idx = self.byte_index_from_char_index(char_index);
@ -107,6 +106,10 @@ impl<'a> TextBuffer for &'a str {
false false
} }
fn as_str(&self) -> &str {
self
}
fn insert_text(&mut self, _text: &str, _ch_idx: usize) -> usize { fn insert_text(&mut self, _text: &str, _ch_idx: usize) -> usize {
0 0
} }