adapt windows backend to new api
This commit is contained in:
parent
58ed00eb11
commit
e78598954f
|
@ -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) {
|
|
||||||
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) {
|
unsafe impl HasRawWindowHandle for Window {
|
||||||
self.app_window.on_event(Event::CursorMotion(x, y));
|
fn raw_window_handle(&self) -> RawWindowHandle {
|
||||||
|
RawWindowHandle::Windows(WindowsHandle {
|
||||||
|
hwnd: self.hwnd as *mut std::ffi::c_void,
|
||||||
|
..WindowsHandle::empty()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue