1
0
Fork 0

refactor to use conversion between Point and Size to PhyPoint and PhySize

This commit is contained in:
Billy Messenger 2020-10-17 17:27:06 -05:00
parent 6bae3e7507
commit 688d45c720
7 changed files with 129 additions and 89 deletions

View file

@ -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: baseview::Size::new(512, 512), initial_size: baseview::Size::new(512.0, 512.0),
min_size: baseview::Size::new(200, 200), min_size: baseview::Size::new(200.0, 200.0),
max_size: baseview::Size::new(1024, 1024), max_size: baseview::Size::new(1024.0, 1024.0),
keep_aspect: false, keep_aspect: false,
}, },
scale: WindowScalePolicy::TrySystemScaleFactor, scale: WindowScalePolicy::TrySystemScaleFactor,

93
src/coordinates.rs Normal file
View file

@ -0,0 +1,93 @@
use crate::WindowInfo;
/// A point in logical coordinates
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Point {
pub x: f64,
pub y: f64
}
impl Point {
/// Create a new point in logical coordinates
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
/// Convert to actual physical coordinates
#[inline]
pub fn to_physical(&self, window_info: &WindowInfo) -> PhyPoint {
PhyPoint {
x: (self.x * window_info.scale()).round() as i32,
y: (self.y * window_info.scale()).round() as i32,
}
}
}
/// A point in actual physical coordinates
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PhyPoint {
pub x: i32,
pub y: i32
}
impl PhyPoint {
/// Create a new point in actual physical coordinates
pub fn new(x: i32, y: i32) -> Self {
Self { x, y }
}
/// Convert to logical coordinates
#[inline]
pub fn to_logical(&self, window_info: &WindowInfo) -> Point {
Point {
x: f64::from(self.x) * window_info.scale_recip(),
y: f64::from(self.y) * window_info.scale_recip(),
}
}
}
/// A size in logical coordinates
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Size {
pub width: f64,
pub height: f64,
}
impl Size {
/// Create a new size in logical coordinates
pub fn new(width: f64, height: f64) -> Self {
Self { width, height }
}
/// Convert to actual physical size
#[inline]
pub fn to_physical(&self, window_info: &WindowInfo) -> PhySize {
PhySize {
width: (self.width * window_info.scale()).round() as u32,
height: (self.height * window_info.scale()).round() as u32,
}
}
}
/// An actual size in physical coordinates
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PhySize {
pub width: u32,
pub height: u32,
}
impl PhySize {
/// Create a new size in actual physical coordinates
pub fn new(width: u32, height: u32) -> Self {
Self { width, height }
}
/// Convert to logical size
#[inline]
pub fn to_logical(&self, window_info: &WindowInfo) -> Size {
Size {
width: f64::from(self.width) * window_info.scale_recip(),
height: f64::from(self.height) * window_info.scale_recip(),
}
}
}

View file

