Skip to content

Commit

Permalink
TextEdit: Clean up password masking
Browse files Browse the repository at this point in the history
Follow-up to #412
  • Loading branch information
emilk committed Jun 12, 2021
1 parent f4a95b1 commit a50ddc2
Showing 1 changed file with 33 additions and 28 deletions.
61 changes: 33 additions & 28 deletions egui/src/widgets/text_edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ pub trait TextBuffer:
/// # Notes
/// `ch_range` is a *character range*, not a byte range.
fn delete_char_range(&mut self, ch_range: Range<usize>);

fn as_str(&self) -> &str {
self.as_ref()
}
}

impl TextBuffer for String {
Expand Down Expand Up @@ -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> {
fn content_ui(self, ui: &mut Ui) -> Response {
let TextEdit {
Expand All @@ -393,6 +403,14 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
lock_focus,
} = self;

let mask_if_password = |text: &str| {
if password {
mask_massword(text)
} else {
text.to_owned()
}
};

let prev_text = text.clone();
let text_style = text_style
.or(ui.style().override_text_style)
Expand All @@ -401,13 +419,7 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
let available_width = ui.available_width();

let make_galley = |ui: &Ui, text: &str| {
let text = if password {
std::iter::repeat(epaint::text::PASSWORD_REPLACEMENT_CHAR)
.take(text.chars().count())
.collect::<String>()
} else {
text.to_owned()
};
let text = mask_if_password(text);
if multiline {
ui.fonts()
.layout_multiline(text_style, text, available_width)
Expand Down Expand Up @@ -718,38 +730,31 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
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 let Some((prev_text, text)) = masked {
response.widget_info(|| WidgetInfo::text_edit(&prev_text, &text));
} 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()),
)
});
} else if selection_changed {
let text_cursor = text_cursor.unwrap();
let char_range =
text_cursor.primary.ccursor.index..=text_cursor.secondary.ccursor.index;
let info = if let Some((_, text)) = masked {
WidgetInfo::text_selection_changed(char_range, text)
} else {
WidgetInfo::text_selection_changed(char_range, &*text)
};
let info =
WidgetInfo::text_selection_changed(char_range, mask_if_password(text.as_str()));
response
.ctx
.output()
.events
.push(OutputEvent::TextSelectionChanged(info));
} else if let Some((prev_text, text)) = masked {
response.widget_info(|| WidgetInfo::text_edit(&prev_text, &text));
} 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
}
Expand Down

0 comments on commit a50ddc2

Please sign in to comment.