TextEdit: Clean up password masking
Follow-up to https://github.com/emilk/egui/pull/412
This commit is contained in:
parent
f4a95b1e5f
commit
a50ddc2703
1 changed files with 33 additions and 28 deletions
|
@ -130,6 +130,10 @@ pub trait TextBuffer:
|
||||||
/// # Notes
|
/// # Notes
|
||||||
/// `ch_range` is a *character range*, not a byte range.
|
/// `ch_range` is a *character range*, not a byte range.
|
||||||
fn delete_char_range(&mut self, ch_range: Range<usize>);
|
fn delete_char_range(&mut self, ch_range: Range<usize>);
|
||||||
|
|
||||||
|
fn as_str(&self) -> &str {
|
||||||
|
self.as_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextBuffer for String {
|
impl TextBuffer for String {
|
||||||
|
@ -375,6 +379,12 @@ impl<'t, S: TextBuffer> Widget for TextEdit<'t, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mask_massword(text: &str) -> String {
|
||||||
|
std::iter::repeat(epaint::text::PASSWORD_REPLACEMENT_CHAR)
|
||||||
|
.take(text.chars().count())
|
||||||
|
.collect::<String>()
|
||||||
|
}
|
||||||
|
|
||||||
impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||||
fn content_ui(self, ui: &mut Ui) -> Response {
|
fn content_ui(self, ui: &mut Ui) -> Response {
|
||||||
let TextEdit {
|
let TextEdit {
|
||||||
|
@ -393,6 +403,14 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||||
lock_focus,
|
lock_focus,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
let mask_if_password = |text: &str| {
|
||||||
|
if password {
|
||||||
|
mask_massword(text)
|
||||||
|
} else {
|
||||||
|
text.to_owned()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let prev_text = text.clone();
|
let prev_text = text.clone();
|
||||||
let text_style = text_style
|
let text_style = text_style
|
||||||
.or(ui.style().override_text_style)
|
.or(ui.style().override_text_style)
|
||||||
|
@ -401,13 +419,7 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||||
let available_width = ui.available_width();
|
let available_width = ui.available_width();
|
||||||
|
|
||||||
let make_galley = |ui: &Ui, text: &str| {
|
let make_galley = |ui: &Ui, text: &str| {
|
||||||
let text = if password {
|
let text = mask_if_password(text);
|
||||||
std::iter::repeat(epaint::text::PASSWORD_REPLACEMENT_CHAR)
|
|
||||||
.take(text.chars().count())
|
|
||||||
.collect::<String>()
|
|
||||||
} else {
|
|
||||||
text.to_owned()
|
|
||||||
};
|
|
||||||
if multiline {
|
if multiline {
|
||||||
ui.fonts()
|
ui.fonts()
|
||||||
.layout_multiline(text_style, text, available_width)
|
.layout_multiline(text_style, text, available_width)
|
||||||
|
@ -718,38 +730,31 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let masked = if self.password {
|
|
||||||
let prev_text_len = prev_text.to_string().len();
|
|
||||||
let text_len = text.to_string().len();
|
|
||||||
Some(("*".repeat(prev_text_len), "*".repeat(text_len)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
if response.changed {
|
if response.changed {
|
||||||
if let Some((prev_text, text)) = masked {
|
response.widget_info(|| {
|
||||||
response.widget_info(|| WidgetInfo::text_edit(&prev_text, &text));
|
WidgetInfo::text_edit(
|
||||||
} else {
|
mask_if_password(prev_text.as_str()),
|
||||||
response.widget_info(|| WidgetInfo::text_edit(&prev_text, &text));
|
mask_if_password(text.as_str()),
|
||||||
}
|
)
|
||||||
|
});
|
||||||
} else if selection_changed {
|
} else if selection_changed {
|
||||||
let text_cursor = text_cursor.unwrap();
|
let text_cursor = text_cursor.unwrap();
|
||||||
let char_range =
|
let char_range =
|
||||||
text_cursor.primary.ccursor.index..=text_cursor.secondary.ccursor.index;
|
text_cursor.primary.ccursor.index..=text_cursor.secondary.ccursor.index;
|
||||||
let info = if let Some((_, text)) = masked {
|
let info =
|
||||||
WidgetInfo::text_selection_changed(char_range, text)
|
WidgetInfo::text_selection_changed(char_range, mask_if_password(text.as_str()));
|
||||||
} else {
|
|
||||||
WidgetInfo::text_selection_changed(char_range, &*text)
|
|
||||||
};
|
|
||||||
response
|
response
|
||||||
.ctx
|
.ctx
|
||||||
.output()
|
.output()
|
||||||
.events
|
.events
|
||||||
.push(OutputEvent::TextSelectionChanged(info));
|
.push(OutputEvent::TextSelectionChanged(info));
|
||||||
} else if let Some((prev_text, text)) = masked {
|
|
||||||
response.widget_info(|| WidgetInfo::text_edit(&prev_text, &text));
|
|
||||||
} else {
|
} else {
|
||||||
response.widget_info(|| WidgetInfo::text_edit(&prev_text, &text));
|
response.widget_info(|| {
|
||||||
|
WidgetInfo::text_edit(
|
||||||
|
mask_if_password(prev_text.as_str()),
|
||||||
|
mask_if_password(text.as_str()),
|
||||||
|
)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue