re-enable chat focusing

Former-commit-id: 8cbcbba82bcb85fec11638085cff26049838fe6d
This commit is contained in:
Imbris 2019-05-06 08:28:57 -04:00
parent 7bade0360e
commit efa2afc5c8
2 changed files with 50 additions and 34 deletions

View File

@ -1,10 +1,8 @@
use conrod_core::{
builder_methods, color,
input::Key,
text::font,
widget::{self, Button, Id, List, Rectangle, Text, TextEdit},
position::Dimension,
UiCell, widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
UiCell, widget_ids, Colorable, Positionable, Sizeable, Widget, WidgetCommon,
};
use super::{
img_ids::Imgs,
@ -69,12 +67,13 @@ pub struct State {
pub enum Event {
SendMessage(String),
Focus(Id),
}
impl<'a> Widget for Chat<'a> {
type State = State;
type Style = ();
type Event = Option<Event>;
type Event = (bool, Option<Event>);
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
State {
@ -103,10 +102,12 @@ impl<'a> Widget for Chat<'a> {
ui.scroll_widget(state.ids.message_box, [0.0, std::f64::MAX]);
}
let keyboard_capturer = ui.global_input().current.widget_capturing_keyboard;
let input_focused = keyboard_capturer == Some(state.ids.input);
// Only show if it has the keyboard captured
// Chat input with rectangle as background
let keyboard_captured = ui.global_input().current.widget_capturing_keyboard == Some(id);
if keyboard_captured {
if input_focused {
let text_edit = TextEdit::new(&state.input)
.w(460.0)
.restrict_to_height(false)
@ -135,12 +136,10 @@ impl<'a> Widget for Chat<'a> {
// Message box
Rectangle::fill([470.0, 174.0])
.rgba(0.0, 0.0, 0.0, 0.4)
.and(|r| {
if keyboard_captured {
r.up_from(self.ids.input_bg, 0.0)
} else {
r.bottom_left_with_margins_on(ui_widgets.window, 10.0, 10.0)
}
.and(|r| if input_focused {
r.up_from(state.ids.input_bg, 0.0)
} else {
r.bottom_left_with_margins_on(ui.window, 10.0, 10.0)
})
.set(state.ids.message_box_bg, ui);
let (mut items, _) = List::flow_down(state.messages.len() + 1)
@ -186,8 +185,13 @@ impl<'a> Widget for Chat<'a> {
}
}
// If the chat widget is focused return a focus event to pass the focus to the input box
let self_focused = keyboard_capturer == Some(id);
let event = if self_focused {
Some(Event::Focus(state.ids.input))
}
// If enter is pressed and the input box is not empty send the current message
if ui
else if ui
.widget_input(state.ids.input)
.presses()
.key()
@ -198,9 +202,12 @@ impl<'a> Widget for Chat<'a> {
{
let msg = state.input.clone();
state.update(|s| s.input.clear());
return Some(Event::SendMessage(msg))
}
Some(Event::SendMessage(msg))
} else {
None
};
None
// Return whether typing and any event that occured
(self_focused || input_focused, event)
}
}

View File

@ -30,7 +30,7 @@ use crate::{
GlobalState,
};
use conrod_core::{
widget::{Button, Image, Text, Rectangle}, widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, color
widget::{Button, Image, Text, Id as WidgId, Rectangle}, widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, color
};
use std::collections::VecDeque;
@ -190,6 +190,8 @@ pub struct Hud {
new_messages: VecDeque<String>,
inventory_space: u32,
show: Show,
to_focus: Option<Option<WidgId>>,
typing: bool,
}
impl Hud {
@ -221,7 +223,9 @@ impl Hud {
ui: true,
inventory_test_button: false,
mini_map: false,
}
},
to_focus: None,
typing: false,
}
}
@ -365,12 +369,16 @@ impl Hud {
.set(self.ids.skillbar, ui_widgets);
// Chat box
match Chat::new(&mut self.new_messages, &self.imgs, &self.fonts)
.set(self.ids.chat, ui_widgets)
{
let (typing, event) = Chat::new(&mut self.new_messages, &self.imgs, &self.fonts)
.set(self.ids.chat, ui_widgets);
self.typing = typing;
match event {
Some(chat::Event::SendMessage(message)) => {
events.push(Event::SendMessage(message));
}
Some(chat::Event::Focus(focus_id)) => {
self.to_focus = Some(Some(focus_id));
}
None => {}
}
self.new_messages = VecDeque::new();
@ -461,18 +469,11 @@ impl Hud {
self.new_messages.push_back(msg);
}
fn typing(&self) -> bool {
match self.ui.widget_capturing_keyboard() {
Some(id) if id == self.ids.chat => true,
_ => false,
}
}
pub fn handle_event(&mut self, event: WinEvent, global_state: &mut GlobalState) -> bool {
let cursor_grabbed = global_state.window.is_cursor_grabbed();
match event {
WinEvent::Ui(event) => {
if (self.typing() && event.is_keyboard() && self.show.ui)
if (self.typing && event.is_keyboard() && self.show.ui)
|| !(cursor_grabbed && event.is_keyboard_or_mouse())
{
self.ui.handle_event(event);
@ -486,19 +487,24 @@ impl Hud {
_ if !self.show.ui => false,
WinEvent::Zoom(_) => !cursor_grabbed && !self.ui.no_widget_capturing_mouse(),
WinEvent::KeyDown(Key::Enter) => {
self.ui.focus_widget(Some(self.ids.chat));
self.ui.focus_widget(if self.typing {
None
} else {
Some(self.ids.chat)
});
true
}
WinEvent::KeyDown(Key::Escape) => {
if self.typing() {
if self.typing {
self.ui.focus_widget(None);
self.typing = false;
} else {
// Close windows on esc
self.show.toggle_windows(global_state);
}
true
}
WinEvent::KeyDown(key) if !self.typing() => match key {
WinEvent::KeyDown(key) if !self.typing => match key {
Key::Map => {
self.show.toggle_map();
true
@ -535,9 +541,9 @@ impl Hud {
},
WinEvent::KeyDown(key) | WinEvent::KeyUp(key) => match key {
Key::ToggleCursor => false,
_ => self.typing(),
_ => self.typing,
},
WinEvent::Char(_) => self.typing(),
WinEvent::Char(_) => self.typing,
WinEvent::SettingsChanged => {
self.settings = global_state.settings.clone();
true
@ -547,6 +553,9 @@ impl Hud {
}
pub fn maintain(&mut self, renderer: &mut Renderer, tps: f64) -> Vec<Event> {
if let Some(maybe_id) = self.to_focus.take() {
self.ui.focus_widget(maybe_id);
}
let events = self.update_layout(tps);
self.ui.maintain(renderer);
events