diff options
-rw-r--r-- | src/events.rs | 4 | ||||
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | src/phosphor.rs | 207 | ||||
-rw-r--r-- | src/window.rs | 7 | ||||
-rw-r--r-- | src/window_builder.rs | 4 | ||||
-rw-r--r-- | src/window_program.rs | 5 |
6 files changed, 117 insertions, 113 deletions
diff --git a/src/events.rs b/src/events.rs index f62b1f5..78ef20a 100644 --- a/src/events.rs +++ b/src/events.rs @@ -39,7 +39,9 @@ pub enum Event { KeyboardInput { key: KeyCode, action: Action }, CharacterInput(char), ModifierChange(ModifiersState), - FileDrop(PathBuf), + DropFile(PathBuf), + HoverFile(PathBuf), + HoverFileCancel, } @@ -4,8 +4,7 @@ mod window_builder; mod window_program; mod phosphor; -pub use events::{Request, Event, Action, Axis, MouseButton, SizeBounds}; -pub(crate) use window::{PhosphorWindow, PointerState}; +pub use events::*; pub use window_builder::WindowBuilder; pub use window_program::WindowProgram; diff --git a/src/phosphor.rs b/src/phosphor.rs index 34d5be5..122f36f 100644 --- a/src/phosphor.rs +++ b/src/phosphor.rs @@ -1,4 +1,5 @@ use crate::*; +use window::{PhosphorWindow, PointerState}; use winit::application::ApplicationHandler; use winit::dpi::{PhysicalPosition, PhysicalSize}; @@ -20,16 +21,13 @@ pub struct Phosphor { impl Phosphor { pub fn new() -> Result<Self, ()> { if let Ok(event_loop) = EventLoop::new() { - Ok( Self { - event_loop, - builders: Vec::new(), - } ) + Ok( Self { event_loop, builders: Vec::new() } ) } else { Err(()) } } - pub fn create_window(&mut self, window: WindowBuilder) { + pub fn add_window(&mut self, window: WindowBuilder) { self.builders.push(window); } @@ -56,6 +54,7 @@ impl PhosphorApplication { let mut marked_ids = Vec::new(); for (id, window) in &mut self.windows { if window.marked_for_destruction { + // Allow marked windows to create new windows. window.handle_requests(&mut self.builders); marked_ids.push(id.clone()); } @@ -81,109 +80,117 @@ impl PhosphorApplication { } pub fn handle_window_event(&mut self, event: WindowEvent, id: WindowId) { - let window = match self.windows.get_mut(&id) { - Some(w) => w, - None => return, - }; - macro_rules! handle { ($event:expr) => { - window.program.handle_event($event, &mut window.requests.as_writer()) - }; } - - match event { - WindowEvent::Resized( PhysicalSize { width, height } ) => { - window.update_buffer_size(Dimensions::new(width, height)); - } - WindowEvent::CloseRequested => { - handle!(Event::CloseRequest); - } - WindowEvent::Destroyed => { - handle!(Event::Close); - } - WindowEvent::DroppedFile(path) => { - handle!(Event::FileDrop(path)); - } - WindowEvent::Focused(focused) => { - handle!(Event::FocusChange(focused)); - } - WindowEvent::KeyboardInput { event, .. } => { - if let Some(smol_str) = event.text { - if event.state.is_pressed() { - for c in smol_str.chars() { - handle!(Event::CharacterInput(c)); - } - } - } - if let PhysicalKey::Code(code) = event.physical_key { - handle!(Event::KeyboardInput { - key: code, - action: event.state.into(), - }); + if let Some(window) = self.windows.get_mut(&id) { + macro_rules! writer { () => { &mut window.requests.as_writer() } } + match event { + WindowEvent::RedrawRequested => + window.redraw(), + WindowEvent::CloseRequested => + window.program.handle_event(Event::CloseRequest, writer!()), + WindowEvent::Destroyed => + window.program.handle_event(Event::Close, writer!()), + WindowEvent::Resized( PhysicalSize { width, height } ) => + window.update_buffer_size(Dimensions::new(width, height)), + WindowEvent::Focused(focused) => + window.program.handle_event(Event::FocusChange(focused), writer!()), + WindowEvent::CursorEntered { .. } => { + window.pointer_state = PointerState::In; + window.program.handle_event(Event::CursorEnter, writer!()); } - } - WindowEvent::ModifiersChanged(modifiers) => { - handle!(Event::ModifierChange(modifiers.state())); - } - WindowEvent::CursorMoved { position, .. } => { - let pointer = Position::new( - position.x as i32 / window.scale() as i32, - position.y as i32 / window.scale() as i32, - ); - if window.pointer != Some(pointer) { - window.pointer = Some(pointer); - handle!(Event::CursorMove(pointer)); + WindowEvent::CursorLeft { .. } => { + if window.mouse_buttons.iter().all(|b| !b) { + window.pointer_state = PointerState::Out; + window.program.handle_event(Event::CursorExit, writer!()); + } else { + window.pointer_state = PointerState::PendingOut; + } } - } - WindowEvent::CursorEntered { .. } => { - window.pointer_state = PointerState::In; - handle!(Event::CursorEnter); - } - WindowEvent::CursorLeft { .. } => { - if window.mouse_buttons.iter().all(|b| !b) { - window.pointer_state = PointerState::Out; - handle!(Event::CursorExit); - } else { - window.pointer_state = PointerState::PendingOut; + WindowEvent::CursorMoved { position, .. } => { + let pointer = Position::new( + position.x as i32 / window.scale() as i32, + position.y as i32 / window.scale() as i32, + ); + if window.pointer != Some(pointer) { + window.pointer = Some(pointer); + window.program.handle_event(Event::CursorMove(pointer), writer!()); + } } - } - WindowEvent::MouseWheel { delta, .. } => match delta { - MouseScrollDelta::LineDelta(x, y) => { - if x != 0.0 { handle!(Event::ScrollLines { axis: Axis::Horizontal, distance: -x }); } - if y != 0.0 { handle!(Event::ScrollLines { axis: Axis::Vertical, distance: -y }); } + WindowEvent::MouseWheel { delta, .. } => match delta { + MouseScrollDelta::LineDelta(x, y) => { + if x != 0.0 { + let axis = Axis::Horizontal; let distance = -x; + window.program.handle_event(Event::ScrollLines { axis, distance }, writer!()); + } + if y != 0.0 { + let axis = Axis::Vertical; let distance = -y; + window.program.handle_event(Event::ScrollLines { axis, distance }, writer!()); + } + } + MouseScrollDelta::PixelDelta(PhysicalPosition {x, y}) => { + if x != 0.0 { + let axis = Axis::Horizontal; let distance = -x as f32; + window.program.handle_event(Event::ScrollPixels { axis, distance }, writer!()); + } + if y != 0.0 { + let axis = Axis::Vertical; let distance = -y as f32; + window.program.handle_event(Event::ScrollPixels { axis, distance }, writer!()); + } + } } - MouseScrollDelta::PixelDelta(PhysicalPosition {x, y}) => { - if x != 0.0 { handle!(Event::ScrollPixels { axis: Axis::Horizontal, distance: -x as f32 }); } - if y != 0.0 { handle!(Event::ScrollPixels { axis: Axis::Vertical, distance: -y as f32 }); } + WindowEvent::MouseInput { state, button, .. } => { + let action = state.into(); + match button { + WinitMouseButton::Left => + window.program.handle_event(Event::MouseButton { button: MouseButton::Left, action }, writer!()), + WinitMouseButton::Middle => + window.program.handle_event(Event::MouseButton { button: MouseButton::Middle, action }, writer!()), + WinitMouseButton::Right => + window.program.handle_event(Event::MouseButton { button: MouseButton::Right, action }, writer!()), + WinitMouseButton::Back => + window.program.handle_event(Event::MouseButton { button: MouseButton::Back, action }, writer!()), + WinitMouseButton::Forward => + window.program.handle_event(Event::MouseButton { button: MouseButton::Forward, action }, writer!()), + _ => (), + } + // Record mouse button hold states, and mark cursor as out when all are released. + let button_index = match button { + WinitMouseButton::Left => 0, + WinitMouseButton::Middle => 1, + WinitMouseButton::Right => 2, + WinitMouseButton::Back => 3, + WinitMouseButton::Forward => 4, + _ => return, + }; + window.mouse_buttons[button_index] = action.is_pressed(); + if window.pointer_state == PointerState::PendingOut && window.mouse_buttons.iter().all(|b| !b) { + window.pointer_state = PointerState::Out; + window.program.handle_event(Event::CursorExit, writer!()); + } } - } - WindowEvent::MouseInput { state, button, .. } => { - let action = state.into(); - match button { - WinitMouseButton::Left => handle!(Event::MouseButton { button: MouseButton::Left, action }), - WinitMouseButton::Middle => handle!(Event::MouseButton { button: MouseButton::Middle, action }), - WinitMouseButton::Right => handle!(Event::MouseButton { button: MouseButton::Right, action }), - WinitMouseButton::Back => handle!(Event::MouseButton { button: MouseButton::Back, action }), - WinitMouseButton::Forward => handle!(Event::MouseButton { button: MouseButton::Forward, action }), - _ => (), + WindowEvent::KeyboardInput { event, .. } => { + if let Some(smol_str) = event.text { + if event.state.is_pressed() { + for c in smol_str.chars() { + window.program.handle_event(Event::CharacterInput(c), writer!()); + } + } + } + if let PhysicalKey::Code(code) = event.physical_key { + let key = code; let action = event.state.into(); + window.program.handle_event(Event::KeyboardInput { key, action }, writer!()); + } } - // Keep track of mouse button hold states, and mark cursor as out when all are released. - let button_index = match button { - WinitMouseButton::Left => 0, - WinitMouseButton::Middle => 1, - WinitMouseButton::Right => 2, - WinitMouseButton::Back => 3, - WinitMouseButton::Forward => 4, - _ => return, - }; - window.mouse_buttons[button_index] = action.is_pressed(); - if window.pointer_state == PointerState::PendingOut && window.mouse_buttons.iter().all(|b| !b) { - window.pointer_state = PointerState::Out; - handle!(Event::CursorExit); + WindowEvent::ModifiersChanged(modifiers) => { + window.program.handle_event(Event::ModifierChange(modifiers.state()), writer!()); } + WindowEvent::DroppedFile(path) => + window.program.handle_event(Event::DropFile(path), writer!()), + WindowEvent::HoveredFile(path) => + window.program.handle_event(Event::HoverFile(path), writer!()), + WindowEvent::HoveredFileCancelled => + window.program.handle_event(Event::HoverFileCancel, writer!()), + _ => (), } - WindowEvent::RedrawRequested => { - window.redraw(); - }, - _ => (), } } } diff --git a/src/window.rs b/src/window.rs index 8d118fa..7403edb 100644 --- a/src/window.rs +++ b/src/window.rs @@ -10,6 +10,7 @@ use winit::window::{CursorIcon, Fullscreen, Window}; use std::rc::Rc; use std::cmp::{min, max}; + fn to_physical_size(dimensions: Dimensions, scale: u32) -> PhysicalSize<u32> { PhysicalSize { width: max(1, dimensions.width * scale), @@ -20,9 +21,9 @@ fn to_physical_size(dimensions: Dimensions, scale: u32) -> PhysicalSize<u32> { #[derive(Copy, Clone, Debug, PartialEq)] pub enum PointerState { - In, - Out, - PendingOut, + In, // pointer is within the screen bounds + Out, // pointer is outside the screen bounds + PendingOut, // pointer is dragging outside the screen bounds } diff --git a/src/window_builder.rs b/src/window_builder.rs index 6761b8d..231aada 100644 --- a/src/window_builder.rs +++ b/src/window_builder.rs @@ -14,8 +14,8 @@ pub struct WindowBuilder { } impl WindowBuilder { - pub fn new(program: Box<dyn WindowProgram>) -> Self { - Self { + pub fn from_program(program: Box<dyn WindowProgram>) -> Self { + WindowBuilder { program, size_bounds: None, dimensions: None, diff --git a/src/window_program.rs b/src/window_program.rs index 9a5df2d..fe0e4c7 100644 --- a/src/window_program.rs +++ b/src/window_program.rs @@ -1,13 +1,8 @@ use crate::*; -use buffer::Buffer; -use event_queue::*; - pub trait WindowProgram { fn handle_event(&mut self, event: Event, requests: &mut EventWriter<Request>); - fn process(&mut self, requests: &mut EventWriter<Request>); - fn render(&mut self, buffer: &mut Buffer, full: bool); } |