egui/egui_demo_lib/src/apps/demo/password.rs

65 lines
2.5 KiB
Rust

//! Source code example about creating a widget which uses `egui::Memory` to store UI state.
//!
//! This is meant to be read as a tutorial, hence the plethora of comments.
/// Password entry field with ability to toggle character hiding.
///
/// ## Example:
/// ``` ignore
/// password_ui(ui, &mut my_password);
/// ```
pub fn password_ui(ui: &mut egui::Ui, password: &mut String) -> egui::Response {
// This widget has its own state — show or hide password characters (`show_plaintext`).
// In this case we use a simple `bool`, but you can also declare your own type.
// It must implement at least `Clone` and be `'static`.
// If you use the `persistence` feature, it also must implement `serde::{Deserialize, Serialize}`.
// Generate an id for the state
let state_id = ui.id().with("show_plaintext");
// Get state for this widget.
// You should get state by value, not by reference to avoid borrowing of `Memory`.
let mut show_plaintext = ui.memory().data.get_temp::<bool>(state_id).unwrap_or(false);
// Process ui, change a local copy of the state
// We want TextEdit to fill entire space, and have button after that, so in that case we can
// change direction to right_to_left.
let result = ui.with_layout(egui::Layout::right_to_left(), |ui| {
// Toggle the `show_plaintext` bool with a button:
let response = ui
.add(egui::SelectableLabel::new(show_plaintext, "👁"))
.on_hover_text("Show/hide password");
if response.clicked() {
show_plaintext = !show_plaintext;
}
// Show the password field:
ui.add_sized(
ui.available_size(),
egui::TextEdit::singleline(password).password(!show_plaintext),
);
});
// Store the (possibly changed) state:
ui.memory().data.insert_temp(state_id, show_plaintext);
// All done! Return the interaction response so the user can check what happened
// (hovered, clicked, …) and maybe show a tooltip:
result.response
}
// A wrapper that allows the more idiomatic usage pattern: `ui.add(…)`
/// Password entry field with ability to toggle character hiding.
///
/// ## Example:
/// ``` ignore
/// ui.add(password(&mut my_password));
/// ```
pub fn password(password: &mut String) -> impl egui::Widget + '_ {
move |ui: &mut egui::Ui| password_ui(ui, password)
}
pub fn url_to_file_source_code() -> String {
format!("https://github.com/emilk/egui/blob/master/{}", file!())
}