mirror of https://github.com/linebender/xilem
Handle scroll events and use winit Modifiers and MouseButton (#178)
This commit is contained in:
parent
277160b484
commit
6500c5058b
File diff suppressed because it is too large
Load Diff
|
@ -42,8 +42,8 @@ cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]
|
||||||
[features]
|
[features]
|
||||||
default = ["x11", "taffy"]
|
default = ["x11", "taffy"]
|
||||||
|
|
||||||
x11 = ["glazier/x11"]
|
x11 = ["winit/x11"]
|
||||||
wayland = ["glazier/wayland"]
|
wayland = ["winit/wayland"]
|
||||||
taffy = ["dep:taffy"]
|
taffy = ["dep:taffy"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -60,11 +60,6 @@ fnv = "1.0.7"
|
||||||
instant = { version = "0.1.6", features = ["wasm-bindgen"] }
|
instant = { version = "0.1.6", features = ["wasm-bindgen"] }
|
||||||
winit = { version = "0.29", features = ["rwh_05"] }
|
winit = { version = "0.29", features = ["rwh_05"] }
|
||||||
|
|
||||||
[dependencies.glazier]
|
|
||||||
git = "https://github.com/linebender/glazier"
|
|
||||||
rev = "8d2a4b2cafd5e6be49bfb4ac8d0bd26fe02f036e"
|
|
||||||
default-features = false
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
test-log = "0.2.11"
|
test-log = "0.2.11"
|
||||||
|
|
108
src/app_main.rs
108
src/app_main.rs
|
@ -14,20 +14,24 @@
|
||||||
|
|
||||||
use std::{num::NonZeroUsize, sync::Arc};
|
use std::{num::NonZeroUsize, sync::Arc};
|
||||||
|
|
||||||
use glazier::{Modifiers, PointerButton};
|
|
||||||
use vello::{
|
use vello::{
|
||||||
kurbo::{Affine, Point, Size},
|
kurbo::{Affine, Point, Size, Vec2},
|
||||||
peniko::Color,
|
peniko::Color,
|
||||||
util::{RenderContext, RenderSurface},
|
util::{RenderContext, RenderSurface},
|
||||||
AaSupport, RenderParams, Renderer, RendererOptions, Scene,
|
AaSupport, RenderParams, Renderer, RendererOptions, Scene,
|
||||||
};
|
};
|
||||||
use winit::{
|
use winit::{
|
||||||
event::WindowEvent,
|
dpi::PhysicalPosition,
|
||||||
|
event::{ElementState, Modifiers, MouseButton, MouseScrollDelta, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
window::{Window, WindowBuilder},
|
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
|
// 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.
|
// 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);
|
let mut main_state = MainState::new(self.app, window);
|
||||||
|
|
||||||
event_loop
|
event_loop
|
||||||
.run(move |event, elwt| match event {
|
.run(move |event, elwt| {
|
||||||
winit::event::Event::WindowEvent {
|
if let winit::event::Event::WindowEvent { event: e, .. } = event {
|
||||||
event: WindowEvent::CloseRequested,
|
match e {
|
||||||
..
|
WindowEvent::CloseRequested => elwt.exit(),
|
||||||
} => elwt.exit(),
|
WindowEvent::RedrawRequested => main_state.paint(),
|
||||||
winit::event::Event::WindowEvent {
|
WindowEvent::Resized(winit::dpi::PhysicalSize { width, height }) => {
|
||||||
event: WindowEvent::RedrawRequested,
|
main_state.size(Size {
|
||||||
..
|
width: width.into(),
|
||||||
} => main_state.paint(),
|
height: height.into(),
|
||||||
winit::event::Event::WindowEvent {
|
});
|
||||||
event: WindowEvent::Resized(winit::dpi::PhysicalSize { width, height }),
|
}
|
||||||
..
|
WindowEvent::ModifiersChanged(modifiers) => main_state.mods(modifiers),
|
||||||
} => 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:
|
|
||||||
WindowEvent::CursorMoved {
|
WindowEvent::CursorMoved {
|
||||||
position: winit::dpi::PhysicalPosition { x, y },
|
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),
|
||||||
},
|
},
|
||||||
..
|
WindowEvent::MouseWheel { delta, .. } => main_state.pointer_wheel(delta),
|
||||||
} => 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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -187,13 +150,13 @@ where
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pointer_down(&mut self, button: PointerButton) {
|
fn pointer_down(&mut self, button: MouseButton) {
|
||||||
self.app
|
self.app
|
||||||
.window_event(Event::MouseDown(self.main_pointer.pressed(button)));
|
.window_event(Event::MouseDown(self.main_pointer.pressed(button)));
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pointer_up(&mut self, button: PointerButton) {
|
fn pointer_up(&mut self, button: MouseButton) {
|
||||||
self.app
|
self.app
|
||||||
.window_event(Event::MouseUp(self.main_pointer.released(button)));
|
.window_event(Event::MouseUp(self.main_pointer.released(button)));
|
||||||
self.window.request_redraw();
|
self.window.request_redraw();
|
||||||
|
@ -204,6 +167,19 @@ where
|
||||||
self.window.request_redraw();
|
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) {
|
fn paint(&mut self) {
|
||||||
self.app.paint();
|
self.app.paint();
|
||||||
self.render();
|
self.render();
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub use box_constraints::BoxConstraints;
|
||||||
pub use button::Button;
|
pub use button::Button;
|
||||||
pub use contexts::{CxState, EventCx, LayoutCx, LifeCycleCx, PaintCx, UpdateCx};
|
pub use contexts::{CxState, EventCx, LayoutCx, LifeCycleCx, PaintCx, UpdateCx};
|
||||||
pub use linear_layout::LinearLayout;
|
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 switch::Switch;
|
||||||
pub use text::TextWidget;
|
pub use text::TextWidget;
|
||||||
pub use tree_structure::TreeStructure;
|
pub use tree_structure::TreeStructure;
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
//!
|
//!
|
||||||
//! Note: arguably this module should be renamed, perhaps we should use
|
//! Note: arguably this module should be renamed, perhaps we should use
|
||||||
//! "event" for this level and maybe "message" at the View level.
|
//! "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 vello::kurbo::{Point, Rect, Vec2};
|
||||||
|
use winit::event::{Modifiers, MouseButton};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
|
@ -35,12 +36,18 @@ pub struct MouseEvent {
|
||||||
pub pos: Point,
|
pub pos: Point,
|
||||||
/// The position of the mouse in the window coordinate space.
|
/// The position of the mouse in the window coordinate space.
|
||||||
pub window_pos: Point,
|
pub window_pos: Point,
|
||||||
pub buttons: PointerButtons,
|
pub buttons: HashSet<MouseButton>,
|
||||||
pub mods: Modifiers,
|
pub mods: Modifiers,
|
||||||
pub count: u8,
|
pub count: u8,
|
||||||
pub focus: bool,
|
pub focus: bool,
|
||||||
pub button: PointerButton,
|
pub button: Option<MouseButton>,
|
||||||
pub wheel_delta: Vec2,
|
pub wheel_delta: Option<ScrollDelta>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum ScrollDelta {
|
||||||
|
Precise(Vec2),
|
||||||
|
Lines(isize, isize),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -62,12 +69,12 @@ impl Default for MouseEvent {
|
||||||
MouseEvent {
|
MouseEvent {
|
||||||
pos: Point::ZERO,
|
pos: Point::ZERO,
|
||||||
window_pos: Point::ZERO,
|
window_pos: Point::ZERO,
|
||||||
buttons: PointerButtons::new(),
|
buttons: HashSet::<MouseButton>::new(),
|
||||||
mods: Modifiers::default(),
|
mods: Modifiers::default(),
|
||||||
count: 0,
|
count: 0,
|
||||||
focus: false,
|
focus: false,
|
||||||
button: PointerButton::None,
|
button: None,
|
||||||
wheel_delta: Vec2::ZERO,
|
wheel_delta: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,32 +107,32 @@ impl PointerCrusher {
|
||||||
self.e.mods = mods;
|
self.e.mods = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pressed(&mut self, button: PointerButton) -> MouseEvent {
|
pub fn pressed(&mut self, button: MouseButton) -> MouseEvent {
|
||||||
self.e.wheel_delta = Vec2::ZERO;
|
self.e.wheel_delta = None;
|
||||||
self.e.buttons.insert(button);
|
self.e.buttons.insert(button);
|
||||||
self.e.count = self.counter.count_for_click(self.e.pos);
|
self.e.count = self.counter.count_for_click(self.e.pos);
|
||||||
self.e.button = button;
|
self.e.button = Some(button);
|
||||||
self.e.clone()
|
self.e.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn released(&mut self, button: PointerButton) -> MouseEvent {
|
pub fn released(&mut self, button: MouseButton) -> MouseEvent {
|
||||||
self.e.wheel_delta = Vec2::ZERO;
|
self.e.wheel_delta = None;
|
||||||
self.e.buttons.remove(button);
|
self.e.buttons.remove(&button);
|
||||||
self.e.button = button;
|
self.e.button = Some(button);
|
||||||
self.e.clone()
|
self.e.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn moved(&mut self, pos: Point) -> MouseEvent {
|
pub fn moved(&mut self, pos: Point) -> MouseEvent {
|
||||||
self.e.wheel_delta = Vec2::ZERO;
|
self.e.wheel_delta = None;
|
||||||
self.e.button = PointerButton::None;
|
self.e.button = None;
|
||||||
self.e.pos = pos;
|
self.e.pos = pos;
|
||||||
self.e.window_pos = pos;
|
self.e.window_pos = pos;
|
||||||
self.e.clone()
|
self.e.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wheel(&mut self, wheel_delta: Vec2) -> MouseEvent {
|
pub fn wheel(&mut self, wheel_delta: ScrollDelta) -> MouseEvent {
|
||||||
self.e.wheel_delta = wheel_delta;
|
self.e.wheel_delta = Some(wheel_delta);
|
||||||
self.e.button = PointerButton::None;
|
self.e.button = None;
|
||||||
self.e.clone()
|
self.e.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue