#[cfg(not(target_arch = "wasm32"))]
#[derive(Default)]
pub struct Screenshotter {
countdown: Option<isize>,
target_path: Option<std::path::PathBuf>,
quit: bool,
pre_screenshot_zoom_factor: Option<f32>,
}
#[cfg(not(target_arch = "wasm32"))]
#[must_use]
pub struct ScreenshotterOutput {
pub quit: bool,
}
#[cfg(not(target_arch = "wasm32"))]
impl Screenshotter {
pub fn screenshot_to_path_then_quit(
&mut self,
egui_ctx: &egui::Context,
path: std::path::PathBuf,
) {
assert!(self.countdown.is_none(), "screenshotter misused");
self.request_screenshot(egui_ctx);
self.target_path = Some(path);
}
pub fn request_screenshot(&mut self, egui_ctx: &egui::Context) {
self.countdown = Some(10);
self.pre_screenshot_zoom_factor = Some(egui_ctx.zoom_factor());
let temporary_pixels_per_points = 2.0;
let scale_factor = temporary_pixels_per_points / egui_ctx.pixels_per_point();
let temporary_viewport_size = scale_factor * egui_ctx.screen_rect().size();
egui_ctx.send_viewport_cmd(egui::ViewportCommand::InnerSize(temporary_viewport_size));
egui_ctx.set_pixels_per_point(temporary_pixels_per_points);
}
pub fn update(&mut self, egui_ctx: &egui::Context) -> ScreenshotterOutput {
if let Some(countdown) = &mut self.countdown {
if *countdown == 0 {
egui_ctx.send_viewport_cmd(egui::ViewportCommand::Screenshot);
}
*countdown -= 1;
egui_ctx.request_repaint(); } else if let Some(pre_screenshot_zoom_factor) = self.pre_screenshot_zoom_factor.take() {
let scale_factor = pre_screenshot_zoom_factor / egui_ctx.zoom_factor();
let old_viewport_size = scale_factor * egui_ctx.screen_rect().size();
egui_ctx.send_viewport_cmd(egui::ViewportCommand::InnerSize(old_viewport_size));
egui_ctx.set_zoom_factor(pre_screenshot_zoom_factor);
}
ScreenshotterOutput { quit: self.quit }
}
pub fn is_screenshotting(&self) -> bool {
self.countdown.is_some()
}
pub fn save(&mut self, image: &egui::ColorImage) {
self.countdown = None;
if let Some(path) = self.target_path.take() {
let w = image.width() as _;
let h = image.height() as _;
let image =
image::RgbaImage::from_raw(w, h, bytemuck::pod_collect_to_vec(&image.pixels))
.expect("Failed to create image");
match image.save(&path) {
Ok(()) => {
re_log::info!("Screenshot saved to {path:?}");
self.quit = true;
}
Err(err) => {
panic!("Failed saving screenshot to {path:?}: {err}");
}
}
} else {
re_viewer_context::Clipboard::with(|cb| {
cb.set_image(image.size, bytemuck::cast_slice(&image.pixels));
});
}
}
}
#[cfg(target_arch = "wasm32")]
#[derive(Default)]
pub struct Screenshotter {}
#[cfg(target_arch = "wasm32")]
impl Screenshotter {
#[allow(clippy::unused_self)]
pub fn is_screenshotting(&self) -> bool {
false
}
}