|
| 1 | +use std::time::{SystemTime, UNIX_EPOCH}; |
| 2 | + |
| 3 | +use bevy_app::{App, Plugin, Update}; |
| 4 | +use bevy_ecs::prelude::*; |
| 5 | +use bevy_input::{common_conditions::input_just_pressed, keyboard::KeyCode}; |
| 6 | +use bevy_render::view::screenshot::{save_to_disk, Screenshot}; |
| 7 | +use bevy_window::{PrimaryWindow, Window}; |
| 8 | + |
| 9 | +/// File format the screenshot will be saved in |
| 10 | +#[derive(Clone, Copy)] |
| 11 | +pub enum ScreenshotFormat { |
| 12 | + /// JPEG format |
| 13 | + Jpeg, |
| 14 | + /// PNG format |
| 15 | + Png, |
| 16 | + /// BMP format |
| 17 | + Bmp, |
| 18 | +} |
| 19 | + |
| 20 | +/// Add this plugin to your app to enable easy screenshotting. |
| 21 | +/// |
| 22 | +/// Add this plugin, press the key, and you have a screenshot 🎉 |
| 23 | +pub struct EasyScreenshotPlugin { |
| 24 | + /// Key that will trigger a screenshot |
| 25 | + pub trigger: KeyCode, |
| 26 | + /// Format of the screenshot |
| 27 | + /// |
| 28 | + /// The corresponding image format must be supported by bevy renderer |
| 29 | + pub format: ScreenshotFormat, |
| 30 | +} |
| 31 | + |
| 32 | +impl Default for EasyScreenshotPlugin { |
| 33 | + fn default() -> Self { |
| 34 | + EasyScreenshotPlugin { |
| 35 | + trigger: KeyCode::PrintScreen, |
| 36 | + format: ScreenshotFormat::Png, |
| 37 | + } |
| 38 | + } |
| 39 | +} |
| 40 | + |
| 41 | +impl Plugin for EasyScreenshotPlugin { |
| 42 | + fn build(&self, app: &mut App) { |
| 43 | + let format = self.format; |
| 44 | + app.add_systems( |
| 45 | + Update, |
| 46 | + (|| { |
| 47 | + move |mut commands: Commands, window: Single<&Window, With<PrimaryWindow>>| { |
| 48 | + let since_the_epoch = SystemTime::now() |
| 49 | + .duration_since(UNIX_EPOCH) |
| 50 | + .expect("time should go forward"); |
| 51 | + |
| 52 | + commands |
| 53 | + .spawn(Screenshot::primary_window()) |
| 54 | + .observe(save_to_disk(format!( |
| 55 | + "{}-{}.{}", |
| 56 | + window.title, |
| 57 | + since_the_epoch.as_millis(), |
| 58 | + match format { |
| 59 | + ScreenshotFormat::Jpeg => "jpg", |
| 60 | + ScreenshotFormat::Png => "png", |
| 61 | + ScreenshotFormat::Bmp => "bmp", |
| 62 | + } |
| 63 | + ))); |
| 64 | + } |
| 65 | + })() |
| 66 | + .run_if(input_just_pressed(self.trigger)), |
| 67 | + ); |
| 68 | + } |
| 69 | +} |
0 commit comments