summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/events.rs4
-rw-r--r--src/lib.rs3
-rw-r--r--src/phosphor.rs207
-rw-r--r--src/window.rs7
-rw-r--r--src/window_builder.rs4
-rw-r--r--src/window_program.rs5
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,
}
diff --git a/src/lib.rs b/src/lib.rs
index 1da2e91..442d5bc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
}