Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
enable scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
chkeita committed Mar 17, 2021
1 parent 5bb6f5e commit 528ff15
Showing 1 changed file with 73 additions and 17 deletions.
90 changes: 73 additions & 17 deletions src/agent/onefuzz-agent/src/local/tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
// Licensed under the MIT License.

use crate::local::common::UiEvent;
use anyhow::Result;
use anyhow::{Context, Result};
use crossterm::{
event::{self, Event, KeyCode},
terminal::enable_raw_mode,
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use futures::{StreamExt, TryStreamExt};
use log::Level;
use onefuzz::utils::try_wait_all_join_handles;
use std::{
cmp::Ordering,
collections::HashMap,
io::{self, Stdout},
error::Error,
io::{self, Stdout, Write},
path::PathBuf,
sync::Arc,
time::Duration,
Expand All @@ -28,7 +30,7 @@ use tokio::{
use tui::{
backend::CrosstermBackend,
layout::{Constraint, Corner, Direction, Layout},
style::{Color, Style},
style::{Color, Modifier, Style},
text::{Span, Spans},
widgets::{Block, Borders},
widgets::{List, ListItem, ListState},
Expand Down Expand Up @@ -66,7 +68,6 @@ pub struct TerminalUi {
pub task_events: UnboundedSender<UiEvent>,
task_event_receiver: mpsc::UnboundedReceiver<UiEvent>,
log_event_receiver: mpsc::UnboundedReceiver<(Level, String)>,
terminal: Terminal<CrosstermBackend<Stdout>>,
}

/// Event driving the refresh of the UI
Expand Down Expand Up @@ -111,15 +112,11 @@ impl TerminalUi {
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err.to_string()))
})
.init();
let stdout = io::stdout();
let backend = CrosstermBackend::new(stdout);
let terminal = Terminal::new(backend)?;

Ok(Self {
task_events: task_event_sender,
task_event_receiver,
log_event_receiver,
terminal,
})
}

Expand All @@ -128,10 +125,13 @@ impl TerminalUi {
loop {
if event::poll(Duration::from_secs(0))? {
let event = event::read()?;
ui_event_tx.send(TerminalEvent::Input(event))?;
ui_event_tx
.send(TerminalEvent::Input(event))?;
} else {
ui_event_tx
.send(TerminalEvent::Tick)?;
interval.tick().await;
}
ui_event_tx.send(TerminalEvent::Tick)?;
interval.tick().await;
}
}

Expand Down Expand Up @@ -204,6 +204,7 @@ impl TerminalUi {

let log_list = List::new(files)
.block(Block::default().borders(Borders::ALL).title("files"))
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.start_corner(Corner::TopLeft);

f.render_stateful_widget(log_list, chunks[0], &mut file_count_state);
Expand Down Expand Up @@ -243,10 +244,57 @@ impl TerminalUi {
})
}
TerminalEvent::Input(Event::Key(k)) if k.code == KeyCode::Char('q') => {
let mut terminal = ui_state.terminal;
disable_raw_mode().map_err(|e| anyhow!("{:?}", e))?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)
.map_err(|e| anyhow!("{:?}", e))?;
terminal.show_cursor()?;
Err(UILoopError::Exit)
}
TerminalEvent::Input(Event::Key(k)) if k.code == KeyCode::Down => {
let mut file_count_state = ui_state.file_count_state;
let count = ui_state.file_count.len();
let i = file_count_state
.selected()
.map(|i| {
if count == 0 {
0
} else {
(i + count + 1) % count
}
})
.unwrap_or_default();

//bail!(UILoopError::Exit)
file_count_state.select(Some(i));
Ok(UILoopState {
file_count_state,
..ui_state
})
}
TerminalEvent::Input(Event::Key(k)) if k.code == KeyCode::Up => {
let mut file_count_state = ui_state.file_count_state;
let count = ui_state.file_count.len();
let i = file_count_state
.selected()
.map(|i| {
if count == 0 {
0
} else {
(i + count - 1) % count
}
})
.unwrap_or_default();
file_count_state.select(Some(i));
Ok(UILoopState {
file_count_state,
..ui_state
})
}

TerminalEvent::FileCount { dir, count } => {
let mut file_count = ui_state.file_count;
file_count.insert(dir, count);
Expand All @@ -259,6 +307,7 @@ impl TerminalUi {
}
})
.await;

match loop_result {
Err(UILoopError::Exit) | Ok(_) => Ok(()),
Err(UILoopError::Anyhow(e)) => Err(e),
Expand All @@ -267,17 +316,24 @@ impl TerminalUi {

pub async fn run(self) -> Result<()> {
enable_raw_mode()?;

let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;

let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;

let (ui_event_tx, ui_event_rx) = mpsc::unbounded_channel();
let ui_event_handle = tokio::spawn(Self::read_ui_events(ui_event_tx.clone()));
let ui_event_tx_clone = ui_event_tx.clone();
let ui_event_handle = tokio::spawn(async { Self::read_ui_events(ui_event_tx_clone).await.context("reading Events")? ; Ok(()) });

let task_event_receiver = self.task_event_receiver;
let external_event_handle =
tokio::spawn(Self::read_commands(ui_event_tx, task_event_receiver));
let mut terminal = self.terminal;
terminal.clear()?;
let initial_state = UILoopState::new(terminal, self.log_event_receiver);
let ui_loop = tokio::spawn(Self::ui_loop(initial_state, ui_event_rx));
try_wait_all_join_handles(vec![ui_event_handle, ui_loop, external_event_handle]).await
try_wait_all_join_handles(vec![ui_event_handle, ui_loop, external_event_handle]).await.context("***** run handle")
}
}

Expand Down

0 comments on commit 528ff15

Please sign in to comment.