use crate::windows::{
WinCore,
WinError,
WinColour,
};
pub use crate::windows::core::{
window_class::{
ClassIdentifier,
ClassAtom,
WindowClassStyle,
WindowClassStyles,
WindowBackgroundColour,
WindowBackgroundSystemColour,
WindowClassInfo,
},
cursor::SystemCursor,
};
use super::{
Icon,
setup_window_procedure,
};
use image::{
ImageBuffer,
Bgra
};
use std::{
ptr::null_mut,
mem::transmute
};
pub enum CursorIcon{
None,
System(SystemCursor),
BGRA8{
position:[u32;2],
image:ImageBuffer<Bgra<u8>,Vec<u8>>,
}
}
pub enum Background{
None,
SystemColour(WindowBackgroundSystemColour),
RGBColour([u8;3]),
}
pub struct WindowClass{
identifier:ClassAtom,
}
impl WindowClass{
pub fn new(attributes:WindowClassAttributes)->Result<WindowClass,WinError>{
let class_name:Vec<u16>=attributes.name
.encode_utf16()
.chain([0].into_iter())
.collect();
let window_icon=match attributes.window_icon{
None=>None,
Some(image)=>Some(Icon::from_bgra(true,[0u32;2],&image).handle())
};
let cursor=match attributes.cursor_icon{
CursorIcon::None=>None,
CursorIcon::System(cursor)=>unsafe{
Some(WinCore.cursor.load_system_cursor(cursor).unwrap())
}
CursorIcon::BGRA8{position,image}=>unsafe{
Some(transmute(Icon::from_bgra(false,position,&image).handle()))
}
};
let background=match attributes.background{
Background::None=>None,
Background::SystemColour(colour)=>{
Some(WindowBackgroundColour::system_colour(colour))
}
Background::RGBColour([red,green,blue])=>unsafe{
let brush=WinCore.brush.create_solid(WinColour::new([red,green,blue])).unwrap();
Some(WindowBackgroundColour::brush(brush))
}
};
let mut style=WindowClassStyles::new()
.set(WindowClassStyle::OwnDeviceContext);
if attributes.no_close{
style=style.set(WindowClassStyle::NoClose)
}
if attributes.drop_shadow{
style=style.set(WindowClassStyle::DropShadow)
}
if attributes.double_clicks{
style=style.set(WindowClassStyle::DoubleClicks)
}
if let Some(class)=unsafe{
WinCore.window_class.register(
class_name.as_ptr(),
style,
setup_window_procedure,
0,
64,
None,
window_icon,
None,
cursor,
background,
null_mut(),
)
}{
Ok(Self{
identifier:class,
})
}
else{
Err(WinError::get_last_error())
}
}
pub const fn atom(&self)->ClassAtom{
self.identifier
}
#[inline(always)]
pub fn identifier(&self)->ClassIdentifier{
ClassIdentifier::atom(self.identifier)
}
pub fn get_info(&self)->WindowClassInfo{
unsafe{
let mut info=WindowClassInfo::new();
WinCore.window_class.get_info(self.identifier(),None,&mut info);
info
}
}
}
impl Drop for WindowClass{
fn drop(&mut self){
unsafe{
let _result=WinCore.window_class.unregister(self.identifier(),None);
}
}
}
pub struct WindowClassAttributes{
pub name:String,
pub window_icon:Option<ImageBuffer<Bgra<u8>,Vec<u8>>>,
pub cursor_icon:CursorIcon,
pub background:Background,
pub no_close:bool,
pub drop_shadow:bool,
pub double_clicks:bool,
}
impl WindowClassAttributes{
pub fn new(name:&str)->WindowClassAttributes{
let name=String::from(name);
Self{
name,
window_icon:None,
cursor_icon:CursorIcon::System(SystemCursor::Arrow),
background:Background::None,
no_close:false,
drop_shadow:false,
double_clicks:false,
}
}
}