handle mouse up event for right and middle buttons (#665)

This commit is contained in:
Demonthos 2022-05-23 01:43:48 -05:00 committed by GitHub
parent 35d58ccc30
commit d48ae42824
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 15 deletions

View File

@ -2,7 +2,10 @@ use std::time::Duration;
use crossterm_winapi::{Console, Handle, InputRecord};
use crate::event::{sys::windows::poll::WinApiPoll, Event};
use crate::event::{
sys::windows::{parse::MouseButtonsPressed, poll::WinApiPoll},
Event,
};
#[cfg(feature = "event-stream")]
use super::super::sys::Waker;
@ -17,6 +20,7 @@ pub(crate) struct WindowsEventSource {
console: Console,
poll: WinApiPoll,
surrogate_buffer: Option<u16>,
mouse_buttons_pressed: MouseButtonsPressed,
}
impl WindowsEventSource {
@ -31,6 +35,7 @@ impl WindowsEventSource {
poll: WinApiPoll::new()?,
surrogate_buffer: None,
mouse_buttons_pressed: MouseButtonsPressed::default(),
})
}
}
@ -47,7 +52,17 @@ impl EventSource for WindowsEventSource {
InputRecord::KeyEvent(record) => {
handle_key_event(record, &mut self.surrogate_buffer)
}
InputRecord::MouseEvent(record) => handle_mouse_event(record),
InputRecord::MouseEvent(record) => {
let mouse_event =
handle_mouse_event(record, &self.mouse_buttons_pressed);
self.mouse_buttons_pressed = MouseButtonsPressed {
left: record.button_state.left_button(),
right: record.button_state.right_button(),
middle: record.button_state.middle_button(),
};
mouse_event
}
InputRecord::WindowBufferSizeEvent(record) => {
Some(Event::Resize(record.size.x as u16, record.size.y as u16))
}

View File

@ -17,8 +17,18 @@ use crate::{
Result,
};
pub(crate) fn handle_mouse_event(mouse_event: MouseEvent) -> Option<Event> {
if let Ok(Some(event)) = parse_mouse_event_record(&mouse_event) {
#[derive(Default)]
pub struct MouseButtonsPressed {
pub(crate) left: bool,
pub(crate) right: bool,
pub(crate) middle: bool,
}
pub(crate) fn handle_mouse_event(
mouse_event: MouseEvent,
buttons_pressed: &MouseButtonsPressed,
) -> Option<Event> {
if let Ok(Some(event)) = parse_mouse_event_record(&mouse_event, buttons_pressed) {
return Some(Event::Mouse(event));
}
@ -287,13 +297,36 @@ pub fn parse_relative_y(y: i16) -> Result<i16> {
Ok(y - window_size.top)
}
fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::event::MouseEvent>> {
fn parse_mouse_event_record(
event: &MouseEvent,
buttons_pressed: &MouseButtonsPressed,
) -> Result<Option<crate::event::MouseEvent>> {
let modifiers = KeyModifiers::from(&event.control_key_state);
let xpos = event.mouse_position.x as u16;
let ypos = parse_relative_y(event.mouse_position.y)? as u16;
let button_state = event.button_state;
let kind = match event.event_flags {
EventFlags::PressOrRelease => {
if button_state.left_button() && !buttons_pressed.left {
Some(MouseEventKind::Down(MouseButton::Left))
} else if !button_state.left_button() && buttons_pressed.left {
Some(MouseEventKind::Up(MouseButton::Left))
} else if button_state.right_button() && !buttons_pressed.right {
Some(MouseEventKind::Down(MouseButton::Right))
} else if !button_state.right_button() && buttons_pressed.right {
Some(MouseEventKind::Up(MouseButton::Right))
} else if button_state.middle_button() && !buttons_pressed.middle {
Some(MouseEventKind::Down(MouseButton::Middle))
} else if !button_state.middle_button() && buttons_pressed.middle {
Some(MouseEventKind::Up(MouseButton::Middle))
} else {
None
}
}
EventFlags::MouseMoved => {
let button = if button_state.right_button() {
MouseButton::Right
} else if button_state.middle_button() {
@ -301,17 +334,6 @@ fn parse_mouse_event_record(event: &MouseEvent) -> Result<Option<crate::event::M
} else {
MouseButton::Left
};
let kind = match event.event_flags {
EventFlags::PressOrRelease => {
if button_state.release_button() {
// in order to read the up button type, we have to check the last down input record.
Some(MouseEventKind::Up(MouseButton::Left))
} else {
Some(MouseEventKind::Down(button))
}
}
EventFlags::MouseMoved => {
if button_state.release_button() {
Some(MouseEventKind::Moved)
} else {