Added SetText event, rewritten based on comments

This commit is contained in:
tommy 2019-07-15 13:04:48 -04:00 committed by Imbris
parent a63e67b8d9
commit 12029d7e7f
2 changed files with 64 additions and 55 deletions

View File

@ -82,15 +82,19 @@ impl<'a> Chat<'a> {
pub struct State { pub struct State {
messages: VecDeque<ClientEvent>, messages: VecDeque<ClientEvent>,
input: String, input: String,
ids: Ids,
history: VecDeque<String>, 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, history_pos: usize,
history_max: usize, history_max: usize,
ids: Ids, history_command: Option<String>,
} }
pub enum Event { pub enum Event {
SendMessage(String), SendMessage(String),
Focus(Id), Focus(Id),
SetText(String),
} }
impl<'a> Widget for Chat<'a> { impl<'a> Widget for Chat<'a> {
@ -105,6 +109,7 @@ impl<'a> Widget for Chat<'a> {
history: VecDeque::new(), history: VecDeque::new(),
history_pos: 0, history_pos: 0,
history_max: 32, history_max: 32,
history_command: None,
ids: Ids::new(id_gen), ids: Ids::new(id_gen),
} }
} }
@ -256,80 +261,73 @@ impl<'a> Widget for Chat<'a> {
} }
} }
// Take a key from the input queue
let keys = ui.widget_input(state.ids.input).presses().key().take(1);
// If the chat widget is focused, return a focus event to pass the focus to the input box. // If the chat widget is focused, return a focus event to pass the focus to the input box.
if keyboard_capturer == Some(id) { if keyboard_capturer == Some(id) {
Some(Event::Focus(state.ids.input)) Some(Event::Focus(state.ids.input))
} }
// If enter is pressed and the input box is not empty, send the current message. // If enter is pressed and the input box is not empty, send the current message.
else if ui else if keys.clone().any(|key_press| match key_press.key {
.widget_input(state.ids.input)
.presses()
.key()
.any(|key_press| match key_press.key {
Key::Return if !state.input.is_empty() => true, Key::Return if !state.input.is_empty() => true,
_ => false, _ => false,
}) }) {
{
let msg = state.input.clone(); let msg = state.input.clone();
state.update(|s| { state.update(|s| {
s.input.clear(); s.input.clear();
// update the history // Update the history
s.history.push_front(msg.clone()); s.history.push_front(msg.clone());
s.history_pos = 0; s.history_pos = 0;
while s.history.len() > s.history_max { s.history.truncate(s.history_max);
s.history.pop_back();
}
}); });
Some(Event::SendMessage(msg)) Some(Event::SendMessage(msg))
} }
// If up is pressed, use history // If up is pressed, use history
else if ui else if keys.clone().any(|key_press| match key_press.key {
.widget_input(state.ids.input)
.presses()
.key()
.any(|key_press| match key_press.key {
Key::Up => true, Key::Up => true,
_ => false, _ => false,
}) }) {
{ if !state.history.is_empty() {
if state.history_pos < state.history.len() {
state.update(|s| { state.update(|s| {
if !s.history.is_empty() {
if s.history_pos < s.history.len() {
s.history_pos += 1; s.history_pos += 1;
if let Some(string) = s.history.get(s.history_pos - 1) { s.history_command = match s.history.get(s.history_pos - 1) {
s.input.clear(); Some(string) => Some(string.to_string()),
s.input.push_str(string); None => None,
}
}
} }
}); });
None }
}
match &state.history_command {
Some(string) => Some(Event::SetText(string.to_string())),
None => None,
}
} }
// If down is pressed, use history // If down is pressed, use history
else if ui else if keys.clone().any(|key_press| match key_press.key {
.widget_input(state.ids.input)
.presses()
.key()
.any(|key_press| match key_press.key {
Key::Down => true, Key::Down => true,
_ => false, _ => false,
}) }) {
{ if state.history_pos > 1 {
state.update(|s| { state.update(|s| {
if !s.history.is_empty() {
if s.history_pos > 1 {
s.history_pos -= 1; s.history_pos -= 1;
s.input.clear(); s.history_command = match s.history.get(s.history_pos - 1) {
if let Some(string) = s.history.get(s.history_pos - 1) { Some(string) => Some(string.to_string()),
s.input.push_str(string); None => None,
}
} else {
s.history_pos = 0;
s.input.clear();
}
} }
}); });
None } else {
state.update(|s| {
s.history_command = None;
s.history_pos = 0;
s.input.clear();
});
}
match &state.history_command {
Some(string) => Some(Event::SetText(string.to_string())),
None => None,
}
} else { } else {
None None
} }

View File

@ -758,8 +758,19 @@ impl Hud {
Some(chat::Event::Focus(focus_id)) => { Some(chat::Event::Focus(focus_id)) => {
self.to_focus = Some(Some(focus_id)); self.to_focus = Some(Some(focus_id));
} }
Some(chat::Event::SetText(text)) => {
let mut q = VecDeque::new();
let mut chat = Chat::new(&mut q, &self.imgs, &self.fonts);
chat = chat.input(text.to_string());
chat = chat.cursor_pos(Index {
line: 0,
char: text.len(),
});
chat.set(self.ids.chat, ui_widgets);
}
None => {} None => {}
} }
self.new_messages = VecDeque::new(); self.new_messages = VecDeque::new();
// Windows // Windows