[egui_glium] Fix paste
This commit is contained in:
parent
08bdbd3cb7
commit
8a0bc97e8c
2 changed files with 69 additions and 39 deletions
|
@ -59,10 +59,7 @@ pub fn run(
|
||||||
*ctx.memory() = egui::app::get_value(storage.as_ref(), EGUI_MEMORY_KEY).unwrap_or_default();
|
*ctx.memory() = egui::app::get_value(storage.as_ref(), EGUI_MEMORY_KEY).unwrap_or_default();
|
||||||
app.setup(&ctx);
|
app.setup(&ctx);
|
||||||
|
|
||||||
let mut raw_input = egui::RawInput {
|
let mut input_state = GliumInputState::from_pixels_per_point(native_pixels_per_point(&display));
|
||||||
pixels_per_point: Some(native_pixels_per_point(&display)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
let mut previous_frame_time = None;
|
let mut previous_frame_time = None;
|
||||||
|
@ -72,11 +69,11 @@ pub fn run(
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
let mut redraw = || {
|
let mut redraw = || {
|
||||||
let egui_start = Instant::now();
|
let egui_start = Instant::now();
|
||||||
raw_input.time = start_time.elapsed().as_nanos() as f64 * 1e-9;
|
input_state.raw.time = start_time.elapsed().as_nanos() as f64 * 1e-9;
|
||||||
raw_input.screen_size =
|
input_state.raw.screen_size =
|
||||||
screen_size_in_pixels(&display) / raw_input.pixels_per_point.unwrap();
|
screen_size_in_pixels(&display) / input_state.raw.pixels_per_point.unwrap();
|
||||||
|
|
||||||
ctx.begin_frame(raw_input.take());
|
ctx.begin_frame(input_state.raw.take());
|
||||||
let mut integration_context = egui::app::IntegrationContext {
|
let mut integration_context = egui::app::IntegrationContext {
|
||||||
info: egui::app::IntegrationInfo {
|
info: egui::app::IntegrationInfo {
|
||||||
web_info: None,
|
web_info: None,
|
||||||
|
@ -105,7 +102,7 @@ pub fn run(
|
||||||
|
|
||||||
if let Some(pixels_per_point) = pixels_per_point {
|
if let Some(pixels_per_point) = pixels_per_point {
|
||||||
// User changed GUI scale
|
// User changed GUI scale
|
||||||
raw_input.pixels_per_point = Some(pixels_per_point);
|
input_state.raw.pixels_per_point = Some(pixels_per_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(window_size) = window_size {
|
if let Some(window_size) = window_size {
|
||||||
|
@ -139,7 +136,7 @@ pub fn run(
|
||||||
glutin::event::Event::RedrawRequested(_) if !cfg!(windows) => redraw(),
|
glutin::event::Event::RedrawRequested(_) if !cfg!(windows) => redraw(),
|
||||||
|
|
||||||
glutin::event::Event::WindowEvent { event, .. } => {
|
glutin::event::Event::WindowEvent { event, .. } => {
|
||||||
input_to_egui(event, clipboard.as_mut(), &mut raw_input, control_flow);
|
input_to_egui(event, clipboard.as_mut(), &mut input_state, control_flow);
|
||||||
display.gl_window().window().request_redraw(); // TODO: ask Egui if the events warrants a repaint instead
|
display.gl_window().window().request_redraw(); // TODO: ask Egui if the events warrants a repaint instead
|
||||||
}
|
}
|
||||||
glutin::event::Event::LoopDestroyed => {
|
glutin::event::Event::LoopDestroyed => {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
#![warn(clippy::all)]
|
#![warn(clippy::all)]
|
||||||
#![allow(clippy::single_match)]
|
#![allow(clippy::single_match)]
|
||||||
#![allow(deprecated)] // TODO: remove
|
|
||||||
|
|
||||||
mod backend;
|
mod backend;
|
||||||
mod painter;
|
mod painter;
|
||||||
|
@ -19,66 +18,100 @@ use {
|
||||||
|
|
||||||
pub use clipboard::ClipboardContext; // TODO: remove
|
pub use clipboard::ClipboardContext; // TODO: remove
|
||||||
|
|
||||||
|
pub struct GliumInputState {
|
||||||
|
raw: egui::RawInput,
|
||||||
|
|
||||||
|
/// Command modifier key.
|
||||||
|
/// Mac command key on Mac, ctrl on Window/Linux.
|
||||||
|
cmd: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GliumInputState {
|
||||||
|
pub fn from_pixels_per_point(pixels_per_point: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
raw: egui::RawInput {
|
||||||
|
pixels_per_point: Some(pixels_per_point),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
cmd: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn input_to_egui(
|
pub fn input_to_egui(
|
||||||
event: glutin::event::WindowEvent,
|
event: glutin::event::WindowEvent,
|
||||||
clipboard: Option<&mut ClipboardContext>,
|
clipboard: Option<&mut ClipboardContext>,
|
||||||
raw_input: &mut RawInput,
|
input_state: &mut GliumInputState,
|
||||||
control_flow: &mut ControlFlow,
|
control_flow: &mut ControlFlow,
|
||||||
) {
|
) {
|
||||||
use glutin::event::WindowEvent::*;
|
use glutin::event::WindowEvent::*;
|
||||||
match event {
|
match event {
|
||||||
CloseRequested | Destroyed => *control_flow = ControlFlow::Exit,
|
CloseRequested | Destroyed => *control_flow = ControlFlow::Exit,
|
||||||
MouseInput { state, .. } => {
|
MouseInput { state, .. } => {
|
||||||
raw_input.mouse_down = state == glutin::event::ElementState::Pressed;
|
input_state.raw.mouse_down = state == glutin::event::ElementState::Pressed;
|
||||||
}
|
}
|
||||||
CursorMoved {
|
CursorMoved {
|
||||||
position: pos_in_pixels,
|
position: pos_in_pixels,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
raw_input.mouse_pos = Some(pos2(
|
input_state.raw.mouse_pos = Some(pos2(
|
||||||
pos_in_pixels.x as f32 / raw_input.pixels_per_point.unwrap(),
|
pos_in_pixels.x as f32 / input_state.raw.pixels_per_point.unwrap(),
|
||||||
pos_in_pixels.y as f32 / raw_input.pixels_per_point.unwrap(),
|
pos_in_pixels.y as f32 / input_state.raw.pixels_per_point.unwrap(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
CursorLeft { .. } => {
|
CursorLeft { .. } => {
|
||||||
raw_input.mouse_pos = None;
|
input_state.raw.mouse_pos = None;
|
||||||
}
|
}
|
||||||
ReceivedCharacter(ch) => {
|
ReceivedCharacter(ch) => {
|
||||||
if printable_char(ch) {
|
if !input_state.cmd && printable_char(ch) {
|
||||||
raw_input.events.push(Event::Text(ch.to_string()));
|
input_state.raw.events.push(Event::Text(ch.to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeyboardInput { input, .. } => {
|
KeyboardInput { input, .. } => {
|
||||||
if let Some(virtual_keycode) = input.virtual_keycode {
|
if let Some(virtual_keycode) = input.virtual_keycode {
|
||||||
if cfg!(target_os = "macos")
|
let is_command_key = if cfg!(target_os = "macos") {
|
||||||
&& input.modifiers.logo()
|
matches!(virtual_keycode, VirtualKeyCode::LWin | VirtualKeyCode::RWin)
|
||||||
&& virtual_keycode == VirtualKeyCode::Q
|
} else {
|
||||||
{
|
matches!(
|
||||||
*control_flow = ControlFlow::Exit;
|
virtual_keycode,
|
||||||
|
VirtualKeyCode::LControl | VirtualKeyCode::RControl
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if is_command_key {
|
||||||
|
input_state.cmd = input.state == glutin::event::ElementState::Pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
match virtual_keycode {
|
if input.state == glutin::event::ElementState::Pressed {
|
||||||
VirtualKeyCode::Paste => {
|
if cfg!(target_os = "macos")
|
||||||
|
&& input_state.cmd
|
||||||
|
&& virtual_keycode == VirtualKeyCode::Q
|
||||||
|
{
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VirtualKeyCode::Paste etc in winit are broken/untrustworthy,
|
||||||
|
// so we detect these things manually:
|
||||||
|
if input_state.cmd && virtual_keycode == VirtualKeyCode::X {
|
||||||
|
input_state.raw.events.push(Event::Cut);
|
||||||
|
} else if input_state.cmd && virtual_keycode == VirtualKeyCode::C {
|
||||||
|
input_state.raw.events.push(Event::Copy);
|
||||||
|
} else if input_state.cmd && virtual_keycode == VirtualKeyCode::V {
|
||||||
if let Some(clipboard) = clipboard {
|
if let Some(clipboard) = clipboard {
|
||||||
match clipboard.get_contents() {
|
match clipboard.get_contents() {
|
||||||
Ok(contents) => {
|
Ok(contents) => {
|
||||||
raw_input.events.push(Event::Text(contents));
|
input_state.raw.events.push(Event::Text(contents));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Paste error: {}", err);
|
eprintln!("Paste error: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if let Some(key) = translate_virtual_key_code(virtual_keycode) {
|
||||||
VirtualKeyCode::Copy => raw_input.events.push(Event::Copy),
|
input_state.raw.events.push(Event::Key {
|
||||||
VirtualKeyCode::Cut => raw_input.events.push(Event::Cut),
|
key,
|
||||||
_ => {
|
pressed: input.state == glutin::event::ElementState::Pressed,
|
||||||
if let Some(key) = translate_virtual_key_code(virtual_keycode) {
|
});
|
||||||
raw_input.events.push(Event::Key {
|
|
||||||
key,
|
|
||||||
pressed: input.state == glutin::event::ElementState::Pressed,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,11 +120,11 @@ pub fn input_to_egui(
|
||||||
match delta {
|
match delta {
|
||||||
glutin::event::MouseScrollDelta::LineDelta(x, y) => {
|
glutin::event::MouseScrollDelta::LineDelta(x, y) => {
|
||||||
let line_height = 24.0; // TODO
|
let line_height = 24.0; // TODO
|
||||||
raw_input.scroll_delta = vec2(x, y) * line_height;
|
input_state.raw.scroll_delta = vec2(x, y) * line_height;
|
||||||
}
|
}
|
||||||
glutin::event::MouseScrollDelta::PixelDelta(delta) => {
|
glutin::event::MouseScrollDelta::PixelDelta(delta) => {
|
||||||
// Actually point delta
|
// Actually point delta
|
||||||
raw_input.scroll_delta = vec2(delta.x as f32, delta.y as f32);
|
input_state.raw.scroll_delta = vec2(delta.x as f32, delta.y as f32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue