Add Point and Size structs
This commit is contained in:
parent
1b9fbf9bb8
commit
dc5d3b9622
|
@ -26,9 +26,9 @@ fn main() {
|
||||||
let window_open_options = baseview::WindowOpenOptions {
|
let window_open_options = baseview::WindowOpenOptions {
|
||||||
title: "baseview".into(),
|
title: "baseview".into(),
|
||||||
size: WindowSize::MinMaxLogical {
|
size: WindowSize::MinMaxLogical {
|
||||||
initial_size: (512, 512),
|
initial_size: baseview::Size::new(512, 512),
|
||||||
min_size: (200, 200),
|
min_size: baseview::Size::new(200, 200),
|
||||||
max_size: (1024, 1024),
|
max_size: baseview::Size::new(1024, 1024),
|
||||||
keep_aspect: false,
|
keep_aspect: false,
|
||||||
},
|
},
|
||||||
scale: WindowScalePolicy::TrySystemScaleFactor,
|
scale: WindowScalePolicy::TrySystemScaleFactor,
|
||||||
|
|
26
src/event.rs
26
src/event.rs
|
@ -1,4 +1,4 @@
|
||||||
use crate::WindowInfo;
|
use crate::{WindowInfo, Point};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum KeyboardEvent {
|
pub enum KeyboardEvent {
|
||||||
|
@ -41,28 +41,20 @@ pub enum ScrollDelta {
|
||||||
pub struct MouseClick {
|
pub struct MouseClick {
|
||||||
pub button: MouseButton,
|
pub button: MouseButton,
|
||||||
pub click_count: usize,
|
pub click_count: usize,
|
||||||
/// The logical X coordinate of the mouse position
|
/// The logical coordinates of the mouse position
|
||||||
logical_x: i32,
|
logical_pos: Point<i32>,
|
||||||
/// The logical Y coordinate of the mouse position
|
/// The physical coordinates of the mouse position
|
||||||
logical_y: i32,
|
physical_pos: Point<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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum MouseEvent {
|
pub enum MouseEvent {
|
||||||
/// The mouse cursor was moved
|
/// The mouse cursor was moved
|
||||||
CursorMoved {
|
CursorMoved {
|
||||||
/// The logical X coordinate of the mouse position
|
/// The logical coordinates of the mouse position
|
||||||
logical_x: i32,
|
logical_pos: Point<i32>,
|
||||||
/// The logical Y coordinate of the mouse position
|
/// The physical coordinates of the mouse position
|
||||||
logical_y: i32,
|
physical_pos: Point<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.
|
/// A mouse button was pressed.
|
||||||
|
|
30
src/lib.rs
30
src/lib.rs
|
@ -45,6 +45,36 @@ impl WindowHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
pub struct Point<T> {
|
||||||
|
pub x: T,
|
||||||
|
pub y: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Point<T> {
|
||||||
|
pub fn new(x: T, y: T) -> Self {
|
||||||
|
Self { x, y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Point<f64>> for Point<i32> {
|
||||||
|
fn from(p: Point<f64>) -> Point<i32> {
|
||||||
|
Point::new(p.x.round() as i32, p.y.round() as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
pub struct Size {
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Size {
|
||||||
|
pub fn new(width: u32, height: u32) -> Self {
|
||||||
|
Self { width, height }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type WindowOpenResult = Result<WindowInfo, ()>;
|
type WindowOpenResult = Result<WindowInfo, ()>;
|
||||||
|
|
||||||
pub trait WindowHandler {
|
pub trait WindowHandler {
|
||||||
|
|
|
@ -1,64 +1,51 @@
|
||||||
|
use crate::{Size, Point};
|
||||||
|
|
||||||
/// The info about the window
|
/// The info about the window
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct WindowInfo {
|
pub struct WindowInfo {
|
||||||
/// The physical the width of the window
|
logical_size: Size,
|
||||||
physical_width: u32,
|
physical_size: Size,
|
||||||
/// The physical height of the window
|
|
||||||
physical_height: u32,
|
|
||||||
/// The logical width of the window
|
|
||||||
logical_width: u32,
|
|
||||||
/// The logical height of the window
|
|
||||||
logical_height: u32,
|
|
||||||
/// The scale factor
|
|
||||||
scale: f64,
|
scale: f64,
|
||||||
scale_recip: f64,
|
scale_recip: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowInfo {
|
impl WindowInfo {
|
||||||
pub fn from_logical_size(logical_width: u32, logical_height: u32, scale: f64) -> Self {
|
pub fn from_logical_size(logical_size: Size, scale: f64) -> Self {
|
||||||
let scale_recip = 1.0 / scale;
|
let scale_recip = 1.0 / scale;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
physical_width: (logical_width as f64 * scale).round() as u32,
|
logical_size,
|
||||||
physical_height: (logical_height as f64 * scale).round() as u32,
|
physical_size: Size {
|
||||||
logical_width,
|
width: (logical_size.width as f64 * scale).round() as u32,
|
||||||
logical_height,
|
height: (logical_size.height as f64 * scale).round() as u32,
|
||||||
|
},
|
||||||
scale,
|
scale,
|
||||||
scale_recip,
|
scale_recip,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_physical_size(physical_width: u32, physical_height: u32, scale: f64) -> Self {
|
pub fn from_physical_size(physical_size: Size, scale: f64) -> Self {
|
||||||
let scale_recip = 1.0 / scale;
|
let scale_recip = 1.0 / scale;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
physical_width,
|
logical_size: Size {
|
||||||
physical_height,
|
width: (physical_size.width as f64 * scale_recip).round() as u32,
|
||||||
logical_width: (physical_width as f64 * scale_recip).round() as u32,
|
height: (physical_size.height as f64 * scale_recip).round() as u32,
|
||||||
logical_height: (physical_height as f64 * scale_recip).round() as u32,
|
},
|
||||||
|
physical_size,
|
||||||
scale,
|
scale,
|
||||||
scale_recip,
|
scale_recip,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The physical width of the window
|
/// The logical size of the window
|
||||||
pub fn physical_width(&self) -> u32 {
|
pub fn logical_size(&self) -> Size {
|
||||||
self.physical_width
|
self.logical_size
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The physical height of the window
|
/// The physical size of the window
|
||||||
pub fn physical_height(&self) -> u32 {
|
pub fn physical_size(&self) -> Size {
|
||||||
self.physical_height
|
self.physical_size
|
||||||
}
|
|
||||||
|
|
||||||
/// The logical width of the window
|
|
||||||
pub fn logical_width(&self) -> u32 {
|
|
||||||
self.logical_width
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The logical height of the window
|
|
||||||
pub fn logical_height(&self) -> u32 {
|
|
||||||
self.logical_height
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The scale factor of the window
|
/// The scale factor of the window
|
||||||
|
@ -67,18 +54,18 @@ impl WindowInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert physical coordinates to logical coordinates
|
/// Convert physical coordinates to logical coordinates
|
||||||
pub fn physical_to_logical(&self, x: f64, y: f64) -> (f64, f64) {
|
pub fn physical_to_logical(&self, physical: Point<f64>) -> Point<f64> {
|
||||||
(
|
Point {
|
||||||
x * self.scale_recip,
|
x: physical.x * self.scale_recip,
|
||||||
y * self.scale_recip
|
y: physical.y * self.scale_recip
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert logical coordinates to physical coordinates
|
/// Convert logical coordinates to physical coordinates
|
||||||
pub fn logical_to_physical(&self, x: f64, y: f64) -> (f64, f64) {
|
pub fn logical_to_physical(&self, logical: Point<f64>) -> Point<f64> {
|
||||||
(
|
Point {
|
||||||
x * self.scale,
|
x: logical.x * self.scale,
|
||||||
y * self.scale
|
y: logical.y * self.scale
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,31 +1,31 @@
|
||||||
use crate::{WindowInfo, Parent};
|
use crate::{WindowInfo, Parent, Size};
|
||||||
|
|
||||||
/// The size of the window
|
/// The size of the window
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum WindowSize {
|
pub enum WindowSize {
|
||||||
/// Use logical width and height
|
/// Use logical width and height
|
||||||
Logical(u32, u32),
|
Logical(Size),
|
||||||
/// Use physical width and height
|
/// Use physical width and height
|
||||||
Physical(u32, u32),
|
Physical(Size),
|
||||||
/// Use minimum and maximum logical width and height
|
/// Use minimum and maximum logical width and height
|
||||||
MinMaxLogical {
|
MinMaxLogical {
|
||||||
/// The initial logical width and height
|
/// The initial logical width and height
|
||||||
initial_size: (u32, u32),
|
initial_size: Size,
|
||||||
/// The minimum logical width and height
|
/// The minimum logical width and height
|
||||||
min_size: (u32, u32),
|
min_size: Size,
|
||||||
/// The maximum logical width and height
|
/// The maximum logical width and height
|
||||||
max_size: (u32, u32),
|
max_size: Size,
|
||||||
/// Whether to keep the aspect ratio when resizing (true), or not (false)
|
/// Whether to keep the aspect ratio when resizing (true), or not (false)
|
||||||
keep_aspect: bool,
|
keep_aspect: bool,
|
||||||
},
|
},
|
||||||
/// Use minimum and maximum physical width and height
|
/// Use minimum and maximum physical width and height
|
||||||
MinMaxPhysical {
|
MinMaxPhysical {
|
||||||
/// The initial physical width and height
|
/// The initial physical width and height
|
||||||
initial_size: (u32, u32),
|
initial_size: Size,
|
||||||
/// The minimum physical width and height
|
/// The minimum physical width and height
|
||||||
min_size: (u32, u32),
|
min_size: Size,
|
||||||
/// The maximum physical width and height
|
/// The maximum physical width and height
|
||||||
max_size: (u32, u32),
|
max_size: Size,
|
||||||
/// Whether to keep the aspect ratio when resizing (true), or not (false)
|
/// Whether to keep the aspect ratio when resizing (true), or not (false)
|
||||||
keep_aspect: bool,
|
keep_aspect: bool,
|
||||||
},
|
},
|
||||||
|
@ -61,13 +61,13 @@ pub struct WindowOpenOptions {
|
||||||
impl WindowOpenOptions {
|
impl WindowOpenOptions {
|
||||||
pub(crate) fn window_info_from_scale(&self, scale: f64) -> WindowInfo {
|
pub(crate) fn window_info_from_scale(&self, scale: f64) -> WindowInfo {
|
||||||
match self.size {
|
match self.size {
|
||||||
WindowSize::Logical(w, h) => WindowInfo::from_logical_size(w, h, scale),
|
WindowSize::Logical(size) => WindowInfo::from_logical_size(size, scale),
|
||||||
WindowSize::Physical(w, h) => WindowInfo::from_physical_size(w, h, scale),
|
WindowSize::Physical(size) => WindowInfo::from_physical_size(size, scale),
|
||||||
WindowSize::MinMaxLogical { initial_size, .. } => {
|
WindowSize::MinMaxLogical { initial_size, .. } => {
|
||||||
WindowInfo::from_logical_size(initial_size.0, initial_size.1, scale)
|
WindowInfo::from_logical_size(initial_size, scale)
|
||||||
},
|
},
|
||||||
WindowSize::MinMaxPhysical { initial_size, .. } => {
|
WindowSize::MinMaxPhysical { initial_size, .. } => {
|
||||||
WindowInfo::from_logical_size(initial_size.0, initial_size.1, scale)
|
WindowInfo::from_logical_size(initial_size, scale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use super::XcbConnection;
|
||||||
use crate::{
|
use crate::{
|
||||||
Event, KeyboardEvent, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta, WindowEvent,
|
Event, KeyboardEvent, MouseButton, MouseCursor, MouseEvent, Parent, ScrollDelta, WindowEvent,
|
||||||
WindowHandle, WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult,
|
WindowHandle, WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult,
|
||||||
WindowScalePolicy,
|
WindowScalePolicy, Size, Point,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
|
@ -25,7 +25,7 @@ pub struct Window {
|
||||||
frame_interval: Duration,
|
frame_interval: Duration,
|
||||||
event_loop_running: bool,
|
event_loop_running: bool,
|
||||||
|
|
||||||
new_physical_size: Option<(u32, u32)>
|
new_physical_size: Option<Size>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -99,8 +99,8 @@ impl Window {
|
||||||
parent_id,
|
parent_id,
|
||||||
0, // x coordinate of the new window
|
0, // x coordinate of the new window
|
||||||
0, // y coordinate of the new window
|
0, // y coordinate of the new window
|
||||||
window_info.physical_width() as u16, // window width
|
window_info.physical_size().width as u16, // window width
|
||||||
window_info.physical_height() as u16, // window height
|
window_info.physical_size().height as u16, // window height
|
||||||
0, // window border
|
0, // window border
|
||||||
xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
|
xcb::WINDOW_CLASS_INPUT_OUTPUT as u16,
|
||||||
screen.root_visual(),
|
screen.root_visual(),
|
||||||
|
@ -200,10 +200,9 @@ impl Window {
|
||||||
self.handle_xcb_event(handler, event);
|
self.handle_xcb_event(handler, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((width, height)) = self.new_physical_size.take() {
|
if let Some(size) = self.new_physical_size.take() {
|
||||||
self.window_info = WindowInfo::from_physical_size(
|
self.window_info = WindowInfo::from_physical_size(
|
||||||
width,
|
size,
|
||||||
height,
|
|
||||||
self.window_info.scale()
|
self.window_info.scale()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -308,10 +307,9 @@ impl Window {
|
||||||
xcb::CONFIGURE_NOTIFY => {
|
xcb::CONFIGURE_NOTIFY => {
|
||||||
let event = unsafe { xcb::cast_event::<xcb::ConfigureNotifyEvent>(&event) };
|
let event = unsafe { xcb::cast_event::<xcb::ConfigureNotifyEvent>(&event) };
|
||||||
|
|
||||||
let new_physical_size = (event.width() as u32, event.height() as u32);
|
let new_physical_size = Size::new(event.width() as u32, event.height() as u32);
|
||||||
let cur_physical_size = (self.window_info.physical_width(), self.window_info.physical_height());
|
|
||||||
|
|
||||||
if self.new_physical_size.is_some() || new_physical_size != cur_physical_size {
|
if self.new_physical_size.is_some() || new_physical_size != self.window_info.physical_size() {
|
||||||
self.new_physical_size = Some(new_physical_size);
|
self.new_physical_size = Some(new_physical_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,18 +322,14 @@ impl Window {
|
||||||
let detail = event.detail();
|
let detail = event.detail();
|
||||||
|
|
||||||
if detail != 4 && detail != 5 {
|
if detail != 4 && detail != 5 {
|
||||||
let (logical_x, logical_y) = self.window_info.physical_to_logical(
|
let physical_pos = Point::new(event.event_x() as f64, event.event_y() as f64);
|
||||||
event.event_x() as f64,
|
let logical_pos = self.window_info.physical_to_logical(physical_pos);
|
||||||
event.event_y() as f64
|
|
||||||
);
|
|
||||||
|
|
||||||
handler.on_event(
|
handler.on_event(
|
||||||
self,
|
self,
|
||||||
Event::Mouse(MouseEvent::CursorMoved {
|
Event::Mouse(MouseEvent::CursorMoved {
|
||||||
logical_x: logical_x.round() as i32,
|
logical_pos: logical_pos.into(),
|
||||||
logical_y: logical_y.round() as i32,
|
physical_pos: physical_pos.into(),
|
||||||
physical_x: event.event_x() as i32,
|
|
||||||
physical_y: event.event_y() as i32,
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,10 +158,10 @@ impl XcbConnection {
|
||||||
pub fn set_resize_policy(&self, window_id: u32, size: &WindowSize, scale: f64) {
|
pub fn set_resize_policy(&self, window_id: u32, size: &WindowSize, scale: f64) {
|
||||||
match size {
|
match size {
|
||||||
WindowSize::MinMaxLogical { min_size, max_size, keep_aspect, .. } => {
|
WindowSize::MinMaxLogical { min_size, max_size, keep_aspect, .. } => {
|
||||||
let min_physical_width = (min_size.0 as f64 * scale).round() as i32;
|
let min_physical_width = (min_size.width as f64 * scale).round() as i32;
|
||||||
let min_physical_height = (min_size.1 as f64 * scale).round() as i32;
|
let min_physical_height = (min_size.height as f64 * scale).round() as i32;
|
||||||
let max_physical_width = (max_size.0 as f64 * scale).round() as i32;
|
let max_physical_width = (max_size.width as f64 * scale).round() as i32;
|
||||||
let max_physical_height = (max_size.1 as f64 * scale).round() as i32;
|
let max_physical_height = (max_size.height as f64 * scale).round() as i32;
|
||||||
|
|
||||||
let size_hints = if *keep_aspect {
|
let size_hints = if *keep_aspect {
|
||||||
xcb_util::icccm::SizeHints::empty()
|
xcb_util::icccm::SizeHints::empty()
|
||||||
|
@ -192,17 +192,17 @@ impl XcbConnection {
|
||||||
WindowSize::MinMaxPhysical { min_size, max_size, keep_aspect, .. } => {
|
WindowSize::MinMaxPhysical { min_size, max_size, keep_aspect, .. } => {
|
||||||
let size_hints = if *keep_aspect {
|
let size_hints = if *keep_aspect {
|
||||||
xcb_util::icccm::SizeHints::empty()
|
xcb_util::icccm::SizeHints::empty()
|
||||||
.min_size(min_size.0 as i32, min_size.1 as i32)
|
.min_size(min_size.width as i32, min_size.height as i32)
|
||||||
.max_size(max_size.0 as i32, max_size.1 as i32)
|
.max_size(max_size.width as i32, max_size.height as i32)
|
||||||
.aspect(
|
.aspect(
|
||||||
(min_size.0 as i32, min_size.1 as i32),
|
(min_size.width as i32, min_size.height as i32),
|
||||||
(max_size.0 as i32, max_size.1 as i32),
|
(max_size.width as i32, max_size.height as i32),
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
} else {
|
} else {
|
||||||
xcb_util::icccm::SizeHints::empty()
|
xcb_util::icccm::SizeHints::empty()
|
||||||
.min_size(min_size.0 as i32, min_size.1 as i32)
|
.min_size(min_size.width as i32, min_size.height as i32)
|
||||||
.max_size(max_size.0 as i32, max_size.1 as i32)
|
.max_size(max_size.width as i32, max_size.height as i32)
|
||||||
.build()
|
.build()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue