egui_demo_lib/demo/
password.rs

1//! Source code example about creating a widget which uses `egui::Memory` to store UI state.
2//!
3//! This is meant to be read as a tutorial, hence the plethora of comments.
4
5/// Password entry field with ability to toggle character hiding.
6///
7/// ## Example:
8/// ``` ignore
9/// password_ui(ui, &mut my_password);
10/// ```
11#[allow(clippy::ptr_arg)] // false positive
12pub fn password_ui(ui: &mut egui::Ui, password: &mut String) -> egui::Response {
13    // This widget has its own state — show or hide password characters (`show_plaintext`).
14    // In this case we use a simple `bool`, but you can also declare your own type.
15    // It must implement at least `Clone` and be `'static`.
16    // If you use the `persistence` feature, it also must implement `serde::{Deserialize, Serialize}`.
17
18    // Generate an id for the state
19    let state_id = ui.id().with("show_plaintext");
20
21    // Get state for this widget.
22    // You should get state by value, not by reference to avoid borrowing of [`Memory`].
23    let mut show_plaintext = ui.data_mut(|d| d.get_temp::<bool>(state_id).unwrap_or(false));
24
25    // Process ui, change a local copy of the state
26    // We want TextEdit to fill entire space, and have button after that, so in that case we can
27    // change direction to right_to_left.
28    let result = ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
29        // Toggle the `show_plaintext` bool with a button:
30        let response = ui
31            .add(egui::SelectableLabel::new(show_plaintext, "👁"))
32            .on_hover_text("Show/hide password");
33
34        if response.clicked() {
35            show_plaintext = !show_plaintext;
36        }
37
38        // Show the password field:
39        ui.add_sized(
40            ui.available_size(),
41            egui::TextEdit::singleline(password).password(!show_plaintext),
42        );
43    });
44
45    // Store the (possibly changed) state:
46    ui.data_mut(|d| d.insert_temp(state_id, show_plaintext));
47
48    // All done! Return the interaction response so the user can check what happened
49    // (hovered, clicked, …) and maybe show a tooltip:
50    result.response
51}
52
53// A wrapper that allows the more idiomatic usage pattern: `ui.add(…)`
54/// Password entry field with ability to toggle character hiding.
55///
56/// ## Example:
57/// ``` ignore
58/// ui.add(password(&mut my_password));
59/// ```
60pub fn password(password: &mut String) -> impl egui::Widget + '_ {
61    move |ui: &mut egui::Ui| password_ui(ui, password)
62}
63
64pub fn url_to_file_source_code() -> String {
65    format!("https://github.com/emilk/egui/blob/master/{}", file!())
66}