mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-13 00:17:11 +00:00
Merge pull request #4 from wose/bug/example-crash
fixes panic when terminal was resized
This commit is contained in:
commit
bd0dcdcc87
10 changed files with 132 additions and 55 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue