use crate::graphics::GraphicsSettings;
use super::{
window_width,
window_height,
window_center,
mouse_cursor,
KeyboardButton,
InnerWindowEvent,
EventLoopState,
Window,
WindowPage,
WindowBase,
WindowSettings,
GeneralSettings,
};
use glium::backend::glutin::DisplayCreationError;
use glium::glutin::{
ContextBuilder,
NotCurrent,
monitor::MonitorHandle,
event_loop::{ControlFlow,EventLoop,EventLoopClosed},
event::{
Event,
WindowEvent as GWindowEvent,
ElementState,
},
window::WindowBuilder,
platform::desktop::EventLoopExtDesktop,
};
pub type PageRef<'a,O>=&'a mut dyn WindowPage<'a,Window=DynamicWindow<'a,O>,Output=O>;
pub struct DynamicWindow<'a,O:PartialEq>{
pub (crate) base:WindowBase,
pub (crate) page_ref:*mut PageRef<'a,O>,
pub (crate) last_page:Option<PageRef<'a,O>>,
}
impl<'a,O:PartialEq> DynamicWindow<'a,O>{
pub fn new<F>(setting:F)->Result<DynamicWindow<'a,O>,DisplayCreationError>
where F:FnOnce(Vec<MonitorHandle>,&mut WindowSettings){
Window::new(setting)
}
pub fn set_page_raw(&mut self,page:PageRef<'a,O>){
unsafe{
*self.page_ref=page
}
}
pub fn set_page(&mut self,page:PageRef<'a,O>){
unsafe{
self.last_page=Some(*self.page_ref);
*self.page_ref=page
}
}
pub fn change_page(&mut self,page:PageRef<'a,O>)->Option<PageRef<'a,O>>{
unsafe{
self.last_page=Some(*self.page_ref);
*self.page_ref=page;
self.last_page.take()
}
}
pub fn take_old_page(&mut self)->Option<PageRef<'a,O>>{
self.last_page.take()
}
pub fn run(mut self,page:PageRef<'a,O>)->O{
let el=&mut self.base.event_loop as *mut EventLoop<InnerWindowEvent>;
let event_loop=unsafe{&mut *el};
let mut current_page=page;
self.page_ref=&mut current_page as *mut PageRef<O>;
#[cfg(not(feature="auto_hide"))]
if let EventLoopState::Closed(output)=self.event_listener(event_loop,&mut current_page){
return output
}
else{
panic!("No page output")
}
#[cfg(feature="auto_hide")]
loop{
if let EventLoopState::Closed(output)=self.event_listener(event_loop,&mut current_page){
return output
}
if let EventLoopState::Closed(output)=self.wait_until_focused(event_loop,&mut current_page){
return output
}
}
}
#[inline(always)]
pub fn stop_events(&self)->Result<(),EventLoopClosed<InnerWindowEvent>>{
self.base.request_event_loop_close()
}
#[cfg(feature="auto_hide")]
#[inline(always)]
fn on_window_hidden(&mut self){
}
#[cfg(feature="auto_hide")]
#[inline(always)]
fn on_window_unhidden(&mut self){
}
}
impl<'a,O:PartialEq> DynamicWindow<'a,O>{
fn event_listener(
&mut self,
event_loop:&mut EventLoop<InnerWindowEvent>,
current_page:&mut PageRef<'a,O>,
)->EventLoopState<O>{
let mut state=EventLoopState::<O>::Running;
event_loop.run_return(|event,_,control_flow|{
paged_event_listener!(self,event,control_flow,current_page,state);
});
state
}
#[cfg(feature="auto_hide")]
fn wait_until_focused(
&mut self,
event_loop:&mut EventLoop<InnerWindowEvent>,
current_page:&mut PageRef<'a,O>
)->EventLoopState<O>{
let mut state=EventLoopState::<O>::Running;
event_loop.run_return(|event,_,control_flow|{
paged_wait_until_focused!(self,event,control_flow,current_page,state);
});
state
}
}
impl<'a,O:PartialEq> Window for DynamicWindow<'a,O>{
#[inline(always)]
fn window_base_mut(&mut self)->&mut WindowBase{
&mut self.base
}
#[inline(always)]
fn window_base(&self)->&WindowBase{
&self.base
}
fn raw(
window_builder:WindowBuilder,
context_builder:ContextBuilder<NotCurrent>,
graphics_settings:GraphicsSettings,
event_loop:EventLoop<InnerWindowEvent>,
general_settings:GeneralSettings,
)->Result<DynamicWindow<'a,O>,DisplayCreationError>{
let base=WindowBase::raw(window_builder,
context_builder,
graphics_settings,
event_loop,
general_settings,
);
match base{
Ok(w)=>{
Ok(Self{
base:w,
page_ref:std::ptr::null_mut(),
last_page:None,
})
}
Err(e)=>Err(e)
}
}
}