mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
map: refactor
This commit is contained in:
39
bin/map/src/app.rs
Normal file
39
bin/map/src/app.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use crate::list::StatefulList;
|
||||
|
||||
pub struct App<'a> {
|
||||
pub items: StatefulList<(&'a str, usize)>,
|
||||
}
|
||||
|
||||
impl<'a> App<'a> {
|
||||
pub fn new() -> App<'a> {
|
||||
App {
|
||||
items: StatefulList::with_items(vec![
|
||||
("node0", 1),
|
||||
("node1", 2),
|
||||
("node2", 1),
|
||||
("node3", 3),
|
||||
("node4", 1),
|
||||
("node5", 4),
|
||||
("node6", 1),
|
||||
("node7", 3),
|
||||
("node8", 1),
|
||||
("node9", 6),
|
||||
("node10", 1),
|
||||
("node11", 3),
|
||||
("node12", 1),
|
||||
("node13", 2),
|
||||
("node14", 1),
|
||||
("node15", 1),
|
||||
("node16", 4),
|
||||
("node17", 1),
|
||||
("node18", 5),
|
||||
("node19", 4),
|
||||
("node20", 1),
|
||||
("node21", 2),
|
||||
("node22", 1),
|
||||
("node23", 3),
|
||||
("node24", 1),
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
44
bin/map/src/list.rs
Normal file
44
bin/map/src/list.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use tui::widgets::ListState;
|
||||
|
||||
pub struct StatefulList<T> {
|
||||
pub state: ListState,
|
||||
pub items: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> StatefulList<T> {
|
||||
pub fn with_items(items: Vec<T>) -> StatefulList<T> {
|
||||
StatefulList { state: ListState::default(), items }
|
||||
}
|
||||
|
||||
pub fn next(&mut self) {
|
||||
let i = match self.state.selected() {
|
||||
Some(i) => {
|
||||
if i >= self.items.len() - 1 {
|
||||
0
|
||||
} else {
|
||||
i + 1
|
||||
}
|
||||
}
|
||||
None => 0,
|
||||
};
|
||||
self.state.select(Some(i));
|
||||
}
|
||||
|
||||
pub fn previous(&mut self) {
|
||||
let i = match self.state.selected() {
|
||||
Some(i) => {
|
||||
if i == 0 {
|
||||
self.items.len() - 1
|
||||
} else {
|
||||
i - 1
|
||||
}
|
||||
}
|
||||
None => 0,
|
||||
};
|
||||
self.state.select(Some(i));
|
||||
}
|
||||
|
||||
pub fn unselect(&mut self) {
|
||||
self.state.select(None);
|
||||
}
|
||||
}
|
||||
@@ -1,87 +1,138 @@
|
||||
// make async task that updates info
|
||||
// this display that
|
||||
//use drk::Result;
|
||||
use std::{io, io::Read};
|
||||
use std::{
|
||||
error::Error,
|
||||
io,
|
||||
io::Read,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use termion::{async_stdin, event::Key, input::TermRead, raw::IntoRawMode};
|
||||
use tui::{
|
||||
backend::TermionBackend,
|
||||
backend::{Backend, TermionBackend},
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Span, Spans, Text},
|
||||
widgets::{ListState, Block, Borders, List, ListItem, Paragraph, Wrap},
|
||||
widgets::{Block, Borders, List, ListItem, ListState, Paragraph, Wrap},
|
||||
Terminal,
|
||||
};
|
||||
|
||||
pub mod app;
|
||||
pub mod list;
|
||||
pub mod ui;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
fn main() -> Result<(), io::Error> {
|
||||
// Set up terminal output
|
||||
let stdout = io::stdout().into_raw_mode()?;
|
||||
let backend = TermionBackend::new(stdout);
|
||||
let mut terminal = Terminal::new(backend)?;
|
||||
|
||||
// create app and run it
|
||||
let tick_rate = Duration::from_millis(250);
|
||||
let app = App::new();
|
||||
let res = run_app(&mut terminal, app, tick_rate);
|
||||
|
||||
terminal.clear()?;
|
||||
|
||||
if let Err(err) = res {
|
||||
println!("{:?}", err)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
// Create a separate thread to poll stdin.
|
||||
// This provides non-blocking input support.
|
||||
//let mut asi = async_stdin();
|
||||
|
||||
//// Clear the terminal before first draw.
|
||||
//terminal.clear()?;
|
||||
//loop {
|
||||
// // Lock the terminal and start a drawing session.
|
||||
// terminal.draw(|frame| {
|
||||
// // Create a layout into which to place our blocks.
|
||||
// let chunks = Layout::default()
|
||||
// .direction(Direction::Vertical)
|
||||
// .constraints([Constraint::Percentage(6), Constraint::Percentage(94)].as_ref())
|
||||
// .split(frame.size());
|
||||
|
||||
// //let size = frame.size();
|
||||
|
||||
// // The text lines for our text box.
|
||||
// let txt = vec![Spans::from("\n Press q to quit.\n")];
|
||||
// // Create a paragraph with the above text...
|
||||
// let graph = Paragraph::new(txt)
|
||||
// // In a block with borders and the given title...
|
||||
// .block(Block::default().title("").borders(Borders::ALL))
|
||||
// // With white foreground and black background...
|
||||
// .style(Style::default().fg(Color::White).bg(Color::Black));
|
||||
|
||||
// // Render into the layout.
|
||||
// frame.render_widget(graph, chunks[0]);
|
||||
|
||||
// // create a list
|
||||
// //let mut items: Vec<ListItem> = Vec::new();
|
||||
// //for num in 1..100 {
|
||||
// // let new_item = ListItem::new(format!("Node {}", num));
|
||||
// // items.push(new_item);
|
||||
// //}
|
||||
|
||||
// //let list = List::new(items)
|
||||
// // .block(Block::default().title("Nodes").borders(Borders::ALL))
|
||||
// // .style(Style::default().fg(Color::White))
|
||||
// // .highlight_style(Style::default().add_modifier(Modifier::ITALIC))
|
||||
// // .highlight_symbol(">>");
|
||||
|
||||
// //// draw a list
|
||||
// //frame.render_widget(list, chunks[1]);
|
||||
|
||||
// // make a paragraph
|
||||
// let mut text1 = String::new();
|
||||
// for num in 1..10000 {
|
||||
// let text2 = format!("\n Node {}\n", num);
|
||||
// text1.push_str(&text2);
|
||||
// }
|
||||
|
||||
// let text = Spans::from(vec![Span::raw(String::from(text1))]);
|
||||
// let graph = Paragraph::new(text)
|
||||
// .block(Block::default().title("").borders(Borders::ALL))
|
||||
// .style(Style::default().fg(Color::White).bg(Color::Black))
|
||||
// .scroll((0, 10000))
|
||||
// .wrap(Wrap { trim: true });
|
||||
|
||||
// frame.render_widget(graph, chunks[1]);
|
||||
// })?;
|
||||
|
||||
// // Iterate over all the keys that have been pressed since the
|
||||
// // last time we checked.
|
||||
// for k in asi.by_ref().keys() {
|
||||
// match k.unwrap() {
|
||||
// // If any of them is q, quit
|
||||
// Key::Char('q') => {
|
||||
// // Clear the terminal before exit so as not to leave
|
||||
// // a mess.
|
||||
// terminal.clear()?;
|
||||
// return Ok(())
|
||||
// }
|
||||
// Key::Char('j') => {}
|
||||
// // Otherwise, throw them away.
|
||||
// _ => (),
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
fn run_app<B: Backend>(
|
||||
terminal: &mut Terminal<B>,
|
||||
mut app: App,
|
||||
tick_rate: Duration,
|
||||
) -> io::Result<()> {
|
||||
let mut asi = async_stdin();
|
||||
|
||||
// Clear the terminal before first draw.
|
||||
terminal.clear()?;
|
||||
let mut last_tick = Instant::now();
|
||||
loop {
|
||||
// Lock the terminal and start a drawing session.
|
||||
terminal.draw(|frame| {
|
||||
// Create a layout into which to place our blocks.
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Percentage(6), Constraint::Percentage(94)].as_ref())
|
||||
.split(frame.size());
|
||||
terminal.draw(|f| ui::ui(f, &mut app))?;
|
||||
|
||||
//let size = frame.size();
|
||||
|
||||
// The text lines for our text box.
|
||||
let txt = vec![Spans::from("\n Press q to quit.\n")];
|
||||
// Create a paragraph with the above text...
|
||||
let graph = Paragraph::new(txt)
|
||||
// In a block with borders and the given title...
|
||||
.block(Block::default().title("").borders(Borders::ALL))
|
||||
// With white foreground and black background...
|
||||
.style(Style::default().fg(Color::White).bg(Color::Black));
|
||||
|
||||
// Render into the layout.
|
||||
frame.render_widget(graph, chunks[0]);
|
||||
|
||||
// create a list
|
||||
//let mut items: Vec<ListItem> = Vec::new();
|
||||
//for num in 1..100 {
|
||||
// let new_item = ListItem::new(format!("Node {}", num));
|
||||
// items.push(new_item);
|
||||
//}
|
||||
|
||||
//let list = List::new(items)
|
||||
// .block(Block::default().title("Nodes").borders(Borders::ALL))
|
||||
// .style(Style::default().fg(Color::White))
|
||||
// .highlight_style(Style::default().add_modifier(Modifier::ITALIC))
|
||||
// .highlight_symbol(">>");
|
||||
|
||||
//// draw a list
|
||||
//frame.render_widget(list, chunks[1]);
|
||||
|
||||
// make a paragraph
|
||||
let mut text1 = String::new();
|
||||
for num in 1..10000 {
|
||||
let text2 = format!("\n Node {}\n", num);
|
||||
text1.push_str(&text2);
|
||||
}
|
||||
|
||||
let text = Spans::from(vec![Span::raw(String::from(text1))]);
|
||||
let graph = Paragraph::new(text)
|
||||
.block(Block::default().title("").borders(Borders::ALL))
|
||||
.style(Style::default().fg(Color::White).bg(Color::Black))
|
||||
.scroll((0, 10000))
|
||||
.wrap(Wrap { trim: true });
|
||||
|
||||
frame.render_widget(graph, chunks[1]);
|
||||
})?;
|
||||
|
||||
// Iterate over all the keys that have been pressed since the
|
||||
// last time we checked.
|
||||
for k in asi.by_ref().keys() {
|
||||
match k.unwrap() {
|
||||
// If any of them is q, quit
|
||||
@@ -91,11 +142,15 @@ fn main() -> Result<(), io::Error> {
|
||||
terminal.clear()?;
|
||||
return Ok(())
|
||||
}
|
||||
Key::Char('j') => {
|
||||
}
|
||||
Key::Char('j') => app.items.next(),
|
||||
Key::Char('k') => app.items.previous(),
|
||||
// Otherwise, throw them away.
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if last_tick.elapsed() >= tick_rate {
|
||||
last_tick = Instant::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
7
bin/map/src/mod.rs
Normal file
7
bin/map/src/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
pub mod list;
|
||||
pub mod app;
|
||||
pub mod ui;
|
||||
|
||||
pub use list::StatefulList;
|
||||
pub use app::App;
|
||||
pub use ui::ui;
|
||||
42
bin/map/src/ui.rs
Normal file
42
bin/map/src/ui.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use crate::app::App;
|
||||
use tui::{
|
||||
backend::Backend,
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::{Color, Modifier, Style},
|
||||
text::{Span, Spans},
|
||||
widgets::{Block, Borders, List, ListItem},
|
||||
Frame,
|
||||
};
|
||||
|
||||
pub fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Percentage(6), Constraint::Percentage(94)].as_ref())
|
||||
.split(f.size());
|
||||
|
||||
// Iterate through all elements in the `items` app and append some debug text to it.
|
||||
let items: Vec<ListItem> = app
|
||||
.items
|
||||
.items
|
||||
.iter()
|
||||
.map(|i| {
|
||||
let mut lines = vec![Spans::from(i.0)];
|
||||
for _ in 0..i.1 {
|
||||
lines.push(Spans::from(Span::styled(
|
||||
"Just some random garbage",
|
||||
Style::default().add_modifier(Modifier::ITALIC),
|
||||
)));
|
||||
}
|
||||
ListItem::new(lines).style(Style::default())
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Create a List from all list items and highlight the currently selected one
|
||||
let items = List::new(items)
|
||||
.block(Block::default().borders(Borders::ALL).title("List"))
|
||||
.highlight_style(Style::default().bg(Color::LightGreen).add_modifier(Modifier::BOLD))
|
||||
.highlight_symbol(">> ");
|
||||
|
||||
// Render the item list
|
||||
f.render_stateful_widget(items, chunks[0], &mut app.items.state);
|
||||
}
|
||||
Reference in New Issue
Block a user