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

Commit 9806217

Browse files
committed
feat!: use crossterm as default backend
1 parent 1be5cf2 commit 9806217

28 files changed

+1696
-2050
lines changed

Cargo.toml

+2-91
Original file line numberDiff line numberDiff line change
@@ -17,111 +17,22 @@ edition = "2018"
1717
[badges]
1818

1919
[features]
20-
default = ["termion"]
21-
curses = ["easycurses", "pancurses"]
20+
default = ["crossterm"]
2221

2322
[dependencies]
2423
bitflags = "1.3"
2524
cassowary = "0.3"
2625
unicode-segmentation = "1.2"
2726
unicode-width = "0.1"
2827
termion = { version = "1.5", optional = true }
29-
rustbox = { version = "0.11", optional = true }
30-
crossterm = { version = "0.20", optional = true }
31-
easycurses = { version = "0.12.2", optional = true }
32-
pancurses = { version = "0.16.1", optional = true, features = ["win32a"] }
28+
crossterm = { version = "0.22", optional = true }
3329
serde = { version = "1", "optional" = true, features = ["derive"]}
3430

3531
[dev-dependencies]
3632
rand = "0.8"
3733
argh = "0.1"
3834

39-
[[example]]
40-
name = "canvas"
41-
path = "examples/canvas.rs"
42-
required-features = ["termion"]
43-
44-
[[example]]
45-
name = "user_input"
46-
path = "examples/user_input.rs"
47-
required-features = ["termion"]
48-
49-
[[example]]
50-
name = "gauge"
51-
path = "examples/gauge.rs"
52-
required-features = ["termion"]
53-
54-
[[example]]
55-
name = "barchart"
56-
path = "examples/barchart.rs"
57-
required-features = ["termion"]
58-
59-
[[example]]
60-
name = "chart"
61-
path = "examples/chart.rs"
62-
required-features = ["termion"]
63-
64-
[[example]]
65-
name = "paragraph"
66-
path = "examples/paragraph.rs"
67-
required-features = ["termion"]
68-
69-
[[example]]
70-
name = "list"
71-
path = "examples/list.rs"
72-
required-features = ["termion"]
73-
74-
[[example]]
75-
name = "table"
76-
path = "examples/table.rs"
77-
required-features = ["termion"]
78-
79-
[[example]]
80-
name = "tabs"
81-
path = "examples/tabs.rs"
82-
required-features = ["termion"]
83-
84-
[[example]]
85-
name = "custom_widget"
86-
path = "examples/custom_widget.rs"
87-
required-features = ["termion"]
88-
89-
[[example]]
90-
name = "layout"
91-
path = "examples/layout.rs"
92-
required-features = ["termion"]
93-
94-
[[example]]
95-
name = "popup"
96-
path = "examples/popup.rs"
97-
required-features = ["termion"]
98-
99-
[[example]]
100-
name = "block"
101-
path = "examples/block.rs"
102-
required-features = ["termion"]
103-
104-
[[example]]
105-
name = "sparkline"
106-
path = "examples/sparkline.rs"
107-
required-features = ["termion"]
108-
10935
[[example]]
11036
name = "termion_demo"
11137
path = "examples/termion_demo.rs"
11238
required-features = ["termion"]
113-
114-
[[example]]
115-
name = "rustbox_demo"
116-
path = "examples/rustbox_demo.rs"
117-
required-features = ["rustbox"]
118-
119-
[[example]]
120-
name = "crossterm_demo"
121-
path = "examples/crossterm_demo.rs"
122-
required-features = ["crossterm"]
123-
124-
[[example]]
125-
name = "curses_demo"
126-
path = "examples/curses_demo.rs"
127-
required-features = ["curses"]

Makefile.toml

+2-20
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ source = "${CARGO_MAKE_RUST_TARGET_OS}"
66
default_value = "unknown"
77

88
[env.TUI_FEATURES.mapping]
9-
linux = "serde,crossterm,termion,rustbox,curses"
10-
macos = "serde,crossterm,termion,rustbox,curses"
9+
linux = "serde,crossterm,termion"
10+
macos = "serde,crossterm,termion"
1111
windows = "serde,crossterm"
1212

