use eframe::{ egui::{Button, CentralPanel, Context, UserAttentionType}, CreationContext, NativeOptions, }; use std::time::{Duration, SystemTime}; fn main() -> eframe::Result<()> { env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). let native_options = NativeOptions { initial_window_size: Some(eframe::egui::vec2(400., 200.)), ..Default::default() }; eframe::run_native( "User attention test", native_options, Box::new(|cc| Box::new(Application::new(cc))), ) } fn repr(attention: UserAttentionType) -> String { format!("{attention:?}") } struct Application { attention: UserAttentionType, request_at: Option, auto_reset: bool, reset_at: Option, } impl Application { fn new(_cc: &CreationContext<'_>) -> Self { Self { attention: UserAttentionType::Informational, request_at: None, auto_reset: false, reset_at: None, } } fn attention_reset_timeout() -> Duration { Duration::from_secs(3) } fn attention_request_timeout() -> Duration { Duration::from_secs(2) } fn repaint_max_timeout() -> Duration { Duration::from_secs(1) } } impl eframe::App for Application { fn update(&mut self, ctx: &Context, frame: &mut eframe::Frame) { if let Some(request_at) = self.request_at { if request_at < SystemTime::now() { self.request_at = None; frame.request_user_attention(self.attention); if self.auto_reset { self.auto_reset = false; self.reset_at = Some(SystemTime::now() + Self::attention_reset_timeout()); } } } if let Some(reset_at) = self.reset_at { if reset_at < SystemTime::now() { self.reset_at = None; frame.request_user_attention(UserAttentionType::Reset); } } CentralPanel::default().show(ctx, |ui| { ui.vertical(|ui| { ui.horizontal(|ui| { ui.label("Attention type:"); eframe::egui::ComboBox::new("attention", "") .selected_text(repr(self.attention)) .show_ui(ui, |ui| { for kind in [ UserAttentionType::Informational, UserAttentionType::Critical, ] { ui.selectable_value(&mut self.attention, kind, repr(kind)); } }) }); let button_enabled = self.request_at.is_none() && self.reset_at.is_none(); let button_text = if button_enabled { format!( "Request in {} seconds", Self::attention_request_timeout().as_secs() ) } else { match self.reset_at { None => "Unfocus the window, fast!".to_owned(), Some(t) => { if let Ok(elapsed) = t.duration_since(SystemTime::now()) { format!("Resetting attention in {} s...", elapsed.as_secs()) } else { "Resetting attention...".to_owned() } } } }; let resp = ui .add_enabled(button_enabled, Button::new(button_text)) .on_hover_text_at_pointer( "After clicking, unfocus the application's window to see the effect", ); ui.checkbox( &mut self.auto_reset, format!( "Reset after {} seconds", Self::attention_reset_timeout().as_secs() ), ); if resp.clicked() { self.request_at = Some(SystemTime::now() + Self::attention_request_timeout()); } }); }); ctx.request_repaint_after(Self::repaint_max_timeout()); } }