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,
GetMessageA, GetWindowLongPtrA, MessageBoxA, PostMessageA, RegisterClassA, SetTimer,
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,
WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW,
WS_SIZEBOX, WS_VISIBLE,
MB_OK, MB_TOPMOST, MSG, WM_CLOSE, WM_CREATE, WM_MOUSEMOVE, WM_PAINT, WM_SHOWWINDOW, WM_TIMER,
WNDCLASSA, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
};
use std::cell::RefCell;
use std::ffi::c_void;
use std::ptr::null_mut;
use std::sync::mpsc;
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) {
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;
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 {
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;
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 {
WM_MOUSEMOVE => {
let x = (lparam & 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;
}
WM_TIMER => {
handle_timer(&win, wparam);
handle_timer(&window_state, wparam);
return 0;
}
WM_PAINT => {
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());
}
pub struct Window<A: AppWindow> {
pub(crate) hwnd: HWND,
struct WindowState<A> {
window_class: ATOM,
app_window: A,
app_message_rx: mpsc::Receiver<A::AppMessage>,
scaling: Option<f64>, // DPI scale, 96.0 is "default".
app_window: A,
}
impl<A: AppWindow> Window<A> {
pub fn open(options: WindowOpenOptions, app_message_rx: mpsc::Receiver<A::AppMessage>) {
pub struct Window {
hwnd: HWND,
}
impl Window {
pub fn open<A: AppWindow>(
options: WindowOpenOptions,
app_message_rx: mpsc::Receiver<A::AppMessage>,
) {
unsafe {
let title = (options.title.to_owned() + "\0").as_ptr() as *const i8;
@ -170,28 +188,15 @@ impl<A: AppWindow> Window<A> {
);
// todo: manage error ^
let mut windows_handle = raw_window_handle::windows::WindowsHandle::empty();
windows_handle.hwnd = hwnd as *mut std::ffi::c_void;
let mut window = Window { hwnd };
let raw_window = RawWindow {
raw_window_handle: raw_window_handle::RawWindowHandle::Windows(windows_handle),
};
let app_window = A::build(&mut window);
let window_info = WindowInfo {
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,
let window_state = Rc::new(RefCell::new(WindowState {
window_class,
app_window,
app_message_rx,
scaling: None,
};
app_window,
}));
let win = Rc::new(RefCell::new(window));
@ -213,18 +218,13 @@ impl<A: AppWindow> Window<A> {
}
}
}
pub fn close(&mut self) {
self.app_window.on_event(Event::WillClose);
// todo: see https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L402
unsafe {
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));
unsafe impl HasRawWindowHandle for Window {
fn raw_window_handle(&self) -> RawWindowHandle {
RawWindowHandle::Windows(WindowsHandle {
hwnd: self.hwnd as *mut std::ffi::c_void,
..WindowsHandle::empty()
})
}
}