mirror of
https://github.com/fdehau/tui-rs.git
synced 2024-10-30 21:20:22 +00:00
Run cargo fmt
This commit is contained in:
parent
295fc77df2
commit
71545a0aa8
@ -24,30 +24,32 @@ impl<'a> App<'a> {
|
||||
fn new() -> App<'a> {
|
||||
App {
|
||||
size: Rect::default(),
|
||||
data: vec![("B1", 9),
|
||||
("B2", 12),
|
||||
("B3", 5),
|
||||
("B4", 8),
|
||||
("B5", 2),
|
||||
("B6", 4),
|
||||
("B7", 5),
|
||||
("B8", 9),
|
||||
("B9", 14),
|
||||
("B10", 15),
|
||||
("B11", 1),
|
||||
("B12", 0),
|
||||
("B13", 4),
|
||||
("B14", 6),
|
||||
("B15", 4),
|
||||
("B16", 6),
|
||||
("B17", 4),
|
||||
("B18", 7),
|
||||
("B19", 13),
|
||||
("B20", 8),
|
||||
("B21", 11),
|
||||
("B22", 9),
|
||||
("B23", 3),
|
||||
("B24", 5)],
|
||||
data: vec![
|
||||
("B1", 9),
|
||||
("B2", 12),
|
||||
("B3", 5),
|
||||
("B4", 8),
|
||||
("B5", 2),
|
||||
("B6", 4),
|
||||
("B7", 5),
|
||||
("B8", 9),
|
||||
("B9", 14),
|
||||
("B10", 15),
|
||||
("B11", 1),
|
||||
("B12", 0),
|
||||
("B13", 4),
|
||||
("B14", 6),
|
||||
("B15", 4),
|
||||
("B16", 6),
|
||||
("B17", 4),
|
||||
("B18", 7),
|
||||
("B19", 13),
|
||||
("B20", 8),
|
||||
("B21", 11),
|
||||
("B22", 9),
|
||||
("B23", 3),
|
||||
("B24", 5),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,9 +88,9 @@ fn main() {
|
||||
|
||||
// Tick
|
||||
thread::spawn(move || loop {
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
|
||||
// App
|
||||
let mut app = App::new();
|
||||
|
@ -56,10 +56,9 @@ fn draw(t: &mut Terminal<MouseBackend>, size: &Rect) {
|
||||
.render(t, &chunks[0]);
|
||||
Block::default()
|
||||
.title("Styled title")
|
||||
.title_style(Style::default()
|
||||
.fg(Color::White)
|
||||
.bg(Color::Red)
|
||||
.modifier(Modifier::Bold))
|
||||
.title_style(Style::default().fg(Color::White).bg(Color::Red).modifier(
|
||||
Modifier::Bold,
|
||||
))
|
||||
.render(t, &chunks[1]);
|
||||
});
|
||||
Group::default()
|
||||
|
@ -46,11 +46,13 @@ impl App {
|
||||
|
||||
fn advance(&mut self) {
|
||||
if self.ball.left() < self.playground.left() ||
|
||||
self.ball.right() > self.playground.right() {
|
||||
self.ball.right() > self.playground.right()
|
||||
{
|
||||
self.dir_x = !self.dir_x;
|
||||
}
|
||||
if self.ball.top() < self.playground.top() ||
|
||||
self.ball.bottom() > self.playground.bottom() {
|
||||
self.ball.bottom() > self.playground.bottom()
|
||||
{
|
||||
self.dir_y = !self.dir_y;
|
||||
}
|
||||
|
||||
@ -97,9 +99,9 @@ fn main() {
|
||||
|
||||
// Tick
|
||||
thread::spawn(move || loop {
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
|
||||
// App
|
||||
let mut app = App::new();
|
||||
@ -160,12 +162,12 @@ fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
|
||||
Canvas::default()
|
||||
.block(Block::default().borders(border::ALL).title("World"))
|
||||
.paint(|ctx| {
|
||||
ctx.draw(&Map {
|
||||
color: Color::White,
|
||||
resolution: MapResolution::High,
|
||||
});
|
||||
ctx.print(app.x, -app.y, "You are here", Color::Yellow);
|
||||
})
|
||||
ctx.draw(&Map {
|
||||
color: Color::White,
|
||||
resolution: MapResolution::High,
|
||||
});
|
||||
ctx.print(app.x, -app.y, "You are here", Color::Yellow);
|
||||
})
|
||||
.x_bounds([-180.0, 180.0])
|
||||
.y_bounds([-90.0, 90.0])
|
||||
.render(t, &chunks[0]);
|
||||
@ -173,33 +175,33 @@ fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
|
||||
.block(Block::default().borders(border::ALL).title("List"))
|
||||
.paint(|ctx| {
|
||||
ctx.draw(&Line {
|
||||
x1: app.ball.left() as f64,
|
||||
y1: app.ball.top() as f64,
|
||||
x2: app.ball.right() as f64,
|
||||
y2: app.ball.top() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
x1: app.ball.left() as f64,
|
||||
y1: app.ball.top() as f64,
|
||||
x2: app.ball.right() as f64,
|
||||
y2: app.ball.top() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
ctx.draw(&Line {
|
||||
x1: app.ball.right() as f64,
|
||||
y1: app.ball.top() as f64,
|
||||
x2: app.ball.right() as f64,
|
||||
y2: app.ball.bottom() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
x1: app.ball.right() as f64,
|
||||
y1: app.ball.top() as f64,
|
||||
x2: app.ball.right() as f64,
|
||||
y2: app.ball.bottom() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
ctx.draw(&Line {
|
||||
x1: app.ball.right() as f64,
|
||||
y1: app.ball.bottom() as f64,
|
||||
x2: app.ball.left() as f64,
|
||||
y2: app.ball.bottom() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
x1: app.ball.right() as f64,
|
||||
y1: app.ball.bottom() as f64,
|
||||
x2: app.ball.left() as f64,
|
||||
y2: app.ball.bottom() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
ctx.draw(&Line {
|
||||
x1: app.ball.left() as f64,
|
||||
y1: app.ball.bottom() as f64,
|
||||
x2: app.ball.left() as f64,
|
||||
y2: app.ball.top() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
x1: app.ball.left() as f64,
|
||||
y1: app.ball.bottom() as f64,
|
||||
x2: app.ball.left() as f64,
|
||||
y2: app.ball.top() as f64,
|
||||
color: Color::Yellow,
|
||||
});
|
||||
})
|
||||
.x_bounds([10.0, 110.0])
|
||||
.y_bounds([10.0, 110.0])
|
||||
|
@ -86,9 +86,9 @@ fn main() {
|
||||
|
||||
// Tick
|
||||
thread::spawn(move || loop {
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
|
||||
// App
|
||||
let mut app = App::new();
|
||||
@ -126,34 +126,48 @@ fn main() {
|
||||
fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
|
||||
|
||||
Chart::default()
|
||||
.block(Block::default()
|
||||
.title("Chart")
|
||||
.title_style(Style::default().fg(Color::Cyan).modifier(Modifier::Bold))
|
||||
.borders(border::ALL))
|
||||
.x_axis(Axis::default()
|
||||
.title("X Axis")
|
||||
.style(Style::default().fg(Color::Gray))
|
||||
.labels_style(Style::default().modifier(Modifier::Italic))
|
||||
.bounds(app.window)
|
||||
.labels(&[&format!("{}", app.window[0]),
|
||||
&format!("{}", (app.window[0] + app.window[1]) / 2.0),
|
||||
&format!("{}", app.window[1])]))
|
||||
.y_axis(Axis::default()
|
||||
.title("Y Axis")
|
||||
.style(Style::default().fg(Color::Gray))
|
||||
.labels_style(Style::default().modifier(Modifier::Italic))
|
||||
.bounds([-20.0, 20.0])
|
||||
.labels(&["-20", "0", "20"]))
|
||||
.datasets(&[Dataset::default()
|
||||
.name("data2")
|
||||
.marker(Marker::Dot)
|
||||
.style(Style::default().fg(Color::Cyan))
|
||||
.data(&app.data1),
|
||||
Dataset::default()
|
||||
.name("data3")
|
||||
.marker(Marker::Braille)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.data(&app.data2)])
|
||||
.block(
|
||||
Block::default()
|
||||
.title("Chart")
|
||||
.title_style(Style::default().fg(Color::Cyan).modifier(Modifier::Bold))
|
||||
.borders(border::ALL),
|
||||
)
|
||||
.x_axis(
|
||||
Axis::default()
|
||||
.title("X Axis")
|
||||
.style(Style::default().fg(Color::Gray))
|
||||
.labels_style(Style::default().modifier(Modifier::Italic))
|
||||
.bounds(app.window)
|
||||
.labels(
|
||||
&[
|
||||
&format!("{}", app.window[0]),
|
||||
&format!("{}", (app.window[0] + app.window[1]) / 2.0),
|
||||
&format!("{}", app.window[1]),
|
||||
],
|
||||
),
|
||||
)
|
||||
.y_axis(
|
||||
Axis::default()
|
||||
.title("Y Axis")
|
||||
.style(Style::default().fg(Color::Gray))
|
||||
.labels_style(Style::default().modifier(Modifier::Italic))
|
||||
.bounds([-20.0, 20.0])
|
||||
.labels(&["-20", "0", "20"]),
|
||||
)
|
||||
.datasets(
|
||||
&[
|
||||
Dataset::default()
|
||||
.name("data2")
|
||||
.marker(Marker::Dot)
|
||||
.style(Style::default().fg(Color::Cyan))
|
||||
.data(&app.data1),
|
||||
Dataset::default()
|
||||
.name("data3")
|
||||
.marker(Marker::Braille)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.data(&app.data2),
|
||||
],
|
||||
)
|
||||
.render(t, &app.size);
|
||||
|
||||
t.draw().unwrap();
|
||||
|
@ -83,9 +83,9 @@ fn main() {
|
||||
|
||||
// Tick
|
||||
thread::spawn(move || loop {
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
|
||||
// App
|
||||
let mut app = App::new();
|
||||
@ -125,10 +125,14 @@ fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
|
||||
Group::default()
|
||||
.direction(Direction::Vertical)
|
||||
.margin(2)
|
||||
.sizes(&[Size::Percent(25),
|
||||
Size::Percent(25),
|
||||
Size::Percent(25),
|
||||
Size::Percent(25)])
|
||||
.sizes(
|
||||
&[
|
||||
Size::Percent(25),
|
||||
Size::Percent(25),
|
||||
Size::Percent(25),
|
||||
Size::Percent(25),
|
||||
],
|
||||
)
|
||||
.render(t, &app.size, |t, chunks| {
|
||||
Gauge::default()
|
||||
.block(Block::default().title("Gauge1").borders(border::ALL))
|
||||
|
103
examples/list.rs
103
examples/list.rs
@ -30,37 +30,61 @@ impl<'a> App<'a> {
|
||||
fn new() -> App<'a> {
|
||||
App {
|
||||
size: Rect::default(),
|
||||
items: vec!["Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8",
|
||||
"Item9", "Item10", "Item11", "Item12", "Item13", "Item14", "Item15",
|
||||
"Item16", "Item17", "Item18", "Item19", "Item20", "Item21", "Item22",
|
||||
"Item23", "Item24"],
|
||||
items: vec![
|
||||
"Item1",
|
||||
"Item2",
|
||||
"Item3",
|
||||
"Item4",
|
||||
"Item5",
|
||||
"Item6",
|
||||
"Item7",
|
||||
"Item8",
|
||||
"Item9",
|
||||
"Item10",
|
||||
"Item11",
|
||||
"Item12",
|
||||
"Item13",
|
||||
"Item14",
|
||||
"Item15",
|
||||
"Item16",
|
||||
"Item17",
|
||||
"Item18",
|
||||
"Item19",
|
||||
"Item20",
|
||||
"Item21",
|
||||
"Item22",
|
||||
"Item23",
|
||||
"Item24",
|
||||
],
|
||||
selected: 0,
|
||||
events: vec![("Event1", "INFO"),
|
||||
("Event2", "INFO"),
|
||||
("Event3", "CRITICAL"),
|
||||
("Event4", "ERROR"),
|
||||
("Event5", "INFO"),
|
||||
("Event6", "INFO"),
|
||||
("Event7", "WARNING"),
|
||||
("Event8", "INFO"),
|
||||
("Event9", "INFO"),
|
||||
("Event10", "INFO"),
|
||||
("Event11", "CRITICAL"),
|
||||
("Event12", "INFO"),
|
||||
("Event13", "INFO"),
|
||||
("Event14", "INFO"),
|
||||
("Event15", "INFO"),
|
||||
("Event16", "INFO"),
|
||||
("Event17", "ERROR"),
|
||||
("Event18", "ERROR"),
|
||||
("Event19", "INFO"),
|
||||
("Event20", "INFO"),
|
||||
("Event21", "WARNING"),
|
||||
("Event22", "INFO"),
|
||||
("Event23", "INFO"),
|
||||
("Event24", "WARNING"),
|
||||
("Event25", "INFO"),
|
||||
("Event26", "INFO")],
|
||||
events: vec![
|
||||
("Event1", "INFO"),
|
||||
("Event2", "INFO"),
|
||||
("Event3", "CRITICAL"),
|
||||
("Event4", "ERROR"),
|
||||
("Event5", "INFO"),
|
||||
("Event6", "INFO"),
|
||||
("Event7", "WARNING"),
|
||||
("Event8", "INFO"),
|
||||
("Event9", "INFO"),
|
||||
("Event10", "INFO"),
|
||||
("Event11", "CRITICAL"),
|
||||
("Event12", "INFO"),
|
||||
("Event13", "INFO"),
|
||||
("Event14", "INFO"),
|
||||
("Event15", "INFO"),
|
||||
("Event16", "INFO"),
|
||||
("Event17", "ERROR"),
|
||||
("Event18", "ERROR"),
|
||||
("Event19", "INFO"),
|
||||
("Event20", "INFO"),
|
||||
("Event21", "WARNING"),
|
||||
("Event22", "INFO"),
|
||||
("Event23", "INFO"),
|
||||
("Event24", "WARNING"),
|
||||
("Event25", "INFO"),
|
||||
("Event26", "INFO"),
|
||||
],
|
||||
info_style: Style::default().fg(Color::White),
|
||||
warning_style: Style::default().fg(Color::Yellow),
|
||||
error_style: Style::default().fg(Color::Magenta),
|
||||
@ -103,9 +127,9 @@ fn main() {
|
||||
|
||||
// Tick
|
||||
thread::spawn(move || loop {
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
|
||||
// App
|
||||
let mut app = App::new();
|
||||
@ -170,16 +194,17 @@ fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
|
||||
.highlight_symbol(">")
|
||||
.render(t, &chunks[0]);
|
||||
{
|
||||
let events = app.events
|
||||
.iter()
|
||||
.map(|&(evt, level)| {
|
||||
Item::StyledData(format!("{}: {}", level, evt), match level {
|
||||
let events = app.events.iter().map(|&(evt, level)| {
|
||||
Item::StyledData(
|
||||
format!("{}: {}", level, evt),
|
||||
match level {
|
||||
"ERROR" => &app.error_style,
|
||||
"CRITICAL" => &app.critical_style,
|
||||
"WARNING" => &app.warning_style,
|
||||
_ => &app.info_style,
|
||||
})
|
||||
});
|
||||
},
|
||||
)
|
||||
});
|
||||
List::new(events)
|
||||
.block(Block::default().borders(border::ALL).title("List"))
|
||||
.render(t, &chunks[1]);
|
||||
|
@ -52,11 +52,13 @@ fn draw(t: &mut Terminal<MouseBackend>, size: &Rect) {
|
||||
.sizes(&[Size::Percent(100)])
|
||||
.render(t, &chunks[0], |t, chunks| {
|
||||
Paragraph::default()
|
||||
.text("This is a line\n{fg=red This is a line}\n{bg=red This is a \
|
||||
.text(
|
||||
"This is a line\n{fg=red This is a line}\n{bg=red This is a \
|
||||
line}\n{mod=italic This is a line}\n{mod=bold This is a \
|
||||
line}\n{mod=crossed_out This is a line}\n{mod=invert This is a \
|
||||
line}\n{mod=underline This is a \
|
||||
line}\n{bg=green;fg=yellow;mod=italic This is a line}\n")
|
||||
line}\n{bg=green;fg=yellow;mod=italic This is a line}\n",
|
||||
)
|
||||
.render(t, &chunks[0]);
|
||||
});
|
||||
});
|
||||
|
@ -39,13 +39,13 @@ fn draw(t: &mut Terminal<RustboxBackend>) {
|
||||
.sizes(&[Size::Percent(100)])
|
||||
.render(t, &size, |t, chunks| {
|
||||
Paragraph::default()
|
||||
.block(Block::default()
|
||||
.title("Rustbox backend")
|
||||
.title_style(Style::default()
|
||||
.fg(Color::Yellow)
|
||||
.modifier(Modifier::Bold))
|
||||
.borders(border::ALL)
|
||||
.border_style(Style::default().fg(Color::Magenta)))
|
||||
.block(
|
||||
Block::default()
|
||||
.title("Rustbox backend")
|
||||
.title_style(Style::default().fg(Color::Yellow).modifier(Modifier::Bold))
|
||||
.borders(border::ALL)
|
||||
.border_style(Style::default().fg(Color::Magenta)),
|
||||
)
|
||||
.text("It {yellow works}!")
|
||||
.render(t, &chunks[0]);
|
||||
});
|
||||
|
@ -83,9 +83,9 @@ fn main() {
|
||||
|
||||
// Tick
|
||||
thread::spawn(move || loop {
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
clock_tx.send(Event::Tick).unwrap();
|
||||
thread::sleep(time::Duration::from_millis(500));
|
||||
});
|
||||
|
||||
// App
|
||||
let mut app = App::new();
|
||||
@ -125,27 +125,29 @@ fn draw(t: &mut Terminal<MouseBackend>, app: &App) {
|
||||
Group::default()
|
||||
.direction(Direction::Vertical)
|
||||
.margin(2)
|
||||
.sizes(&[Size::Fixed(3), Size::Fixed(3), Size::Fixed(7), Size::Min(0)])
|
||||
.sizes(
|
||||
&[Size::Fixed(3), Size::Fixed(3), Size::Fixed(7), Size::Min(0)],
|
||||
)
|
||||
.render(t, &app.size, |t, chunks| {
|
||||
Sparkline::default()
|
||||
.block(Block::default()
|
||||
.title("Data1")
|
||||
.borders(border::LEFT | border::RIGHT))
|
||||
.block(Block::default().title("Data1").borders(
|
||||
border::LEFT | border::RIGHT,
|
||||
))
|
||||
.data(&app.data1)
|
||||
.style(Style::default().fg(Color::Yellow))
|
||||
.render(t, &chunks[0]);
|
||||
Sparkline::default()
|
||||
.block(Block::default()
|
||||
.title("Data2")
|
||||
.borders(border::LEFT | border::RIGHT))
|
||||
.block(Block::default().title("Data2").borders(
|
||||
border::LEFT | border::RIGHT,
|
||||
))
|
||||
.data(&app.data2)
|
||||
.style(Style::default().bg(Color::Green))
|
||||
.render(t, &chunks[1]);
|
||||
// Multiline
|
||||
Sparkline::default()
|
||||
.block(Block::default()
|
||||
.title("Data3")
|
||||
.borders(border::LEFT | border::RIGHT))
|
||||
.block(Block::default().title("Data3").borders(
|
||||
border::LEFT | border::RIGHT,
|
||||
))
|
||||
.data(&app.data3)
|
||||
.style(Style::default().fg(Color::Red))
|
||||
.render(t, &chunks[2]);
|
||||
|
@ -13,8 +13,10 @@ use self::log4rs::config::{Appender, Config, Root};
|
||||
|
||||
pub fn setup_log(file_name: &str) {
|
||||
let log = FileAppender::builder()
|
||||
.encoder(Box::new(PatternEncoder::new("{l} / {d(%H:%M:%S)} / \
|
||||
{M}:{L}{n}{m}{n}{n}")))
|
||||
.encoder(Box::new(PatternEncoder::new(
|
||||
"{l} / {d(%H:%M:%S)} / \
|
||||
{M}:{L}{n}{m}{n}{n}",
|
||||
)))
|
||||
.build(file_name)
|
||||
.unwrap();
|
||||
|
||||
|
@ -15,7 +15,8 @@ pub use self::termion::{TermionBackend, MouseBackend, RawBackend};
|
||||
|
||||
pub trait Backend {
|
||||
fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>
|
||||
where I: Iterator<Item = (u16, u16, &'a Cell)>;
|
||||
where
|
||||
I: Iterator<Item = (u16, u16, &'a Cell)>;
|
||||
fn hide_cursor(&mut self) -> Result<(), io::Error>;
|
||||
fn show_cursor(&mut self) -> Result<(), io::Error>;
|
||||
fn clear(&mut self) -> Result<(), io::Error>;
|
||||
|
@ -28,18 +28,20 @@ impl RustboxBackend {
|
||||
|
||||
impl Backend for RustboxBackend {
|
||||
fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>
|
||||
where I: Iterator<Item = (u16, u16, &'a Cell)>
|
||||
where
|
||||
I: Iterator<Item = (u16, u16, &'a Cell)>,
|
||||
{
|
||||
let mut inst = 0;
|
||||
for (x, y, cell) in content {
|
||||
inst += 1;
|
||||
self.rustbox
|
||||
.print(x as usize,
|
||||
y as usize,
|
||||
cell.style.modifier.into(),
|
||||
cell.style.fg.into(),
|
||||
cell.style.bg.into(),
|
||||
&cell.symbol);
|
||||
self.rustbox.print(
|
||||
x as usize,
|
||||
y as usize,
|
||||
cell.style.modifier.into(),
|
||||
cell.style.fg.into(),
|
||||
cell.style.bg.into(),
|
||||
&cell.symbol,
|
||||
);
|
||||
}
|
||||
debug!("{} instructions outputed", inst);
|
||||
Ok(())
|
||||
@ -56,11 +58,11 @@ impl Backend for RustboxBackend {
|
||||
}
|
||||
fn size(&self) -> Result<Rect, io::Error> {
|
||||
Ok(Rect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: self.rustbox.width() as u16,
|
||||
height: self.rustbox.height() as u16,
|
||||
})
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: self.rustbox.width() as u16,
|
||||
height: self.rustbox.height() as u16,
|
||||
})
|
||||
}
|
||||
fn flush(&mut self) -> Result<(), io::Error> {
|
||||
self.rustbox.present();
|
||||
|
@ -11,7 +11,8 @@ use layout::Rect;
|
||||
use style::{Style, Color, Modifier};
|
||||
|
||||
pub struct TermionBackend<W>
|
||||
where W: Write
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
stdout: W,
|
||||
}
|
||||
@ -36,7 +37,8 @@ impl MouseBackend {
|
||||
}
|
||||
|
||||
impl<W> Backend for TermionBackend<W>
|
||||
where W: Write
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
/// Clears the entire screen and move the cursor to the top left of the screen
|
||||
fn clear(&mut self) -> Result<(), io::Error> {
|
||||
@ -61,7 +63,8 @@ impl<W> Backend for TermionBackend<W>
|
||||
}
|
||||
|
||||
fn draw<'a, I>(&mut self, content: I) -> Result<(), io::Error>
|
||||
where I: Iterator<Item = (u16, u16, &'a Cell)>
|
||||
where
|
||||
I: Iterator<Item = (u16, u16, &'a Cell)>,
|
||||
{
|
||||
let mut string = String::with_capacity(content.size_hint().0 * 3);
|
||||
let mut style = Style::default();
|
||||
@ -98,12 +101,14 @@ impl<W> Backend for TermionBackend<W>
|
||||
inst += 1;
|
||||
}
|
||||
debug!("{} instructions outputed.", inst);
|
||||
write!(self.stdout,
|
||||
"{}{}{}{}",
|
||||
string,
|
||||
Color::Reset.termion_fg(),
|
||||
Color::Reset.termion_bg(),
|
||||
Modifier::Reset.termion_modifier())?;
|
||||
write!(
|
||||
self.stdout,
|
||||
"{}{}{}{}",
|
||||
string,
|
||||
Color::Reset.termion_fg(),
|
||||
Color::Reset.termion_bg(),
|
||||
Modifier::Reset.termion_modifier()
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -111,11 +116,11 @@ impl<W> Backend for TermionBackend<W>
|
||||
fn size(&self) -> Result<Rect, io::Error> {
|
||||
let terminal = try!(termion::terminal_size());
|
||||
Ok(Rect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: terminal.0,
|
||||
height: terminal.1,
|
||||
})
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: terminal.0,
|
||||
height: terminal.1,
|
||||
})
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<(), io::Error> {
|
||||
|
@ -155,22 +155,29 @@ impl Buffer {
|
||||
|
||||
/// Returns the index in the Vec<Cell> for the given (x, y)
|
||||
pub fn index_of(&self, x: u16, y: u16) -> usize {
|
||||
debug_assert!(x >= self.area.left() && x < self.area.right() && y >= self.area.top() &&
|
||||
y < self.area.bottom(),
|
||||
"Trying to access position outside the buffer: x={}, y={}, area={:?}",
|
||||
x,
|
||||
y,
|
||||
self.area);
|
||||
debug_assert!(
|
||||
x >= self.area.left() && x < self.area.right() && y >= self.area.top() &&
|
||||
y < self.area.bottom(),
|
||||
"Trying to access position outside the buffer: x={}, y={}, area={:?}",
|
||||
x,
|
||||
y,
|
||||
self.area
|
||||
);
|
||||
((y - self.area.y) * self.area.width + (x - self.area.x)) as usize
|
||||
}
|
||||
|
||||
/// Returns the coordinates of a cell given its index
|
||||
pub fn pos_of(&self, i: usize) -> (u16, u16) {
|
||||
debug_assert!(i >= self.content.len(),
|
||||
"Trying to get the coords of a cell outside the buffer: i={} len={}",
|
||||
i,
|
||||
self.content.len());
|
||||
(self.area.x + i as u16 % self.area.width, self.area.y + i as u16 / self.area.width)
|
||||
debug_assert!(
|
||||
i >= self.content.len(),
|
||||
"Trying to get the coords of a cell outside the buffer: i={} len={}",
|
||||
i,
|
||||
self.content.len()
|
||||
);
|
||||
(
|
||||
self.area.x + i as u16 % self.area.width,
|
||||
self.area.y + i as u16 / self.area.width,
|
||||
)
|
||||
}
|
||||
|
||||
/// Print a string, starting at the position (x, y)
|
||||
|
@ -106,7 +106,7 @@ impl Rect {
|
||||
|
||||
pub fn intersects(&self, other: &Rect) -> bool {
|
||||
self.x < other.x + other.width && self.x + self.width > other.x &&
|
||||
self.y < other.y + other.height && self.y + self.height > other.y
|
||||
self.y < other.y + other.height && self.y + self.height > other.y
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,23 +160,15 @@ pub fn split(area: &Rect, dir: &Direction, margin: u16, sizes: &[Size]) -> Vec<R
|
||||
}
|
||||
if let Some(first) = elements.first() {
|
||||
constraints.push(match *dir {
|
||||
Direction::Horizontal => {
|
||||
first.left() | EQ(REQUIRED) | dest_area.left() as f64
|
||||
}
|
||||
Direction::Vertical => {
|
||||
first.top() | EQ(REQUIRED) | dest_area.top() as f64
|
||||
}
|
||||
});
|
||||
Direction::Horizontal => first.left() | EQ(REQUIRED) | dest_area.left() as f64,
|
||||
Direction::Vertical => first.top() | EQ(REQUIRED) | dest_area.top() as f64,
|
||||
});
|
||||
}
|
||||
if let Some(last) = elements.last() {
|
||||
constraints.push(match *dir {
|
||||
Direction::Horizontal => {
|
||||
last.right() | EQ(REQUIRED) | dest_area.right() as f64
|
||||
}
|
||||
Direction::Vertical => {
|
||||
last.bottom() | EQ(REQUIRED) | dest_area.bottom() as f64
|
||||
}
|
||||
});
|
||||
Direction::Horizontal => last.right() | EQ(REQUIRED) | dest_area.right() as f64,
|
||||
Direction::Vertical => last.bottom() | EQ(REQUIRED) | dest_area.bottom() as f64,
|
||||
});
|
||||
}
|
||||
match *dir {
|
||||
Direction::Horizontal => {
|
||||
@ -187,14 +179,13 @@ pub fn split(area: &Rect, dir: &Direction, margin: u16, sizes: &[Size]) -> Vec<R
|
||||
constraints.push(elements[i].y | EQ(REQUIRED) | dest_area.y as f64);
|
||||
constraints.push(elements[i].height | EQ(REQUIRED) | dest_area.height as f64);
|
||||
constraints.push(match *size {
|
||||
Size::Fixed(v) => elements[i].width | EQ(WEAK) | v as f64,
|
||||
Size::Percent(v) => {
|
||||
elements[i].width | EQ(WEAK) |
|
||||
((v * dest_area.width) as f64 / 100.0)
|
||||
}
|
||||
Size::Min(v) => elements[i].width | GE(WEAK) | v as f64,
|
||||
Size::Max(v) => elements[i].width | LE(WEAK) | v as f64,
|
||||
});
|
||||
Size::Fixed(v) => elements[i].width | EQ(WEAK) | v as f64,
|
||||
Size::Percent(v) => {
|
||||
elements[i].width | EQ(WEAK) | ((v * dest_area.width) as f64 / 100.0)
|
||||
}
|
||||
Size::Min(v) => elements[i].width | GE(WEAK) | v as f64,
|
||||
Size::Max(v) => elements[i].width | LE(WEAK) | v as f64,
|
||||
});
|
||||
}
|
||||
}
|
||||
Direction::Vertical => {
|
||||
@ -205,14 +196,13 @@ pub fn split(area: &Rect, dir: &Direction, margin: u16, sizes: &[Size]) -> Vec<R
|
||||
constraints.push(elements[i].x | EQ(REQUIRED) | dest_area.x as f64);
|
||||
constraints.push(elements[i].width | EQ(REQUIRED) | dest_area.width as f64);
|
||||
constraints.push(match *size {
|
||||
Size::Fixed(v) => elements[i].height | EQ(WEAK) | v as f64,
|
||||
Size::Percent(v) => {
|
||||
elements[i].height | EQ(WEAK) |
|
||||
((v * dest_area.height) as f64 / 100.0)
|
||||
}
|
||||
Size::Min(v) => elements[i].height | GE(WEAK) | v as f64,
|
||||
Size::Max(v) => elements[i].height | LE(WEAK) | v as f64,
|
||||
});
|
||||
Size::Fixed(v) => elements[i].height | EQ(WEAK) | v as f64,
|
||||
Size::Percent(v) => {
|
||||
elements[i].height | EQ(WEAK) | ((v * dest_area.height) as f64 / 100.0)
|
||||
}
|
||||
Size::Min(v) => elements[i].height | GE(WEAK) | v as f64,
|
||||
Size::Max(v) => elements[i].height | LE(WEAK) | v as f64,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -332,8 +322,9 @@ impl Group {
|
||||
self
|
||||
}
|
||||
pub fn render<F, B>(&self, t: &mut Terminal<B>, area: &Rect, mut f: F)
|
||||
where B: Backend,
|
||||
F: FnMut(&mut Terminal<B>, &[Rect])
|
||||
where
|
||||
B: Backend,
|
||||
F: FnMut(&mut Terminal<B>, &[Rect]),
|
||||
{
|
||||
let chunks = t.compute_layout(self, area);
|
||||
f(t, &chunks);
|
||||
|
@ -15,7 +15,8 @@ pub struct LayoutEntry {
|
||||
|
||||
/// Interface to the terminal backed by Termion
|
||||
pub struct Terminal<B>
|
||||
where B: Backend
|
||||
where
|
||||
B: Backend,
|
||||
{
|
||||
backend: B,
|
||||
/// Cache to prevent the layout to be computed at each draw call
|
||||
@ -28,18 +29,19 @@ pub struct Terminal<B>
|
||||
}
|
||||
|
||||
impl<B> Terminal<B>
|
||||
where B: Backend
|
||||
where
|
||||
B: Backend,
|
||||
{
|
||||
/// Wrapper around Termion initialization. Each buffer is initialized with a blank string and
|
||||
/// default colors for the foreground and the background
|
||||
pub fn new(backend: B) -> Result<Terminal<B>, io::Error> {
|
||||
let size = try!(backend.size());
|
||||
Ok(Terminal {
|
||||
backend: backend,
|
||||
layout_cache: HashMap::new(),
|
||||
buffers: [Buffer::empty(size), Buffer::empty(size)],
|
||||
current: 0,
|
||||
})
|
||||
backend: backend,
|
||||
layout_cache: HashMap::new(),
|
||||
buffers: [Buffer::empty(size), Buffer::empty(size)],
|
||||
current: 0,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn backend(&self) -> &B {
|
||||
@ -58,9 +60,11 @@ impl<B> Terminal<B>
|
||||
.entry((group.clone(), *area))
|
||||
.or_insert_with(|| {
|
||||
let chunks = split(area, &group.direction, group.margin, &group.sizes);
|
||||
debug!("New layout computed:\n* Group = {:?}\n* Chunks = {:?}",
|
||||
group,
|
||||
chunks);
|
||||
debug!(
|
||||
"New layout computed:\n* Group = {:?}\n* Chunks = {:?}",
|
||||
group,
|
||||
chunks
|
||||
);
|
||||
LayoutEntry {
|
||||
chunks: chunks,
|
||||
hot: true,
|
||||
@ -80,19 +84,20 @@ impl<B> Terminal<B>
|
||||
.zip(self.buffers[1 - self.current].content.iter())
|
||||
.enumerate()
|
||||
.filter_map(|(i, (c, p))| if c != p {
|
||||
let i = i as u16;
|
||||
let x = i % width;
|
||||
let y = i / width;
|
||||
Some((x, y, c))
|
||||
} else {
|
||||
None
|
||||
});
|
||||
let i = i as u16;
|
||||
let x = i % width;
|
||||
let y = i / width;
|
||||
Some((x, y, c))
|
||||
} else {
|
||||
None
|
||||
});
|
||||
self.backend.draw(content)
|
||||
}
|
||||
|
||||
/// Calls the draw method of a given widget on the current buffer
|
||||
pub fn render<W>(&mut self, widget: &mut W, area: &Rect)
|
||||
where W: Widget
|
||||
where
|
||||
W: Widget,
|
||||
{
|
||||
widget.draw(area, &mut self.buffers[self.current]);
|
||||
}
|
||||
|
@ -123,10 +123,13 @@ impl<'a> Widget for BarChart<'a> {
|
||||
|
||||
self.background(&chart_area, buf, self.style.bg);
|
||||
|
||||
let max = self.max
|
||||
.unwrap_or_else(|| self.data.iter().fold(0, |acc, &(_, v)| max(v, acc)));
|
||||
let max_index = min((chart_area.width / (self.bar_width + self.bar_gap)) as usize,
|
||||
self.data.len());
|
||||
let max = self.max.unwrap_or_else(|| {
|
||||
self.data.iter().fold(0, |acc, &(_, v)| max(v, acc))
|
||||
});
|
||||
let max_index = min(
|
||||
(chart_area.width / (self.bar_width + self.bar_gap)) as usize,
|
||||
self.data.len(),
|
||||
);
|
||||
let mut data = self.data
|
||||
.iter()
|
||||
.take(max_index)
|
||||
@ -147,9 +150,10 @@ impl<'a> Widget for BarChart<'a> {
|
||||
};
|
||||
|
||||
for x in 0..self.bar_width {
|
||||
buf.get_mut(chart_area.left() + i as u16 * (self.bar_width + self.bar_gap) + x,
|
||||
chart_area.top() + j)
|
||||
.set_symbol(symbol)
|
||||
buf.get_mut(
|
||||
chart_area.left() + i as u16 * (self.bar_width + self.bar_gap) + x,
|
||||
chart_area.top() + j,
|
||||
).set_symbol(symbol)
|
||||
.set_style(self.style);
|
||||
}
|
||||
|
||||
@ -167,18 +171,22 @@ impl<'a> Widget for BarChart<'a> {
|
||||
let value_label = &self.values[i];
|
||||
let width = value_label.width() as u16;
|
||||
if width < self.bar_width {
|
||||
buf.set_string(chart_area.left() + i as u16 * (self.bar_width + self.bar_gap) +
|
||||
(self.bar_width - width) / 2,
|
||||
chart_area.bottom() - 2,
|
||||
value_label,
|
||||
&self.value_style);
|
||||
buf.set_string(
|
||||
chart_area.left() + i as u16 * (self.bar_width + self.bar_gap) +
|
||||
(self.bar_width - width) / 2,
|
||||
chart_area.bottom() - 2,
|
||||
value_label,
|
||||
&self.value_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
buf.set_stringn(chart_area.left() + i as u16 * (self.bar_width + self.bar_gap),
|
||||
chart_area.bottom() - 1,
|
||||
label,
|
||||
self.bar_width as usize,
|
||||
&self.label_style);
|
||||
buf.set_stringn(
|
||||
chart_area.left() + i as u16 * (self.bar_width + self.bar_gap),
|
||||
chart_area.bottom() - 1,
|
||||
label,
|
||||
self.bar_width as usize,
|
||||
&self.label_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,17 +125,17 @@ impl<'a> Widget for Block<'a> {
|
||||
if self.borders.intersects(border::RIGHT) {
|
||||
let x = area.right() - 1;
|
||||
for y in area.top()..area.bottom() {
|
||||
buf.get_mut(x, y)
|
||||
.set_symbol(line::VERTICAL)
|
||||
.set_style(self.border_style);
|
||||
buf.get_mut(x, y).set_symbol(line::VERTICAL).set_style(
|
||||
self.border_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
if self.borders.intersects(border::BOTTOM) {
|
||||
let y = area.bottom() - 1;
|
||||
for x in area.left()..area.right() {
|
||||
buf.get_mut(x, y)
|
||||
.set_symbol(line::HORIZONTAL)
|
||||
.set_style(self.border_style);
|
||||
buf.get_mut(x, y).set_symbol(line::HORIZONTAL).set_style(
|
||||
self.border_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,11 +174,13 @@ impl<'a> Widget for Block<'a> {
|
||||
0
|
||||
};
|
||||
let width = area.width - lx - rx;
|
||||
buf.set_stringn(area.left() + lx,
|
||||
area.top(),
|
||||
title,
|
||||
width as usize,
|
||||
&self.title_style);
|
||||
buf.set_stringn(
|
||||
area.left() + lx,
|
||||
area.top(),
|
||||
title,
|
||||
width as usize,
|
||||
&self.title_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,10 @@ impl Iterator for LineIterator {
|
||||
type Item = (f64, f64);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.current < self.end {
|
||||
let pos = (self.x + (self.current * self.dx) / self.end * self.dir_x,
|
||||
self.y + (self.current * self.dy) / self.end * self.dir_y);
|
||||
let pos = (
|
||||
self.x + (self.current * self.dx) / self.end * self.dir_x,
|
||||
self.y + (self.current * self.dy) / self.end * self.dir_y,
|
||||
);
|
||||
self.current += 1.0;
|
||||
Some(pos)
|
||||
} else {
|
||||
|
@ -12,10 +12,12 @@ use buffer::Buffer;
|
||||
use widgets::{Block, Widget};
|
||||
use layout::Rect;
|
||||
|
||||
pub const DOTS: [[u16; 2]; 4] = [[0x0001, 0x0008],
|
||||
[0x0002, 0x0010],
|
||||
[0x0004, 0x0020],
|
||||
[0x0040, 0x0080]];
|
||||
pub const DOTS: [[u16; 2]; 4] = [
|
||||
[0x0001, 0x0008],
|
||||
[0x0002, 0x0010],
|
||||
[0x0004, 0x0020],
|
||||
[0x0040, 0x0080],
|
||||
];
|
||||
pub const BRAILLE_OFFSET: u16 = 0x2800;
|
||||
pub const BRAILLE_BLANK: char = '⠀';
|
||||
|
||||
@ -85,16 +87,18 @@ pub struct Context<'a> {
|
||||
impl<'a> Context<'a> {
|
||||
/// Draw any object that may implement the Shape trait
|
||||
pub fn draw<'b, S>(&mut self, shape: &'b S)
|
||||
where S: Shape<'b>
|
||||
where
|
||||
S: Shape<'b>,
|
||||
{
|
||||
self.dirty = true;
|
||||
let left = self.x_bounds[0];
|
||||
let right = self.x_bounds[1];
|
||||
let bottom = self.y_bounds[0];
|
||||
let top = self.y_bounds[1];
|
||||
for (x, y) in shape
|
||||
.points()
|
||||
.filter(|&(x, y)| !(x < left || x > right || y < bottom || y > top)) {
|
||||
for (x, y) in shape.points().filter(|&(x, y)| {
|
||||
!(x < left || x > right || y < bottom || y > top)
|
||||
})
|
||||
{
|
||||
let dy = ((top - y) * (self.height - 1) as f64 * 4.0 / (top - bottom)) as usize;
|
||||
let dx = ((x - left) * (self.width - 1) as f64 * 2.0 / (right - left)) as usize;
|
||||
let index = dy / 4 * self.width as usize + dx / 2;
|
||||
@ -112,13 +116,12 @@ impl<'a> Context<'a> {
|
||||
|
||||
/// Print a string on the canvas at the given position
|
||||
pub fn print(&mut self, x: f64, y: f64, text: &'a str, color: Color) {
|
||||
self.labels
|
||||
.push(Label {
|
||||
x: x,
|
||||
y: y,
|
||||
text: text,
|
||||
color: color,
|
||||
});
|
||||
self.labels.push(Label {
|
||||
x: x,
|
||||
y: y,
|
||||
text: text,
|
||||
color: color,
|
||||
});
|
||||
}
|
||||
|
||||
/// Push the last layer if necessary
|
||||
@ -167,7 +170,8 @@ impl<'a> Context<'a> {
|
||||
/// # }
|
||||
/// ```
|
||||
pub struct Canvas<'a, F>
|
||||
where F: Fn(&mut Context)
|
||||
where
|
||||
F: Fn(&mut Context),
|
||||
{
|
||||
block: Option<Block<'a>>,
|
||||
x_bounds: [f64; 2],
|
||||
@ -177,7 +181,8 @@ pub struct Canvas<'a, F>
|
||||
}
|
||||
|
||||
impl<'a, F> Default for Canvas<'a, F>
|
||||
where F: Fn(&mut Context)
|
||||
where
|
||||
F: Fn(&mut Context),
|
||||
{
|
||||
fn default() -> Canvas<'a, F> {
|
||||
Canvas {
|
||||
@ -191,7 +196,8 @@ impl<'a, F> Default for Canvas<'a, F>
|
||||
}
|
||||
|
||||
impl<'a, F> Canvas<'a, F>
|
||||
where F: Fn(&mut Context)
|
||||
where
|
||||
F: Fn(&mut Context),
|
||||
{
|
||||
pub fn block(&mut self, block: Block<'a>) -> &mut Canvas<'a, F> {
|
||||
self.block = Some(block);
|
||||
@ -219,7 +225,8 @@ impl<'a, F> Canvas<'a, F>
|
||||
}
|
||||
|
||||
impl<'a, F> Widget for Canvas<'a, F>
|
||||
where F: Fn(&mut Context)
|
||||
where
|
||||
F: Fn(&mut Context),
|
||||
{
|
||||
fn draw(&mut self, area: &Rect, buf: &mut Buffer) {
|
||||
let canvas_area = match self.block {
|
||||
@ -253,10 +260,11 @@ impl<'a, F> Widget for Canvas<'a, F>
|
||||
// Retreive painted points for each layer
|
||||
for layer in ctx.layers {
|
||||
for (i, (ch, color)) in layer
|
||||
.string
|
||||
.chars()
|
||||
.zip(layer.colors.into_iter())
|
||||
.enumerate() {
|
||||
.string
|
||||
.chars()
|
||||
.zip(layer.colors.into_iter())
|
||||
.enumerate()
|
||||
{
|
||||
if ch != BRAILLE_BLANK {
|
||||
let (x, y) = (i % width, i / width);
|
||||
buf.get_mut(x as u16 + canvas_area.left(), y as u16 + canvas_area.top())
|
||||
@ -269,21 +277,23 @@ impl<'a, F> Widget for Canvas<'a, F>
|
||||
|
||||
// Finally draw the labels
|
||||
let style = Style::default().bg(self.background_color);
|
||||
for label in ctx.labels
|
||||
.iter()
|
||||
.filter(|l| {
|
||||
!(l.x < self.x_bounds[0] || l.x > self.x_bounds[1] ||
|
||||
l.y < self.y_bounds[0] ||
|
||||
l.y > self.y_bounds[1])
|
||||
}) {
|
||||
for label in ctx.labels.iter().filter(|l| {
|
||||
!(l.x < self.x_bounds[0] || l.x > self.x_bounds[1] || l.y < self.y_bounds[0] ||
|
||||
l.y > self.y_bounds[1])
|
||||
})
|
||||
{
|
||||
let dy = ((self.y_bounds[1] - label.y) * (canvas_area.height - 1) as f64 /
|
||||
(self.y_bounds[1] - self.y_bounds[0])) as u16;
|
||||
(self.y_bounds[1] - self.y_bounds[0])) as
|
||||
u16;
|
||||
let dx = ((label.x - self.x_bounds[0]) * (canvas_area.width - 1) as f64 /
|
||||
(self.x_bounds[1] - self.x_bounds[0])) as u16;
|
||||
buf.set_string(dx + canvas_area.left(),
|
||||
dy + canvas_area.top(),
|
||||
label.text,
|
||||
&style.fg(label.color));
|
||||
(self.x_bounds[1] - self.x_bounds[0])) as
|
||||
u16;
|
||||
buf.set_string(
|
||||
dx + canvas_area.left(),
|
||||
dy + canvas_area.top(),
|
||||
label.text,
|
||||
&style.fg(label.color),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -293,11 +293,14 @@ impl<'a> Chart<'a> {
|
||||
let legend_width = inner_width + 2;
|
||||
let legend_height = self.datasets.len() as u16 + 2;
|
||||
if legend_width < layout.graph_area.width / 3 &&
|
||||
legend_height < layout.graph_area.height / 3 {
|
||||
layout.legend_area = Some(Rect::new(layout.graph_area.right() - legend_width,
|
||||
layout.graph_area.top(),
|
||||
legend_width,
|
||||
legend_height));
|
||||
legend_height < layout.graph_area.height / 3
|
||||
{
|
||||
layout.legend_area = Some(Rect::new(
|
||||
layout.graph_area.right() - legend_width,
|
||||
layout.graph_area.top(),
|
||||
legend_width,
|
||||
legend_height,
|
||||
));
|
||||
}
|
||||
}
|
||||
layout
|
||||
@ -338,12 +341,13 @@ impl<'a> Widget for Chart<'a> {
|
||||
let labels_len = labels.len() as u16;
|
||||
if total_width < graph_area.width && labels_len > 1 {
|
||||
for (i, label) in labels.iter().enumerate() {
|
||||
buf.set_string(graph_area.left() +
|
||||
i as u16 * (graph_area.width - 1) / (labels_len - 1) -
|
||||
label.width() as u16,
|
||||
y,
|
||||
label,
|
||||
&self.x_axis.labels_style);
|
||||
buf.set_string(
|
||||
graph_area.left() + i as u16 * (graph_area.width - 1) / (labels_len - 1) -
|
||||
label.width() as u16,
|
||||
y,
|
||||
label,
|
||||
&self.x_axis.labels_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -354,10 +358,12 @@ impl<'a> Widget for Chart<'a> {
|
||||
for (i, label) in labels.iter().enumerate() {
|
||||
let dy = i as u16 * (graph_area.height - 1) / (labels_len - 1);
|
||||
if dy < graph_area.bottom() {
|
||||
buf.set_string(x,
|
||||
graph_area.bottom() - 1 - dy,
|
||||
label,
|
||||
&self.y_axis.labels_style);
|
||||
buf.set_string(
|
||||
x,
|
||||
graph_area.bottom() - 1 - dy,
|
||||
label,
|
||||
&self.y_axis.labels_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -389,20 +395,18 @@ impl<'a> Widget for Chart<'a> {
|
||||
for dataset in self.datasets {
|
||||
match dataset.marker {
|
||||
Marker::Dot => {
|
||||
for &(x, y) in dataset
|
||||
.data
|
||||
.iter()
|
||||
.filter(|&&(x, y)| {
|
||||
!(x < self.x_axis.bounds[0] || x > self.x_axis.bounds[1] ||
|
||||
y < self.y_axis.bounds[0] ||
|
||||
y > self.y_axis.bounds[1])
|
||||
}) {
|
||||
for &(x, y) in dataset.data.iter().filter(|&&(x, y)| {
|
||||
!(x < self.x_axis.bounds[0] || x > self.x_axis.bounds[1] ||
|
||||
y < self.y_axis.bounds[0] ||
|
||||
y > self.y_axis.bounds[1])
|
||||
})
|
||||
{
|
||||
let dy = ((self.y_axis.bounds[1] - y) * (graph_area.height - 1) as f64 /
|
||||
(self.y_axis.bounds[1] - self.y_axis.bounds[0])) as
|
||||
u16;
|
||||
(self.y_axis.bounds[1] - self.y_axis.bounds[0])) as
|
||||
u16;
|
||||
let dx = ((x - self.x_axis.bounds[0]) * (graph_area.width - 1) as f64 /
|
||||
(self.x_axis.bounds[1] - self.x_axis.bounds[0])) as
|
||||
u16;
|
||||
(self.x_axis.bounds[1] - self.x_axis.bounds[0])) as
|
||||
u16;
|
||||
|
||||
buf.get_mut(graph_area.left() + dx, graph_area.top() + dy)
|
||||
.set_symbol(symbols::DOT)
|
||||
@ -416,25 +420,28 @@ impl<'a> Widget for Chart<'a> {
|
||||
.x_bounds(self.x_axis.bounds)
|
||||
.y_bounds(self.y_axis.bounds)
|
||||
.paint(|ctx| {
|
||||
ctx.draw(&Points {
|
||||
coords: dataset.data,
|
||||
color: dataset.style.fg,
|
||||
});
|
||||
})
|
||||
ctx.draw(&Points {
|
||||
coords: dataset.data,
|
||||
color: dataset.style.fg,
|
||||
});
|
||||
})
|
||||
.draw(&graph_area, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(legend_area) = layout.legend_area {
|
||||
Block::default()
|
||||
.borders(border::ALL)
|
||||
.draw(&legend_area, buf);
|
||||
Block::default().borders(border::ALL).draw(
|
||||
&legend_area,
|
||||
buf,
|
||||
);
|
||||
for (i, dataset) in self.datasets.iter().enumerate() {
|
||||
buf.set_string(legend_area.x + 1,
|
||||
legend_area.y + 1 + i as u16,
|
||||
dataset.name,
|
||||
&dataset.style);
|
||||
buf.set_string(
|
||||
legend_area.x + 1,
|
||||
legend_area.y + 1 + i as u16,
|
||||
dataset.name,
|
||||
&dataset.style,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,9 +98,9 @@ impl<'a> Widget for Gauge<'a> {
|
||||
|
||||
// Fix colors
|
||||
for x in gauge_area.left()..end {
|
||||
buf.get_mut(x, y)
|
||||
.set_fg(self.style.bg)
|
||||
.set_bg(self.style.fg);
|
||||
buf.get_mut(x, y).set_fg(self.style.bg).set_bg(
|
||||
self.style.fg,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ pub enum Item<'i, D: 'i> {
|
||||
}
|
||||
|
||||
pub struct List<'b, 'i, L, D: 'i>
|
||||
where L: Iterator<Item = Item<'i, D>>
|
||||
where
|
||||
L: Iterator<Item = Item<'i, D>>,
|
||||
{
|
||||
block: Option<Block<'b>>,
|
||||
items: L,
|
||||
@ -23,7 +24,8 @@ pub struct List<'b, 'i, L, D: 'i>
|
||||
}
|
||||
|
||||
impl<'b, 'i, L, D> Default for List<'b, 'i, L, D>
|
||||
where L: Iterator<Item = Item<'i, D>> + Default
|
||||
where
|
||||
L: Iterator<Item = Item<'i, D>> + Default,
|
||||
{
|
||||
fn default() -> List<'b, 'i, L, D> {
|
||||
List {
|
||||
@ -35,7 +37,8 @@ impl<'b, 'i, L, D> Default for List<'b, 'i, L, D>
|
||||
}
|
||||
|
||||
impl<'b, 'i, L, D> List<'b, 'i, L, D>
|
||||
where L: Iterator<Item = Item<'i, D>>
|
||||
where
|
||||
L: Iterator<Item = Item<'i, D>>,
|
||||
{
|
||||
pub fn new(items: L) -> List<'b, 'i, L, D> {
|
||||
List {
|
||||
@ -51,7 +54,8 @@ impl<'b, 'i, L, D> List<'b, 'i, L, D>
|
||||
}
|
||||
|
||||
pub fn items<I>(&'b mut self, items: I) -> &mut List<'b, 'i, L, D>
|
||||
where I: IntoIterator<Item = Item<'i, D>, IntoIter = L>
|
||||
where
|
||||
I: IntoIterator<Item = Item<'i, D>, IntoIter = L>,
|
||||
{
|
||||
self.items = items.into_iter();
|
||||
self
|
||||
@ -64,8 +68,9 @@ impl<'b, 'i, L, D> List<'b, 'i, L, D>
|
||||
}
|
||||
|
||||
impl<'b, 'i, L, D> Widget for List<'b, 'i, L, D>
|
||||
where L: Iterator<Item = Item<'i, D>>,
|
||||
D: Display
|
||||
where
|
||||
L: Iterator<Item = Item<'i, D>>,
|
||||
D: Display,
|
||||
{
|
||||
fn draw(&mut self, area: &Rect, buf: &mut Buffer) {
|
||||
let list_area = match self.block {
|
||||
@ -82,24 +87,28 @@ impl<'b, 'i, L, D> Widget for List<'b, 'i, L, D>
|
||||
|
||||
self.background(&list_area, buf, self.style.bg);
|
||||
|
||||
for (i, item) in self.items
|
||||
.by_ref()
|
||||
.enumerate()
|
||||
.take(list_area.height as usize) {
|
||||
for (i, item) in self.items.by_ref().enumerate().take(
|
||||
list_area.height as usize,
|
||||
)
|
||||
{
|
||||
match item {
|
||||
Item::Data(ref v) => {
|
||||
buf.set_stringn(list_area.left(),
|
||||
list_area.top() + i as u16,
|
||||
&format!("{}", v),
|
||||
list_area.width as usize,
|
||||
&Style::default());
|
||||
buf.set_stringn(
|
||||
list_area.left(),
|
||||
list_area.top() + i as u16,
|
||||
&format!("{}", v),
|
||||
list_area.width as usize,
|
||||
&Style::default(),
|
||||
);
|
||||
}
|
||||
Item::StyledData(ref v, ref s) => {
|
||||
buf.set_stringn(list_area.left(),
|
||||
list_area.top() + i as u16,
|
||||
&format!("{}", v),
|
||||
list_area.width as usize,
|
||||
s);
|
||||
buf.set_stringn(
|
||||
list_area.left(),
|
||||
list_area.top() + i as u16,
|
||||
&format!("{}", v),
|
||||
list_area.width as usize,
|
||||
s,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -160,7 +169,8 @@ impl<'b> SelectableList<'b> {
|
||||
}
|
||||
|
||||
pub fn items<I>(&'b mut self, items: &'b [I]) -> &mut SelectableList<'b>
|
||||
where I: AsRef<str> + 'b
|
||||
where
|
||||
I: AsRef<str> + 'b,
|
||||
{
|
||||
self.items = items.iter().map(|i| i.as_ref()).collect::<Vec<&str>>();
|
||||
self
|
||||
@ -218,10 +228,10 @@ impl<'b> Widget for SelectableList<'b> {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, item)| if i == selected {
|
||||
Item::StyledData(format!("{} {}", highlight_symbol, item), highlight_style)
|
||||
} else {
|
||||
Item::StyledData(format!("{} {}", blank_symbol, item), &self.style)
|
||||
})
|
||||
Item::StyledData(format!("{} {}", highlight_symbol, item), highlight_style)
|
||||
} else {
|
||||
Item::StyledData(format!("{} {}", blank_symbol, item), &self.style)
|
||||
})
|
||||
.skip(offset as usize);
|
||||
List::new(items)
|
||||
.block(self.block.unwrap_or_default())
|
||||
|
@ -84,7 +84,8 @@ impl<'a> Paragraph<'a> {
|
||||
}
|
||||
|
||||
struct Parser<'a, T>
|
||||
where T: Iterator<Item = &'a str>
|
||||
where
|
||||
T: Iterator<Item = &'a str>,
|
||||
{
|
||||
text: T,
|
||||
mark: bool,
|
||||
@ -96,7 +97,8 @@ struct Parser<'a, T>
|
||||
}
|
||||
|
||||
impl<'a, T> Parser<'a, T>
|
||||
where T: Iterator<Item = &'a str>
|
||||
where
|
||||
T: Iterator<Item = &'a str>,
|
||||
{
|
||||
fn new(text: T, base_style: Style) -> Parser<'a, T> {
|
||||
Parser {
|
||||
@ -176,7 +178,8 @@ impl<'a, T> Parser<'a, T>
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for Parser<'a, T>
|
||||
where T: Iterator<Item = &'a str>
|
||||
where
|
||||
T: Iterator<Item = &'a str>,
|
||||
{
|
||||
type Item = (&'a str, Style);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -92,14 +92,14 @@ impl<'a> Widget for Tabs<'a> {
|
||||
self.background(&tabs_area, buf, self.style.bg);
|
||||
|
||||
let mut x = tabs_area.left();
|
||||
for (title, style) in self.titles
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, t)| if i == self.selected {
|
||||
(t, &self.highlight_style)
|
||||
} else {
|
||||
(t, &self.style)
|
||||
}) {
|
||||
for (title, style) in self.titles.iter().enumerate().map(|(i, t)| if i ==
|
||||
self.selected
|
||||
{
|
||||
(t, &self.highlight_style)
|
||||
} else {
|
||||
(t, &self.style)
|
||||
})
|
||||
{
|
||||
x += 1;
|
||||
if x > tabs_area.right() {
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user