mirror of https://github.com/emilk/egui.git
Browse Source
* add method for requesting attention to the main window * use another enum member for user attention type instead of nested `Option`s (also, document the enum members now that they don't mirror `winit`) * update the docstring Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * add an example app for testing window attention requests * Apply suggestions from code review Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * remove `chrono` dependency and improve the attention example's readability --------- Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>pull/2934/head
TicClick
2 years ago
committed by
GitHub
9 changed files with 206 additions and 3 deletions
@ -0,0 +1,11 @@ |
|||
[package] |
|||
name = "user_attention" |
|||
version = "0.1.0" |
|||
authors = ["TicClick <ya@ticclick.ch>"] |
|||
license = "MIT OR Apache-2.0" |
|||
edition = "2021" |
|||
rust-version = "1.65" |
|||
publish = false |
|||
|
|||
[dependencies] |
|||
eframe = { path = "../../crates/eframe" } |
@ -0,0 +1,7 @@ |
|||
An example of requesting a user's attention to the main window, and resetting the ongoing attention animations when necessary. Only works on native platforms. |
|||
|
|||
```sh |
|||
cargo run -p user_attention |
|||
``` |
|||
|
|||
![](screenshot.png) |
After Width: | Height: | Size: 4.5 KiB |
@ -0,0 +1,130 @@ |
|||
use eframe::egui::{Button, CentralPanel, Context, UserAttentionType}; |
|||
use eframe::{CreationContext, NativeOptions}; |
|||
|
|||
use std::time::{Duration, SystemTime}; |
|||
|
|||
fn repr(attention: UserAttentionType) -> String { |
|||
format!("{:?}", attention) |
|||
} |
|||
|
|||
struct Application { |
|||
attention: UserAttentionType, |
|||
request_at: Option<SystemTime>, |
|||
|
|||
auto_reset: bool, |
|||
reset_at: Option<SystemTime>, |
|||
} |
|||
|
|||
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()); |
|||
} |
|||
} |
|||
|
|||
fn main() -> eframe::Result<()> { |
|||
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))), |
|||
) |
|||
} |
Loading…
Reference in new issue