1
0
Fork 0

refactor and modify events

This commit is contained in:
Billy Messenger 2020-10-17 13:35:39 -05:00
parent a4c226277c
commit 1b9fbf9bb8
7 changed files with 195 additions and 84 deletions

View file

@ -1,4 +1,4 @@
use baseview::{Event, Window, WindowHandler};
use baseview::{Event, Window, WindowHandler, WindowSize, WindowScalePolicy};
struct MyProgram {}
@ -25,9 +25,13 @@ impl WindowHandler for MyProgram {
fn main() {
let window_open_options = baseview::WindowOpenOptions {
title: "baseview".into(),
logical_size: (512, 512),
resize: baseview::WindowResize::None,
scale: 1.0,
size: WindowSize::MinMaxLogical {
initial_size: (512, 512),
min_size: (200, 200),
max_size: (1024, 1024),
keep_aspect: false,
},
scale: WindowScalePolicy::TrySystemScaleFactor,
parent: baseview::Parent::None,
};

View file

@ -41,18 +41,28 @@ pub enum ScrollDelta {
pub struct MouseClick {
pub button: MouseButton,
pub click_count: usize,
pub x: i32,
pub y: i32,
/// The logical X coordinate of the mouse position
logical_x: i32,
/// The logical Y coordinate of the mouse position
logical_y: i32,
/// The physical X coordinate of the mouse position
physical_x: i32,
/// The physical Y coordinate of the mouse position
physical_y: i32,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum MouseEvent {
/// The mouse cursor was moved
CursorMoved {
/// The X coordinate of the mouse position
x: i32,
/// The Y coordinate of the mouse position
y: i32,
/// The logical X coordinate of the mouse position
logical_x: i32,
/// The logical Y coordinate of the mouse position
logical_y: i32,
/// The physical X coordinate of the mouse position
physical_x: i32,
/// The physical Y coordinate of the mouse position
physical_y: i32,
},
/// A mouse button was pressed.
@ -74,7 +84,7 @@ pub enum MouseEvent {
CursorLeft,
}
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug)]
pub enum WindowEvent {
Resized(WindowInfo),
Focused,

View file

@ -19,11 +19,14 @@ mod event;
mod keyboard;
mod mouse_cursor;
mod window_info;
mod window_open_options;
pub use event::*;
pub use keyboard::*;
pub use mouse_cursor::MouseCursor;
pub use window_info::WindowInfo;
pub use window_open_options::*;
#[derive(Debug)]
pub enum Parent {
None,
AsIfParented,
@ -32,30 +35,6 @@ pub enum Parent {
unsafe impl Send for Parent {}
pub enum WindowResize {
None,
MinMax {
min_logical_size: (u32, u32),
max_logical_size: (u32, u32),
keep_aspect: bool,
},
}
pub struct WindowOpenOptions {
pub title: String,
/// The logical width and height of the window
pub logical_size: (u32, u32),
pub resize: WindowResize,
/// The dpi scale factor. This will used in conjunction with the dpi scale
/// factor of the system.
pub scale: f64,
pub parent: Parent,
}
pub struct WindowHandle {
thread: std::thread::JoinHandle<()>,
}

View file

@ -1,5 +1,5 @@
/// The info about the window
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone)]
pub struct WindowInfo {
/// The physical the width of the window
physical_width: u32,
@ -66,11 +66,19 @@ impl WindowInfo {
self.scale
}
/// Convert physical mouse coordinates to logical coordinates
/// Convert physical coordinates to logical coordinates
pub fn physical_to_logical(&self, x: f64, y: f64) -> (f64, f64) {
(
x * self.scale_recip,
y * self.scale_recip
)
}
/// Convert logicalcoordinates to physical coordinates
pub fn logical_to_physical(&self, x: f64, y: f64) -> (f64, f64) {
(
x * self.scale,
y * self.scale
)
}
}

View file

@ -0,0 +1,74 @@
use crate::{WindowInfo, Parent};
/// The size of the window
#[derive(Debug)]
pub enum WindowSize {
/// Use logical width and height
Logical(u32, u32),
/// Use physical width and height
Physical(u32, u32),
/// Use minimum and maximum logical width and height
MinMaxLogical {
/// The initial logical width and height
initial_size: (u32, u32),
/// The minimum logical width and height
min_size: (u32, u32),
/// The maximum logical width and height
max_size: (u32, u32),
/// Whether to keep the aspect ratio when resizing (true), or not (false)
keep_aspect: bool,
},
/// Use minimum and maximum physical width and height
MinMaxPhysical {
/// The initial physical width and height
initial_size: (u32, u32),
/// The minimum physical width and height
min_size: (u32, u32),
/// The maximum physical width and height
max_size: (u32, u32),
/// Whether to keep the aspect ratio when resizing (true), or not (false)
keep_aspect: bool,
},
}
/// The dpi scaling policy of the window
#[derive(Debug)]
pub enum WindowScalePolicy {
/// Try using the system scale factor
TrySystemScaleFactor,
/// Try using the system scale factor in addition to the given scale factor
TrySystemScaleFactorTimes(f64),
/// Use the given scale factor
UseScaleFactor(f64),
/// No scaling
NoScaling,
}
/// The options for opening a new window
#[derive(Debug)]
pub struct WindowOpenOptions {
pub title: String,
/// The size information about the window
pub size: WindowSize,
/// The scaling of the window
pub scale: WindowScalePolicy,
pub parent: Parent,
}
impl WindowOpenOptions {
pub(crate) fn window_info_from_scale(&self, scale: f64) -> WindowInfo {
match self.size {
WindowSize::Logical(w, h) => WindowInfo::from_logical_size(w, h, scale),
WindowSize::Physical(w, h) => WindowInfo::from_physical_size(w, h, scale),
WindowSize::MinMaxLogical { initial_size, .. } => {
WindowInfo::from_logical_size(initial_size.0, initial_size.1, scale)
},
WindowSize::MinMaxPhysical { initial_size, .. } => {
WindowInfo::from_logical_size(initial_size.0, initial_size.1, scale)
}
}
}
}

View file

@ -12,7 +12,8 @@ use raw_window_handle::{
use super::XcbConnection;
use crate::{
Event, KeyboardEvent, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta, WindowEvent,
WindowHandle, WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult, WindowResize,
WindowHandle, WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult,
WindowScalePolicy,
};
pub struct Window {
@ -79,14 +80,16 @@ impl Window {
],
);
let scaling = xcb_connection.get_scaling().unwrap_or(1.0) * options.scale;
let scaling = match options.scale {
WindowScalePolicy::TrySystemScaleFactor =>
xcb_connection.get_scaling().unwrap_or(1.0),
WindowScalePolicy::TrySystemScaleFactorTimes(user_scale) =>
xcb_connection.get_scaling().unwrap_or(1.0) * user_scale,
WindowScalePolicy::UseScaleFactor(user_scale) => user_scale,
WindowScalePolicy::NoScaling => 1.0,
};
let (logical_width, logical_height) = options.logical_size;
let window_info = WindowInfo::from_logical_size(
logical_width,
logical_height,
scaling
);
let window_info = options.window_info_from_scale(scaling);
let window_id = xcb_connection.conn.generate_id();
xcb::create_window(
@ -127,42 +130,6 @@ impl Window {
title.as_bytes(),
);
match options.resize {
WindowResize::MinMax { min_logical_size, max_logical_size, keep_aspect } => {
let min_physical_width = (min_logical_size.0 as f64 * scaling).round() as i32;
let min_physical_height = (min_logical_size.1 as f64 * scaling).round() as i32;
let max_physical_width = (max_logical_size.0 as f64 * scaling).round() as i32;
let max_physical_height = (max_logical_size.1 as f64 * scaling).round() as i32;
let size_hints = if keep_aspect {
xcb_util::icccm::SizeHints::empty()
.min_size(min_physical_width, min_physical_height)
.max_size(max_physical_width, max_physical_height)
.aspect(
(min_physical_width, min_physical_height),
(max_physical_width, max_physical_height),
)
.build()
} else {
xcb_util::icccm::SizeHints::empty()
.min_size(min_physical_width, min_physical_height)
.max_size(max_physical_width, max_physical_height)
.build()
};
xcb_connection.atoms.wm_normal_hints
.map(|wm_normal_hints| {
xcb_util::icccm::set_wm_size_hints(
&xcb_connection.conn,
window_id,
wm_normal_hints,
&size_hints,
);
});
}
_ => {}
}
xcb_connection.atoms.wm_protocols
.zip(xcb_connection.atoms.wm_delete_window)
.map(|(wm_protocols, wm_delete_window)| {
@ -173,6 +140,8 @@ impl Window {
&[wm_delete_window],
);
});
xcb_connection.set_resize_policy(window_id, &options.size, scaling);
xcb_connection.conn.flush();
@ -363,8 +332,10 @@ impl Window {
handler.on_event(
self,
Event::Mouse(MouseEvent::CursorMoved {
x: logical_x.round() as i32,
y: logical_y.round() as i32,
logical_x: logical_x.round() as i32,
logical_y: logical_y.round() as i32,
physical_x: event.event_x() as i32,
physical_y: event.event_y() as i32,
}),
);
}

View file

@ -5,7 +5,7 @@
use std::ffi::{CStr, CString};
use std::collections::HashMap;
use crate::MouseCursor;
use crate::{MouseCursor, WindowSize};
use super::cursor;
@ -154,4 +154,69 @@ impl XcbConnection {
.entry(cursor)
.or_insert_with(|| cursor::get_xcursor(dpy, cursor))
}
pub fn set_resize_policy(&self, window_id: u32, size: &WindowSize, scale: f64) {
match size {
WindowSize::MinMaxLogical { min_size, max_size, keep_aspect, .. } => {
let min_physical_width = (min_size.0 as f64 * scale).round() as i32;
let min_physical_height = (min_size.1 as f64 * scale).round() as i32;
let max_physical_width = (max_size.0 as f64 * scale).round() as i32;
let max_physical_height = (max_size.1 as f64 * scale).round() as i32;
let size_hints = if *keep_aspect {
xcb_util::icccm::SizeHints::empty()
.min_size(min_physical_width, min_physical_height)
.max_size(max_physical_width, max_physical_height)
.aspect(
(min_physical_width, min_physical_height),
(max_physical_width, max_physical_height),
)
.build()
} else {
xcb_util::icccm::SizeHints::empty()
.min_size(min_physical_width, min_physical_height)
.max_size(max_physical_width, max_physical_height)
.build()
};
self.atoms.wm_normal_hints
.map(|wm_normal_hints| {
xcb_util::icccm::set_wm_size_hints(
&self.conn,
window_id,
wm_normal_hints,
&size_hints,
);
});
}
WindowSize::MinMaxPhysical { min_size, max_size, keep_aspect, .. } => {
let size_hints = if *keep_aspect {
xcb_util::icccm::SizeHints::empty()
.min_size(min_size.0 as i32, min_size.1 as i32)
.max_size(max_size.0 as i32, max_size.1 as i32)
.aspect(
(min_size.0 as i32, min_size.1 as i32),
(max_size.0 as i32, max_size.1 as i32),
)
.build()
} else {
xcb_util::icccm::SizeHints::empty()
.min_size(min_size.0 as i32, min_size.1 as i32)
.max_size(max_size.0 as i32, max_size.1 as i32)
.build()
};
self.atoms.wm_normal_hints
.map(|wm_normal_hints| {
xcb_util::icccm::set_wm_size_hints(
&self.conn,
window_id,
wm_normal_hints,
&size_hints,
);
});
}
_ => {}
}
}
}