diff --git a/README.md b/README.md index 4f3c082..92fee76 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,84 @@ # imgui-winit-support -See the examples for [`imgui-glium-renderer`][glium] or [`imgui-glow-renderer`][glow] -for simple examples of this platform backend with different renderers +This crate provides a winit-based backend platform for [`imgui-rs`]. -[glium]: ../../imgui-glium-renderer/examples -[glow]: ../../imgui-glow-renderer/examples +A backend platform handles window/input device events and manages their state. + +# Using the library + +There are five things you need to do to use this library correctly: + +1. Initialize a [`WinitPlatform`] instance. +2. Attach it to a winit [`Window`] with [`WinitPlatform::attach_window`]. +3. Pass events to the platform (every frame) with [`WinitPlatform::handle_event`]. +4. Call the frame preparation callback [`WinitPlatform::prepare_frame`] (every frame) +5. Call the render preparation callback [`WinitPlatform::prepare_render`] (every frame) + +## Complete example (without a renderer) + +```no_run +use imgui::Context; +use imgui_winit_support::{HiDpiMode, WinitPlatform}; +use std::time::Instant; +use winit::event::{Event, WindowEvent}; +use winit::event_loop::{ControlFlow, EventLoop}; +use winit::window::Window; + +let mut event_loop = EventLoop::new().expect("Failed to create EventLoop"); +let mut window = Window::new(&event_loop).unwrap(); + +let mut imgui = Context::create(); +// configure imgui-rs Context if necessary + +let mut platform = WinitPlatform::init(&mut imgui); // step 1 +platform.attach_window(imgui.io_mut(), &window, HiDpiMode::Default); // step 2 + +let mut last_frame = Instant::now(); +let mut run = true; +event_loop.run(move |event, window_target| { + match event { + Event::NewEvents(_) => { + // other application-specific logic + let now = Instant::now(); + imgui.io_mut().update_delta_time(now - last_frame); + last_frame = now; + }, + Event::AboutToWait => { + // other application-specific logic + platform.prepare_frame(imgui.io_mut(), &window) // step 4 + .expect("Failed to prepare frame"); + window.request_redraw(); + } + Event::WindowEvent { event: WindowEvent::RedrawRequested, .. } => { + let ui = imgui.frame(); + // application-specific rendering *under the UI* + + // construct the UI + + platform.prepare_render(&ui, &window); // step 5 + // render the UI with a renderer + let draw_data = imgui.render(); + // renderer.render(..., draw_data).expect("UI rendering failed"); + + // application-specific rendering *over the UI* + }, + Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { + window_target.exit(); + } + // other application-specific event handling + event => { + platform.handle_event(imgui.io_mut(), &window, &event); // step 3 + // other application-specific event handling + } + } +}).expect("EventLoop error"); +``` + +## License + +Licensed under either of + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT) + +at your option. \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ddc1c8e..b74b110 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,77 +1,6 @@ -//! This crate provides a winit-based backend platform for imgui-rs. -//! -//! A backend platform handles window/input device events and manages their -//! state. -//! -//! # Using the library -//! -//! There are five things you need to do to use this library correctly: -//! -//! 1. Initialize a `WinitPlatform` instance -//! 2. Attach it to a winit `Window` -//! 3. Pass events to the platform (every frame) -//! 4. Call frame preparation callback (every frame) -//! 5. Call render preparation callback (every frame) -//! -//! ## Complete example (without a renderer) -//! -//! ```no_run -//! use imgui::Context; -//! use imgui_winit_support::{HiDpiMode, WinitPlatform}; -//! use std::time::Instant; -//! use winit::event::{Event, WindowEvent}; -//! use winit::event_loop::{ControlFlow, EventLoop}; -//! use winit::window::Window; -//! -//! let mut event_loop = EventLoop::new().expect("Failed to create EventLoop"); -//! let mut window = Window::new(&event_loop).unwrap(); -//! -//! let mut imgui = Context::create(); -//! // configure imgui-rs Context if necessary -//! -//! let mut platform = WinitPlatform::init(&mut imgui); // step 1 -//! platform.attach_window(imgui.io_mut(), &window, HiDpiMode::Default); // step 2 -//! -//! let mut last_frame = Instant::now(); -//! let mut run = true; -//! event_loop.run(move |event, window_target| { -//! match event { -//! Event::NewEvents(_) => { -//! // other application-specific logic -//! let now = Instant::now(); -//! imgui.io_mut().update_delta_time(now - last_frame); -//! last_frame = now; -//! }, -//! Event::AboutToWait => { -//! // other application-specific logic -//! platform.prepare_frame(imgui.io_mut(), &window) // step 4 -//! .expect("Failed to prepare frame"); -//! window.request_redraw(); -//! } -//! Event::WindowEvent { event: WindowEvent::RedrawRequested, .. } => { -//! let ui = imgui.frame(); -//! // application-specific rendering *under the UI* -//! -//! // construct the UI -//! -//! platform.prepare_render(&ui, &window); // step 5 -//! // render the UI with a renderer -//! let draw_data = imgui.render(); -//! // renderer.render(..., draw_data).expect("UI rendering failed"); -//! -//! // application-specific rendering *over the UI* -//! }, -//! Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { -//! window_target.exit(); -//! } -//! // other application-specific event handling -//! event => { -//! platform.handle_event(imgui.io_mut(), &window, &event); // step 3 -//! // other application-specific event handling -//! } -//! } -//! }).expect("EventLoop error"); -//! ``` +#![doc = include_str!("../README.md")] +#![deny(rust_2018_idioms)] +#![deny(missing_docs)] use imgui::{self, BackendFlags, ConfigFlags, Context, Io, Key, Ui}; use std::cmp::Ordering; @@ -98,210 +27,6 @@ pub struct WinitPlatform { cursor_cache: Option, } -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -struct CursorSettings { - cursor: Option, - draw_cursor: bool, -} - -fn to_winit_cursor(cursor: imgui::MouseCursor) -> MouseCursor { - match cursor { - imgui::MouseCursor::Arrow => MouseCursor::Default, - imgui::MouseCursor::TextInput => MouseCursor::Text, - imgui::MouseCursor::ResizeAll => MouseCursor::Move, - imgui::MouseCursor::ResizeNS => MouseCursor::NsResize, - imgui::MouseCursor::ResizeEW => MouseCursor::EwResize, - imgui::MouseCursor::ResizeNESW => MouseCursor::NeswResize, - imgui::MouseCursor::ResizeNWSE => MouseCursor::NwseResize, - imgui::MouseCursor::Hand => MouseCursor::Grab, - imgui::MouseCursor::NotAllowed => MouseCursor::NotAllowed, - } -} - -impl CursorSettings { - fn apply(&self, window: &Window) { - match self.cursor { - Some(mouse_cursor) if !self.draw_cursor => { - window.set_cursor_visible(true); - window.set_cursor_icon(to_winit_cursor(mouse_cursor)); - } - _ => window.set_cursor_visible(false), - } - } -} - -#[derive(Copy, Clone, Debug, PartialEq)] -enum ActiveHiDpiMode { - Default, - Rounded, - Locked, -} - -/// DPI factor handling mode. -/// -/// Applications that use imgui-rs might want to customize the used DPI factor and not use -/// directly the value coming from winit. -/// -/// **Note: if you use a mode other than default and the DPI factor is adjusted, winit and imgui-rs -/// will use different logical coordinates, so be careful if you pass around logical size or -/// position values.** -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum HiDpiMode { - /// The DPI factor from winit is used directly without adjustment - Default, - /// The DPI factor from winit is rounded to an integer value. - /// - /// This prevents the user interface from becoming blurry with non-integer scaling. - Rounded, - /// The DPI factor from winit is ignored, and the included value is used instead. - /// - /// This is useful if you want to force some DPI factor (e.g. 1.0) and not care about the value - /// coming from winit. - Locked(f64), -} - -impl HiDpiMode { - fn apply(&self, hidpi_factor: f64) -> (ActiveHiDpiMode, f64) { - match *self { - HiDpiMode::Default => (ActiveHiDpiMode::Default, hidpi_factor), - HiDpiMode::Rounded => (ActiveHiDpiMode::Rounded, hidpi_factor.round()), - HiDpiMode::Locked(value) => (ActiveHiDpiMode::Locked, value), - } - } -} - -fn to_imgui_mouse_button(button: MouseButton) -> Option { - match button { - MouseButton::Left | MouseButton::Other(0) => Some(imgui::MouseButton::Left), - MouseButton::Right | MouseButton::Other(1) => Some(imgui::MouseButton::Right), - MouseButton::Middle | MouseButton::Other(2) => Some(imgui::MouseButton::Middle), - MouseButton::Other(3) => Some(imgui::MouseButton::Extra1), - MouseButton::Other(4) => Some(imgui::MouseButton::Extra2), - _ => None, - } -} - -fn to_imgui_key(key: winit::keyboard::Key, location: KeyLocation) -> Option { - match (key.as_ref(), location) { - (WinitKey::Named(NamedKey::Tab), _) => Some(Key::Tab), - (WinitKey::Named(NamedKey::ArrowLeft), _) => Some(Key::LeftArrow), - (WinitKey::Named(NamedKey::ArrowRight), _) => Some(Key::RightArrow), - (WinitKey::Named(NamedKey::ArrowUp), _) => Some(Key::UpArrow), - (WinitKey::Named(NamedKey::ArrowDown), _) => Some(Key::DownArrow), - (WinitKey::Named(NamedKey::PageUp), _) => Some(Key::PageUp), - (WinitKey::Named(NamedKey::PageDown), _) => Some(Key::PageDown), - (WinitKey::Named(NamedKey::Home), _) => Some(Key::Home), - (WinitKey::Named(NamedKey::End), _) => Some(Key::End), - (WinitKey::Named(NamedKey::Insert), _) => Some(Key::Insert), - (WinitKey::Named(NamedKey::Delete), _) => Some(Key::Delete), - (WinitKey::Named(NamedKey::Backspace), _) => Some(Key::Backspace), - (WinitKey::Named(NamedKey::Space), _) => Some(Key::Space), - (WinitKey::Named(NamedKey::Enter), KeyLocation::Standard) => Some(Key::Enter), - (WinitKey::Named(NamedKey::Enter), KeyLocation::Numpad) => Some(Key::KeypadEnter), - (WinitKey::Named(NamedKey::Escape), _) => Some(Key::Escape), - (WinitKey::Named(NamedKey::Control), KeyLocation::Left) => Some(Key::LeftCtrl), - (WinitKey::Named(NamedKey::Control), KeyLocation::Right) => Some(Key::RightCtrl), - (WinitKey::Named(NamedKey::Shift), KeyLocation::Left) => Some(Key::LeftShift), - (WinitKey::Named(NamedKey::Shift), KeyLocation::Right) => Some(Key::RightShift), - (WinitKey::Named(NamedKey::Alt), KeyLocation::Left) => Some(Key::LeftAlt), - (WinitKey::Named(NamedKey::Alt), KeyLocation::Right) => Some(Key::RightAlt), - (WinitKey::Named(NamedKey::Super), KeyLocation::Left) => Some(Key::LeftSuper), - (WinitKey::Named(NamedKey::Super), KeyLocation::Right) => Some(Key::RightSuper), - (WinitKey::Named(NamedKey::ContextMenu), _) => Some(Key::Menu), - (WinitKey::Named(NamedKey::F1), _) => Some(Key::F1), - (WinitKey::Named(NamedKey::F2), _) => Some(Key::F2), - (WinitKey::Named(NamedKey::F3), _) => Some(Key::F3), - (WinitKey::Named(NamedKey::F4), _) => Some(Key::F4), - (WinitKey::Named(NamedKey::F5), _) => Some(Key::F5), - (WinitKey::Named(NamedKey::F6), _) => Some(Key::F6), - (WinitKey::Named(NamedKey::F7), _) => Some(Key::F7), - (WinitKey::Named(NamedKey::F8), _) => Some(Key::F8), - (WinitKey::Named(NamedKey::F9), _) => Some(Key::F9), - (WinitKey::Named(NamedKey::F10), _) => Some(Key::F10), - (WinitKey::Named(NamedKey::F11), _) => Some(Key::F11), - (WinitKey::Named(NamedKey::F12), _) => Some(Key::F12), - (WinitKey::Named(NamedKey::CapsLock), _) => Some(Key::CapsLock), - (WinitKey::Named(NamedKey::ScrollLock), _) => Some(Key::ScrollLock), - (WinitKey::Named(NamedKey::NumLock), _) => Some(Key::NumLock), - (WinitKey::Named(NamedKey::PrintScreen), _) => Some(Key::PrintScreen), - (WinitKey::Named(NamedKey::Pause), _) => Some(Key::Pause), - (WinitKey::Character("0"), KeyLocation::Standard) => Some(Key::Alpha0), - (WinitKey::Character("1"), KeyLocation::Standard) => Some(Key::Alpha1), - (WinitKey::Character("2"), KeyLocation::Standard) => Some(Key::Alpha2), - (WinitKey::Character("3"), KeyLocation::Standard) => Some(Key::Alpha3), - (WinitKey::Character("4"), KeyLocation::Standard) => Some(Key::Alpha4), - (WinitKey::Character("5"), KeyLocation::Standard) => Some(Key::Alpha5), - (WinitKey::Character("6"), KeyLocation::Standard) => Some(Key::Alpha6), - (WinitKey::Character("7"), KeyLocation::Standard) => Some(Key::Alpha7), - (WinitKey::Character("8"), KeyLocation::Standard) => Some(Key::Alpha8), - (WinitKey::Character("9"), KeyLocation::Standard) => Some(Key::Alpha9), - (WinitKey::Character("0"), KeyLocation::Numpad) => Some(Key::Keypad0), - (WinitKey::Character("1"), KeyLocation::Numpad) => Some(Key::Keypad1), - (WinitKey::Character("2"), KeyLocation::Numpad) => Some(Key::Keypad2), - (WinitKey::Character("3"), KeyLocation::Numpad) => Some(Key::Keypad3), - (WinitKey::Character("4"), KeyLocation::Numpad) => Some(Key::Keypad4), - (WinitKey::Character("5"), KeyLocation::Numpad) => Some(Key::Keypad5), - (WinitKey::Character("6"), KeyLocation::Numpad) => Some(Key::Keypad6), - (WinitKey::Character("7"), KeyLocation::Numpad) => Some(Key::Keypad7), - (WinitKey::Character("8"), KeyLocation::Numpad) => Some(Key::Keypad8), - (WinitKey::Character("9"), KeyLocation::Numpad) => Some(Key::Keypad9), - (WinitKey::Character("a"), _) => Some(Key::A), - (WinitKey::Character("b"), _) => Some(Key::B), - (WinitKey::Character("c"), _) => Some(Key::C), - (WinitKey::Character("d"), _) => Some(Key::D), - (WinitKey::Character("e"), _) => Some(Key::E), - (WinitKey::Character("f"), _) => Some(Key::F), - (WinitKey::Character("g"), _) => Some(Key::G), - (WinitKey::Character("h"), _) => Some(Key::H), - (WinitKey::Character("i"), _) => Some(Key::I), - (WinitKey::Character("j"), _) => Some(Key::J), - (WinitKey::Character("k"), _) => Some(Key::K), - (WinitKey::Character("l"), _) => Some(Key::L), - (WinitKey::Character("m"), _) => Some(Key::M), - (WinitKey::Character("n"), _) => Some(Key::N), - (WinitKey::Character("o"), _) => Some(Key::O), - (WinitKey::Character("p"), _) => Some(Key::P), - (WinitKey::Character("q"), _) => Some(Key::Q), - (WinitKey::Character("r"), _) => Some(Key::R), - (WinitKey::Character("s"), _) => Some(Key::S), - (WinitKey::Character("t"), _) => Some(Key::T), - (WinitKey::Character("u"), _) => Some(Key::U), - (WinitKey::Character("v"), _) => Some(Key::V), - (WinitKey::Character("w"), _) => Some(Key::W), - (WinitKey::Character("x"), _) => Some(Key::X), - (WinitKey::Character("y"), _) => Some(Key::Y), - (WinitKey::Character("z"), _) => Some(Key::Z), - (WinitKey::Character("'"), _) => Some(Key::Apostrophe), - (WinitKey::Character(","), KeyLocation::Standard) => Some(Key::Comma), - (WinitKey::Character("-"), KeyLocation::Standard) => Some(Key::Minus), - (WinitKey::Character("-"), KeyLocation::Numpad) => Some(Key::KeypadSubtract), - (WinitKey::Character("."), KeyLocation::Standard) => Some(Key::Period), - (WinitKey::Character("."), KeyLocation::Numpad) => Some(Key::KeypadDecimal), - (WinitKey::Character("/"), KeyLocation::Standard) => Some(Key::Slash), - (WinitKey::Character("/"), KeyLocation::Numpad) => Some(Key::KeypadDivide), - (WinitKey::Character(";"), _) => Some(Key::Semicolon), - (WinitKey::Character("="), KeyLocation::Standard) => Some(Key::Equal), - (WinitKey::Character("="), KeyLocation::Numpad) => Some(Key::KeypadEqual), - (WinitKey::Character("["), _) => Some(Key::LeftBracket), - (WinitKey::Character("\\"), _) => Some(Key::Backslash), - (WinitKey::Character("]"), _) => Some(Key::RightBracket), - (WinitKey::Character("`"), _) => Some(Key::GraveAccent), - (WinitKey::Character("*"), KeyLocation::Numpad) => Some(Key::KeypadMultiply), - (WinitKey::Character("+"), KeyLocation::Numpad) => Some(Key::KeypadAdd), - _ => None, - } -} - -fn handle_key_modifier(io: &mut Io, key: &WinitKey, down: bool) { - match key { - WinitKey::Named(NamedKey::Shift) => io.add_key_event(imgui::Key::ModShift, down), - WinitKey::Named(NamedKey::Control) => io.add_key_event(imgui::Key::ModCtrl, down), - WinitKey::Named(NamedKey::Alt) => io.add_key_event(imgui::Key::ModAlt, down), - WinitKey::Named(NamedKey::Super) => io.add_key_event(imgui::Key::ModSuper, down), - _ => {} - } -} - impl WinitPlatform { /// Initializes a winit platform instance and configures imgui. /// @@ -310,7 +35,7 @@ impl WinitPlatform { /// * backend flags are updated /// * keys are configured /// * platform name is set - pub fn init(imgui: &mut Context) -> WinitPlatform { + pub fn new(imgui: &mut Context) -> WinitPlatform { let io = imgui.io_mut(); io.backend_flags.insert(BackendFlags::HAS_MOUSE_CURSORS); io.backend_flags.insert(BackendFlags::HAS_SET_MOUSE_POS); @@ -324,6 +49,14 @@ impl WinitPlatform { cursor_cache: None, } } + + /// Initializes a winit platform instance and configures imgui. + /// Deprecated since `0.13.0` -- use `new` instead. + #[deprecated = "use `new` instead"] + pub fn init(imgui: &mut Context) -> WinitPlatform { + Self::new(imgui) + } + /// Attaches the platform instance to a winit window. /// /// This function configures imgui-rs in the following ways: @@ -574,3 +307,207 @@ impl WinitPlatform { } } } + +/// DPI factor handling mode. +/// +/// Applications that use imgui-rs might want to customize the used DPI factor and not use +/// directly the value coming from winit. +/// +/// **Note: if you use a mode other than default and the DPI factor is adjusted, winit and imgui-rs +/// will use different logical coordinates, so be careful if you pass around logical size or +/// position values.** +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum HiDpiMode { + /// The DPI factor from winit is used directly without adjustment + Default, + /// The DPI factor from winit is rounded to an integer value. + /// + /// This prevents the user interface from becoming blurry with non-integer scaling. + Rounded, + /// The DPI factor from winit is ignored, and the included value is used instead. + /// + /// This is useful if you want to force some DPI factor (e.g. 1.0) and not care about the value + /// coming from winit. + Locked(f64), +} + +impl HiDpiMode { + fn apply(&self, hidpi_factor: f64) -> (ActiveHiDpiMode, f64) { + match *self { + HiDpiMode::Default => (ActiveHiDpiMode::Default, hidpi_factor), + HiDpiMode::Rounded => (ActiveHiDpiMode::Rounded, hidpi_factor.round()), + HiDpiMode::Locked(value) => (ActiveHiDpiMode::Locked, value), + } + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +struct CursorSettings { + cursor: Option, + draw_cursor: bool, +} + +fn to_winit_cursor(cursor: imgui::MouseCursor) -> MouseCursor { + match cursor { + imgui::MouseCursor::Arrow => MouseCursor::Default, + imgui::MouseCursor::TextInput => MouseCursor::Text, + imgui::MouseCursor::ResizeAll => MouseCursor::Move, + imgui::MouseCursor::ResizeNS => MouseCursor::NsResize, + imgui::MouseCursor::ResizeEW => MouseCursor::EwResize, + imgui::MouseCursor::ResizeNESW => MouseCursor::NeswResize, + imgui::MouseCursor::ResizeNWSE => MouseCursor::NwseResize, + imgui::MouseCursor::Hand => MouseCursor::Grab, + imgui::MouseCursor::NotAllowed => MouseCursor::NotAllowed, + } +} + +impl CursorSettings { + fn apply(&self, window: &Window) { + match self.cursor { + Some(mouse_cursor) if !self.draw_cursor => { + window.set_cursor_visible(true); + window.set_cursor_icon(to_winit_cursor(mouse_cursor)); + } + _ => window.set_cursor_visible(false), + } + } +} + +#[derive(Copy, Clone, Debug, PartialEq)] +enum ActiveHiDpiMode { + Default, + Rounded, + Locked, +} + +fn to_imgui_mouse_button(button: MouseButton) -> Option { + match button { + MouseButton::Left | MouseButton::Other(0) => Some(imgui::MouseButton::Left), + MouseButton::Right | MouseButton::Other(1) => Some(imgui::MouseButton::Right), + MouseButton::Middle | MouseButton::Other(2) => Some(imgui::MouseButton::Middle), + MouseButton::Other(3) => Some(imgui::MouseButton::Extra1), + MouseButton::Other(4) => Some(imgui::MouseButton::Extra2), + _ => None, + } +} + +fn to_imgui_key(key: winit::keyboard::Key, location: KeyLocation) -> Option { + match (key.as_ref(), location) { + (WinitKey::Named(NamedKey::Tab), _) => Some(Key::Tab), + (WinitKey::Named(NamedKey::ArrowLeft), _) => Some(Key::LeftArrow), + (WinitKey::Named(NamedKey::ArrowRight), _) => Some(Key::RightArrow), + (WinitKey::Named(NamedKey::ArrowUp), _) => Some(Key::UpArrow), + (WinitKey::Named(NamedKey::ArrowDown), _) => Some(Key::DownArrow), + (WinitKey::Named(NamedKey::PageUp), _) => Some(Key::PageUp), + (WinitKey::Named(NamedKey::PageDown), _) => Some(Key::PageDown), + (WinitKey::Named(NamedKey::Home), _) => Some(Key::Home), + (WinitKey::Named(NamedKey::End), _) => Some(Key::End), + (WinitKey::Named(NamedKey::Insert), _) => Some(Key::Insert), + (WinitKey::Named(NamedKey::Delete), _) => Some(Key::Delete), + (WinitKey::Named(NamedKey::Backspace), _) => Some(Key::Backspace), + (WinitKey::Named(NamedKey::Space), _) => Some(Key::Space), + (WinitKey::Named(NamedKey::Enter), KeyLocation::Standard) => Some(Key::Enter), + (WinitKey::Named(NamedKey::Enter), KeyLocation::Numpad) => Some(Key::KeypadEnter), + (WinitKey::Named(NamedKey::Escape), _) => Some(Key::Escape), + (WinitKey::Named(NamedKey::Control), KeyLocation::Left) => Some(Key::LeftCtrl), + (WinitKey::Named(NamedKey::Control), KeyLocation::Right) => Some(Key::RightCtrl), + (WinitKey::Named(NamedKey::Shift), KeyLocation::Left) => Some(Key::LeftShift), + (WinitKey::Named(NamedKey::Shift), KeyLocation::Right) => Some(Key::RightShift), + (WinitKey::Named(NamedKey::Alt), KeyLocation::Left) => Some(Key::LeftAlt), + (WinitKey::Named(NamedKey::Alt), KeyLocation::Right) => Some(Key::RightAlt), + (WinitKey::Named(NamedKey::Super), KeyLocation::Left) => Some(Key::LeftSuper), + (WinitKey::Named(NamedKey::Super), KeyLocation::Right) => Some(Key::RightSuper), + (WinitKey::Named(NamedKey::ContextMenu), _) => Some(Key::Menu), + (WinitKey::Named(NamedKey::F1), _) => Some(Key::F1), + (WinitKey::Named(NamedKey::F2), _) => Some(Key::F2), + (WinitKey::Named(NamedKey::F3), _) => Some(Key::F3), + (WinitKey::Named(NamedKey::F4), _) => Some(Key::F4), + (WinitKey::Named(NamedKey::F5), _) => Some(Key::F5), + (WinitKey::Named(NamedKey::F6), _) => Some(Key::F6), + (WinitKey::Named(NamedKey::F7), _) => Some(Key::F7), + (WinitKey::Named(NamedKey::F8), _) => Some(Key::F8), + (WinitKey::Named(NamedKey::F9), _) => Some(Key::F9), + (WinitKey::Named(NamedKey::F10), _) => Some(Key::F10), + (WinitKey::Named(NamedKey::F11), _) => Some(Key::F11), + (WinitKey::Named(NamedKey::F12), _) => Some(Key::F12), + (WinitKey::Named(NamedKey::CapsLock), _) => Some(Key::CapsLock), + (WinitKey::Named(NamedKey::ScrollLock), _) => Some(Key::ScrollLock), + (WinitKey::Named(NamedKey::NumLock), _) => Some(Key::NumLock), + (WinitKey::Named(NamedKey::PrintScreen), _) => Some(Key::PrintScreen), + (WinitKey::Named(NamedKey::Pause), _) => Some(Key::Pause), + (WinitKey::Character("0"), KeyLocation::Standard) => Some(Key::Alpha0), + (WinitKey::Character("1"), KeyLocation::Standard) => Some(Key::Alpha1), + (WinitKey::Character("2"), KeyLocation::Standard) => Some(Key::Alpha2), + (WinitKey::Character("3"), KeyLocation::Standard) => Some(Key::Alpha3), + (WinitKey::Character("4"), KeyLocation::Standard) => Some(Key::Alpha4), + (WinitKey::Character("5"), KeyLocation::Standard) => Some(Key::Alpha5), + (WinitKey::Character("6"), KeyLocation::Standard) => Some(Key::Alpha6), + (WinitKey::Character("7"), KeyLocation::Standard) => Some(Key::Alpha7), + (WinitKey::Character("8"), KeyLocation::Standard) => Some(Key::Alpha8), + (WinitKey::Character("9"), KeyLocation::Standard) => Some(Key::Alpha9), + (WinitKey::Character("0"), KeyLocation::Numpad) => Some(Key::Keypad0), + (WinitKey::Character("1"), KeyLocation::Numpad) => Some(Key::Keypad1), + (WinitKey::Character("2"), KeyLocation::Numpad) => Some(Key::Keypad2), + (WinitKey::Character("3"), KeyLocation::Numpad) => Some(Key::Keypad3), + (WinitKey::Character("4"), KeyLocation::Numpad) => Some(Key::Keypad4), + (WinitKey::Character("5"), KeyLocation::Numpad) => Some(Key::Keypad5), + (WinitKey::Character("6"), KeyLocation::Numpad) => Some(Key::Keypad6), + (WinitKey::Character("7"), KeyLocation::Numpad) => Some(Key::Keypad7), + (WinitKey::Character("8"), KeyLocation::Numpad) => Some(Key::Keypad8), + (WinitKey::Character("9"), KeyLocation::Numpad) => Some(Key::Keypad9), + (WinitKey::Character("a"), _) => Some(Key::A), + (WinitKey::Character("b"), _) => Some(Key::B), + (WinitKey::Character("c"), _) => Some(Key::C), + (WinitKey::Character("d"), _) => Some(Key::D), + (WinitKey::Character("e"), _) => Some(Key::E), + (WinitKey::Character("f"), _) => Some(Key::F), + (WinitKey::Character("g"), _) => Some(Key::G), + (WinitKey::Character("h"), _) => Some(Key::H), + (WinitKey::Character("i"), _) => Some(Key::I), + (WinitKey::Character("j"), _) => Some(Key::J), + (WinitKey::Character("k"), _) => Some(Key::K), + (WinitKey::Character("l"), _) => Some(Key::L), + (WinitKey::Character("m"), _) => Some(Key::M), + (WinitKey::Character("n"), _) => Some(Key::N), + (WinitKey::Character("o"), _) => Some(Key::O), + (WinitKey::Character("p"), _) => Some(Key::P), + (WinitKey::Character("q"), _) => Some(Key::Q), + (WinitKey::Character("r"), _) => Some(Key::R), + (WinitKey::Character("s"), _) => Some(Key::S), + (WinitKey::Character("t"), _) => Some(Key::T), + (WinitKey::Character("u"), _) => Some(Key::U), + (WinitKey::Character("v"), _) => Some(Key::V), + (WinitKey::Character("w"), _) => Some(Key::W), + (WinitKey::Character("x"), _) => Some(Key::X), + (WinitKey::Character("y"), _) => Some(Key::Y), + (WinitKey::Character("z"), _) => Some(Key::Z), + (WinitKey::Character("'"), _) => Some(Key::Apostrophe), + (WinitKey::Character(","), KeyLocation::Standard) => Some(Key::Comma), + (WinitKey::Character("-"), KeyLocation::Standard) => Some(Key::Minus), + (WinitKey::Character("-"), KeyLocation::Numpad) => Some(Key::KeypadSubtract), + (WinitKey::Character("."), KeyLocation::Standard) => Some(Key::Period), + (WinitKey::Character("."), KeyLocation::Numpad) => Some(Key::KeypadDecimal), + (WinitKey::Character("/"), KeyLocation::Standard) => Some(Key::Slash), + (WinitKey::Character("/"), KeyLocation::Numpad) => Some(Key::KeypadDivide), + (WinitKey::Character(";"), _) => Some(Key::Semicolon), + (WinitKey::Character("="), KeyLocation::Standard) => Some(Key::Equal), + (WinitKey::Character("="), KeyLocation::Numpad) => Some(Key::KeypadEqual), + (WinitKey::Character("["), _) => Some(Key::LeftBracket), + (WinitKey::Character("\\"), _) => Some(Key::Backslash), + (WinitKey::Character("]"), _) => Some(Key::RightBracket), + (WinitKey::Character("`"), _) => Some(Key::GraveAccent), + (WinitKey::Character("*"), KeyLocation::Numpad) => Some(Key::KeypadMultiply), + (WinitKey::Character("+"), KeyLocation::Numpad) => Some(Key::KeypadAdd), + _ => None, + } +} + +fn handle_key_modifier(io: &mut Io, key: &WinitKey, down: bool) { + match key { + WinitKey::Named(NamedKey::Shift) => io.add_key_event(imgui::Key::ModShift, down), + WinitKey::Named(NamedKey::Control) => io.add_key_event(imgui::Key::ModCtrl, down), + WinitKey::Named(NamedKey::Alt) => io.add_key_event(imgui::Key::ModAlt, down), + WinitKey::Named(NamedKey::Super) => io.add_key_event(imgui::Key::ModSuper, down), + _ => {} + } +}