diff --git a/examples/hello_world.rs b/examples/hello_world.rs index bb851a1..99c1c4e 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -16,7 +16,8 @@ fn main() { let mut support = Support::init(); loop { - let active = support.render(CLEAR_COLOR, hello_world); + support.render(CLEAR_COLOR, hello_world); + let active = support.update_events(); if !active { break } } } diff --git a/examples/support/mod.rs b/examples/support/mod.rs index fd64a5f..842cf07 100644 --- a/examples/support/mod.rs +++ b/examples/support/mod.rs @@ -1,8 +1,8 @@ use glium::{DisplayBuild, Surface}; use glium::backend::glutin_backend::GlutinFacade; use glium::glutin; -use glium::glutin::{ElementState, Event, MouseButton, VirtualKeyCode}; -use imgui::{ImGui, Ui}; +use glium::glutin::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode}; +use imgui::{ImGui, Ui, ImGuiKey}; use imgui::glium_renderer::Renderer; use time::SteadyTime; @@ -12,7 +12,8 @@ pub struct Support { renderer: Renderer, last_frame: SteadyTime, mouse_pos: (i32, i32), - mouse_pressed: (bool, bool, bool) + mouse_pressed: (bool, bool, bool), + mouse_wheel: f32, } impl Support { @@ -24,29 +25,53 @@ impl Support { let mut imgui = ImGui::init(); let renderer = Renderer::init(&mut imgui, &display).unwrap(); + // TODO: How can we get the virtual key -> scancode mapping from glium? + imgui.set_imgui_key(ImGuiKey::Tab, 15); + imgui.set_imgui_key(ImGuiKey::LeftArrow, 75); + imgui.set_imgui_key(ImGuiKey::RightArrow, 77); + imgui.set_imgui_key(ImGuiKey::UpArrow, 72); + imgui.set_imgui_key(ImGuiKey::DownArrow, 80); + imgui.set_imgui_key(ImGuiKey::PageUp, 73); + imgui.set_imgui_key(ImGuiKey::PageDown, 81); + imgui.set_imgui_key(ImGuiKey::Home, 71); + imgui.set_imgui_key(ImGuiKey::End, 79); + imgui.set_imgui_key(ImGuiKey::Delete, 83); + imgui.set_imgui_key(ImGuiKey::Backspace, 14); + imgui.set_imgui_key(ImGuiKey::Enter, 28); + imgui.set_imgui_key(ImGuiKey::Escape, 1); + imgui.set_imgui_key(ImGuiKey::A, 30); + imgui.set_imgui_key(ImGuiKey::C, 46); + imgui.set_imgui_key(ImGuiKey::V, 47); + imgui.set_imgui_key(ImGuiKey::X, 45); + imgui.set_imgui_key(ImGuiKey::Y, 21); + imgui.set_imgui_key(ImGuiKey::Z, 44); + Support { display: display, imgui: imgui, renderer: renderer, last_frame: SteadyTime::now(), mouse_pos: (0, 0), - mouse_pressed: (false, false, false) + mouse_pressed: (false, false, false), + mouse_wheel: 0.0 } } pub fn update_mouse(&mut self) { self.imgui.set_mouse_pos(self.mouse_pos.0 as f32, self.mouse_pos.1 as f32); self.imgui.set_mouse_down(&[self.mouse_pressed.0, self.mouse_pressed.1, self.mouse_pressed.2, false, false]); + self.imgui.set_mouse_wheel(self.mouse_wheel); } pub fn render<'ui, 'a: 'ui , F: FnMut(&Ui<'ui>)>( - &'a mut self, clear_color: (f32, f32, f32, f32), mut f: F) -> bool { + &'a mut self, clear_color: (f32, f32, f32, f32), mut f: F) { let now = SteadyTime::now(); let delta = now - self.last_frame; let delta_f = delta.num_nanoseconds().unwrap() as f32 / 1_000_000_000.0; self.last_frame = now; self.update_mouse(); + self.mouse_wheel = 0.0; let mut target = self.display.draw(); target.clear_color(clear_color.0, clear_color.1, @@ -58,20 +83,39 @@ impl Support { self.renderer.render(&mut target, ui).unwrap(); target.finish().unwrap(); + } + pub fn update_events(&mut self) -> bool { for event in self.display.poll_events() { match event { - Event::Closed | - Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Escape)) - => return false, - Event::MouseMoved(pos) => self.mouse_pos = pos, - Event::MouseInput(state, MouseButton::Left) => - self.mouse_pressed.0 = state == ElementState::Pressed, - Event::MouseInput(state, MouseButton::Right) => - self.mouse_pressed.1 = state == ElementState::Pressed, - Event::MouseInput(state, MouseButton::Middle) => - self.mouse_pressed.2 = state == ElementState::Pressed, - _ => () + Event::Closed => return false, + // TODO: Why does glutin not give us scancodes for left/right control? + Event::KeyboardInput(state, _, Some(code)) + if code == VirtualKeyCode::RControl || code == VirtualKeyCode::LControl + => self.imgui.set_key_ctrl(state == ElementState::Pressed), + Event::KeyboardInput(state, scancode, code) => { + println!("KeyCode {:?} scancode {} pressed? {}", code, scancode, + state == ElementState::Pressed); + self.imgui.set_key(scancode, state == ElementState::Pressed); + // TODO: This hack to do Ctrl should not be needed! + if scancode == 29 { + println!("Bad! Hacking in ctrl key press"); + self.imgui.set_key_ctrl(state == ElementState::Pressed); + } + }, + Event::MouseMoved(pos) => self.mouse_pos = pos, + Event::MouseInput(state, MouseButton::Left) => + self.mouse_pressed.0 = state == ElementState::Pressed, + Event::MouseInput(state, MouseButton::Right) => + self.mouse_pressed.1 = state == ElementState::Pressed, + Event::MouseInput(state, MouseButton::Middle) => + self.mouse_pressed.2 = state == ElementState::Pressed, + Event::MouseWheel(MouseScrollDelta::LineDelta(_, y)) => self.mouse_wheel = y, + Event::ReceivedCharacter(c) => { + println!("Got character {}", c); + self.imgui.add_input_character(c); + }, + _ => () } } true diff --git a/examples/test_window.rs b/examples/test_window.rs index d185dc0..b79df03 100644 --- a/examples/test_window.rs +++ b/examples/test_window.rs @@ -8,16 +8,17 @@ use self::support::Support; mod support; -const CLEAR_COLOR: (f32, f32, f32, f32) = (1.0, 1.0, 1.0, 1.0); +const CLEAR_COLOR: (f32, f32, f32, f32) = (0.2, 0.2, 0.2, 1.0); fn main() { let mut support = Support::init(); loop { let mut open = true; - let active = support.render(CLEAR_COLOR, |ui| { + support.render(CLEAR_COLOR, |ui| { ui.show_test_window(&mut open) }); + let active = support.update_events(); if !active || !open { break } } } diff --git a/examples/test_window_impl.rs b/examples/test_window_impl.rs index 6dbdaa0..61c5344 100644 --- a/examples/test_window_impl.rs +++ b/examples/test_window_impl.rs @@ -92,9 +92,10 @@ fn main() { let mut opened = true; loop { - let active = support.render(state.clear_color, |ui| { + support.render(state.clear_color, |ui| { show_test_window(ui, &mut state, &mut opened); }); + let active = support.update_events(); if !active || !opened { break } } } diff --git a/src/lib.rs b/src/lib.rs index cc678e9..f2ba293 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,7 +26,8 @@ pub use imgui_sys::{ ImGuiWindowFlags_NoScrollbar, ImGuiWindowFlags_NoScrollWithMouse, ImGuiWindowFlags_NoCollapse, ImGuiWindowFlags_AlwaysAutoResize, ImGuiWindowFlags_ShowBorders, ImGuiWindowFlags_NoSavedSettings, ImGuiWindowFlags_NoInputs, ImGuiWindowFlags_MenuBar, - ImVec2, ImVec4 + ImVec2, ImVec4, + ImGuiKey }; pub use menus::{Menu, MenuItem}; pub use sliders::{SliderFloat, SliderInt}; @@ -221,6 +222,21 @@ impl ImGui { let io = self.io_mut(); io.key_alt = value; } + pub fn set_key(&mut self, key: u8, pressed: bool) { + let io = self.io_mut(); + io.keys_down[key as usize] = pressed; + } + pub fn set_imgui_key(&mut self, key: ImGuiKey, mapping: u8) { + let io = self.io_mut(); + io.key_map[key as usize] = mapping as i32; + } + pub fn add_input_character(&mut self, character: char) { + unsafe { + // TODO: This is not good. We should use char::encode_ut8 when it stabilizes + // (or whatever stabilizes to fill its place) and call ImGuiIO_AddInputCharactersUTF8 + imgui_sys::ImGuiIO_AddInputCharacter(character as u16); + } + } pub fn get_time(&self) -> f32 { unsafe { imgui_sys::igGetTime() } } pub fn get_frame_count(&self) -> i32 { unsafe { imgui_sys::igGetFrameCount() } } pub fn get_frame_rate(&self) -> f32 { self.io().framerate }