use crate::{
event_loop::{Event, EventLoopTarget, WindowEvent},
EventLoop,
};
use concoct::{Context, Handle, Object, Signal};
use winit::window::{Window as RawWindow, WindowBuilder};
mod builder;
pub use self::builder::Builder;
enum WindowState {
Builder(WindowBuilder),
Window { window: RawWindow },
}
pub struct Window {
state: Option<WindowState>,
}
impl Default for Window {
fn default() -> Self {
Self::new()
}
}
impl Window {
pub fn new() -> Self {
Self::builder().build()
}
pub(crate) fn from_builder(builder: WindowBuilder) -> Self {
Self {
state: Some(WindowState::Builder(builder)),
}
}
pub fn builder() -> Builder {
Builder::default()
}
pub fn insert<E>(cx: &mut Context<Self>, event_loop: &Handle<EventLoop<E>>)
where
E: Clone,
{
event_loop.bind(&cx.handle(), Self::handle);
match cx.state.take().unwrap() {
WindowState::Builder(builder) => {
let window = match event_loop.borrow_mut().raw.as_mut().unwrap() {
EventLoopTarget::EventLoop(event_loop) => builder.build(event_loop).unwrap(),
EventLoopTarget::WindowTarget(event_loop) => builder.build(event_loop).unwrap(),
};
cx.state = Some(WindowState::Window { window });
}
WindowState::Window { .. } => todo!(),
}
}
pub fn raw(&self) -> &RawWindow {
match self.state.as_ref().unwrap() {
WindowState::Window { window } => window,
_ => todo!(),
}
}
pub fn is_visible(&self) -> Option<bool> {
self.raw().is_visible()
}
pub fn set_visible(&self, visible: bool) {
self.raw().set_visible(visible)
}
pub fn handle<E>(cx: &mut Context<Self>, event: Event<E>) {
match event {
Event::Window { window_id, event } => {
if window_id == cx.raw().id() {
cx.emit(event);
}
}
_ => {}
}
}
}
impl Object for Window {}
impl Signal<WindowEvent> for Window {}