refactor and modify events
This commit is contained in:
parent
a4c226277c
commit
1b9fbf9bb8
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
24
src/event.rs
24
src/event.rs
|
@ -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,
|
||||
|
|
27
src/lib.rs
27
src/lib.rs
|
@ -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<()>,
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
74
src/window_open_options.rs
Normal file
74
src/window_open_options.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue