Add background_color support for all existing wigets

This commit is contained in:
Florian Dehau 2016-11-02 17:08:52 +01:00
parent d038b283db
commit a36e20f217
14 changed files with 330 additions and 182 deletions

View file

@ -15,12 +15,13 @@ fn main() {
let stdin = io::stdin();
terminal.clear();
terminal.hide_cursor();
draw(&mut terminal);
for c in stdin.keys() {
draw(&mut terminal);
let evt = c.unwrap();
if evt == event::Key::Char('q') {
break;
}
draw(&mut terminal);
}
terminal.show_cursor();
}
@ -29,18 +30,38 @@ fn draw(t: &mut Terminal) {
Group::default()
.direction(Direction::Vertical)
.sizes(&[Size::Fixed(7), Size::Min(5), Size::Fixed(3)])
.sizes(&[Size::Fixed(7), Size::Min(0), Size::Fixed(7)])
.render(t, &Terminal::size().unwrap(), |t, chunks| {
Block::default()
.title("Block")
.title_color(Color::Red)
.borders(border::ALL)
.title("Top")
.title_color(Color::Magenta)
.background_color(Color::White)
.border_color(Color::Magenta)
.borders(border::BOTTOM)
.render(&chunks[0], t);
Group::default()
.direction(Direction::Vertical)
.sizes(&[Size::Fixed(7), Size::Min(5), Size::Fixed(3)])
.direction(Direction::Horizontal)
.sizes(&[Size::Fixed(7), Size::Min(0), Size::Fixed(7)])
.render(t, &chunks[1], |t, chunks| {
Block::default().title("Block").render(&chunks[0], t);
Block::default().title("Left").title_color(Color::Yellow).render(&chunks[0], t);
Block::default()
.title("Middle")
.title_color(Color::Cyan)
.border_color(Color::Cyan)
.borders(border::LEFT | border::RIGHT)
.render(&chunks[1], t);
Block::default()
.title("Right")
.title_color(Color::Green)
.render(&chunks[2], t);
});
Block::default()
.title("Bottom")
.title_color(Color::Red)
.border_color(Color::Red)
.borders(border::TOP)
.render(&chunks[2], t);
});
t.finish();
}

View file

