-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an input event history tracker to the egui demo lib (#4693)
This is great for testing how e.g. keyboard events are seen by egui: ![image](https://github.com/emilk/egui/assets/1148717/b2187060-6533-439c-9f43-fc49b8213c28) * Relevant: #3653
- Loading branch information
Showing
6 changed files
with
193 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
crates/egui_demo_lib/src/demo/tests/input_event_history.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
//! Show the history of all the input events to | ||
|
||
struct HistoryEntry { | ||
summary: String, | ||
entries: Vec<String>, | ||
} | ||
|
||
#[derive(Default)] | ||
struct DeduplicatedHistory { | ||
history: std::collections::VecDeque<HistoryEntry>, | ||
} | ||
|
||
impl DeduplicatedHistory { | ||
fn add(&mut self, summary: String, full: String) { | ||
if let Some(entry) = self.history.back_mut() { | ||
if entry.summary == summary { | ||
entry.entries.push(full); | ||
return; | ||
} | ||
} | ||
self.history.push_back(HistoryEntry { | ||
summary, | ||
entries: vec![full], | ||
}); | ||
if self.history.len() > 100 { | ||
self.history.pop_front(); | ||
} | ||
} | ||
|
||
fn ui(&self, ui: &mut egui::Ui) { | ||
egui::ScrollArea::vertical() | ||
.auto_shrink(false) | ||
.show(ui, |ui| { | ||
ui.spacing_mut().item_spacing.y = 4.0; | ||
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend); | ||
|
||
for HistoryEntry { summary, entries } in self.history.iter().rev() { | ||
ui.horizontal(|ui| { | ||
let response = ui.code(summary); | ||
if entries.len() < 2 { | ||
response | ||
} else { | ||
response | ui.weak(format!(" x{}", entries.len())) | ||
} | ||
}) | ||
.inner | ||
.on_hover_ui(|ui| { | ||
ui.spacing_mut().item_spacing.y = 4.0; | ||
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend); | ||
for entry in entries.iter().rev() { | ||
ui.code(entry); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] | ||
#[derive(Default)] | ||
pub struct InputEventHistory { | ||
#[cfg_attr(feature = "serde", serde(skip))] | ||
history: DeduplicatedHistory, | ||
|
||
include_pointer_movements: bool, | ||
} | ||
|
||
impl crate::Demo for InputEventHistory { | ||
fn name(&self) -> &'static str { | ||
"Input Event History" | ||
} | ||
|
||
fn show(&mut self, ctx: &egui::Context, open: &mut bool) { | ||
egui::Window::new(self.name()) | ||
.default_width(800.0) | ||
.open(open) | ||
.resizable(true) | ||
.scroll(false) | ||
.show(ctx, |ui| { | ||
use crate::View as _; | ||
self.ui(ui); | ||
}); | ||
} | ||
} | ||
|
||
impl crate::View for InputEventHistory { | ||
fn ui(&mut self, ui: &mut egui::Ui) { | ||
ui.input(|i| { | ||
for event in &i.raw.events { | ||
if !self.include_pointer_movements | ||
&& matches!( | ||
event, | ||
egui::Event::PointerMoved(_) | egui::Event::MouseMoved(_) | ||
) | ||
{ | ||
continue; | ||
} | ||
|
||
let summary = event_summary(event); | ||
let full = format!("{event:#?}"); | ||
self.history.add(summary, full); | ||
} | ||
}); | ||
|
||
ui.vertical_centered(|ui| { | ||
ui.add(crate::egui_github_link_file!()); | ||
}); | ||
|
||
ui.label("Recent history of raw input events to egui."); | ||
ui.label("Hover any entry for details."); | ||
ui.checkbox( | ||
&mut self.include_pointer_movements, | ||
"Include pointer/mouse movements", | ||
); | ||
|
||
ui.add_space(8.0); | ||
|
||
self.history.ui(ui); | ||
} | ||
} | ||
|
||
fn event_summary(event: &egui::Event) -> String { | ||
match event { | ||
egui::Event::PointerMoved(_) => "PointerMoved { .. }".to_owned(), | ||
egui::Event::MouseMoved(_) => "MouseMoved { .. }".to_owned(), | ||
egui::Event::Zoom(_) => "Zoom { .. }".to_owned(), | ||
egui::Event::Touch { phase, .. } => format!("Zoom {{ phase: {phase:?}, .. }}"), | ||
egui::Event::MouseWheel { unit, .. } => format!("MouseWheel {{ unit: {unit:?}, .. }}"), | ||
|
||
_ => format!("{event:?}"), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters