use iced::{advanced::image::Bytes, widget::image::Handle};
#[derive(Debug, Clone)]
pub struct RgbaHandle(Handle);
impl RgbaHandle {
pub fn new(width: u32, height: u32, pixels: impl Into<Bytes>) -> Self {
Self(Handle::from_rgba(width, height, pixels.into()))
}
pub fn raw(&self) -> (u32, u32, &Bytes) {
let Handle::Rgba {
width,
height,
ref pixels,
..
} = self.0
else {
unreachable!("handle is guaranteed to be Rgba")
};
(width, height, pixels)
}
}
impl From<RgbaHandle> for Handle {
fn from(value: RgbaHandle) -> Self {
value.0
}
}
#[derive(thiserror::Error, Debug)]
pub enum ScreenshotError {
#[error("Could not get position of the mouse")]
MousePosition,
#[error("Could not get the active monitor: {0}")]
Monitor(xcap::XCapError),
#[error("Could not take a screenshot: {0}")]
Screenshot(xcap::XCapError),
}
pub fn screenshot() -> Result<RgbaHandle, ScreenshotError> {
let mouse_position::mouse_position::Mouse::Position { x, y } =
mouse_position::mouse_position::Mouse::get_mouse_position()
else {
return Err(ScreenshotError::MousePosition);
};
let monitor = xcap::Monitor::from_point(x, y).map_err(ScreenshotError::Monitor)?;
let screenshot = monitor
.capture_image()
.map_err(ScreenshotError::Screenshot)?;
Ok(RgbaHandle::new(
screenshot.width(),
screenshot.height(),
screenshot.into_raw(),
))
}