@ -70,9 +70,10 @@ impl SinSignal {
impl Iterator for SinSignal {
type Item = (f64, f64);
fn next(&mut self) -> Option<(f64, f64)> {
fn next(&mut self) -> Option<Self::Item> {
let point = (self.x, (self.x * 1.0 / self.period).sin() * self.scale);
self.x += self.interval;
Some((self.x, ((self.x * 1.0 / self.period).sin() + 1.0) * self.scale))
Some(point)
}
}
@ -131,7 +132,7 @@ fn main() {
info!("Start");
let mut rand_signal = RandomSignal::new(Range::new(0, 100));
let mut sin_signal = SinSignal::new(1.0, 4.0, 20.0);
let mut sin_signal = SinSignal::new(0.2, 5.0, 20.0);
let mut sin_signal2 = SinSignal::new(0.1, 2.0, 10.0);
let mut app = App {
@ -149,7 +150,7 @@ fn main() {
show_chart: true,
progress: 0,
data: rand_signal.clone().take(200).collect(),
data2: sin_signal.clone().take(30).collect(),
data2: sin_signal.clone().take(100).collect(),
data3: sin_signal2.clone().take(200).collect(),
data4: vec![("B1", 9),
("B2", 12),
@ -173,7 +174,7 @@ fn main() {
let (tx, rx) = mpsc::channel();
let input_tx = tx.clone();
for _ in 0..30 {
for _ in 0..100 {
sin_signal.next();
}
for _ in 0..200 {
@ -246,12 +247,12 @@ fn main() {
}
app.data.insert(0, rand_signal.next().unwrap());
app.data.pop();
app.data2.remove(0);
app.data2.push(sin_signal.next().unwrap());
for _ in 0..10 {
app.data3.remove(0);
for _ in 0..5 {
app.data2.remove(0);
app.data2.push(sin_signal.next().unwrap());
}
for _ in 0..10 {
app.data3.remove(0);
app.data3.push(sin_signal2.next().unwrap());
}
let i = app.data4.pop().unwrap();
@ -279,6 +280,7 @@ fn draw(t: &mut Terminal, app: &App) {
Tabs::default()
.block(Block::default().borders(border::ALL).title("Tabs"))
.titles(&app.tabs.titles)
.color(Color::Green)
.highlight_color(Color::Yellow)
.select(app.tabs.selection)
.render(&chunks[0], t);
@ -292,15 +294,22 @@ fn draw(t: &mut Terminal, app: &App) {
.sizes(&[Size::Percent(50), Size::Percent(50)])
.render(t, &chunks[1], |t, chunks| {
Table::default()
.block(Block::default().title("Servers").borders(border::ALL))
.titles(&["Server", "Location", "Status"])
.block(Block::default()
.title("Servers")
.borders(border::ALL))
.header(&["Server", "Location", "Status"])
.header_color(Color::Red)
.widths(&[20, 20, 20])
.rows(&[&["Europe#1", "Paris", "Up"],
&["Europe#2", "Berlin", "Up"]])
.color(Color::Green)
.render(&chunks[0], t);
Canvas::default()
.block(Block::default().title("World").borders(border::ALL))
.layers(&[&[Map::default().resolution(MapResolution::High)]])
.layers(&[&[&Map {
color: Color::Green,
resolution: MapResolution::High,
}]])
.x_bounds([-180.0, 180.0])
.y_bounds([-90.0, 90.0])
.render(&chunks[1], t);
@ -360,8 +369,8 @@ fn draw_main(t: &mut Terminal, app: &App, area: &Rect) {
.title("List"))
.items(&app.items)
.select(app.selected)
.selection_color(Color::Yellow)
.selection_symbol(">")
.highlight_color(Color::Yellow)
.highlight_symbol(">")
.render(&chunks[0], t);
List::default()
.block(Block::default()
@ -395,8 +404,8 @@ fn draw_main(t: &mut Terminal, app: &App, area: &Rect) {
.y_axis(Axis::default()
.title("Y Axis")
.color(Color::Gray)
.bounds([0.0, 40.0])
.labels(&["0", "20", "40"]))
.bounds([-25.0, 25.0])
.labels(&["-25", "0", "25"]))
.datasets(&[Dataset::default()
.marker(Marker::Dot)
.color(Color::Cyan)
@ -411,9 +420,9 @@ fn draw_main(t: &mut Terminal, app: &App, area: &Rect) {
Text::default()
.block(Block::default().borders(border::ALL).title("Footer"))
.wrap(true)
.fg(app.colors[app.color_index])
.text("This a paragraph with several lines.\nYou can change the \
color.\nUse \\{[color] [text]} to highlight the text with the \
.color(app.colors[app.color_index])
.text("This is a paragraph with several lines.\nYou can change the \
color.\nUse \\{[color] [text]} to highlight the text with a \
color. For example, {red u}{green n}{yellow d}{magenta e}{cyan r} \
{gray t}{light_gray h}{light_red e} {light_green r}{light_yellow \
a}{light_magenta i}{light_cyan n}{white b}{red o}{green w}.\nOh, \

View file

@ -16,6 +16,7 @@ pub struct BarChart<'a> {
bar_color: Color,
value_color: Color,
label_color: Color,
background_color: Color,
data: &'a [(&'a str, u64)],
values: Vec<String>,
}
@ -25,13 +26,14 @@ impl<'a> Default for BarChart<'a> {
BarChart {
block: None,
max: None,
data: &[],
values: Vec::new(),
bar_width: 1,
bar_gap: 1,
bar_color: Color::Reset,
value_color: Color::Reset,
label_color: Color::Reset,
data: &[],
values: Vec::new(),
background_color: Color::Reset,
}
}
}
@ -75,6 +77,10 @@ impl<'a> BarChart<'a> {
self.label_color = color;
self
}
pub fn background_color(&'a mut self, color: Color) -> &mut BarChart<'a> {
self.background_color = color;
self
}
}
impl<'a> Widget for BarChart<'a> {
@ -91,6 +97,10 @@ impl<'a> Widget for BarChart<'a> {
return;
}
if self.background_color != Color::Reset {
self.background(&chart_area, buf, self.background_color);
}
let max = self.max.unwrap_or(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());
@ -119,7 +129,7 @@ impl<'a> Widget for BarChart<'a> {
chart_area.top() + j,
symbol,
self.bar_color,
Color::Reset);
self.background_color);
}
if d.1 > 8 {
@ -149,7 +159,7 @@ impl<'a> Widget for BarChart<'a> {
label,
self.bar_width as usize,
self.label_color,
Color::Reset);
self.background_color);
}
}
}

View file

@ -6,11 +6,11 @@ use symbols::line;
#[derive(Clone, Copy)]
pub struct Block<'a> {
title: Option<&'a str>,
title_color: Color,
borders: border::Flags,
border_color: Color,
bg: Color,
pub title: Option<&'a str>,
pub title_color: Color,
pub borders: border::Flags,
pub border_color: Color,
pub background_color: Color,
}
impl<'a> Default for Block<'a> {
@ -20,7 +20,7 @@ impl<'a> Default for Block<'a> {
title_color: Color::Reset,
borders: border::NONE,
border_color: Color::Reset,
bg: Color::Reset,
background_color: Color::Reset,
}
}
}
@ -41,8 +41,8 @@ impl<'a> Block<'a> {
self
}
pub fn bg(mut self, color: Color) -> Block<'a> {
self.bg = color;
pub fn background_color(mut self, color: Color) -> Block<'a> {
self.background_color = color;
self
}
@ -81,27 +81,47 @@ impl<'a> Widget for Block<'a> {
return;
}
if self.background_color != Color::Reset {
self.background(area, buf, self.background_color)
}
// Sides
if self.borders.intersects(border::LEFT) {
for y in area.top()..area.bottom() {
buf.set_cell(area.left(), y, line::VERTICAL, self.border_color, self.bg);
buf.set_cell(area.left(),
y,
line::VERTICAL,
self.border_color,
self.background_color);
}
}
if self.borders.intersects(border::TOP) {
for x in area.left()..area.right() {
buf.set_cell(x, area.top(), line::HORIZONTAL, self.border_color, self.bg);
buf.set_cell(x,
area.top(),
line::HORIZONTAL,
self.border_color,
self.background_color);
}
}
if self.borders.intersects(border::RIGHT) {
let x = area.right() - 1;
for y in area.top()..area.bottom() {
buf.set_cell(x, y, line::VERTICAL, self.border_color, self.bg);
buf.set_cell(x,
y,
line::VERTICAL,
self.border_color,
self.background_color);
}
}
if self.borders.intersects(border::BOTTOM) {
let y = area.bottom() - 1;
for x in area.left()..area.right() {
buf.set_cell(x, y, line::HORIZONTAL, self.border_color, self.bg);
buf.set_cell(x,
y,
line::HORIZONTAL,
self.border_color,
self.background_color);
}
}
@ -137,7 +157,7 @@ impl<'a> Widget for Block<'a> {
title,
width as usize,
self.title_color,
self.bg);
self.background_color);
}
}
}

View file

@ -19,8 +19,8 @@ impl MapResolution {
}
pub struct Map {
resolution: MapResolution,
color: Color,
pub resolution: MapResolution,
pub color: Color,
}
impl Default for Map {
@ -41,13 +41,6 @@ impl<'a> Shape<'a> for Map {
}
}
impl Map {
pub fn resolution(&mut self, resolution: MapResolution) -> &mut Map {
self.resolution = resolution;
self
}
}
impl<'a> IntoIterator for &'a Map {
type Item = (f64, f64);
type IntoIter = PointsIterator<'a>;

View file

@ -29,6 +29,7 @@ pub struct Canvas<'a> {
x_bounds: [f64; 2],
y_bounds: [f64; 2],
layers: &'a [&'a [&'a Shape<'a>]],
background_color: Color,
}
impl<'a> Default for Canvas<'a> {
@ -38,6 +39,7 @@ impl<'a> Default for Canvas<'a> {
x_bounds: [0.0, 0.0],
y_bounds: [0.0, 0.0],
layers: &[],
background_color: Color::Reset,
}
}
}
@ -59,6 +61,11 @@ impl<'a> Canvas<'a> {
self.layers = layers;
self
}
pub fn background_color(&'a mut self, color: Color) -> &mut Canvas<'a> {
self.background_color = color;
self
}
}
impl<'a> Widget for Canvas<'a> {
@ -81,17 +88,17 @@ impl<'a> Widget for Canvas<'a> {
for layer in self.layers {
let mut grid: Vec<u16> = vec![BRAILLE_OFFSET; width * height + 1];
let mut colors: Vec<Color> = vec![Color::Reset; width * height + 1];
let mut grid: Vec<u16> = vec![BRAILLE_OFFSET; width * height];
let mut colors: Vec<Color> = vec![Color::Reset; width * height];
for shape in layer.iter() {
for (x, y) in shape.points().filter(|&(x, y)| {
!(x < x_bounds[0] || x > x_bounds[1] || y < y_bounds[0] || y > y_bounds[1])
}) {
let dy = ((self.y_bounds[1] - y) * canvas_area.height as f64 * 4.0 /
let dy = ((self.y_bounds[1] - y) * (canvas_area.height - 1) as f64 * 4.0 /
(self.y_bounds[1] -
self.y_bounds[0])) as usize;
let dx = ((x - self.x_bounds[0]) * canvas_area.width as f64 * 2.0 /
let dx = ((x - self.x_bounds[0]) * (canvas_area.width - 1) as f64 * 2.0 /
(self.x_bounds[1] -
self.x_bounds[0])) as usize;
let index = dy / 4 * width + dx / 2;
@ -100,8 +107,7 @@ impl<'a> Widget for Canvas<'a> {
}
}
let mut string = String::from_utf16(&grid).unwrap();
string.pop();
let string = String::from_utf16(&grid).unwrap();
for (i, (ch, color)) in string.chars().zip(colors.into_iter()).enumerate() {
if ch != BRAILLE_BLANK {
let (x, y) = (i % width, i / width);
@ -111,7 +117,7 @@ impl<'a> Widget for Canvas<'a> {
c.symbol.clear();
c.symbol.push(ch);
c.fg = color;
c.bg = Color::Reset;
c.bg = self.background_color;
});
}
}

View file

@ -131,7 +131,7 @@ pub struct Chart<'a> {
x_axis: Axis<'a>,
y_axis: Axis<'a>,
datasets: &'a [Dataset<'a>],
bg: Color,
background_color: Color,
}
impl<'a> Default for Chart<'a> {
@ -140,7 +140,7 @@ impl<'a> Default for Chart<'a> {
block: None,
x_axis: Axis::default(),
y_axis: Axis::default(),
bg: Color::Reset,
background_color: Color::Reset,
datasets: &[],
}
}
@ -152,8 +152,8 @@ impl<'a> Chart<'a> {
self
}
pub fn bg(&mut self, bg: Color) -> &mut Chart<'a> {
self.bg = bg;
pub fn background_color(&mut self, background_color: Color) -> &mut Chart<'a> {
self.background_color = background_color;
self
}
@ -237,18 +237,22 @@ impl<'a> Widget for Chart<'a> {
let layout = self.layout(&chart_area);
let graph_area = layout.graph_area;
if graph_area.width == 0 || graph_area.height == 0 {
if graph_area.width < 1 || graph_area.height < 1 {
return;
}
if self.background_color != Color::Reset {
self.background(&chart_area, buf, self.background_color);
}
if let Some((x, y)) = layout.legend_x {
let title = self.x_axis.title.unwrap();
buf.set_string(x, y, title, self.x_axis.title_color, self.bg);
buf.set_string(x, y, title, self.x_axis.title_color, self.background_color);
}
if let Some((x, y)) = layout.legend_y {
let title = self.y_axis.title.unwrap();
buf.set_string(x, y, title, self.y_axis.title_color, self.bg);
buf.set_string(x, y, title, self.y_axis.title_color, self.background_color);
}
if let Some(y) = layout.label_x {
@ -263,7 +267,7 @@ impl<'a> Widget for Chart<'a> {
y,
label,
self.x_axis.labels_color,
self.bg);
self.background_color);
}
}
}
@ -278,26 +282,38 @@ impl<'a> Widget for Chart<'a> {
graph_area.bottom() - 1 - dy,
label,
self.y_axis.labels_color,
self.bg);
self.background_color);
}
}
}
if let Some(y) = layout.axis_x {
for x in graph_area.left()..graph_area.right() {
buf.set_cell(x, y, symbols::line::HORIZONTAL, self.x_axis.color, self.bg);
buf.set_cell(x,
y,
symbols::line::HORIZONTAL,
self.x_axis.color,
self.background_color);
}
}
if let Some(x) = layout.axis_y {
for y in graph_area.top()..graph_area.bottom() {
buf.set_cell(x, y, symbols::line::VERTICAL, self.y_axis.color, self.bg);
buf.set_cell(x,
y,
symbols::line::VERTICAL,
self.y_axis.color,
self.background_color);
}
}
if let Some(y) = layout.axis_x {
if let Some(x) = layout.axis_y {
buf.set_cell(x, y, symbols::line::BOTTOM_LEFT, self.x_axis.color, self.bg);
buf.set_cell(x,
y,
symbols::line::BOTTOM_LEFT,
self.x_axis.color,
self.background_color);
}
}
@ -309,20 +325,23 @@ impl<'a> Widget for Chart<'a> {
y < self.y_axis.bounds[0] ||
y > self.y_axis.bounds[1])
}) {
let dy = (self.y_axis.bounds[1] - y) * graph_area.height as f64 /
(self.y_axis.bounds[1] - self.y_axis.bounds[0]);
let dx = (x - self.x_axis.bounds[0]) * graph_area.width as f64 /
(self.x_axis.bounds[1] - self.x_axis.bounds[0]);
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;
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;
buf.set_cell(dx as u16 + graph_area.left(),
dy as u16 + graph_area.top(),
buf.set_cell(graph_area.left() + dx,
graph_area.top() + dy,
symbols::BLACK_CIRCLE,
dataset.color,
self.bg);
self.background_color);
}
}
Marker::Braille => {
Canvas::default()
.background_color(self.background_color)
.x_bounds(self.x_axis.bounds)
.y_bounds(self.y_axis.bounds)
.layers(&[&[&Points {

View file

@ -70,28 +70,32 @@ impl<'a> Widget for Gauge<'a> {
};
if gauge_area.height < 1 {
return;
} else {
// Gauge
let width = (gauge_area.width * self.percent) / 100;
let end = gauge_area.left() + width;
}
for x in gauge_area.left()..end {
buf.set_symbol(x, gauge_area.top(), " ");
}
if self.background_color != Color::Reset {
self.background(&gauge_area, buf, self.background_color);
}
// Label
let label = format!("{}%", self.percent);
let label_width = label.width() as u16;
let middle = (gauge_area.width - label_width) / 2 + gauge_area.left();
buf.set_string(middle,
gauge_area.top(),
&label,
self.color,
self.background_color);
// Gauge
let width = (gauge_area.width * self.percent) / 100;
let end = gauge_area.left() + width;
for x in gauge_area.left()..end {
buf.set_colors(x, gauge_area.top(), self.background_color, self.color);
}
for x in gauge_area.left()..end {
buf.set_symbol(x, gauge_area.top(), " ");
}
// Label
let label = format!("{}%", self.percent);
let label_width = label.width() as u16;
let middle = (gauge_area.width - label_width) / 2 + gauge_area.left();
buf.set_string(middle,
gauge_area.top(),
&label,
self.color,
self.background_color);
for x in gauge_area.left()..end {
buf.set_colors(x, gauge_area.top(), self.background_color, self.color);
}
}
}

View file

@ -9,24 +9,24 @@ use style::Color;
pub struct List<'a> {
block: Option<Block<'a>>,
items: &'a [&'a str],
selected: usize,
selection_symbol: Option<&'a str>,
selection_color: Color,
color: Color,
background_color: Color,
items: &'a [&'a str],
highlight_color: Color,
highlight_symbol: Option<&'a str>,
}
impl<'a> Default for List<'a> {
fn default() -> List<'a> {
List {
block: None,
items: &[],
selected: 0,
selection_symbol: None,
selection_color: Color::Reset,
color: Color::Reset,
background_color: Color::Reset,
items: &[],
highlight_color: Color::Reset,
highlight_symbol: None,
}
}
}
@ -52,13 +52,13 @@ impl<'a> List<'a> {
self
}
pub fn selection_symbol(&'a mut self, selection_symbol: &'a str) -> &mut List<'a> {
self.selection_symbol = Some(selection_symbol);
pub fn highlight_symbol(&'a mut self, highlight_symbol: &'a str) -> &mut List<'a> {
self.highlight_symbol = Some(highlight_symbol);
self
}
pub fn selection_color(&'a mut self, selection_color: Color) -> &mut List<'a> {
self.selection_color = selection_color;
pub fn highlight_color(&'a mut self, highlight_color: Color) -> &mut List<'a> {
self.highlight_color = highlight_color;
self
}
@ -79,10 +79,14 @@ impl<'a> Widget for List<'a> {
None => *area,
};
if list_area.height < 1 {
if list_area.width < 1 || list_area.height < 1 {
return;
}
if self.background_color != Color::Reset {
self.background(&list_area, buf, self.background_color);
}
let list_length = self.items.len();
let list_height = list_area.height as usize;
let bound = min(list_height, list_length);
@ -91,7 +95,8 @@ impl<'a> Widget for List<'a> {
} else {
0
};
let x = match self.selection_symbol {
let x = match self.highlight_symbol {
Some(s) => (s.width() + 1) as u16 + list_area.left(),
None => list_area.left(),
};
@ -102,7 +107,7 @@ impl<'a> Widget for List<'a> {
let index = i + offset;
let item = self.items[index];
let color = if index == self.selected {
self.selection_color
self.highlight_color
} else {
self.color
};
@ -113,13 +118,14 @@ impl<'a> Widget for List<'a> {
color,
self.background_color);
}
}
if let Some(s) = self.selection_symbol {
buf.set_string(list_area.left(),
list_area.top() + (self.selected - offset) as u16,
s,
self.selection_color,
self.background_color);
if let Some(s) = self.highlight_symbol {
buf.set_string(list_area.left(),
list_area.top() + (self.selected - offset) as u16,
s,
self.highlight_color,
self.background_color);
}
}
}
}

View file

@ -22,6 +22,7 @@ pub use self::table::Table;
use buffer::Buffer;
use layout::Rect;
use terminal::Terminal;
use style::Color;
pub mod border {
bitflags! {
@ -38,6 +39,13 @@ pub mod border {
pub trait Widget {
fn buffer(&self, area: &Rect, buf: &mut Buffer);
fn background(&self, area: &Rect, buf: &mut Buffer, color: Color) {
for y in area.top()..area.bottom() {
for x in area.left()..area.right() {
buf.set_bg(x, y, color);
}
}
}
fn render(&self, area: &Rect, t: &mut Terminal)
where Self: Sized
{

View file

@ -63,43 +63,44 @@ impl<'a> Widget for Sparkline<'a> {
}
None => *area,
};
if spark_area.height < 1 {
return;
} else {
let max = match self.max {
Some(v) => v,
None => *self.data.iter().max().unwrap_or(&1u64),
};
let max_index = min(spark_area.width as usize, self.data.len());
let mut data = self.data
.iter()
.take(max_index)
.map(|e| e * spark_area.height as u64 * 8 / max)
.collect::<Vec<u64>>();
for j in (0..spark_area.height).rev() {
for (i, d) in data.iter_mut().enumerate() {
let symbol = match *d {
0 => " ",
1 => bar::ONE_EIGHTH,
2 => bar::ONE_QUATER,
3 => bar::THREE_EIGHTHS,
4 => bar::HALF,
5 => bar::FIVE_EIGHTHS,
6 => bar::THREE_QUATERS,
7 => bar::SEVEN_EIGHTHS,
_ => bar::FULL,
};
buf.set_cell(spark_area.left() + i as u16,
spark_area.top() + j,
symbol,
self.color,
self.background_color);
}
if *d > 8 {
*d -= 8;
} else {
*d = 0;
}
let max = match self.max {
Some(v) => v,
None => *self.data.iter().max().unwrap_or(&1u64),
};
let max_index = min(spark_area.width as usize, self.data.len());
let mut data = self.data
.iter()
.take(max_index)
.map(|e| e * spark_area.height as u64 * 8 / max)
.collect::<Vec<u64>>();
for j in (0..spark_area.height).rev() {
for (i, d) in data.iter_mut().enumerate() {
let symbol = match *d {
0 => " ",
1 => bar::ONE_EIGHTH,
2 => bar::ONE_QUATER,
3 => bar::THREE_EIGHTHS,
4 => bar::HALF,
5 => bar::FIVE_EIGHTHS,
6 => bar::THREE_QUATERS,
7 => bar::SEVEN_EIGHTHS,
_ => bar::FULL,
};
buf.set_cell(spark_area.left() + i as u16,
spark_area.top() + j,
symbol,
self.color,
self.background_color);
if *d > 8 {
*d -= 8;
} else {
*d = 0;
}
}
}

View file

@ -9,20 +9,26 @@ use style::Color;
pub struct Table<'a> {
block: Option<Block<'a>>,
titles: &'a [&'a str],
header: &'a [&'a str],
header_color: Color,
widths: &'a [u16],
rows: &'a [&'a [&'a str]],
color: Color,
column_spacing: u16,
background_color: Color,
}
impl<'a> Default for Table<'a> {
fn default() -> Table<'a> {
Table {
block: None,
titles: &[],
header: &[],
header_color: Color::Reset,
widths: &[],
rows: &[],
color: Color::Reset,
column_spacing: 1,
background_color: Color::Reset,
}
}
}
@ -33,8 +39,13 @@ impl<'a> Table<'a> {
self
}
pub fn titles(&mut self, titles: &'a [&'a str]) -> &mut Table<'a> {
self.titles = titles;
pub fn header(&mut self, header: &'a [&'a str]) -> &mut Table<'a> {
self.header = header;
self
}
pub fn header_color(&mut self, color: Color) -> &mut Table<'a> {
self.header_color = color;
self
}
@ -48,14 +59,26 @@ impl<'a> Table<'a> {
self
}
pub fn color(&mut self, color: Color) -> &mut Table<'a> {
self.color = color;
self
}
pub fn column_spacing(&mut self, spacing: u16) -> &mut Table<'a> {
self.column_spacing = spacing;
self
}
pub fn background_color(&mut self, color: Color) -> &mut Table<'a> {
self.background_color = color;
self
}
}
impl<'a> Widget for Table<'a> {
fn buffer(&self, area: &Rect, buf: &mut Buffer) {
// Render block if necessary and get the drawing area
let table_area = match self.block {
Some(ref b) => {
b.buffer(area, buf);
@ -64,9 +87,14 @@ impl<'a> Widget for Table<'a> {
None => *area,
};
// Set the background
if self.background_color != Color::Reset {
self.background(&table_area, buf, self.background_color);
}
let mut x = 0;
let mut widths = Vec::with_capacity(self.widths.len());
for (width, title) in self.widths.iter().zip(self.titles.iter()) {
for (width, title) in self.widths.iter().zip(self.header.iter()) {
let w = max(title.width() as u16, *width);
if x + w < table_area.width {
widths.push(w);
@ -78,8 +106,8 @@ impl<'a> Widget for Table<'a> {
if y < table_area.bottom() {
x = table_area.left();
for (w, t) in widths.iter().zip(self.titles.iter()) {
buf.set_string(x, y, t, Color::Reset, Color::Reset);
for (w, t) in widths.iter().zip(self.header.iter()) {
buf.set_string(x, y, t, self.header_color, self.background_color);
x += *w + self.column_spacing;
}
}
@ -94,8 +122,8 @@ impl<'a> Widget for Table<'a> {
y + i as u16,
elt,
*w as usize,
Color::Reset,
Color::Reset);
self.color,
self.background_color);
x += *w + self.column_spacing;
}
}

View file

@ -10,8 +10,9 @@ pub struct Tabs<'a> {
block: Option<Block<'a>>,
titles: &'a [&'a str],
selected: usize,
highlight_color: Color,
color: Color,
background_color: Color,
highlight_color: Color,
}
impl<'a> Default for Tabs<'a> {
@ -20,8 +21,9 @@ impl<'a> Default for Tabs<'a> {
block: None,
titles: &[],
selected: 0,
highlight_color: Color::Reset,
color: Color::Reset,
background_color: Color::Reset,
highlight_color: Color::Reset,
}
}
}
@ -47,6 +49,11 @@ impl<'a> Tabs<'a> {
self
}
pub fn background_color(&mut self, color: Color) -> &mut Tabs<'a> {
self.background_color = color;
self
}
pub fn highlight_color(&mut self, color: Color) -> &mut Tabs<'a> {
self.highlight_color = color;
self
@ -55,6 +62,7 @@ impl<'a> Tabs<'a> {
impl<'a> Widget for Tabs<'a> {
fn buffer(&self, area: &Rect, buf: &mut Buffer) {
let tabs_area = match self.block {
Some(b) => {
b.buffer(area, buf);
@ -62,10 +70,15 @@ impl<'a> Widget for Tabs<'a> {
}
None => *area,
};
if tabs_area.height < 1 {
return;
}
if self.background_color != Color::Reset {
self.background(&tabs_area, buf, self.background_color);
}
let mut x = tabs_area.left();
for (title, color) in self.titles.iter().enumerate().map(|(i, t)| if i == self.selected {
(t, self.highlight_color)
@ -76,16 +89,16 @@ impl<'a> Widget for Tabs<'a> {
if x > tabs_area.right() {
break;
} else {
buf.set_string(x, tabs_area.top(), title, color, Color::Reset);
buf.set_string(x, tabs_area.top(), title, color, self.background_color);
x += title.width() as u16 + 1;
if x > tabs_area.right() {
if x >= tabs_area.right() {
break;
} else {
buf.set_cell(x,
tabs_area.top(),
line::VERTICAL,
Color::Reset,
Color::Reset);
self.color,
self.background_color);
x += 1;
}
}

View file

@ -7,8 +7,8 @@ use style::Color;
pub struct Text<'a> {
block: Option<Block<'a>>,
fg: Color,
bg: Color,
color: Color,
background_color: Color,
wrapping: bool,
text: &'a str,
colors: &'a [(u16, u16, u16, Color, Color)],
@ -18,8 +18,8 @@ impl<'a> Default for Text<'a> {
fn default() -> Text<'a> {
Text {
block: None,
fg: Color::Reset,
bg: Color::Reset,
color: Color::Reset,
background_color: Color::Reset,
wrapping: false,
text: "",
colors: &[],
@ -38,13 +38,13 @@ impl<'a> Text<'a> {
self
}
pub fn bg(&mut self, bg: Color) -> &mut Text<'a> {
self.bg = bg;
pub fn background_color(&mut self, background_color: Color) -> &mut Text<'a> {
self.background_color = background_color;
self
}
pub fn fg(&mut self, fg: Color) -> &mut Text<'a> {
self.fg = fg;
pub fn color(&mut self, color: Color) -> &mut Text<'a> {
self.color = color;
self
}
@ -64,17 +64,19 @@ struct Parser<'a> {
mark: bool,
color_string: String,
color: Color,
base_color: Color,
escaping: bool,
coloring: bool,
}
impl<'a> Parser<'a> {
fn new(text: &'a str) -> Parser<'a> {
fn new(text: &'a str, base_color: Color) -> Parser<'a> {
Parser {
text: UnicodeSegmentation::graphemes(text, true).rev().collect::<Vec<&str>>(),
mark: false,
color_string: String::from(""),
color: Color::Reset,
color: base_color,
base_color: base_color,
escaping: false,
coloring: false,
}
@ -103,8 +105,8 @@ impl<'a> Parser<'a> {
fn reset(&mut self) {
self.coloring = false;
self.mark = false;
self.color = Color::Reset;
self.color_string = String::from("");
self.color = self.base_color;
self.color_string.clear();
}
}
@ -125,7 +127,7 @@ impl<'a> Iterator for Parser<'a> {
self.escaping = false;
Some((s, self.color))
} else {
self.color = Color::Reset;
self.color = self.base_color;
self.mark = true;
self.next()
}
@ -162,9 +164,13 @@ impl<'a> Widget for Text<'a> {
return;
}
if self.background_color != Color::Reset {
self.background(&text_area, buf, self.background_color);
}
let mut x = 0;
let mut y = 0;
for (s, c) in Parser::new(self.text) {
for (s, c) in Parser::new(self.text, self.color) {
if s == "\n" {
x = 0;
y += 1;
@ -182,7 +188,11 @@ impl<'a> Widget for Text<'a> {
break;
}
buf.set_cell(text_area.left() + x, text_area.top() + y, s, c, self.bg);
buf.set_cell(text_area.left() + x,
text_area.top() + y,
s,
c,
self.background_color);
x += 1;
}