Handle scroll events and use winit Modifiers and MouseButton (#178)

This commit is contained in:
Aaron Muir Hamilton 2024-02-29 13:45:26 -05:00 committed by GitHub
parent 277160b484
commit 6500c5058b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 124 additions and 1538 deletions

1498
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,8 @@ cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
[features]
default = ["x11", "taffy"]
x11 = ["glazier/x11"]
wayland = ["glazier/wayland"]
x11 = ["winit/x11"]
wayland = ["winit/wayland"]
taffy = ["dep:taffy"]
[dependencies]
@ -60,11 +60,6 @@ fnv = "1.0.7"
instant = { version = "0.1.6", features = ["wasm-bindgen"] }
winit = { version = "0.29", features = ["rwh_05"] }
[dependencies.glazier]
git = "https://github.com/linebender/glazier"
rev = "8d2a4b2cafd5e6be49bfb4ac8d0bd26fe02f036e"
default-features = false
[dev-dependencies]
env_logger = "0.10.0"
test-log = "0.2.11"

View File

@ -14,20 +14,24 @@
use std::{num::NonZeroUsize, sync::Arc};
use glazier::{Modifiers, PointerButton};
use vello::{
kurbo::{Affine, Point, Size},
kurbo::{Affine, Point, Size, Vec2},
peniko::Color,
util::{RenderContext, RenderSurface},
AaSupport, RenderParams, Renderer, RendererOptions, Scene,
};
use winit::{
event::WindowEvent,
dpi::PhysicalPosition,
event::{ElementState, Modifiers, MouseButton, MouseScrollDelta, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::{Window, WindowBuilder},
};
use crate::{app::App, view::View, widget::Event, widget::PointerCrusher};
use crate::{
app::App,
view::View,
widget::{Event, PointerCrusher, ScrollDelta},
};
// This is a bit of a hack just to get a window launched. The real version
// would deal with multiple windows and have other ways to configure things.
@ -75,72 +79,31 @@ impl<T: Send + 'static, V: View<T> + 'static> AppLauncher<T, V> {
let mut main_state = MainState::new(self.app, window);
event_loop
.run(move |event, elwt| match event {
winit::event::Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => elwt.exit(),
winit::event::Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => main_state.paint(),
winit::event::Event::WindowEvent {
event: WindowEvent::Resized(winit::dpi::PhysicalSize { width, height }),
..
} => main_state.size(Size {
width: width.into(),
height: height.into(),
}),
winit::event::Event::WindowEvent {
event: WindowEvent::ModifiersChanged(modifiers),
..
} => {
let mut m = Modifiers::empty();
let ms = modifiers.state();
if ms.contains(winit::keyboard::ModifiersState::SHIFT) {
m |= Modifiers::SHIFT;
}
if ms.contains(winit::keyboard::ModifiersState::CONTROL) {
m |= Modifiers::CONTROL;
}
if ms.contains(winit::keyboard::ModifiersState::SUPER) {
m |= Modifiers::SUPER;
}
if ms.contains(winit::keyboard::ModifiersState::ALT) {
m |= Modifiers::ALT;
}
main_state.mods(m);
}
winit::event::Event::WindowEvent {
event:
.run(move |event, elwt| {
if let winit::event::Event::WindowEvent { event: e, .. } = event {
match e {
WindowEvent::CloseRequested => elwt.exit(),
WindowEvent::RedrawRequested => main_state.paint(),
WindowEvent::Resized(winit::dpi::PhysicalSize { width, height }) => {
main_state.size(Size {
width: width.into(),
height: height.into(),
});
}
WindowEvent::ModifiersChanged(modifiers) => main_state.mods(modifiers),
WindowEvent::CursorMoved {
position: winit::dpi::PhysicalPosition { x, y },
..
} => main_state.pointer_move(Point { x, y }),
WindowEvent::CursorLeft { .. } => main_state.pointer_leave(),
WindowEvent::MouseInput { state, button, .. } => match state {
ElementState::Pressed => main_state.pointer_down(button),
ElementState::Released => main_state.pointer_up(button),
},
..
} => main_state.pointer_move(Point { x, y }),
winit::event::Event::WindowEvent {
event: WindowEvent::CursorLeft { .. },
..
} => main_state.pointer_leave(),
winit::event::Event::WindowEvent {
event: WindowEvent::MouseInput { state, button, .. },
..
} => {
let b = match button {
winit::event::MouseButton::Left => PointerButton::Primary,
winit::event::MouseButton::Right => PointerButton::Secondary,
winit::event::MouseButton::Middle => PointerButton::Auxiliary,
winit::event::MouseButton::Back => PointerButton::X1,
winit::event::MouseButton::Forward => PointerButton::X2,
winit::event::MouseButton::Other(_) => PointerButton::None,
};
match state {
winit::event::ElementState::Pressed => main_state.pointer_down(b),
winit::event::ElementState::Released => main_state.pointer_up(b),
WindowEvent::MouseWheel { delta, .. } => main_state.pointer_wheel(delta),
_ => (),
}
}
_ => (),
})
.unwrap();
}
@ -187,13 +150,13 @@ where
self.window.request_redraw();
}
fn pointer_down(&mut self, button: PointerButton) {
fn pointer_down(&mut self, button: MouseButton) {
self.app
.window_event(Event::MouseDown(self.main_pointer.pressed(button)));
self.window.request_redraw();
}
fn pointer_up(&mut self, button: PointerButton) {
fn pointer_up(&mut self, button: MouseButton) {
self.app
.window_event(Event::MouseUp(self.main_pointer.released(button)));
self.window.request_redraw();
@ -204,6 +167,19 @@ where
self.window.request_redraw();
}
fn pointer_wheel(&mut self, delta: MouseScrollDelta) {
self.app
.window_event(Event::MouseWheel(self.main_pointer.wheel(match delta {
MouseScrollDelta::LineDelta(x, y) => {
ScrollDelta::Lines(x.trunc() as isize, y.trunc() as isize)
}
MouseScrollDelta::PixelDelta(PhysicalPosition { x, y }) => {
ScrollDelta::Precise(Vec2::new(x, y) * (1.0 / self.window.scale_factor()))
}
})));
self.window.request_redraw();
}
fn paint(&mut self) {
self.app.paint();
self.render();

View File

@ -34,7 +34,7 @@ pub use box_constraints::BoxConstraints;
pub use button::Button;
pub use contexts::{CxState, EventCx, LayoutCx, LifeCycleCx, PaintCx, UpdateCx};
pub use linear_layout::LinearLayout;
pub use raw_event::{Event, LifeCycle, MouseEvent, PointerCrusher, ViewContext};
pub use raw_event::{Event, LifeCycle, MouseEvent, PointerCrusher, ScrollDelta, ViewContext};
pub use switch::Switch;
pub use text::TextWidget;
pub use tree_structure::TreeStructure;

View File

@ -16,9 +16,10 @@
//!
//! Note: arguably this module should be renamed, perhaps we should use
//! "event" for this level and maybe "message" at the View level.
use std::collections::HashSet;
use glazier::{Modifiers, PointerButton, PointerButtons};
use vello::kurbo::{Point, Rect, Vec2};
use winit::event::{Modifiers, MouseButton};
#[derive(Debug, Clone)]
pub enum Event {
@ -35,12 +36,18 @@ pub struct MouseEvent {
pub pos: Point,
/// The position of the mouse in the window coordinate space.
pub window_pos: Point,
pub buttons: PointerButtons,
pub buttons: HashSet<MouseButton>,
pub mods: Modifiers,
pub count: u8,
pub focus: bool,
pub button: PointerButton,
pub wheel_delta: Vec2,
pub button: Option<MouseButton>,
pub wheel_delta: Option<ScrollDelta>,
}
#[derive(Debug, Clone)]
pub enum ScrollDelta {
Precise(Vec2),
Lines(isize, isize),
}
#[derive(Debug)]
@ -62,12 +69,12 @@ impl Default for MouseEvent {
MouseEvent {
pos: Point::ZERO,
window_pos: Point::ZERO,
buttons: PointerButtons::new(),
buttons: HashSet::<MouseButton>::new(),
mods: Modifiers::default(),
count: 0,
focus: false,
button: PointerButton::None,
wheel_delta: Vec2::ZERO,
button: None,
wheel_delta: None,
}
}
}
@ -100,32 +107,32 @@ impl PointerCrusher {
self.e.mods = mods;
}
pub fn pressed(&mut self, button: PointerButton) -> MouseEvent {
self.e.wheel_delta = Vec2::ZERO;
pub fn pressed(&mut self, button: MouseButton) -> MouseEvent {
self.e.wheel_delta = None;
self.e.buttons.insert(button);
self.e.count = self.counter.count_for_click(self.e.pos);
self.e.button = button;
self.e.button = Some(button);
self.e.clone()
}
pub fn released(&mut self, button: PointerButton) -> MouseEvent {
self.e.wheel_delta = Vec2::ZERO;
self.e.buttons.remove(button);
self.e.button = button;
pub fn released(&mut self, button: MouseButton) -> MouseEvent {
self.e.wheel_delta = None;
self.e.buttons.remove(&button);
self.e.button = Some(button);
self.e.clone()
}
pub fn moved(&mut self, pos: Point) -> MouseEvent {
self.e.wheel_delta = Vec2::ZERO;
self.e.button = PointerButton::None;
self.e.wheel_delta = None;
self.e.button = None;
self.e.pos = pos;
self.e.window_pos = pos;
self.e.clone()
}
pub fn wheel(&mut self, wheel_delta: Vec2) -> MouseEvent {
self.e.wheel_delta = wheel_delta;
self.e.button = PointerButton::None;
pub fn wheel(&mut self, wheel_delta: ScrollDelta) -> MouseEvent {
self.e.wheel_delta = Some(wheel_delta);
self.e.button = None;
self.e.clone()
}
}