Revert to Receiver trait. Add create_context method to Receiver trait.
This commit is contained in:
parent
a5829cee88
commit
b0c3792c74
|
@ -1,5 +1,3 @@
|
||||||
use std::sync::mpsc;
|
|
||||||
|
|
||||||
use baseview::Message;
|
use baseview::Message;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -10,22 +8,21 @@ fn main() {
|
||||||
parent: baseview::Parent::None,
|
parent: baseview::Parent::None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let (message_tx, message_rx) = mpsc::channel::<Message>();
|
|
||||||
|
|
||||||
let my_program = MyProgram {};
|
let my_program = MyProgram {};
|
||||||
|
|
||||||
let window = baseview::Window::build(window_open_options, message_tx);
|
let _ = baseview::Window::open(window_open_options, my_program);
|
||||||
|
|
||||||
// Get raw window handle!
|
|
||||||
let _raw_handle = window.raw_window_handle();
|
|
||||||
|
|
||||||
my_program_loop(my_program, message_rx);
|
|
||||||
}
|
}
|
||||||
struct MyProgram {}
|
struct MyProgram {}
|
||||||
|
|
||||||
fn my_program_loop(_my_program: MyProgram, message_rx: mpsc::Receiver<Message>) {
|
impl baseview::Receiver for MyProgram {
|
||||||
loop {
|
fn create_context(
|
||||||
let message = message_rx.recv().unwrap();
|
&mut self,
|
||||||
|
_window: raw_window_handle::RawWindowHandle,
|
||||||
|
_window_info: &baseview::WindowInfo,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_message(&mut self, message: Message) {
|
||||||
match message {
|
match message {
|
||||||
Message::CursorMotion(x, y) => {
|
Message::CursorMotion(x, y) => {
|
||||||
println!("Cursor moved, x: {}, y: {}", x, y);
|
println!("Cursor moved, x: {}, y: {}", x, y);
|
||||||
|
|
|
@ -32,3 +32,12 @@ pub struct WindowOpenOptions<'a> {
|
||||||
|
|
||||||
pub parent: Parent,
|
pub parent: Parent,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Receiver {
|
||||||
|
fn create_context(
|
||||||
|
&mut self,
|
||||||
|
window: raw_window_handle::RawWindowHandle,
|
||||||
|
window_info: &WindowInfo,
|
||||||
|
);
|
||||||
|
fn on_message(&mut self, message: Message);
|
||||||
|
}
|
||||||
|
|
|
@ -8,10 +8,12 @@ use cocoa::foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize, NSString};
|
||||||
|
|
||||||
use crate::{Message, MouseButtonID, MouseScroll, Receiver, WindowOpenOptions};
|
use crate::{Message, MouseButtonID, MouseScroll, Receiver, WindowOpenOptions};
|
||||||
|
|
||||||
pub struct Window {}
|
pub struct Window<R: Receiver> {
|
||||||
|
receiver: R,
|
||||||
|
}
|
||||||
|
|
||||||
impl Window {
|
impl<R: Receiver> Window<R> {
|
||||||
pub fn open(options: WindowOpenOptions, message_tx: mpsc::Sender<Message>) -> Self {
|
pub fn open(options: WindowOpenOptions, receiver: R) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _pool = NSAutoreleasePool::new(nil);
|
let _pool = NSAutoreleasePool::new(nil);
|
||||||
|
|
||||||
|
@ -42,14 +44,6 @@ impl Window {
|
||||||
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
|
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
|
||||||
app.run();
|
app.run();
|
||||||
|
|
||||||
message_tx
|
|
||||||
.send(Message::Opened(WindowInfo {
|
|
||||||
width: options.width as u32,
|
|
||||||
height: options.height as u32,
|
|
||||||
dpi: None,
|
|
||||||
}))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
Window { receiver }
|
Window { receiver }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ extern crate winapi;
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
use std::sync::mpsc;
|
|
||||||
|
|
||||||
use self::winapi::shared::guiddef::GUID;
|
use self::winapi::shared::guiddef::GUID;
|
||||||
use self::winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM};
|
use self::winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM};
|
||||||
|
@ -113,19 +112,20 @@ unsafe fn unregister_wnd_class(wnd_class: ATOM) {
|
||||||
|
|
||||||
unsafe fn init_gl_context() {}
|
unsafe fn init_gl_context() {}
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window<R: Receiver> {
|
||||||
pub(crate) hwnd: HWND,
|
pub(crate) hwnd: HWND,
|
||||||
hdc: HDC,
|
hdc: HDC,
|
||||||
gl_context: HGLRC,
|
gl_context: HGLRC,
|
||||||
window_class: ATOM,
|
window_class: ATOM,
|
||||||
|
receiver: R,
|
||||||
scaling: Option<f64>, // DPI scale, 96.0 is "default".
|
scaling: Option<f64>, // DPI scale, 96.0 is "default".
|
||||||
r: f32,
|
r: f32,
|
||||||
g: f32,
|
g: f32,
|
||||||
b: f32,
|
b: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl<R: Receiver> Window<R> {
|
||||||
pub fn open(options: WindowOpenOptions, message_tx: mpsc::Sender<Message>) {
|
pub fn open(options: WindowOpenOptions, receiver: R) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut window = Window {
|
let mut window = Window {
|
||||||
hwnd: null_mut(),
|
hwnd: null_mut(),
|
||||||
|
@ -241,14 +241,6 @@ impl Window {
|
||||||
|
|
||||||
SetTimer(hwnd, 4242, 13, None);
|
SetTimer(hwnd, 4242, 13, None);
|
||||||
|
|
||||||
message_tx
|
|
||||||
.send(Message::Opened(WindowInfo {
|
|
||||||
width: options.width as u32,
|
|
||||||
height: options.height as u32,
|
|
||||||
dpi: None,
|
|
||||||
}))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// todo: decide what to do with the message pump
|
// todo: decide what to do with the message pump
|
||||||
if parent.is_null() {
|
if parent.is_null() {
|
||||||
let mut msg: MSG = std::mem::zeroed();
|
let mut msg: MSG = std::mem::zeroed();
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::sync::mpsc;
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use ::x11::xlib;
|
use ::x11::xlib;
|
||||||
// use xcb::dri2; // needed later
|
// use xcb::dri2; // needed later
|
||||||
|
|
||||||
use super::XcbConnection;
|
use super::XcbConnection;
|
||||||
use crate::{Message, MouseButtonID, MouseScroll, Parent, WindowInfo, WindowOpenOptions};
|
use crate::{Message, MouseButtonID, MouseScroll, Parent, Receiver, WindowInfo, WindowOpenOptions};
|
||||||
|
|
||||||
use raw_window_handle::RawWindowHandle;
|
use raw_window_handle::RawWindowHandle;
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window<R: Receiver> {
|
||||||
scaling: Option<f64>, // DPI scale, 96.0 is "default".
|
scaling: Option<f64>, // DPI scale, 96.0 is "default".
|
||||||
raw_handle: RawWindowHandle,
|
xcb_connection: XcbConnection,
|
||||||
|
receiver: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl<R: Receiver> Window<R> {
|
||||||
pub fn open(options: WindowOpenOptions, message_tx: mpsc::Sender<Message>) -> Self {
|
pub fn open(options: WindowOpenOptions, receiver: R) -> Self {
|
||||||
// Convert the parent to a X11 window ID if we're given one
|
// Convert the parent to a X11 window ID if we're given one
|
||||||
let parent = match options.parent {
|
let parent = match options.parent {
|
||||||
Parent::None => None,
|
Parent::None => None,
|
||||||
|
@ -128,30 +128,121 @@ impl Window {
|
||||||
|
|
||||||
let mut x11_window = Self {
|
let mut x11_window = Self {
|
||||||
scaling: None,
|
scaling: None,
|
||||||
raw_handle,
|
xcb_connection,
|
||||||
|
receiver,
|
||||||
};
|
};
|
||||||
|
|
||||||
x11_window.scaling =
|
x11_window.scaling = get_scaling_xft(&x11_window.xcb_connection)
|
||||||
get_scaling_xft(&xcb_connection).or(get_scaling_screen_dimensions(&xcb_connection));
|
.or(get_scaling_screen_dimensions(&x11_window.xcb_connection));
|
||||||
println!("Scale factor: {:?}", x11_window.scaling);
|
println!("Scale factor: {:?}", x11_window.scaling);
|
||||||
|
|
||||||
message_tx
|
let window_info = WindowInfo {
|
||||||
.send(Message::Opened(WindowInfo {
|
width: options.width as u32,
|
||||||
width: options.width as u32,
|
height: options.height as u32,
|
||||||
height: options.height as u32,
|
dpi: x11_window.scaling,
|
||||||
dpi: x11_window.scaling,
|
};
|
||||||
}))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
thread::spawn(move || {
|
x11_window.receiver.create_context(raw_handle, &window_info);
|
||||||
run_event_loop(xcb_connection, message_tx);
|
|
||||||
});
|
x11_window.run_event_loop();
|
||||||
|
|
||||||
x11_window
|
x11_window
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn raw_window_handle(&self) -> RawWindowHandle {
|
// Event loop
|
||||||
self.raw_handle
|
fn run_event_loop(&mut self) {
|
||||||
|
//let raw_display = self.xcb_connection.conn.get_raw_dpy();
|
||||||
|
loop {
|
||||||
|
let ev = self.xcb_connection.conn.wait_for_event();
|
||||||
|
if let Some(event) = ev {
|
||||||
|
let event_type = event.response_type() & !0x80;
|
||||||
|
|
||||||
|
// For all of the keyboard and mouse events, you can fetch
|
||||||
|
// `x`, `y`, `detail`, and `state`.
|
||||||
|
// - `x` and `y` are the position inside the window where the cursor currently is
|
||||||
|
// when the event happened.
|
||||||
|
// - `detail` will tell you which keycode was pressed/released (for keyboard events)
|
||||||
|
// or which mouse button was pressed/released (for mouse events).
|
||||||
|
// For mouse events, here's what the value means (at least on my current mouse):
|
||||||
|
// 1 = left mouse button
|
||||||
|
// 2 = middle mouse button (scroll wheel)
|
||||||
|
// 3 = right mouse button
|
||||||
|
// 4 = scroll wheel up
|
||||||
|
// 5 = scroll wheel down
|
||||||
|
// 8 = lower side button ("back" button)
|
||||||
|
// 9 = upper side button ("forward" button)
|
||||||
|
// Note that you *will* get a "button released" event for even the scroll wheel
|
||||||
|
// events, which you can probably ignore.
|
||||||
|
// - `state` will tell you the state of the main three mouse buttons and some of
|
||||||
|
// the keyboard modifier keys at the time of the event.
|
||||||
|
// http://rtbo.github.io/rust-xcb/src/xcb/ffi/xproto.rs.html#445
|
||||||
|
|
||||||
|
match event_type {
|
||||||
|
xcb::EXPOSE => {
|
||||||
|
#[cfg(all(feature = "gl_renderer", not(feature = "wgpu_renderer")))]
|
||||||
|
opengl_util::xcb_expose(window_id, raw_display, self.ctx);
|
||||||
|
}
|
||||||
|
xcb::MOTION_NOTIFY => {
|
||||||
|
let event = unsafe { xcb::cast_event::<xcb::MotionNotifyEvent>(&event) };
|
||||||
|
let detail = event.detail();
|
||||||
|
|
||||||
|
if detail != 4 && detail != 5 {
|
||||||
|
self.receiver.on_message(Message::CursorMotion(
|
||||||
|
event.event_x() as i32,
|
||||||
|
event.event_y() as i32,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xcb::BUTTON_PRESS => {
|
||||||
|
let event = unsafe { xcb::cast_event::<xcb::ButtonPressEvent>(&event) };
|
||||||
|
let detail = event.detail();
|
||||||
|
|
||||||
|
match detail {
|
||||||
|
4 => {
|
||||||
|
self.receiver.on_message(Message::MouseScroll(MouseScroll {
|
||||||
|
x_delta: 0.0,
|
||||||
|
y_delta: 1.0,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
self.receiver.on_message(Message::MouseScroll(MouseScroll {
|
||||||
|
x_delta: 0.0,
|
||||||
|
y_delta: -1.0,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
detail => {
|
||||||
|
let button_id = mouse_id(detail);
|
||||||
|
self.receiver.on_message(Message::MouseDown(button_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xcb::BUTTON_RELEASE => {
|
||||||
|
let event = unsafe { xcb::cast_event::<xcb::ButtonPressEvent>(&event) };
|
||||||
|
let detail = event.detail();
|
||||||
|
|
||||||
|
if detail != 4 && detail != 5 {
|
||||||
|
let button_id = mouse_id(detail);
|
||||||
|
self.receiver.on_message(Message::MouseUp(button_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xcb::KEY_PRESS => {
|
||||||
|
let event = unsafe { xcb::cast_event::<xcb::KeyPressEvent>(&event) };
|
||||||
|
let detail = event.detail();
|
||||||
|
|
||||||
|
self.receiver.on_message(Message::KeyDown(detail));
|
||||||
|
}
|
||||||
|
xcb::KEY_RELEASE => {
|
||||||
|
let event = unsafe { xcb::cast_event::<xcb::KeyReleaseEvent>(&event) };
|
||||||
|
let detail = event.detail();
|
||||||
|
|
||||||
|
self.receiver.on_message(Message::KeyUp(detail));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Unhandled event type: {:?}", event_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,108 +324,6 @@ fn get_scaling_screen_dimensions(xcb_connection: &XcbConnection) -> Option<f64>
|
||||||
Some(yres)
|
Some(yres)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event loop
|
|
||||||
fn run_event_loop(xcb_connection: XcbConnection, message_tx: mpsc::Sender<Message>) {
|
|
||||||
//let raw_display = self.xcb_connection.conn.get_raw_dpy();
|
|
||||||
loop {
|
|
||||||
let ev = xcb_connection.conn.wait_for_event();
|
|
||||||
if let Some(event) = ev {
|
|
||||||
let event_type = event.response_type() & !0x80;
|
|
||||||
|
|
||||||
// For all of the keyboard and mouse events, you can fetch
|
|
||||||
// `x`, `y`, `detail`, and `state`.
|
|
||||||
// - `x` and `y` are the position inside the window where the cursor currently is
|
|
||||||
// when the event happened.
|
|
||||||
// - `detail` will tell you which keycode was pressed/released (for keyboard events)
|
|
||||||
// or which mouse button was pressed/released (for mouse events).
|
|
||||||
// For mouse events, here's what the value means (at least on my current mouse):
|
|
||||||
// 1 = left mouse button
|
|
||||||
// 2 = middle mouse button (scroll wheel)
|
|
||||||
// 3 = right mouse button
|
|
||||||
// 4 = scroll wheel up
|
|
||||||
// 5 = scroll wheel down
|
|
||||||
// 8 = lower side button ("back" button)
|
|
||||||
// 9 = upper side button ("forward" button)
|
|
||||||
// Note that you *will* get a "button released" event for even the scroll wheel
|
|
||||||
// events, which you can probably ignore.
|
|
||||||
// - `state` will tell you the state of the main three mouse buttons and some of
|
|
||||||
// the keyboard modifier keys at the time of the event.
|
|
||||||
// http://rtbo.github.io/rust-xcb/src/xcb/ffi/xproto.rs.html#445
|
|
||||||
|
|
||||||
match event_type {
|
|
||||||
xcb::EXPOSE => {
|
|
||||||
#[cfg(all(feature = "gl_renderer", not(feature = "wgpu_renderer")))]
|
|
||||||
opengl_util::xcb_expose(window_id, raw_display, self.ctx);
|
|
||||||
}
|
|
||||||
xcb::MOTION_NOTIFY => {
|
|
||||||
let event = unsafe { xcb::cast_event::<xcb::MotionNotifyEvent>(&event) };
|
|
||||||
let detail = event.detail();
|
|
||||||
|
|
||||||
if detail != 4 && detail != 5 {
|
|
||||||
message_tx
|
|
||||||
.send(Message::CursorMotion(
|
|
||||||
event.event_x() as i32,
|
|
||||||
event.event_y() as i32,
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xcb::BUTTON_PRESS => {
|
|
||||||
let event = unsafe { xcb::cast_event::<xcb::ButtonPressEvent>(&event) };
|
|
||||||
let detail = event.detail();
|
|
||||||
|
|
||||||
match detail {
|
|
||||||
4 => {
|
|
||||||
message_tx
|
|
||||||
.send(Message::MouseScroll(MouseScroll {
|
|
||||||
x_delta: 0.0,
|
|
||||||
y_delta: 1.0,
|
|
||||||
}))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
5 => {
|
|
||||||
message_tx
|
|
||||||
.send(Message::MouseScroll(MouseScroll {
|
|
||||||
x_delta: 0.0,
|
|
||||||
y_delta: -1.0,
|
|
||||||
}))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
detail => {
|
|
||||||
let button_id = mouse_id(detail);
|
|
||||||
message_tx.send(Message::MouseDown(button_id)).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xcb::BUTTON_RELEASE => {
|
|
||||||
let event = unsafe { xcb::cast_event::<xcb::ButtonPressEvent>(&event) };
|
|
||||||
let detail = event.detail();
|
|
||||||
|
|
||||||
if detail != 4 && detail != 5 {
|
|
||||||
let button_id = mouse_id(detail);
|
|
||||||
message_tx.send(Message::MouseUp(button_id)).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xcb::KEY_PRESS => {
|
|
||||||
let event = unsafe { xcb::cast_event::<xcb::KeyPressEvent>(&event) };
|
|
||||||
let detail = event.detail();
|
|
||||||
|
|
||||||
message_tx.send(Message::KeyDown(detail)).unwrap();
|
|
||||||
}
|
|
||||||
xcb::KEY_RELEASE => {
|
|
||||||
let event = unsafe { xcb::cast_event::<xcb::KeyReleaseEvent>(&event) };
|
|
||||||
let detail = event.detail();
|
|
||||||
|
|
||||||
message_tx.send(Message::KeyUp(detail)).unwrap();
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
println!("Unhandled event type: {:?}", event_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mouse_id(id: u8) -> MouseButtonID {
|
fn mouse_id(id: u8) -> MouseButtonID {
|
||||||
match id {
|
match id {
|
||||||
1 => MouseButtonID::Left,
|
1 => MouseButtonID::Left,
|
||||||
|
|
Loading…
Reference in a new issue