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

Commit

Permalink
refactor(widgets): merge List widgets and add multiline items
Browse files Browse the repository at this point in the history
* Move SelectableList functionnalities to List and remove it
* Text::Styled now holds a list of strings and their associated styles allowing
complex styling within the same line.
* Allow multiline items in List
* List takes a Vec<Text> as the items need to be iterated over multiple
times to be correctly diplayed. An easy solution is thus to require
ownership
  • Loading branch information
fdehau committed Dec 9, 2018
1 parent 3819eae commit 88ab74e
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 259 deletions.
32 changes: 19 additions & 13 deletions examples/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use tui::layout::{Constraint, Direction, Layout, Rect};
use tui::style::{Color, Modifier, Style};
use tui::widgets::canvas::{Canvas, Line, Map, MapResolution};
use tui::widgets::{
Axis, BarChart, Block, Borders, Chart, Dataset, Gauge, List, Marker, Paragraph, Row,
SelectableList, Sparkline, Table, Tabs, Text, Widget,
Axis, BarChart, Block, Borders, Chart, Dataset, Gauge, List, Marker, Paragraph, Row, Sparkline,
Table, Tabs, Text, Widget,
};
use tui::{Frame, Terminal};

Expand Down Expand Up @@ -315,28 +315,34 @@ where
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.direction(Direction::Horizontal)
.split(chunks[0]);
SelectableList::default()
let items = app.items.iter().map(|i| Text::raw(*i)).collect();
List::new(items)
.block(Block::default().borders(Borders::ALL).title("List"))
.items(&app.items)
.select(Some(app.selected))
.highlight_style(Style::default().fg(Color::Yellow).modifier(Modifier::Bold))
.highlight_symbol(">")
.render(f, chunks[0]);
let info_style = Style::default().fg(Color::White);
let info_style = Style::default().fg(Color::Blue);
let warning_style = Style::default().fg(Color::Yellow);
let error_style = Style::default().fg(Color::Magenta);
let critical_style = Style::default().fg(Color::Red);
let events = app.events.iter().map(|&(evt, level)| {
Text::styled(
format!("{}: {}", level, evt),
match level {
let events = app
.events
.iter()
.map(|&(evt, level)| {
let level_style = match level {
"ERROR" => error_style,
"CRITICAL" => critical_style,
"WARNING" => warning_style,
_ => info_style,
},
)
});
"INFO" => info_style,
_ => Style::default(),
};
Text::with_styles(vec![
(format!("{:<10}", level), level_style),
(format!(" : {}", evt), Style::default()),
])
})
.collect();
List::new(events)
.block(Block::default().borders(Borders::ALL).title("List"))
.render(f, chunks[1]);
Expand Down
7 changes: 5 additions & 2 deletions examples/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ use tui::Terminal;
use util::event::{Event, Events};

