#![doc = include_str!("../README.md")]
use std::cell::RefCell;
use winit::{
event_loop::{ControlFlow, EventLoop},
platform::run_on_demand::EventLoopExtRunOnDemand,
};
pub use dialog::Dialog;
pub use egui;
pub use egui::{Color32, RichText};
pub use winit::{
self,
dpi::{LogicalSize, PhysicalSize},
window::{Icon, WindowAttributes},
};
pub mod dialog;
mod renderer;
mod window;
thread_local! {
static EVENT_LOOP: RefCell<Option<EventLoop<()>>> = const { RefCell::new(None) };
}
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum Error {
#[error("failed to run event loop {0:?}")]
EventLoop(#[from] winit::error::EventLoopError),
#[error("failed to find an appropriate wgpu adapter")]
FailedToFindAdapter,
#[error("failed select appropriate surface texture format")]
FailedToSelectSurfaceTextureFormat,
#[error("failed to request wgpu device {0:?}")]
FailedToRequestDevice(#[from] egui_wgpu::wgpu::RequestDeviceError),
#[error("failed to create wgpu surface {0:?}")]
FailedToCreateSurface(#[from] egui_wgpu::wgpu::CreateSurfaceError),
#[error("failed to acquire next swapchain texture {0:?}")]
SwapchainError(#[from] egui_wgpu::wgpu::SurfaceError),
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
pub fn create_window<F, R>(draw: F, info: WindowAttributes) -> Result<Option<R>>
where
F: FnMut(&mut egui::Ui) -> Option<R>,
{
EVENT_LOOP
.try_with(|ev_cell| {
let mut ev_cell = ev_cell.borrow_mut();
if ev_cell.is_none() {
let ev = EventLoop::new()?;
ev.set_control_flow(ControlFlow::Poll);
ev_cell.replace(ev);
}
let mut app = window::PopupWindow::new(draw, info);
ev_cell.as_mut().unwrap().run_app_on_demand(&mut app)?;
if let Some(e) = app.error {
Err(e)
} else {
Ok(app.draw_result)
}
})
.unwrap()
}