mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
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:
commit
cf022dfd00
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user