fn main() -> Result<(), failure::Error> {
stderrlog::new().verbosity(4).init()?;
stderrlog::new()
.module(module_path!())
.verbosity(4)
.init()?;

// Terminal initialization
let stdout = io::stdout().into_raw_mode()?;
Expand All @@ -48,7 +51,7 @@ fn main() -> Result<(), failure::Error> {
.split(f.size());

Block::default()
.title("Block")
.title("Block 1")
.borders(Borders::ALL)
.render(&mut f, chunks[0]);
Block::default()
Expand Down
78 changes: 56 additions & 22 deletions examples/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use termion::screen::AlternateScreen;
use tui::backend::TermionBackend;
use tui::layout::{Constraint, Corner, Direction, Layout};
use tui::style::{Color, Modifier, Style};
use tui::widgets::{Block, Borders, List, SelectableList, Text, Widget};
use tui::widgets::{Block, Borders, List, Text, Widget};
use tui::Terminal;

use util::event::{Event, Events};
Expand All @@ -33,13 +33,34 @@ impl<'a> App<'a> {
fn new() -> App<'a> {
App {
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",
"Item1\nItem11\nItem12",
"Item2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222",
"Item3",
"Item4",
"Item5",
"Item6",
"Item7",
"Item8",
"Item9",
"Item10",
"Item11",
"Item12",
"Item13",
"Item14",
"Item15",
"Item16",
"Item17",
"Item18",
"Item19",
"Item20",
"Item21",
"Item22",
"Item23",
"Item24",
],
selected: None,
events: vec![
("Event1", "INFO"),
("Event1\nlorem ipsum", "INFO"),
("Event2", "INFO"),
("Event3", "CRITICAL"),
("Event4", "ERROR"),
Expand All @@ -66,7 +87,7 @@ impl<'a> App<'a> {
("Event25", "INFO"),
("Event26", "INFO"),
],
info_style: Style::default().fg(Color::White),
info_style: Style::default().fg(Color::Blue),
warning_style: Style::default().fg(Color::Yellow),
error_style: Style::default().fg(Color::Magenta),
critical_style: Style::default().fg(Color::Red),
Expand Down Expand Up @@ -101,26 +122,39 @@ fn main() -> Result<(), failure::Error> {
.split(f.size());

let style = Style::default().fg(Color::Black).bg(Color::White);
SelectableList::default()
.block(Block::default().borders(Borders::ALL).title("List"))
.items(&app.items)
.select(app.selected)
.style(style)
.highlight_style(style.fg(Color::LightGreen).modifier(Modifier::Bold))
.highlight_symbol(">")
.render(&mut f, chunks[0]);
{
let events = app.events.iter().map(|&(evt, level)| {
Text::styled(
format!("{}: {}", level, evt),
match level {
let items = app
.items
.iter()
.map(|i| Text::raw(*i))
.collect::<Vec<Text>>();
List::new(items)
.block(Block::default().borders(Borders::ALL).title("List"))
.style(style)
.select(app.selected)
.highlight_style(style.fg(Color::LightGreen).modifier(Modifier::Bold))
.highlight_symbol(">")
.render(&mut f, chunks[0]);
}
{
let events = app
.events
.iter()
.map(|&(evt, level)| {
let level_style = match level {
"ERROR" => app.error_style,
"CRITICAL" => app.critical_style,
"WARNING" => app.warning_style,
_ => app.info_style,
},
)
});
"INFO" => app.info_style,
_ => Default::default(),
};
Text::with_styles(vec![
(format!("{:<10}", level), level_style),
(" : ".to_owned(), Default::default()),
(evt.to_owned(), Default::default()),
])
})
.collect();
List::new(events)
.block(Block::default().borders(Borders::ALL).title("List"))
.start_corner(Corner::BottomLeft)
Expand Down
10 changes: 8 additions & 2 deletions examples/user_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use termion::raw::IntoRawMode;
use termion::screen::AlternateScreen;
use tui::backend::TermionBackend;
use tui::layout::{Constraint, Direction, Layout};
use tui::style::{Color, Style};
use tui::style::{Color, Modifier, Style};
use tui::widgets::{Block, Borders, List, Paragraph, Text, Widget};
use tui::Terminal;
use unicode_width::UnicodeWidthStr;
Expand Down Expand Up @@ -80,7 +80,13 @@ fn main() -> Result<(), failure::Error> {
.messages
.iter()
.enumerate()
.map(|(i, m)| Text::raw(format!("{}: {}", i, m)));
.map(|(i, m)| {
Text::with_styles(vec![
(format!("{}", i), Style::default().modifier(Modifier::Bold)),
(format!(" : {}", m), Style::default()),
])
})
.collect();
List::new(messages)
.block(Block::default().borders(Borders::ALL).title("Messages"))
.render(&mut f, chunks[1]);
Expand Down
4 changes: 2 additions & 2 deletions src/backend/rustbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ pub struct RustboxBackend {

impl RustboxBackend {
pub fn new() -> Result<RustboxBackend, rustbox::InitError> {
let rustbox = try!(rustbox::RustBox::init(Default::default()));
Ok(RustboxBackend { rustbox: rustbox })
let rustbox = rustbox::RustBox::init(Default::default())?;
Ok(RustboxBackend { rustbox })
}

pub fn with_rustbox(instance: rustbox::RustBox) -> RustboxBackend {
Expand Down
2 changes: 1 addition & 1 deletion src/backend/termion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ where

/// Return the size of the terminal
fn size(&self) -> io::Result<Rect> {
let terminal = try!(termion::terminal_size());
let terminal = termion::terminal_size()?;
Ok(Rect::new(0, 0, terminal.0, terminal.1))
}

Expand Down
8 changes: 3 additions & 5 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl Buffer {
}

/// Returns a Buffer containing the given lines
pub fn with_lines<S>(lines: Vec<S>) -> Buffer
pub fn with_lines<S>(lines: &[S]) -> Buffer
where
S: AsRef<str>,
{
Expand All @@ -171,10 +171,8 @@ impl Buffer {
width,
height,
});
let mut y = 0;
for line in &lines {
buffer.set_string(0, y, line, Style::default());
y += 1;
for (y, line) in lines.iter().enumerate() {
buffer.set_string(0, y as u16, line, Style::default());
}
buffer
}
Expand Down
Loading

0 comments on commit 88ab74e

Please sign in to comment.