Merge pull request #4 from wose/bug/example-crash

fixes panic when terminal was resized
This commit is contained in:
Florian Dehau 2017-05-17 07:42:57 +02:00 committed by GitHub
commit bd0dcdcc87
10 changed files with 132 additions and 55 deletions

View file

@ -12,16 +12,18 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border, BarChart};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color, Modifier};
struct App<'a> {
size: Rect,
data: Vec<(&'a str, u64)>,
}
impl<'a> App<'a> {
fn new() -> App<'a> {
App {
size: Rect::default(),
data: vec![("B1", 9),
("B2", 12),
("B3", 5),
@ -96,9 +98,16 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
app.size = terminal.size().unwrap();
draw(&mut terminal, &app);
loop {
let size = terminal.size().unwrap();
if app.size != size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = rx.recv().unwrap();
match evt {
Event::Input(input) => {
@ -118,13 +127,11 @@ fn main() {
fn draw(t: &mut Terminal<TermionBackend>, app: &App) {
let size = t.size().unwrap();
Group::default()
.direction(Direction::Vertical)
.margin(2)
.sizes(&[Size::Percent(50), Size::Percent(50)])
.render(t, &size, |t, chunks| {
.render(t, &app.size, |t, chunks| {
BarChart::default()
.block(Block::default().title("Data1").borders(border::ALL))
.data(&app.data)

View file

@ -8,7 +8,7 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color, Modifier};
fn main() {
@ -16,9 +16,16 @@ fn main() {
let stdin = io::stdin();
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
draw(&mut terminal);
let mut term_size = terminal.size().unwrap();
draw(&mut terminal, &term_size);
for c in stdin.keys() {
draw(&mut terminal);
let size = terminal.size().unwrap();
if term_size != size {
terminal.resize(size).unwrap();
term_size = size;
}
draw(&mut terminal, &term_size);
let evt = c.unwrap();
if evt == event::Key::Char('q') {
break;
@ -27,9 +34,7 @@ fn main() {
terminal.show_cursor().unwrap();
}
fn draw(t: &mut Terminal<TermionBackend>) {
let size = t.size().unwrap();
fn draw(t: &mut Terminal<TermionBackend>, size: &Rect) {
// Wrapping block for a group
// Just draw the block and the group on the same area and build the group

View file

@ -24,6 +24,8 @@ struct App {
playground: Rect,
vx: u16,
vy: u16,
dir_x: bool,
dir_y: bool,
}
@ -33,23 +35,36 @@ impl App {
size: Default::default(),
x: 0.0,
y: 0.0,
ball: Rect::new(20, 20, 10, 10),
ball: Rect::new(10, 30, 10, 10),
playground: Rect::new(10, 10, 100, 100),
vx: 1,
vy: 1,
dir_x: true,
dir_y: true,
}
}
fn advance(&mut self) {
if self.ball.left() < self.playground.left() ||
self.ball.right() > self.playground.right() {
self.vx = !self.vx;
} else if self.ball.top() < self.playground.top() ||
self.ball.bottom() > self.playground.bottom() {
self.vy = !self.vy;
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.dir_y = !self.dir_y;
}
if self.dir_x {
self.ball.x += self.vx;
} else {
self.ball.x -= self.vx;
}
if self.dir_y {
self.ball.y += self.vy;
} else {
self.ball.y -= self.vy
}
self.ball.x += self.vx;
self.ball.y += self.vy;
}
}
@ -94,11 +109,16 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
let size = terminal.size().unwrap();
app.size = size;
app.size = terminal.size().unwrap();
draw(&mut terminal, &app);
loop {
let size = terminal.size().unwrap();
if size != app.size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = rx.recv().unwrap();
match evt {
Event::Input(input) => {
@ -126,11 +146,6 @@ fn main() {
app.advance();
}
}
let size = terminal.size().unwrap();
if size != app.size {
app.size = size;
terminal.resize(size).unwrap();
}
draw(&mut terminal, &app);
}

View file

@ -15,9 +15,11 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border, Chart, Axis, Marker, Dataset};
use tui::layout::Rect;
use tui::style::{Style, Color, Modifier};
struct App {
size: Rect,
signal1: SinSignal,
data1: Vec<(f64, f64)>,
signal2: SinSignal,
@ -32,6 +34,7 @@ impl App {
let data1 = signal1.by_ref().take(200).collect::<Vec<(f64, f64)>>();
let data2 = signal2.by_ref().take(200).collect::<Vec<(f64, f64)>>();
App {
size: Rect::default(),
signal1: signal1,
data1: data1,
signal2: signal2,
@ -95,9 +98,16 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
app.size = terminal.size().unwrap();
draw(&mut terminal, &app);
loop {
let size = terminal.size().unwrap();
if app.size != size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = rx.recv().unwrap();
match evt {
Event::Input(input) => {
@ -117,8 +127,6 @@ fn main() {
fn draw(t: &mut Terminal<TermionBackend>, app: &App) {
let size = t.size().unwrap();
Chart::default()
.block(Block::default()
.title("Chart")
@ -150,7 +158,7 @@ fn draw(t: &mut Terminal<TermionBackend>, app: &App) {
.marker(Marker::Braille)
.style(Style::default().fg(Color::Yellow))
.data(&app.data2)])
.render(t, &size);
.render(t, &app.size);
t.draw().unwrap();
}

View file

@ -12,10 +12,11 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border, Gauge};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color, Modifier};
struct App {
size: Rect,
progress1: u16,
progress2: u16,
progress3: u16,
@ -25,6 +26,7 @@ struct App {
impl App {
fn new() -> App {
App {
size: Rect::default(),
progress1: 0,
progress2: 0,
progress3: 0,
@ -93,9 +95,16 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
app.size = terminal.size().unwrap();
draw(&mut terminal, &app);
loop {
let size = terminal.size().unwrap();
if size != app.size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = rx.recv().unwrap();
match evt {
Event::Input(input) => {
@ -115,13 +124,11 @@ fn main() {
fn draw(t: &mut Terminal<TermionBackend>, app: &App) {
let size = t.size().unwrap();
Group::default()
.direction(Direction::Vertical)
.margin(2)
.sizes(&[Size::Percent(25), Size::Percent(25), Size::Percent(25), Size::Percent(25)])
.render(t, &size, |t, chunks| {
.render(t, &app.size, |t, chunks| {
Gauge::default()
.block(Block::default().title("Gauge1").borders(border::ALL))
.style(Style::default().fg(Color::Yellow))

View file

@ -12,10 +12,11 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border, SelectableList, List};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color, Modifier};
struct App<'a> {
size: Rect,
items: Vec<&'a str>,
selected: usize,
events: Vec<(&'a str, &'a str)>,
@ -28,6 +29,7 @@ struct App<'a> {
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",
@ -113,9 +115,16 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
app.size = terminal.size().unwrap();
draw(&mut terminal, &app);
loop {
let size = terminal.size().unwrap();
if size != app.size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = rx.recv().unwrap();
match evt {
Event::Input(input) => {
@ -151,12 +160,10 @@ fn main() {
fn draw(t: &mut Terminal<TermionBackend>, app: &App) {
let size = t.size().unwrap();
Group::default()
.direction(Direction::Horizontal)
.sizes(&[Size::Percent(50), Size::Percent(50)])
.render(t, &size, |t, chunks| {
.render(t, &app.size, |t, chunks| {
SelectableList::default()
.block(Block::default()
.borders(border::ALL)

View file

@ -8,7 +8,7 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, Paragraph};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color};
fn main() {
@ -16,9 +16,18 @@ fn main() {
let stdin = io::stdin();
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
draw(&mut terminal);
let mut term_size = terminal.size().unwrap();
draw(&mut terminal, &term_size);
for c in stdin.keys() {
draw(&mut terminal);
let size = terminal.size().unwrap();
if size != term_size {
terminal.resize(size).unwrap();
term_size = size;
}
draw(&mut terminal, &term_size);
let evt = c.unwrap();
if evt == event::Key::Char('q') {
break;
@ -27,9 +36,7 @@ fn main() {
terminal.show_cursor().unwrap();
}
fn draw(t: &mut Terminal<TermionBackend>) {
let size = t.size().unwrap();
fn draw(t: &mut Terminal<TermionBackend>, size: &Rect) {
Block::default()
.style(Style::default().bg(Color::White))

View file

@ -15,10 +15,11 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border, Sparkline};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color};
struct App {
size: Rect,
signal: RandomSignal,
data1: Vec<u64>,
data2: Vec<u64>,
@ -32,6 +33,7 @@ impl App {
let data2 = signal.by_ref().take(200).collect::<Vec<u64>>();
let data3 = signal.by_ref().take(200).collect::<Vec<u64>>();
App {
size: Rect::default(),
signal: signal,
data1: data1,
data2: data2,
@ -93,9 +95,16 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
app.size = terminal.size().unwrap();
draw(&mut terminal, &app);
loop {
let size = terminal.size().unwrap();
if size != app.size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = rx.recv().unwrap();
match evt {
Event::Input(input) => {
@ -115,13 +124,11 @@ fn main() {
fn draw(t: &mut Terminal<TermionBackend>, app: &App) {
let size = t.size().unwrap();
Group::default()
.direction(Direction::Vertical)
.margin(2)
.sizes(&[Size::Fixed(3), Size::Fixed(3), Size::Fixed(7), Size::Min(0)])
.render(t, &size, |t, chunks| {
.render(t, &app.size, |t, chunks| {
Sparkline::default()
.block(Block::default().title("Data1").borders(border::LEFT | border::RIGHT))
.data(&app.data1)

View file

@ -9,10 +9,11 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border, Table};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color, Modifier};
struct App<'a> {
size: Rect,
items: Vec<Vec<&'a str>>,
selected: usize,
}
@ -20,6 +21,7 @@ struct App<'a> {
impl<'a> App<'a> {
fn new() -> App<'a> {
App {
size: Rect::default(),
items: vec![vec!["Row12", "Row12", "Row13"],
vec!["Row21", "Row22", "Row23"],
vec!["Row31", "Row32", "Row33"],
@ -43,11 +45,18 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
app.size = terminal.size().unwrap();
draw(&mut terminal, &app);
// Input
let stdin = io::stdin();
for c in stdin.keys() {
let size = terminal.size().unwrap();
if size != app.size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = c.unwrap();
match evt {
event::Key::Char('q') => {
@ -76,13 +85,11 @@ fn main() {
fn draw(t: &mut Terminal<TermionBackend>, app: &App) {
let size = t.size().unwrap();
Group::default()
.direction(Direction::Horizontal)
.sizes(&[Size::Percent(100)])
.margin(5)
.render(t, &size, |t, chunks| {
.render(t, &app.size, |t, chunks| {
let selected_style = Style::default().fg(Color::Yellow).modifier(Modifier::Bold);
let normal_style = Style::default().fg(Color::White);
Table::default()

View file

@ -11,10 +11,11 @@ use termion::input::TermRead;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::widgets::{Widget, Block, border, Tabs};
use tui::layout::{Group, Direction, Size};
use tui::layout::{Group, Direction, Size, Rect};
use tui::style::{Style, Color};
struct App<'a> {
size: Rect,
tabs: MyTabs<'a>,
}
@ -25,6 +26,7 @@ fn main() {
// App
let mut app = App {
size: Rect::default(),
tabs: MyTabs {
titles: vec!["Tab0", "Tab1", "Tab2", "Tab3"],
selection: 0,
@ -34,11 +36,18 @@ fn main() {
// First draw call
terminal.clear().unwrap();
terminal.hide_cursor().unwrap();
app.size = terminal.size().unwrap();
draw(&mut terminal, &mut app);
// Main loop
let stdin = io::stdin();
for c in stdin.keys() {
let size = terminal.size().unwrap();
if size != app.size {
terminal.resize(size).unwrap();
app.size = size;
}
let evt = c.unwrap();
match evt {
event::Key::Char('q') => {
@ -56,17 +65,15 @@ fn main() {
fn draw(t: &mut Terminal<TermionBackend>, app: &mut App) {
let size = t.size().unwrap();
Block::default()
.style(Style::default().bg(Color::White))
.render(t, &size);
.render(t, &app.size);
Group::default()
.direction(Direction::Vertical)
.margin(5)
.sizes(&[Size::Fixed(3), Size::Min(0)])
.render(t, &size, |t, chunks| {
.render(t, &app.size, |t, chunks| {
Tabs::default()
.block(Block::default().borders(border::ALL).title("Tabs"))
.titles(&app.tabs.titles)