Display cursor for "join room" overlay

This commit is contained in:
Joscha 2022-02-26 13:31:25 +01:00
parent 3ac3bbb99e
commit 3c68debd32
3 changed files with 25 additions and 10 deletions

View file

@ -15,6 +15,7 @@ use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tui::backend::CrosstermBackend; use tui::backend::CrosstermBackend;
use tui::layout::{Constraint, Direction, Layout}; use tui::layout::{Constraint, Direction, Layout};
use tui::widgets::Paragraph;
use tui::{Frame, Terminal}; use tui::{Frame, Terminal};
use crate::room::Room; use crate::room::Room;
@ -92,9 +93,9 @@ impl Ui {
// Do a little dance to please the borrow checker // Do a little dance to please the borrow checker
let cursor = frame.cursor(); let cursor = frame.cursor();
drop(frame); drop(frame);
terminal.set_cursor_opt(cursor)?;
terminal.flush()?; terminal.flush()?;
terminal.set_cursor_opt(cursor)?; // Must happen after flush
terminal.flush_backend()?; terminal.flush_backend()?;
terminal.swap_buffers(); terminal.swap_buffers();
@ -136,7 +137,10 @@ impl Ui {
match reaction { match reaction {
OverlayReaction::Handled => {} OverlayReaction::Handled => {}
OverlayReaction::Close => self.overlay = None, OverlayReaction::Close => self.overlay = None,
OverlayReaction::JoinRoom(name) => todo!(), OverlayReaction::JoinRoom(name) => {
self.overlay = None;
// TODO Join room
}
} }
} }
return CONTINUE; return CONTINUE;
@ -197,7 +201,9 @@ impl Ui {
if let Some(overlay) = &mut self.overlay { if let Some(overlay) = &mut self.overlay {
match overlay { match overlay {
Overlay::JoinRoom(state) => { Overlay::JoinRoom(state) => {
frame.render_stateful_widget(JoinRoom, entire_area, state) frame.render_stateful_widget(JoinRoom, entire_area, state);
let (x, y) = state.last_cursor_pos();
frame.set_cursor(x, y);
} }
} }
} }

View file

@ -44,3 +44,9 @@ impl EventHandler for JoinRoomState {
}) })
} }
} }
impl JoinRoomState {
pub fn last_cursor_pos(&self) -> (u16, u16) {
self.room.last_cursor_pos()
}
}

View file

@ -18,7 +18,12 @@ impl StatefulWidget for TextLine {
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
Paragraph::new(&state.content as &str).render(area, buf); Paragraph::new(&state.content as &str).render(area, buf);
// Paragraph::new("foo").render(area, buf);
// Determine cursor position
let prefix = state.content.chars().take(state.cursor).collect::<String>();
let position = prefix.width() as u16;
let x = area.x + position.min(area.width);
state.last_cursor_pos = (x, area.y);
} }
} }
@ -27,6 +32,7 @@ impl StatefulWidget for TextLine {
pub struct TextLineState { pub struct TextLineState {
content: String, content: String,
cursor: usize, cursor: usize,
last_cursor_pos: (u16, u16),
} }
impl TextLineState { impl TextLineState {
@ -34,12 +40,9 @@ impl TextLineState {
self.content.clone() self.content.clone()
} }
/// Set a frame's cursor position to this text line's cursor position /// The cursor's position from when the widget was last rendered.
pub fn set_cursor<B: Backend>(&self, f: &mut Frame<B>, area: Rect) { pub fn last_cursor_pos(&self) -> (u16, u16) {
let prefix = self.content.chars().take(self.cursor).collect::<String>(); self.last_cursor_pos
let position = prefix.width() as u16;
let x = area.x + cmp::min(position, area.width);
f.set_cursor(x, area.y);
} }
fn chars(&self) -> usize { fn chars(&self) -> usize {