1313
[tasks.default]
@@ -66,11 +66,6 @@ args = [
6666
]
6767

6868
[tasks.test]
69-
linux_alias = "test-unix"
70-
mac_alias = "test-unix"
71-
windows_alias = "test-windows"
72-
73-
[tasks.test-unix]
7469
command = "cargo"
7570
args = [
7671
"test",
@@ -79,19 +74,6 @@ args = [
7974
"${TUI_FEATURES}"
8075
]
8176

82-
# Documentation tests cannot be run on Windows for now
83-
[tasks.test-windows]
84-
command = "cargo"
85-
args = [
86-
"test",
87-
"--no-default-features",
88-
"--features",
89-
"${TUI_FEATURES}",
90-
"--lib",
91-
"--tests",
92-
"--examples",
93-
]
94-
9577
[tasks.run-example]
9678
private = true
9779
condition = { env_set = ["TUI_EXAMPLE_NAME", "TUI_FEATURES"] }

examples/barchart.rs

+101-71
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
#[allow(dead_code)]
2-
mod util;
3-
4-
use crate::util::event::{Event, Events};
5-
use std::{error::Error, io};
6-
use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen};
1+
use crossterm::{
2+
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
3+
execute,
4+
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
5+
};
6+
use std::{
7+
error::Error,
8+
io,
9+
time::{Duration, Instant},
10+
};
711
use tui::{
8-
backend::TermionBackend,
12+
backend::{Backend, CrosstermBackend},
913
layout::{Constraint, Direction, Layout},
1014
style::{Color, Modifier, Style},
1115
widgets::{BarChart, Block, Borders},
12-
Terminal,
16+
Frame, Terminal,
1317
};
1418

1519
struct App<'a> {
@@ -48,85 +52,111 @@ impl<'a> App<'a> {
4852
}
4953
}
5054

51-
fn update(&mut self) {
55+
fn on_tick(&mut self) {
5256
let value = self.data.pop().unwrap();
5357
self.data.insert(0, value);
5458
}
5559
}
5660

