diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs index a72dd655cd..eb198ad7ee 100644 --- a/voxygen/src/hud/chat.rs +++ b/voxygen/src/hud/chat.rs @@ -38,8 +38,8 @@ impl Chat { new_messages: false, } } - pub fn is_input_box(&self, id: Id) -> bool { - id == self.ids.input + pub fn input_box_id(&self) -> Id { + self.ids.input } pub fn new_message(&mut self, msg: String) { self.messages.push_front(msg); diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index cf671afcd8..fd9643e325 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -1155,7 +1155,7 @@ impl Hud { } // update whether keyboard is captured self.typing = if let Some(widget_id) = ui_widgets.global_input().current.widget_capturing_keyboard { - self.chat.is_input_box(widget_id) + widget_id == self.chat.input_box_id() } else { false }; @@ -1178,12 +1178,30 @@ impl Hud { pub fn handle_event(&mut self, event: WinEvent) -> bool { match event { WinEvent::Ui(event) => { - if !(self.cursor_grabbed && event.is_keyboard_or_mouse()) { + if (self.typing && event.is_keyboard()) || !(self.cursor_grabbed && event.is_keyboard_or_mouse()) { self.ui.handle_event(event); } true }, - _ if self.cursor_grabbed => false, + WinEvent::KeyDown(Key::Enter) => { + if self.cursor_grabbed && self.typing { + self.ui.focus_widget(None); + self.typing = false; + } else if !self.typing { + self.ui.focus_widget(Some(self.chat.input_box_id())); + self.typing = true; + }; + true + } + WinEvent::KeyDown(Key::Escape) if self.typing => { + if self.typing { + self.typing = false; + self.ui.focus_widget(None); + true + } else { + false + } + } WinEvent::KeyDown(key) | WinEvent::KeyUp(key) => match key { Key::ToggleCursor => false, _ => self.typing, diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index e1f5e7649c..d7101e86f9 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -16,7 +16,7 @@ use conrod_core::{ widget::{Id as WidgId, id::Generator}, render::Primitive, event::Input, - input::{touch::Touch, Widget, Motion}, + input::{touch::Touch, Widget, Motion, Button, MouseButton}, }; use vek::*; use crate::{ @@ -53,6 +53,12 @@ impl Event { _ => false, } } + pub fn is_keyboard(&self) -> bool { + match self.0 { + Input::Press(Button::Keyboard(_)) | Input::Release(Button::Keyboard(_)) | Input::Text(_) => true, + _ => false, + } + } pub fn new_resize(dims: Vec2) -> Self { Self(Input::Resize(dims.x, dims.y)) } @@ -224,6 +230,33 @@ impl Ui { self.ui.set_widgets() } + // Workaround because conrod currently gives us no way to programmatically set which widget is capturing key input + // Note the widget must be visible and not covered by other widgets at its center for this to work + // Accepts option so widget can be "unfocused" + pub fn focus_widget(&mut self, id: Option) { + let (x, y) = match id { + // get position of widget + Some(id) => if let Some([x, y]) = self.ui.xy_of(id) { + (x, y) + } else { + return; + }, + // outside window (origin is center) + None => (self.ui.win_h, self.ui.win_w) + }; + // things to consider: does cursor need to be moved back?, should we check if the mouse if already pressed and then trigger a release? + self.ui.handle_event( + Input::Motion(Motion::MouseCursor { x, y }) + ); + self.ui.handle_event( + Input::Press(Button::Mouse(MouseButton::Left)) + ); + self.ui.handle_event( + Input::Release(Button::Mouse(MouseButton::Left)) + ); + } + + pub fn handle_event(&mut self, event: Event) { match event.0 { Input::Resize(w, h) => self.window_resized = Some(Vec2::new(w, h)), diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index d3fdbe8895..959fe36c9e 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -48,6 +48,7 @@ impl Window { let mut key_map = HashMap::new(); key_map.insert(glutin::VirtualKeyCode::Tab, Key::ToggleCursor); key_map.insert(glutin::VirtualKeyCode::Escape, Key::Escape); + key_map.insert(glutin::VirtualKeyCode::Return, Key::Enter); key_map.insert(glutin::VirtualKeyCode::W, Key::MoveForward); key_map.insert(glutin::VirtualKeyCode::A, Key::MoveLeft); key_map.insert(glutin::VirtualKeyCode::S, Key::MoveBack); @@ -73,7 +74,7 @@ impl Window { pub fn renderer_mut(&mut self) -> &mut Renderer { &mut self.renderer } pub fn fetch_events(&mut self) -> Vec { - let mut events = vec![]; + let mut events = vec![]; // Refresh ui size (used when changing playstates) if self.needs_refresh_resize { events.push(Event::Ui(ui::Event::new_resize(self.logical_size()))); @@ -168,6 +169,7 @@ pub enum Key { MoveBack, MoveLeft, MoveRight, + Enter, Escape, }