mirror of
https://github.com/fdehau/tui-rs.git
synced 2024-11-11 01:10:24 +00:00
Update list and table to be more flexible
* Move List to SelectableList * Create a more generic List * Change the way to pass items to the table widget * Update demo
This commit is contained in:
parent
d70e2d1678
commit
ad239ef23c
@ -22,8 +22,8 @@ use log4rs::encode::pattern::PatternEncoder;
|
|||||||
use log4rs::config::{Appender, Config, Root};
|
use log4rs::config::{Appender, Config, Root};
|
||||||
|
|
||||||
use tui::{Terminal, TermionBackend};
|
use tui::{Terminal, TermionBackend};
|
||||||
use tui::widgets::{Widget, Block, List, Gauge, Sparkline, Paragraph, border, Chart, Axis, Dataset,
|
use tui::widgets::{Widget, Block, SelectableList, List, Gauge, Sparkline, Paragraph, border,
|
||||||
BarChart, Marker, Tabs, Table};
|
Chart, Axis, Dataset, BarChart, Marker, Tabs, Table};
|
||||||
use tui::widgets::canvas::{Canvas, Map, MapResolution, Line};
|
use tui::widgets::canvas::{Canvas, Map, MapResolution, Line};
|
||||||
use tui::layout::{Group, Direction, Size, Rect};
|
use tui::layout::{Group, Direction, Size, Rect};
|
||||||
use tui::style::{Style, Color, Modifier};
|
use tui::style::{Style, Color, Modifier};
|
||||||
@ -105,7 +105,7 @@ impl MyTabs {
|
|||||||
struct App<'a> {
|
struct App<'a> {
|
||||||
size: Rect,
|
size: Rect,
|
||||||
items: Vec<&'a str>,
|
items: Vec<&'a str>,
|
||||||
items2: Vec<&'a str>,
|
events: Vec<(&'a str, &'a str)>,
|
||||||
selected: usize,
|
selected: usize,
|
||||||
tabs: MyTabs,
|
tabs: MyTabs,
|
||||||
show_chart: bool,
|
show_chart: bool,
|
||||||
@ -155,10 +155,32 @@ fn main() {
|
|||||||
items: vec!["Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8",
|
items: vec!["Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8",
|
||||||
"Item9", "Item10", "Item11", "Item12", "Item13", "Item14", "Item15", "Item16",
|
"Item9", "Item10", "Item11", "Item12", "Item13", "Item14", "Item15", "Item16",
|
||||||
"Item17", "Item18", "Item19", "Item20", "Item21", "Item22", "Item23", "Item24"],
|
"Item17", "Item18", "Item19", "Item20", "Item21", "Item22", "Item23", "Item24"],
|
||||||
items2: vec!["Event1", "Event2", "Event3", "Event4", "Event5", "Event6", "Event7",
|
events: vec![("Event1", "INFO"),
|
||||||
"Event8", "Event9", "Event10", "Event11", "Event12", "Event13", "Event14",
|
("Event2", "INFO"),
|
||||||
"Event15", "Event16", "Event17", "Event18", "Event19", "Event20", "Event21",
|
("Event3", "CRITICAL"),
|
||||||
"Event22", "Event23", "Event24", "Event25", "Event26"],
|
("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")],
|
||||||
selected: 0,
|
selected: 0,
|
||||||
tabs: MyTabs {
|
tabs: MyTabs {
|
||||||
titles: ["Tab0", "Tab1"],
|
titles: ["Tab0", "Tab1"],
|
||||||
@ -309,8 +331,8 @@ fn main() {
|
|||||||
app.data4.insert(0, i);
|
app.data4.insert(0, i);
|
||||||
app.window[0] += 1.0;
|
app.window[0] += 1.0;
|
||||||
app.window[1] += 1.0;
|
app.window[1] += 1.0;
|
||||||
let i = app.items2.pop().unwrap();
|
let i = app.events.pop().unwrap();
|
||||||
app.items2.insert(0, i);
|
app.events.insert(0, i);
|
||||||
app.color_index += 1;
|
app.color_index += 1;
|
||||||
if app.color_index >= app.colors.len() {
|
if app.color_index >= app.colors.len() {
|
||||||
app.color_index = 0;
|
app.color_index = 0;
|
||||||
@ -343,17 +365,26 @@ fn draw(t: &mut Terminal<TermionBackend>, app: &App) -> Result<(), io::Error> {
|
|||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.sizes(&[Size::Percent(30), Size::Percent(70)])
|
.sizes(&[Size::Percent(30), Size::Percent(70)])
|
||||||
.render(t, &chunks[1], |t, chunks| {
|
.render(t, &chunks[1], |t, chunks| {
|
||||||
|
let up_style = Style::default().fg(Color::Green);
|
||||||
|
let failure_style = Style::default().fg(Color::Red);
|
||||||
Table::default()
|
Table::default()
|
||||||
.block(Block::default()
|
.block(Block::default()
|
||||||
.title("Servers")
|
.title("Servers")
|
||||||
.borders(border::ALL))
|
.borders(border::ALL))
|
||||||
.header(&["Server", "Location", "Status"])
|
.header(&["Server", "Location", "Status"])
|
||||||
.header_style(Style::default().fg(Color::Red))
|
.header_style(Style::default().fg(Color::Yellow))
|
||||||
.widths(&[15, 15, 10])
|
.widths(&[15, 15, 10])
|
||||||
.rows(app.servers
|
.rows(&app.servers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| vec![s.name, s.location, s.status])
|
.map(|s| {
|
||||||
.collect::<Vec<Vec<&str>>>())
|
(vec![s.name, s.location, s.status],
|
||||||
|
if s.status == "Up" {
|
||||||
|
&up_style
|
||||||
|
} else {
|
||||||
|
&failure_style
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Vec<(Vec<&str>, &Style)>>())
|
||||||
.render(t, &chunks[0]);
|
.render(t, &chunks[0]);
|
||||||
|
|
||||||
Canvas::default()
|
Canvas::default()
|
||||||
@ -438,7 +469,7 @@ fn draw_main(t: &mut Terminal<TermionBackend>, app: &App, area: &Rect) {
|
|||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.sizes(&[Size::Percent(50), Size::Percent(50)])
|
.sizes(&[Size::Percent(50), Size::Percent(50)])
|
||||||
.render(t, &chunks[0], |t, chunks| {
|
.render(t, &chunks[0], |t, chunks| {
|
||||||
List::default()
|
SelectableList::default()
|
||||||
.block(Block::default()
|
.block(Block::default()
|
||||||
.borders(border::ALL)
|
.borders(border::ALL)
|
||||||
.title("List"))
|
.title("List"))
|
||||||
@ -447,11 +478,20 @@ fn draw_main(t: &mut Terminal<TermionBackend>, app: &App, area: &Rect) {
|
|||||||
.highlight_style(Style::default().fg(Color::Yellow).modifier(Modifier::Bold))
|
.highlight_style(Style::default().fg(Color::Yellow).modifier(Modifier::Bold))
|
||||||
.highlight_symbol(">")
|
.highlight_symbol(">")
|
||||||
.render(t, &chunks[0]);
|
.render(t, &chunks[0]);
|
||||||
|
let info_style = Style::default().fg(Color::White);
|
||||||
|
let warning_style = Style::default().fg(Color::Yellow);
|
||||||
|
let error_style = Style::default().fg(Color::Magenta);
|
||||||
|
let critical_style = Style::default().fg(Color::Red);
|
||||||
List::default()
|
List::default()
|
||||||
.block(Block::default()
|
.block(Block::default()
|
||||||
.borders(border::ALL)
|
.borders(border::ALL)
|
||||||
.title("List"))
|
.title("List"))
|
||||||
.items(&app.items2)
|
.items(&app.events.iter().map(|&(evt, level)| (format!("{}: {}", level, evt), match level {
|
||||||
|
"ERROR" => &error_style,
|
||||||
|
"CRITICAL" => &critical_style,
|
||||||
|
"WARNING" => &warning_style,
|
||||||
|
_ => &info_style,
|
||||||
|
})).collect::<Vec<(String, &Style)>>())
|
||||||
.render(t, &chunks[1]);
|
.render(t, &chunks[1]);
|
||||||
});
|
});
|
||||||
BarChart::default()
|
BarChart::default()
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::iter;
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
@ -7,86 +8,50 @@ use widgets::{Widget, Block};
|
|||||||
use layout::Rect;
|
use layout::Rect;
|
||||||
use style::Style;
|
use style::Style;
|
||||||
|
|
||||||
/// A widget to display several items among which one can be selected (optional)
|
|
||||||
///
|
pub struct List<'a, T>
|
||||||
/// # Examples
|
where T: AsRef<str> + 'a
|
||||||
///
|
{
|
||||||
/// ```
|
|
||||||
/// # extern crate tui;
|
|
||||||
/// # use tui::widgets::{Block, border, List};
|
|
||||||
/// # use tui::style::{Style, Color, Modifier};
|
|
||||||
/// # fn main() {
|
|
||||||
/// List::default()
|
|
||||||
/// .block(Block::default().title("List").borders(border::ALL))
|
|
||||||
/// .items(&["Item 1", "Item 2", "Item 3"])
|
|
||||||
/// .select(1)
|
|
||||||
/// .style(Style::default().fg(Color::White))
|
|
||||||
/// .highlight_style(Style::default().modifier(Modifier::Italic))
|
|
||||||
/// .highlight_symbol(">>");
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
pub struct List<'a> {
|
|
||||||
block: Option<Block<'a>>,
|
block: Option<Block<'a>>,
|
||||||
/// Items to be displayed
|
items: &'a [(T, &'a Style)],
|
||||||
items: &'a [&'a str],
|
|
||||||
/// Index of the one selected
|
|
||||||
selected: Option<usize>,
|
|
||||||
/// Base style of the widget
|
|
||||||
style: Style,
|
style: Style,
|
||||||
/// Style used to render selected item
|
|
||||||
highlight_style: Style,
|
|
||||||
/// Symbol in front of the selected item (Shift all items to the right)
|
|
||||||
highlight_symbol: Option<&'a str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for List<'a> {
|
impl<'a, T> Default for List<'a, T>
|
||||||
fn default() -> List<'a> {
|
where T: AsRef<str> + 'a
|
||||||
|
{
|
||||||
|
fn default() -> List<'a, T> {
|
||||||
List {
|
List {
|
||||||
block: None,
|
block: None,
|
||||||
items: &[],
|
items: &[],
|
||||||
selected: None,
|
|
||||||
style: Default::default(),
|
style: Default::default(),
|
||||||
highlight_style: Default::default(),
|
|
||||||
highlight_symbol: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> List<'a> {
|
impl<'a, T> List<'a, T>
|
||||||
pub fn block(&'a mut self, block: Block<'a>) -> &mut List<'a> {
|
where T: AsRef<str> + 'a
|
||||||
|
{
|
||||||
|
pub fn block(&'a mut self, block: Block<'a>) -> &mut List<'a, T> {
|
||||||
self.block = Some(block);
|
self.block = Some(block);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn items(&'a mut self, items: &'a [&'a str]) -> &mut List<'a> {
|
pub fn items(&'a mut self, items: &'a [(T, &'a Style)]) -> &mut List<'a, T> {
|
||||||
self.items = items;
|
self.items = items;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn style(&'a mut self, style: Style) -> &mut List<'a> {
|
pub fn style(&'a mut self, style: Style) -> &mut List<'a, T> {
|
||||||
self.style = style;
|
self.style = style;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn highlight_symbol(&'a mut self, highlight_symbol: &'a str) -> &mut List<'a> {
|
|
||||||
self.highlight_symbol = Some(highlight_symbol);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn highlight_style(&'a mut self, highlight_style: Style) -> &mut List<'a> {
|
|
||||||
self.highlight_style = highlight_style;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn select(&'a mut self, index: usize) -> &'a mut List<'a> {
|
|
||||||
self.selected = Some(index);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Widget for List<'a> {
|
impl<'a, T> Widget for List<'a, T>
|
||||||
|
where T: AsRef<str> + 'a
|
||||||
|
{
|
||||||
fn draw(&self, area: &Rect, buf: &mut Buffer) {
|
fn draw(&self, area: &Rect, buf: &mut Buffer) {
|
||||||
|
|
||||||
let list_area = match self.block {
|
let list_area = match self.block {
|
||||||
Some(ref b) => {
|
Some(ref b) => {
|
||||||
b.draw(area, buf);
|
b.draw(area, buf);
|
||||||
@ -101,7 +66,104 @@ impl<'a> Widget for List<'a> {
|
|||||||
|
|
||||||
self.background(&list_area, buf, self.style.bg);
|
self.background(&list_area, buf, self.style.bg);
|
||||||
|
|
||||||
let list_length = self.items.len();
|
let max_index = min(self.items.len(), list_area.height as usize);
|
||||||
|
for (i, &(ref item, style)) in self.items.iter().enumerate().take(max_index) {
|
||||||
|
buf.set_stringn(list_area.left(),
|
||||||
|
list_area.top() + i as u16,
|
||||||
|
item.as_ref(),
|
||||||
|
list_area.width as usize,
|
||||||
|
&style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// A widget to display several items among which one can be selected (optional)
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # extern crate tui;
|
||||||
|
/// # use tui::widgets::{Block, border, SelectableList};
|
||||||
|
/// # use tui::style::{Style, Color, Modifier};
|
||||||
|
/// # fn main() {
|
||||||
|
/// SelectableList::default()
|
||||||
|
/// .block(Block::default().title("SelectableList").borders(border::ALL))
|
||||||
|
/// .items(&["Item 1", "Item 2", "Item 3"])
|
||||||
|
/// .select(1)
|
||||||
|
/// .style(Style::default().fg(Color::White))
|
||||||
|
/// .highlight_style(Style::default().modifier(Modifier::Italic))
|
||||||
|
/// .highlight_symbol(">>");
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub struct SelectableList<'a> {
|
||||||
|
block: Option<Block<'a>>,
|
||||||
|
/// Items to be displayed
|
||||||
|
items: &'a [&'a str],
|
||||||
|
/// Index of the one selected
|
||||||
|
selected: Option<usize>,
|
||||||
|
/// Base style of the widget
|
||||||
|
style: Style,
|
||||||
|
/// Style used to render selected item
|
||||||
|
highlight_style: Style,
|
||||||
|
/// Symbol in front of the selected item (Shift all items to the right)
|
||||||
|
highlight_symbol: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Default for SelectableList<'a> {
|
||||||
|
fn default() -> SelectableList<'a> {
|
||||||
|
SelectableList {
|
||||||
|
block: None,
|
||||||
|
items: &[],
|
||||||
|
selected: None,
|
||||||
|
style: Default::default(),
|
||||||
|
highlight_style: Default::default(),
|
||||||
|
highlight_symbol: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SelectableList<'a> {
|
||||||
|
pub fn block(&'a mut self, block: Block<'a>) -> &mut SelectableList<'a> {
|
||||||
|
self.block = Some(block);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn items(&'a mut self, items: &'a [&'a str]) -> &mut SelectableList<'a> {
|
||||||
|
self.items = items;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn style(&'a mut self, style: Style) -> &mut SelectableList<'a> {
|
||||||
|
self.style = style;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn highlight_symbol(&'a mut self, highlight_symbol: &'a str) -> &mut SelectableList<'a> {
|
||||||
|
self.highlight_symbol = Some(highlight_symbol);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn highlight_style(&'a mut self, highlight_style: Style) -> &mut SelectableList<'a> {
|
||||||
|
self.highlight_style = highlight_style;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select(&'a mut self, index: usize) -> &'a mut SelectableList<'a> {
|
||||||
|
self.selected = Some(index);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Widget for SelectableList<'a> {
|
||||||
|
fn draw(&self, area: &Rect, buf: &mut Buffer) {
|
||||||
|
|
||||||
|
let list_area = match self.block {
|
||||||
|
Some(ref b) => b.inner(area),
|
||||||
|
None => *area,
|
||||||
|
};
|
||||||
|
|
||||||
let list_height = list_area.height as usize;
|
let list_height = list_area.height as usize;
|
||||||
|
|
||||||
// Use highlight_style only if something is selected
|
// Use highlight_style only if something is selected
|
||||||
@ -109,41 +171,30 @@ impl<'a> Widget for List<'a> {
|
|||||||
Some(i) => (i, &self.highlight_style),
|
Some(i) => (i, &self.highlight_style),
|
||||||
None => (0, &self.style),
|
None => (0, &self.style),
|
||||||
};
|
};
|
||||||
|
let highlight_symbol = self.highlight_symbol.unwrap_or("");
|
||||||
|
let blank_symbol = iter::repeat(" ").take(highlight_symbol.width()).collect::<String>();
|
||||||
// Make sure the list show the selected item
|
// Make sure the list show the selected item
|
||||||
let offset = if selected >= list_height {
|
let offset = if selected >= list_height {
|
||||||
selected - list_height + 1
|
selected - list_height + 1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
let items = self.items
|
||||||
// Move items to the right if a highlight symbol was provided
|
.iter()
|
||||||
let x = match self.highlight_symbol {
|
.cloned()
|
||||||
Some(s) => (s.width() + 1) as u16 + list_area.left(),
|
.enumerate()
|
||||||
None => list_area.left(),
|
.map(|(i, item)| if i == selected {
|
||||||
};
|
(format!("{} {}", highlight_symbol, item), highlight_style)
|
||||||
|
} else {
|
||||||
|
(format!("{} {}", blank_symbol, item), &self.style)
|
||||||
|
})
|
||||||
|
.skip(offset as usize)
|
||||||
|
.collect::<Vec<(String, &Style)>>();
|
||||||
|
|
||||||
// Render items
|
// Render items
|
||||||
if x < list_area.right() {
|
List::default()
|
||||||
let width = (list_area.right() - x) as usize;
|
.block(self.block.unwrap_or(Default::default()))
|
||||||
let max_index = min(list_height, list_length);
|
.items(&items)
|
||||||
for i in 0..max_index {
|
.draw(area, buf);
|
||||||
let index = i + offset;
|
|
||||||
let item = self.items[index];
|
|
||||||
let style = if index == selected {
|
|
||||||
highlight_style
|
|
||||||
} else {
|
|
||||||
&self.style
|
|
||||||
};
|
|
||||||
buf.set_stringn(x, list_area.top() + i as u16, item, width, style);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(s) = self.highlight_symbol {
|
|
||||||
buf.set_string(list_area.left(),
|
|
||||||
list_area.top() + (selected - offset) as u16,
|
|
||||||
s,
|
|
||||||
&self.highlight_style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub mod canvas;
|
|||||||
|
|
||||||
pub use self::block::Block;
|
pub use self::block::Block;
|
||||||
pub use self::paragraph::Paragraph;
|
pub use self::paragraph::Paragraph;
|
||||||
pub use self::list::List;
|
pub use self::list::{List, SelectableList};
|
||||||
pub use self::gauge::Gauge;
|
pub use self::gauge::Gauge;
|
||||||
pub use self::sparkline::Sparkline;
|
pub use self::sparkline::Sparkline;
|
||||||
pub use self::chart::{Chart, Axis, Dataset, Marker};
|
pub use self::chart::{Chart, Axis, Dataset, Marker};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::borrow::Cow;
|
|
||||||
|
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
@ -23,11 +22,12 @@ use style::Style;
|
|||||||
/// .widths(&[5, 5, 10])
|
/// .widths(&[5, 5, 10])
|
||||||
/// .style(Style::default().fg(Color::White))
|
/// .style(Style::default().fg(Color::White))
|
||||||
/// .column_spacing(1)
|
/// .column_spacing(1)
|
||||||
/// .rows(vec![["Row11", "Row12", "Row13"].as_ref(),
|
/// .rows(&[&["Row11", "Row12", "Row13"],
|
||||||
/// ["Row21", "Row22", "Row23"].as_ref(),
|
/// &["Row21", "Row22", "Row23"],
|
||||||
/// ["Row31", "Row32", "Row33"].as_ref()]);
|
/// &["Row31", "Row32", "Row33"]]);
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
|
||||||
pub struct Table<'a> {
|
pub struct Table<'a> {
|
||||||
/// A block to wrap the widget in
|
/// A block to wrap the widget in
|
||||||
block: Option<Block<'a>>,
|
block: Option<Block<'a>>,
|
||||||
@ -43,9 +43,7 @@ pub struct Table<'a> {
|
|||||||
/// Space between each column
|
/// Space between each column
|
||||||
column_spacing: u16,
|
column_spacing: u16,
|
||||||
/// Data to display in each row
|
/// Data to display in each row
|
||||||
rows: Vec<Cow<'a, [&'a str]>>,
|
rows: Vec<(Vec<&'a str>, &'a Style)>,
|
||||||
/// Style for each row
|
|
||||||
row_style: Style,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Default for Table<'a> {
|
impl<'a> Default for Table<'a> {
|
||||||
@ -57,7 +55,6 @@ impl<'a> Default for Table<'a> {
|
|||||||
header_style: Style::default(),
|
header_style: Style::default(),
|
||||||
widths: &[],
|
widths: &[],
|
||||||
rows: Vec::new(),
|
rows: Vec::new(),
|
||||||
row_style: Style::default(),
|
|
||||||
column_spacing: 1,
|
column_spacing: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,15 +81,15 @@ impl<'a> Table<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rows<R>(&mut self, rows: Vec<R>) -> &mut Table<'a>
|
pub fn rows<S, R>(&mut self, rows: &'a [(R, &'a Style)]) -> &mut Table<'a>
|
||||||
where R: Into<Cow<'a, [&'a str]>>
|
where S: AsRef<str> + 'a,
|
||||||
|
R: AsRef<[S]> + 'a
|
||||||
{
|
{
|
||||||
self.rows = rows.into_iter().map(|r| r.into()).collect::<Vec<Cow<'a, [&'a str]>>>();
|
self.rows = rows.iter()
|
||||||
self
|
.map(|&(ref r, style)| {
|
||||||
}
|
(r.as_ref().iter().map(|i| i.as_ref()).collect::<Vec<&'a str>>(), style)
|
||||||
|
})
|
||||||
pub fn row_style(&mut self, style: Style) -> &mut Table<'a> {
|
.collect::<Vec<(Vec<&'a str>, &'a Style)>>();
|
||||||
self.row_style = style;
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,10 +144,10 @@ impl<'a> Widget for Table<'a> {
|
|||||||
|
|
||||||
if y < table_area.bottom() {
|
if y < table_area.bottom() {
|
||||||
let remaining = (table_area.bottom() - y) as usize;
|
let remaining = (table_area.bottom() - y) as usize;
|
||||||
for (i, row) in self.rows.iter().take(remaining).enumerate() {
|
for (i, &(ref row, style)) in self.rows.iter().take(remaining).enumerate() {
|
||||||
x = table_area.left();
|
x = table_area.left();
|
||||||
for (w, elt) in widths.iter().zip(row.iter()) {
|
for (w, elt) in widths.iter().zip(row.iter()) {
|
||||||
buf.set_stringn(x, y + i as u16, elt, *w as usize, &self.row_style);
|
buf.set_stringn(x, y + i as u16, elt, *w as usize, style);
|
||||||
x += *w + self.column_spacing;
|
x += *w + self.column_spacing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user