1
0
Fork 0

adapt windows backend to new api

This commit is contained in:
Micah Johnston 2020-09-07 02:37:52 -05:00 committed by micah
parent 58ed00eb11
commit e78598954f

View file

@ -6,18 +6,20 @@ use winapi::um::winuser::{
AdjustWindowRectEx, CreateWindowExA, DefWindowProcA, DestroyWindow, DispatchMessageA, AdjustWindowRectEx, CreateWindowExA, DefWindowProcA, DestroyWindow, DispatchMessageA,
GetMessageA, GetWindowLongPtrA, MessageBoxA, PostMessageA, RegisterClassA, SetTimer, GetMessageA, GetWindowLongPtrA, MessageBoxA, PostMessageA, RegisterClassA, SetTimer,
SetWindowLongPtrA, TranslateMessage, UnregisterClassA, CS_OWNDC, GWLP_USERDATA, MB_ICONERROR, SetWindowLongPtrA, TranslateMessage, UnregisterClassA, CS_OWNDC, GWLP_USERDATA, MB_ICONERROR,
MB_OK, MB_TOPMOST, MSG, WM_CREATE, WM_MOUSEMOVE, WM_PAINT, WM_SHOWWINDOW, WM_TIMER, WNDCLASSA, MB_OK, MB_TOPMOST, MSG, WM_CLOSE, WM_CREATE, WM_MOUSEMOVE, WM_PAINT, WM_SHOWWINDOW, WM_TIMER,
WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW, WNDCLASSA, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
WS_SIZEBOX, WS_VISIBLE, WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
}; };
use std::cell::RefCell;
use std::ffi::c_void; use std::ffi::c_void;
use std::ptr::null_mut; use std::ptr::null_mut;
use std::sync::mpsc;
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell; use std::sync::mpsc;
use crate::{AppWindow, Event, Parent::WithParent, RawWindow, WindowInfo, WindowOpenOptions}; use raw_window_handle::{windows::WindowsHandle, HasRawWindowHandle, RawWindowHandle};
use crate::{AppWindow, Event, Parent::WithParent, WindowInfo, WindowOpenOptions};
unsafe fn message_box(title: &str, msg: &str) { unsafe fn message_box(title: &str, msg: &str) {
let title = (title.to_owned() + "\0").as_ptr() as *const i8; let title = (title.to_owned() + "\0").as_ptr() as *const i8;
@ -46,7 +48,7 @@ unsafe fn generate_guid() -> String {
const WIN_FRAME_TIMER: usize = 4242; const WIN_FRAME_TIMER: usize = 4242;
unsafe fn handle_timer<A: AppWindow>(win: &RefCell<Window<A>>, timer_id: usize) { unsafe fn handle_timer<A: AppWindow>(window_state: &RefCell<WindowState<A>>, timer_id: usize) {
match timer_id { match timer_id {
WIN_FRAME_TIMER => {} WIN_FRAME_TIMER => {}
_ => (), _ => (),
@ -66,22 +68,33 @@ unsafe extern "system" fn wnd_proc<A: AppWindow>(
let win_ptr = GetWindowLongPtrA(hwnd, GWLP_USERDATA) as *const c_void; let win_ptr = GetWindowLongPtrA(hwnd, GWLP_USERDATA) as *const c_void;
if !win_ptr.is_null() { if !win_ptr.is_null() {
let win = &*(win_ptr as *const RefCell<Window<A>>); let window_state = &*(win_ptr as *const RefCell<WindowState<A>>);
let mut window = Window { hwnd };
match msg { match msg {
WM_MOUSEMOVE => { WM_MOUSEMOVE => {
let x = (lparam & 0xFFFF) as i32; let x = (lparam & 0xFFFF) as i32;
let y = ((lparam >> 16) & 0xFFFF) as i32; let y = ((lparam >> 16) & 0xFFFF) as i32;
win.borrow_mut().handle_mouse_motion(x, y); window_state
.borrow_mut()
.app_window
.on_event(&mut window, Event::CursorMotion(x, y));
return 0; return 0;
} }
WM_TIMER => { WM_TIMER => {
handle_timer(&win, wparam); handle_timer(&window_state, wparam);
return 0; return 0;
} }
WM_PAINT => { WM_PAINT => {
return 0; return 0;
} }
WM_CLOSE => {
window_state
.borrow_mut()
.app_window
.on_event(&mut window, Event::WillClose);
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
_ => {} _ => {}
} }
} }
@ -113,16 +126,21 @@ unsafe fn unregister_wnd_class(wnd_class: ATOM) {
UnregisterClassA(wnd_class as _, null_mut()); UnregisterClassA(wnd_class as _, null_mut());
} }
pub struct Window<A: AppWindow> { struct WindowState<A> {
pub(crate) hwnd: HWND,
window_class: ATOM, window_class: ATOM,
app_window: A,
app_message_rx: mpsc::Receiver<A::AppMessage>,
scaling: Option<f64>, // DPI scale, 96.0 is "default". scaling: Option<f64>, // DPI scale, 96.0 is "default".
app_window: A,
} }
impl<A: AppWindow> Window<A> { pub struct Window {
pub fn open(options: WindowOpenOptions, app_message_rx: mpsc::Receiver<A::AppMessage>) { hwnd: HWND,
}
impl Window {
pub fn open<A: AppWindow>(
options: WindowOpenOptions,
app_message_rx: mpsc::Receiver<A::AppMessage>,
) {
unsafe { unsafe {
let title = (options.title.to_owned() + "\0").as_ptr() as *const i8; let title = (options.title.to_owned() + "\0").as_ptr() as *const i8;
@ -170,28 +188,15 @@ impl<A: AppWindow> Window<A> {
); );
// todo: manage error ^ // todo: manage error ^
let mut windows_handle = raw_window_handle::windows::WindowsHandle::empty(); let mut window = Window { hwnd };
windows_handle.hwnd = hwnd as *mut std::ffi::c_void;
let raw_window = RawWindow { let app_window = A::build(&mut window);
raw_window_handle: raw_window_handle::RawWindowHandle::Windows(windows_handle),
};
let window_info = WindowInfo { let window_state = Rc::new(RefCell::new(WindowState {
width: options.width as u32,
height: options.height as u32,
scale: 1.0,
};
let app_window = A::build(raw_window, &window_info);
let window = Window {
hwnd,
window_class, window_class,
app_window,
app_message_rx,
scaling: None, scaling: None,
}; app_window,
}));
let win = Rc::new(RefCell::new(window)); let win = Rc::new(RefCell::new(window));
@ -213,18 +218,13 @@ impl<A: AppWindow> Window<A> {
} }
} }
} }
}
pub fn close(&mut self) { unsafe impl HasRawWindowHandle for Window {
self.app_window.on_event(Event::WillClose); fn raw_window_handle(&self) -> RawWindowHandle {
RawWindowHandle::Windows(WindowsHandle {
// todo: see https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L402 hwnd: self.hwnd as *mut std::ffi::c_void,
unsafe { ..WindowsHandle::empty()
DestroyWindow(self.hwnd); })
unregister_wnd_class(self.window_class);
}
}
pub(crate) fn handle_mouse_motion(&mut self, x: i32, y: i32) {
self.app_window.on_event(Event::CursorMotion(x, y));
} }
} }