mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 05:40:03 -04:00
Multiple mouse button support (#135)
Add support for primary, secondary and middle mouse buttons. Also improve ability to click things in low FPS situations.
This introduces a lot of breaking changes:
Backends/integrations now pass mouse events via the even stream.
Response has an interface of mostly methods instead of public members.
input.mouse is now input.pointer and has new interface.
* Rename 'mouse' to 'pointer' everywhere (pointer = mouse or touch)
* Make Response::clicked and Response::double_clicked into methods
* Remove Response::active and add dragged() and interact_pointer_pos()
* Support multiple mouse buttons
* Make PointerState interface all methods
* Make most members of Response private
This commit is contained in:
@@ -29,12 +29,14 @@ use {
|
||||
pub use clipboard::ClipboardContext; // TODO: remove
|
||||
|
||||
pub struct GliumInputState {
|
||||
pub pointer_pos_in_points: Option<Pos2>,
|
||||
pub raw: egui::RawInput,
|
||||
}
|
||||
|
||||
impl GliumInputState {
|
||||
pub fn from_pixels_per_point(pixels_per_point: f32) -> Self {
|
||||
Self {
|
||||
pointer_pos_in_points: Default::default(),
|
||||
raw: egui::RawInput {
|
||||
pixels_per_point: Some(pixels_per_point),
|
||||
..Default::default()
|
||||
@@ -52,23 +54,38 @@ pub fn input_to_egui(
|
||||
use glutin::event::WindowEvent;
|
||||
match event {
|
||||
WindowEvent::CloseRequested | WindowEvent::Destroyed => *control_flow = ControlFlow::Exit,
|
||||
WindowEvent::MouseInput { state, .. } => {
|
||||
input_state.raw.mouse_down = state == glutin::event::ElementState::Pressed;
|
||||
WindowEvent::MouseInput { state, button, .. } => {
|
||||
if let Some(pos_in_points) = input_state.pointer_pos_in_points {
|
||||
if let Some(button) = translate_mouse_button(button) {
|
||||
input_state.raw.events.push(egui::Event::PointerButton {
|
||||
pos: pos_in_points,
|
||||
button,
|
||||
pressed: state == glutin::event::ElementState::Pressed,
|
||||
modifiers: input_state.raw.modifiers,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
WindowEvent::CursorMoved {
|
||||
position: pos_in_pixels,
|
||||
..
|
||||
} => {
|
||||
input_state.raw.mouse_pos = Some(pos2(
|
||||
let pos_in_points = pos2(
|
||||
pos_in_pixels.x as f32 / input_state.raw.pixels_per_point.unwrap(),
|
||||
pos_in_pixels.y as f32 / input_state.raw.pixels_per_point.unwrap(),
|
||||
));
|
||||
);
|
||||
input_state.pointer_pos_in_points = Some(pos_in_points);
|
||||
input_state
|
||||
.raw
|
||||
.events
|
||||
.push(egui::Event::PointerMoved(pos_in_points));
|
||||
}
|
||||
WindowEvent::CursorLeft { .. } => {
|
||||
input_state.raw.mouse_pos = None;
|
||||
input_state.pointer_pos_in_points = None;
|
||||
input_state.raw.events.push(egui::Event::PointerGone);
|
||||
}
|
||||
WindowEvent::ReceivedCharacter(ch) => {
|
||||
if printable_char(ch)
|
||||
if is_printable_char(ch)
|
||||
&& !input_state.raw.modifiers.ctrl
|
||||
&& !input_state.raw.modifiers.mac_cmd
|
||||
{
|
||||
@@ -79,6 +96,7 @@ pub fn input_to_egui(
|
||||
if let Some(keycode) = input.virtual_keycode {
|
||||
let pressed = input.state == glutin::event::ElementState::Pressed;
|
||||
|
||||
// We could also use `WindowEvent::ModifiersChanged` instead, I guess.
|
||||
if matches!(keycode, VirtualKeyCode::LAlt | VirtualKeyCode::RAlt) {
|
||||
input_state.raw.modifiers.alt = pressed;
|
||||
}
|
||||
@@ -157,7 +175,7 @@ pub fn input_to_egui(
|
||||
/// Ignore those.
|
||||
/// We also ignore '\r', '\n', '\t'.
|
||||
/// Newlines are handled by the `Key::Enter` event.
|
||||
fn printable_char(chr: char) -> bool {
|
||||
fn is_printable_char(chr: char) -> bool {
|
||||
let is_in_private_use_area = '\u{e000}' <= chr && chr <= '\u{f8ff}'
|
||||
|| '\u{f0000}' <= chr && chr <= '\u{ffffd}'
|
||||
|| '\u{100000}' <= chr && chr <= '\u{10fffd}';
|
||||
@@ -165,6 +183,15 @@ fn printable_char(chr: char) -> bool {
|
||||
!is_in_private_use_area && !chr.is_ascii_control()
|
||||
}
|
||||
|
||||
pub fn translate_mouse_button(button: glutin::event::MouseButton) -> Option<egui::PointerButton> {
|
||||
match button {
|
||||
glutin::event::MouseButton::Left => Some(egui::PointerButton::Primary),
|
||||
glutin::event::MouseButton::Right => Some(egui::PointerButton::Secondary),
|
||||
glutin::event::MouseButton::Middle => Some(egui::PointerButton::Middle),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn translate_virtual_key_code(key: VirtualKeyCode) -> Option<egui::Key> {
|
||||
use VirtualKeyCode::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user