use crate::application::*;
use crate::window::*;
use browser_window_core::prelude::*;
use std::{
future::Future
};
use unsafe_send_sync::UnsafeSend;
macro_rules! _def_event {
( $(#[$metas:meta])*, $args_type:ty, $name:ident, $name_async:ident ) => {
$(#[$metas])*
#[cfg(not(feature = "threadsafe"))]
pub fn $name<H>( &mut self, handler: H ) -> &mut Self where
H: FnMut( &$args_type ) + 'static
{
self.events.$name.register( handler );
self
}
$(#[$metas])*
#[cfg(feature = "threadsafe")]
pub fn $name<H>( &mut self, handler: H ) -> &mut Self where
H: FnMut( &$args_type ) + Send + 'static
{
self.events.$name.register( handler );
self
}
$(#[$metas])*
#[cfg(not(feature = "threadsafe"))]
pub fn $name_async<H,F>( &mut self, handler: H ) -> &mut Self where
H: FnMut( &$args_type ) -> F + 'static,
F: Future<Output=()> + 'static
{
self.events.$name.register_async( handler );
self
}
$(#[$metas])*
#[cfg(feature = "threadsafe")]
pub fn $name_async<H,F>( &mut self, handler: H ) -> &mut Self where
H: FnMut( &$args_type ) -> F + Send + 'static,
F: Future<Output=()> + 'static
{
self.events.$name.register_async( handler );
self
}
};
}
macro_rules! def_event {
( $(#[$metas:meta])* $args_type:ty, $name:ident, $name_async:ident ) => {
_def_event!( $(#[$metas])*, $args_type, $name, $name_async );
};
( $(#[$metas:meta])* $name:ident, $name_async:ident ) => {
_def_event!( $(#[$metas])*, WindowHandle, $name, $name_async );
};
}
pub struct WindowBuilder {
pub(in crate) borders: bool,
pub(in crate) events: Box<WindowEvents>,
pub(in crate) height: Option<u32>,
pub(in crate) minimizable: bool,
pub(in crate) parent: Option<UnsafeSend<WindowHandle>>,
pub(in crate) resizable: bool,
pub(in crate) title: Option<String>,
pub(in crate) width: Option<u32>
}
struct WindowUserData {
events: Box<WindowEvents>
}
impl WindowBuilder {
def_event!{ #[doc(hidden)]
on_close, on_close_async
}
def_event!{ #[doc(hidden)]
WindowResizeEventArgs, on_resize, on_resize_async
}
pub fn borders( &mut self, value: bool ) -> &mut Self {
self.borders = value; self
}
fn build( self, app: ApplicationHandle ) {
let title: &str = match self.title.as_ref() {
None => "",
Some( t ) => t
};
let window_options = cbw_WindowOptions {
borders: self.borders,
minimizable: self.minimizable,
resizable: self.resizable
};
let user_data = Box::new( WindowUserData {
events: unsafe { Box::from_raw( Box::into_raw( self.events ) ) } } );
let parent_impl_handle = match self.parent {
None => WindowImpl::default(),
Some( parent ) => parent.inner
};
let _impl_handle = WindowImpl::new(
app.inner,
parent_impl_handle,
title.into(),
self.width as _,
self.height as _,
&window_options,
Box::into_raw( user_data ) as _
);
}
pub fn height( &mut self, height: u32 ) -> &mut Self {
self.height = Some( height );
self
}
pub fn minimizable( &mut self, value: bool ) -> &mut Self {
self.minimizable = value; self
}
pub fn parent<W>( &mut self, bw: &W ) -> &mut Self where
W: OwnedWindow
{
self.parent = Some( UnsafeSend::new( bw.window_handle() ) );
self
}
pub fn new() -> Self {
Self {
borders: true,
height: None,
minimizable: true,
parent: None,
resizable: true,
title: None,
width: None,
events: Box::new( WindowEvents::default() )
}
}
pub fn size( &mut self, width: u32, height: u32 ) -> &mut Self {
self.width = Some( width );
self.height = Some( height );
self
}
pub fn title<S: Into<String>>( &mut self, title: S ) -> &mut Self {
self.title = Some( title.into() );
self
}
pub fn width( &mut self, width: u32 ) -> &mut Self {
self.width = Some( width );
self
}
pub fn resizable( &mut self, resizable: bool ) -> &mut Self {
self.resizable = resizable; self
}
}