5761
fn main() -> Result<(), Box<dyn Error>> {
58-
// Terminal initialization
59-
let stdout = io::stdout().into_raw_mode()?;
60-
let stdout = MouseTerminal::from(stdout);
61-
let stdout = AlternateScreen::from(stdout);
62-
let backend = TermionBackend::new(stdout);
62+
// setup terminal
63+
enable_raw_mode()?;
64+
let mut stdout = io::stdout();
65+
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
66+
let backend = CrosstermBackend::new(stdout);
6367
let mut terminal = Terminal::new(backend)?;
6468

65-
// Setup event handlers
66-
let events = Events::new();
67-
68-
// App
69-
let mut app = App::new();
69+
// create app and run it
70+
let tick_rate = Duration::from_millis(250);
71+
let app = App::new();
72+
let res = run_app(&mut terminal, app, tick_rate);
7073

71-
loop {
72-
terminal.draw(|f| {
73-
let chunks = Layout::default()
74-
.direction(Direction::Vertical)
75-
.margin(2)
76-
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
77-
.split(f.size());
78-
let barchart = BarChart::default()
79-
.block(Block::default().title("Data1").borders(Borders::ALL))
80-
.data(&app.data)
81-
.bar_width(9)
82-
.bar_style(Style::default().fg(Color::Yellow))
83-
.value_style(Style::default().fg(Color::Black).bg(Color::Yellow));
84-
f.render_widget(barchart, chunks[0]);
74+
// restore terminal
75+
disable_raw_mode()?;
76+
execute!(
77+
terminal.backend_mut(),
78+
LeaveAlternateScreen,
79+
DisableMouseCapture
80+
)?;
81+
terminal.show_cursor()?;
8582

86-
let chunks = Layout::default()
87-
.direction(Direction::Horizontal)
88-
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
89-
.split(chunks[1]);
83+
if let Err(err) = res {
84+
println!("{:?}", err)
85+
}
9086

91-
let barchart = BarChart::default()
92-
.block(Block::default().title("Data2").borders(Borders::ALL))
93-
.data(&app.data)
94-
.bar_width(5)
95-
.bar_gap(3)
96-
.bar_style(Style::default().fg(Color::Green))
97-
.value_style(
98-
Style::default()
99-
.bg(Color::Green)
100-
.add_modifier(Modifier::BOLD),
101-
);
102-
f.render_widget(barchart, chunks[0]);
87+
Ok(())
88+
}
10389

104-
let barchart = BarChart::default()
105-
.block(Block::default().title("Data3").borders(Borders::ALL))
106-
.data(&app.data)
107-
.bar_style(Style::default().fg(Color::Red))
108-
.bar_width(7)
109-
.bar_gap(0)
110-
.value_style(Style::default().bg(Color::Red))
111-
.label_style(
112-
Style::default()
113-
.fg(Color::Cyan)
114-
.add_modifier(Modifier::ITALIC),
115-
);
116-
f.render_widget(barchart, chunks[1]);
117-
})?;
90+
fn run_app<B: Backend>(
91+
terminal: &mut Terminal<B>,
92+
mut app: App,
93+
tick_rate: Duration,
94+
) -> io::Result<()> {
95+
let mut last_tick = Instant::now();
96+
loop {
97+
terminal.draw(|f| ui(f, &mut app))?;
11898

119-
match events.next()? {
120-
Event::Input(input) => {
121-
if input == Key::Char('q') {
122-
break;
99+
let timeout = tick_rate
100+
.checked_sub(last_tick.elapsed())
101+
.unwrap_or_else(|| Duration::from_secs(0));
102+
if crossterm::event::poll(timeout)? {
103+
if let Event::Key(key) = event::read()? {
104+
match key.code {
105+
KeyCode::Char('q') => return Ok(()),
106+
_ => {}
123107
}
124108
}
125-
Event::Tick => {
126-
app.update();
127-
}
109+
}
110+
if last_tick.elapsed() >= tick_rate {
111+
app.on_tick();
112+
last_tick = Instant::now();
128113
}
129114
}
115+
}
130116

131-
Ok(())
117+
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
118+
let chunks = Layout::default()
119+
.direction(Direction::Vertical)
120+
.margin(2)
121+
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
122+
.split(f.size());
123+
let barchart = BarChart::default()
124+
.block(Block::default().title("Data1").borders(Borders::ALL))
125+
.data(&app.data)
126+
.bar_width(9)
127+
.bar_style(Style::default().fg(Color::Yellow))
128+
.value_style(Style::default().fg(Color::Black).bg(Color::Yellow));
129+
f.render_widget(barchart, chunks[0]);
130+
131+
let chunks = Layout::default()
132+
.direction(Direction::Horizontal)
133+
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
134+
.split(chunks[1]);
135+
136+
let barchart = BarChart::default()
137+
.block(Block::default().title("Data2").borders(Borders::ALL))
138+
.data(&app.data)
139+
.bar_width(5)
140+
.bar_gap(3)
141+
.bar_style(Style::default().fg(Color::Green))
142+
.value_style(
143+
Style::default()
144+
.bg(Color::Green)
145+
.add_modifier(Modifier::BOLD),
146+
);
147+
f.render_widget(barchart, chunks[0]);
148+
149+
let barchart = BarChart::default()
150+
.block(Block::default().title("Data3").borders(Borders::ALL))
151+
.data(&app.data)
152+
.bar_style(Style::default().fg(Color::Red))
153+
.bar_width(7)
154+
.bar_gap(0)
155+
.value_style(Style::default().bg(Color::Red))
156+
.label_style(
157+
Style::default()
158+
.fg(Color::Cyan)
159+
.add_modifier(Modifier::ITALIC),
160+
);
161+
f.render_widget(barchart, chunks[1]);
132162
}

0 commit comments

Comments
 (0)