masonry: Use own `PointerButton` enum (#333)

This brings the `PointerButton` enum from glazier and has all code
outside of the winit event loop integration using it.

For now, it has a `todo!()` for the `MouseButton::Other` as it isn't
clear what that is for.
This commit is contained in:
Bruce Mitchener 2024-06-04 15:53:14 +07:00 committed by GitHub
parent 5a2db6dce8
commit 36bbe77352
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 71 additions and 34 deletions

View File

@ -11,7 +11,7 @@ use crate::WidgetId;
use std::{collections::HashSet, path::PathBuf};
use accesskit::{Action, ActionData};
use winit::event::{Ime, KeyEvent, Modifiers, MouseButton};
use winit::event::{Ime, KeyEvent, Modifiers};
use winit::keyboard::ModifiersState;
// TODO - Occluded(bool) event
@ -30,14 +30,34 @@ pub enum WindowEvent {
RebuildAccessTree,
}
/// An indicator of which pointer button was pressed.
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
#[repr(u8)]
pub enum PointerButton {
/// No mouse button.
None,
/// Primary button, commonly the left mouse button, touch contact, pen contact.
Primary,
/// Secondary button, commonly the right mouse button, pen barrel button.
Secondary,
/// Auxiliary button, commonly the middle mouse button.
Auxiliary,
/// X1 (back) Mouse.
X1,
/// X2 (forward) Mouse.
X2,
/// Other mouse button. This isn't fleshed out yet.
Other,
}
// TODO - How can RenderRoot express "I started a drag-and-drop op"?
// TODO - Touchpad, Touch, AxisMotion
// TODO - How to handle CursorEntered?
// Note to self: Events like "pointerenter", "pointerleave" are handled differently at the Widget level. But that's weird because WidgetPod can distribute them. Need to think about this again.
#[derive(Debug, Clone)]
pub enum PointerEvent {
PointerDown(MouseButton, PointerState),
PointerUp(MouseButton, PointerState),
PointerDown(PointerButton, PointerState),
PointerUp(PointerButton, PointerState),
PointerMove(PointerState),
PointerEnter(PointerState),
PointerLeave(PointerState),
@ -72,7 +92,7 @@ pub struct PointerState {
// pub device_id: DeviceId,
pub physical_position: PhysicalPosition<f64>,
pub position: LogicalPosition<f64>,
pub buttons: HashSet<MouseButton>,
pub buttons: HashSet<PointerButton>,
pub mods: Modifiers,
pub count: u8,
pub focus: bool,

View File

@ -13,16 +13,32 @@ use vello::{peniko::Color, AaSupport, RenderParams, Renderer, RendererOptions, S
use wgpu::PresentMode;
use winit::application::ApplicationHandler;
use winit::error::EventLoopError;
use winit::event::WindowEvent as WinitWindowEvent;
use winit::event::{MouseButton as WinitMouseButton, WindowEvent as WinitWindowEvent};
use winit::event_loop::{ActiveEventLoop, EventLoopProxy};
use winit::window::{Window, WindowAttributes, WindowId};
use crate::app_driver::{AppDriver, DriverCtx};
use crate::dpi::LogicalPosition;
use crate::event::{PointerState, WindowEvent};
use crate::event::{PointerButton, PointerState, WindowEvent};
use crate::render_root::{self, RenderRoot, WindowSizePolicy};
use crate::{PointerEvent, TextEvent, Widget};
impl From<WinitMouseButton> for PointerButton {
fn from(button: WinitMouseButton) -> Self {
match button {
WinitMouseButton::Left => PointerButton::Primary,
WinitMouseButton::Right => PointerButton::Secondary,
WinitMouseButton::Middle => PointerButton::Auxiliary,
WinitMouseButton::Back => PointerButton::X1,
WinitMouseButton::Forward => PointerButton::X2,
WinitMouseButton::Other(other) => {
warn!("Got winit MouseButton::Other({other}) which is not yet fully supported.");
PointerButton::Other
}
}
}
}
pub enum WindowState<'a> {
Uninitialized(WindowAttributes),
Rendering {
@ -257,14 +273,14 @@ impl ApplicationHandler<accesskit_winit::Event> for MainState<'_> {
winit::event::ElementState::Pressed => {
self.render_root
.handle_pointer_event(PointerEvent::PointerDown(
button,
button.into(),
self.pointer_state.clone(),
));
}
winit::event::ElementState::Released => {
self.render_root
.handle_pointer_event(PointerEvent::PointerUp(
button,
button.into(),
self.pointer_state.clone(),
));
}
@ -299,14 +315,14 @@ impl ApplicationHandler<accesskit_winit::Event> for MainState<'_> {
));
self.render_root
.handle_pointer_event(PointerEvent::PointerDown(
winit::event::MouseButton::Left,
PointerButton::Primary,
self.pointer_state.clone(),
));
}
winit::event::TouchPhase::Ended => {
self.render_root
.handle_pointer_event(PointerEvent::PointerUp(
winit::event::MouseButton::Left,
PointerButton::Primary,
self.pointer_state.clone(),
));
}

View File

@ -13,13 +13,13 @@ use wgpu::{
BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d, ImageCopyBuffer,
TextureDescriptor, TextureFormat, TextureUsages,
};
use winit::event::{Ime, MouseButton};
use winit::event::Ime;
use super::screenshots::get_image_diff;
use super::snapshot_utils::get_cargo_workspace;
use crate::action::Action;
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
use crate::event::{PointerEvent, PointerState, TextEvent, WindowEvent};
use crate::event::{PointerButton, PointerEvent, PointerState, TextEvent, WindowEvent};
use crate::event_loop_runner::try_init_tracing;
use crate::render_root::{RenderRoot, RenderRootSignal, WindowSizePolicy};
use crate::widget::{WidgetMut, WidgetRef};
@ -351,13 +351,13 @@ impl TestHarness {
}
/// Send a MouseDown event to the window.
pub fn mouse_button_press(&mut self, button: MouseButton) {
pub fn mouse_button_press(&mut self, button: PointerButton) {
self.mouse_state.buttons.insert(button);
self.process_pointer_event(PointerEvent::PointerDown(button, self.mouse_state.clone()));
}
/// Send a MouseUp event to the window.
pub fn mouse_button_release(&mut self, button: MouseButton) {
pub fn mouse_button_release(&mut self, button: PointerButton) {
self.mouse_state.buttons.remove(&button);
self.process_pointer_event(PointerEvent::PointerUp(button, self.mouse_state.clone()));
}
@ -379,8 +379,8 @@ impl TestHarness {
let widget_center = widget_rect.center();
self.mouse_move(widget_center);
self.mouse_button_press(MouseButton::Left);
self.mouse_button_release(MouseButton::Left);
self.mouse_button_press(PointerButton::Primary);
self.mouse_button_release(PointerButton::Primary);
}
/// Use [`mouse_move`](Self::mouse_move) to set the internal mouse pos to the center of the given widget.

View File

@ -7,11 +7,14 @@ use kurbo::Point;
use parley::FontContext;
use vello::Scene;
use winit::{
event::{Ime, MouseButton},
event::Ime,
keyboard::{Key, NamedKey},
};
use crate::{event::PointerState, Action, EventCtx, Handled, TextEvent};
use crate::{
event::{PointerButton, PointerState},
Action, EventCtx, Handled, TextEvent,
};
use super::{
offset_for_delete_backwards,
@ -92,7 +95,7 @@ impl<T: EditableText> TextEditor<T> {
&mut self,
origin: Point,
state: &PointerState,
button: MouseButton,
button: PointerButton,
) -> bool {
// TODO: If we have a selection and we're hovering over it,
// implement (optional?) click and drag

View File

@ -12,10 +12,9 @@ use parley::FontContext;
use unicode_segmentation::{GraphemeCursor, UnicodeSegmentation};
use vello::peniko::{Brush, Color};
use vello::Scene;
use winit::event::MouseButton;
use winit::keyboard::NamedKey;
use crate::event::PointerState;
use crate::event::{PointerButton, PointerState};
use crate::{Handled, TextEvent};
use super::{TextBrush, TextLayout, TextStorage};
@ -61,10 +60,10 @@ impl<T: Selectable> TextWithSelection<T> {
&mut self,
origin: Point,
state: &PointerState,
button: MouseButton,
button: PointerButton,
) -> bool {
// TODO: work out which button is the primary button?
if button == MouseButton::Left {
if button == PointerButton::Primary {
self.selecting_with_mouse = true;
self.needs_selection_update = true;
// TODO: Much of this juggling seems unnecessary
@ -90,8 +89,8 @@ impl<T: Selectable> TextWithSelection<T> {
}
}
pub fn pointer_up(&mut self, _origin: Point, _state: &PointerState, button: MouseButton) {
if button == MouseButton::Left {
pub fn pointer_up(&mut self, _origin: Point, _state: &PointerState, button: PointerButton) {
if button == PointerButton::Primary {
self.selecting_with_mouse = false;
}
}

View File

@ -238,10 +238,10 @@ impl Widget for ScrollBar {
#[cfg(test)]
mod tests {
use insta::assert_debug_snapshot;
use winit::event::MouseButton;
use super::*;
use crate::assert_render_snapshot;
use crate::event::PointerButton;
use crate::testing::{widget_ids, TestHarness, TestWidgetExt};
#[test]
@ -262,7 +262,7 @@ mod tests {
assert_render_snapshot!(harness, "scrollbar_middle");
harness.mouse_button_press(MouseButton::Left);
harness.mouse_button_press(PointerButton::Primary);
harness.mouse_move(Point::new(30.0, 150.0));
assert_render_snapshot!(harness, "scrollbar_down");

View File

@ -7,9 +7,9 @@ use accesskit::Role;
use smallvec::{smallvec, SmallVec};
use tracing::{trace, trace_span, warn, Span};
use vello::Scene;
use winit::event::MouseButton;
use crate::dpi::LogicalPosition;
use crate::event::PointerButton;
use crate::kurbo::Line;
use crate::paint_scene_helpers::{fill_color, stroke};
use crate::widget::flex::Axis;
@ -372,7 +372,7 @@ impl Widget for Split {
fn on_pointer_event(&mut self, ctx: &mut EventCtx, event: &PointerEvent) {
if self.draggable {
match event {
PointerEvent::PointerDown(MouseButton::Left, state) => {
PointerEvent::PointerDown(PointerButton::Primary, state) => {
if self.bar_hit_test(ctx.size(), state.position) {
ctx.set_handled();
ctx.set_active(true);
@ -391,7 +391,7 @@ impl Widget for Split {
}
}
}
PointerEvent::PointerUp(MouseButton::Left, state) => {
PointerEvent::PointerUp(PointerButton::Primary, state) => {
if ctx.is_active() {
ctx.set_handled();
ctx.set_active(false);

View File

@ -2,9 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
use assert_matches::assert_matches;
use winit::event::MouseButton;
use crate::event::{PointerEvent, PointerState};
use crate::event::{PointerButton, PointerEvent, PointerState};
use crate::testing::{widget_ids, Record, Recording, TestHarness, TestWidgetExt as _};
use crate::widget::{Button, Flex, Label, SizedBox};
use crate::*;
@ -233,7 +232,7 @@ fn get_pointer_events_while_active() {
// We press the button
harness.mouse_move_to(button);
harness.mouse_button_press(MouseButton::Left);
harness.mouse_button_press(PointerButton::Primary);
assert_matches!(
next_pointer_event(&button_rec),
@ -277,7 +276,7 @@ fn get_pointer_events_while_active() {
// We release the button
harness.mouse_button_release(MouseButton::Left);
harness.mouse_button_release(PointerButton::Primary);
assert_matches!(
next_pointer_event(&button_rec),