@ -42,9 +42,7 @@ pub struct MouseClick {
pub button: MouseButton, pub button: MouseButton,
pub click_count: usize, pub click_count: usize,
/// The logical coordinates of the mouse position /// The logical coordinates of the mouse position
logical_pos: Point<i32>, pub position: Point,
/// The physical coordinates of the mouse position
physical_pos: Point<i32>,
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
@ -52,9 +50,7 @@ pub enum MouseEvent {
/// The mouse cursor was moved /// The mouse cursor was moved
CursorMoved { CursorMoved {
/// The logical coordinates of the mouse position /// The logical coordinates of the mouse position
logical_pos: Point<i32>, position: Point,
/// The physical coordinates of the mouse position
physical_pos: Point<i32>,
}, },
/// A mouse button was pressed. /// A mouse button was pressed.

View file

@ -15,11 +15,13 @@ mod macos;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub use macos::*; pub use macos::*;
mod coordinates;
mod event; mod event;
mod keyboard; mod keyboard;
mod mouse_cursor; mod mouse_cursor;
mod window_info; mod window_info;
mod window_open_options; mod window_open_options;
pub use coordinates::*;
pub use event::*; pub use event::*;
pub use keyboard::*; pub use keyboard::*;
pub use mouse_cursor::MouseCursor; pub use mouse_cursor::MouseCursor;
@ -45,36 +47,6 @@ 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 {

View file

@ -25,6 +25,7 @@ use raw_window_handle::{
use crate::{ use crate::{
Event, KeyboardEvent, MouseButton, MouseEvent, Parent::WithParent, ScrollDelta, WindowEvent, Event, KeyboardEvent, MouseButton, MouseEvent, Parent::WithParent, ScrollDelta, WindowEvent,
WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult, WindowScalePolicy, Size, Point, WindowHandler, WindowInfo, WindowOpenOptions, WindowOpenResult, WindowScalePolicy, Size, Point,
PhySize, PhyPoint,
}; };
unsafe fn message_box(title: &str, msg: &str) { unsafe fn message_box(title: &str, msg: &str) {
@ -76,19 +77,19 @@ unsafe extern "system" fn wnd_proc<H: WindowHandler>(
match msg { match msg {
WM_MOUSEMOVE => { WM_MOUSEMOVE => {
let x = (lparam & 0xFFFF) as f64; let x = (lparam & 0xFFFF) as i32;
let y = ((lparam >> 16) & 0xFFFF) as f64; let y = ((lparam >> 16) & 0xFFFF) as i32;
let physical_pos = Point::new(x, y);
let physical_pos = PhyPoint { x, y };
let mut window_state = window_state.borrow_mut(); let mut window_state = window_state.borrow_mut();
let logical_pos = window_state.window_info.physical_to_logical(physical_pos); let logical_pos = physical_pos.to_logical(&window_state.window_info);
window_state.handler.on_event( window_state.handler.on_event(
&mut window, &mut window,
Event::Mouse(MouseEvent::CursorMoved { Event::Mouse(MouseEvent::CursorMoved {
logical_pos: logical_pos.into(), position: logical_pos,
physical_pos: physical_pos.into(),
}), }),
); );
return 0; return 0;

View file

@ -1,26 +1,21 @@
use crate::{Size, Point}; use crate::{Size, PhySize};
/// The info about the window /// The info about the window
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct WindowInfo { pub struct WindowInfo {
logical_size: Size, logical_size: Size,
physical_size: Size, physical_size: PhySize,
scale: f64, scale: f64,
scale_recip: f64, scale_recip: f64,
} }
impl WindowInfo { impl WindowInfo {
pub fn from_logical_size(logical_size: Size, scale: f64) -> Self { pub fn from_logical_size(logical_size: Size, scale: f64) -> Self {
let (scale_recip, physical_size) = if scale == 1.0 { let scale_recip = if scale == 1.0 { 1.0 } else { 1.0 / scale };
(1.0, logical_size)
} else { let physical_size = PhySize {
( width: (logical_size.width * scale).round() as u32,
1.0 / scale, height: (logical_size.height * scale).round() as u32,
Size {
width: (logical_size.width as f64 * scale).round() as u32,
height: (logical_size.height as f64 * scale).round() as u32,
}
)
}; };
Self { Self {
@ -31,18 +26,12 @@ impl WindowInfo {
} }
} }
pub fn from_physical_size(physical_size: Size, scale: f64) -> Self { pub fn from_physical_size(physical_size: PhySize, scale: f64) -> Self {
let (scale_recip, logical_size) = if scale == 1.0 { let scale_recip = if scale == 1.0 { 1.0 } else { 1.0 / scale };
(1.0, physical_size)
} else { let logical_size = Size {
let scale_recip = 1.0 / scale; width: f64::from(physical_size.width) * scale_recip,
( height: f64::from(physical_size.height) * scale_recip,
scale_recip,
Size {
width: (physical_size.width as f64 * scale_recip).round() as u32,
height: (physical_size.height as f64 * scale_recip).round() as u32,
}
)
}; };
Self { Self {
@ -59,7 +48,7 @@ impl WindowInfo {
} }
/// The physical size of the window /// The physical size of the window
pub fn physical_size(&self) -> Size { pub fn physical_size(&self) -> PhySize {
self.physical_size self.physical_size
} }
@ -68,19 +57,8 @@ impl WindowInfo {
self.scale self.scale
} }
/// Convert physical coordinates to logical coordinates /// The reciprocal of the scale factor of the window
pub fn physical_to_logical(&self, physical: Point<f64>) -> Point<f64> { pub fn scale_recip(&self) -> f64 {
Point { self.scale_recip
x: physical.x * self.scale_recip,
y: physical.y * self.scale_recip
}
}
/// Convert logical coordinates to physical coordinates
pub fn logical_to_physical(&self, logical: Point<f64>) -> Point<f64> {
Point {
x: logical.x * self.scale,
y: logical.y * self.scale
}
} }
} }

View file

@ -1,4 +1,4 @@
use crate::{WindowInfo, Parent, Size}; use crate::{WindowInfo, Parent, Size, PhySize};
/// The size of the window /// The size of the window
#[derive(Debug)] #[derive(Debug)]
@ -6,7 +6,7 @@ pub enum WindowSize {
/// Use logical width and height /// Use logical width and height
Logical(Size), Logical(Size),
/// Use physical width and height /// Use physical width and height
Physical(Size), Physical(PhySize),
/// 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
@ -21,11 +21,11 @@ pub enum WindowSize {
/// 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: Size, initial_size: PhySize,
/// The minimum physical width and height /// The minimum physical width and height
min_size: Size, min_size: PhySize,
/// The maximum physical width and height /// The maximum physical width and height
max_size: Size, max_size: PhySize,
/// 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,
}, },