Merge branch 'chat_history' into 'master'

Basic chat window history functionality, closes #186

Closes #186

See merge request veloren/veloren!331
This commit is contained in:
Imbris 2019-09-02 05:12:23 +00:00
commit cf022dfd00
2 changed files with 60 additions and 15 deletions

View File

@ -36,6 +36,9 @@ pub struct Chat<'a> {
#[conrod(common_builder)] #[conrod(common_builder)]
common: widget::CommonBuilder, common: widget::CommonBuilder,
// TODO: add an option to adjust this
history_max: usize,
} }
impl<'a> Chat<'a> { impl<'a> Chat<'a> {
@ -51,6 +54,7 @@ impl<'a> Chat<'a> {
imgs, imgs,
fonts, fonts,
common: widget::CommonBuilder::default(), common: widget::CommonBuilder::default(),
history_max: 32,
} }
} }
@ -82,8 +86,11 @@ impl<'a> Chat<'a> {
pub struct State { pub struct State {
messages: VecDeque<ClientEvent>, messages: VecDeque<ClientEvent>,
input: String, input: String,
ids: Ids, ids: Ids,
history: VecDeque<String>,
// Index into the history Vec, history_pos == 0 is history not in use
// otherwise index is history_pos -1
history_pos: usize,
} }
pub enum Event { pub enum Event {
@ -100,6 +107,8 @@ impl<'a> Widget for Chat<'a> {
State { State {
input: "".to_owned(), input: "".to_owned(),
messages: VecDeque::new(), messages: VecDeque::new(),
history: VecDeque::new(),
history_pos: 0,
ids: Ids::new(id_gen), ids: Ids::new(id_gen),
} }
} }
@ -124,6 +133,39 @@ impl<'a> Widget for Chat<'a> {
} }
}); });
// If up or down are pressed move through history
// TODO: move cursor to the end of the last line
match ui.widget_input(state.ids.input).presses().key().fold(
(false, false),
|(up, down), key_press| match key_press.key {
Key::Up => (true, down),
Key::Down => (up, true),
_ => (up, down),
},
) {
(true, false) => {
if state.history_pos < state.history.len() {
state.update(|s| {
s.history_pos += 1;
s.input = s.history.get(s.history_pos - 1).unwrap().to_owned();
});
}
}
(false, true) => {
if state.history_pos > 0 {
state.update(|s| {
s.history_pos -= 1;
if s.history_pos > 0 {
s.input = s.history.get(s.history_pos - 1).unwrap().to_owned();
} else {
s.input.clear();
}
});
}
}
_ => {}
}
let keyboard_capturer = ui.global_input().current.widget_capturing_keyboard; let keyboard_capturer = ui.global_input().current.widget_capturing_keyboard;
if let Some(input) = &self.force_input { if let Some(input) = &self.force_input {
@ -136,8 +178,7 @@ impl<'a> Widget for Chat<'a> {
// Only show if it has the keyboard captured. // Only show if it has the keyboard captured.
// Chat input uses a rectangle as its background. // Chat input uses a rectangle as its background.
if input_focused { if input_focused {
let input = self.force_input.as_ref().unwrap_or(&state.input); let mut text_edit = TextEdit::new(&state.input)
let mut text_edit = TextEdit::new(input)
.w(460.0) .w(460.0)
.restrict_to_height(false) .restrict_to_height(false)
.color(TEXT_COLOR) .color(TEXT_COLOR)
@ -266,7 +307,16 @@ impl<'a> Widget for Chat<'a> {
}) })
{ {
let msg = state.input.clone(); let msg = state.input.clone();
state.update(|s| s.input.clear()); state.update(|s| {
s.input.clear();
// Update the history
// Don't add if this is identical to the last message in the history
s.history_pos = 0;
if s.history.get(0).map_or(true, |h| h != &msg) {
s.history.push_front(msg.clone());
s.history.truncate(self.history_max);
}
});
Some(Event::SendMessage(msg)) Some(Event::SendMessage(msg))
} else { } else {
None None

View File

@ -741,17 +741,11 @@ impl Hud {
} }
// Chat box // Chat box
let mut chat = Chat::new(&mut self.new_messages, &self.imgs, &self.fonts); match Chat::new(&mut self.new_messages, &self.imgs, &self.fonts)
.and_then(self.force_chat_input.take(), |c, input| c.input(input))
if let Some(input) = self.force_chat_input.take() { .and_then(self.force_chat_cursor.take(), |c, pos| c.cursor_pos(pos))
chat = chat.input(input); .set(self.ids.chat, ui_widgets)
} {
if let Some(pos) = self.force_chat_cursor.take() {
chat = chat.cursor_pos(pos);
}
match chat.set(self.ids.chat, ui_widgets) {
Some(chat::Event::SendMessage(message)) => { Some(chat::Event::SendMessage(message)) => {
events.push(Event::SendMessage(message)); events.push(Event::SendMessage(message));
} }
@ -760,6 +754,7 @@ impl Hud {
} }
None => {} None => {}
} }
self.new_messages = VecDeque::new(); self.new_messages = VecDeque::new();
// Windows // Windows