egui Keyboard Input: Arrow Keys, Clicks & Events | Rust GUI Ep 21
Video: egui Keyboard Input: Arrow Keys, Clicks & Events | Rust GUI Ep 21 by Taught by Celeste AI - AI Coding Coach
Watch full page →egui Keyboard Input: Arrow Keys, Clicks & Events | Rust GUI Ep 21
In this tutorial, you will learn how to handle keyboard and mouse input in an egui application using Rust. We build a Key Explorer app that reacts to arrow keys, WASD for movement, Tab for cycling colors, Space for resetting, and mouse clicks to place markers on a canvas.
Code
use egui::{Color32, Key, Pos2, Rect, Sense, Vec2};
const COLORS: &[Color32] = &[
Color32::RED,
Color32::GREEN,
Color32::BLUE,
Color32::YELLOW,
];
struct MyApp {
pos: Pos2,
color_idx: usize,
markers: Vec<Pos2>,
}
impl Default for MyApp {
fn default() -> Self {
Self {
pos: Pos2::new(100.0, 100.0),
color_idx: 0,
markers: Vec::new(),
}
}
}
impl MyApp {
fn update(&mut self, ctx: &egui::Context) {
// Request continuous repaint to keep input responsive
ctx.request_repaint();
// Read input state each frame
let input = ctx.input(|i| i.clone());
// Move position with arrow keys or WASD
let delta = 5.0;
if input.key_pressed(Key::ArrowUp) || input.key_pressed(Key::W) {
self.pos.y -= delta;
}
if input.key_pressed(Key::ArrowDown) || input.key_pressed(Key::S) {
self.pos.y += delta;
}
if input.key_pressed(Key::ArrowLeft) || input.key_pressed(Key::A) {
self.pos.x -= delta;
}
if input.key_pressed(Key::ArrowRight) || input.key_pressed(Key::D) {
self.pos.x += delta;
}
// Cycle colors with Tab key
if input.key_pressed(Key::Tab) {
self.color_idx = (self.color_idx + 1) % COLORS.len();
}
// Reset position and markers with Space key
if input.key_pressed(Key::Space) {
self.pos = Pos2::new(100.0, 100.0);
self.markers.clear();
}
// Create a clickable canvas area
egui::CentralPanel::default().show(ctx, |ui| {
let (rect, response) = ui.allocate_exact_size(Vec2::new(300.0, 300.0), Sense::click());
// On mouse click inside canvas, add a marker
if response.clicked() {
if let Some(click_pos) = response.interact_pointer_pos() {
// Clamp click position inside canvas rect
let pos = Pos2::new(
click_pos.x.clamp(rect.left(), rect.right()),
click_pos.y.clamp(rect.top(), rect.bottom()),
);
self.markers.push(pos);
}
}
// Paint markers as filled circles
let painter = ui.painter();
for &marker_pos in &self.markers {
painter.circle_filled(marker_pos, 5.0, COLORS[self.color_idx]);
}
// Paint a movable square cursor at current position
let cursor_rect = Rect::from_center_size(self.pos, Vec2::splat(20.0));
painter.rect_stroke(cursor_rect, 0.0, (2.0, COLORS[self.color_idx]));
});
}
}
Key Points
- Use
ctx.input(|i| i.key_pressed(Key::...))to detect single key presses like arrow keys and WASD. - Cycle through colors or reset state by responding to Tab and Space keys respectively.
- Call
ctx.request_repaint()to keep the UI updating and responsive to input events. - Use
Sense::click()on UI elements to detect mouse clicks andresponse.interact_pointer_pos()to get click coordinates. - Draw interactive markers and a movable cursor on a canvas using egui's painter API with
circle_filledandrect_stroke.