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};
7 use tui::{
8 backend::TermionBackend,
9 layout::{Alignment, Constraint, Direction, Layout, Rect},
10 style::{Color, Modifier, Style},
11 text::{Span, Spans},
12 widgets::{Block, Borders, Clear, Paragraph, Wrap},
13 Terminal,
14 };
15
16 /// helper function to create a centered rect using up
17 /// certain percentage of the available rect `r`
centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect18 fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
19 let popup_layout = Layout::default()
20 .direction(Direction::Vertical)
21 .constraints(
22 [
23 Constraint::Percentage((100 - percent_y) / 2),
24 Constraint::Percentage(percent_y),
25 Constraint::Percentage((100 - percent_y) / 2),
26 ]
27 .as_ref(),
28 )
29 .split(r);
30
31 Layout::default()
32 .direction(Direction::Horizontal)
33 .constraints(
34 [
35 Constraint::Percentage((100 - percent_x) / 2),
36 Constraint::Percentage(percent_x),
37 Constraint::Percentage((100 - percent_x) / 2),
38 ]
39 .as_ref(),
40 )
41 .split(popup_layout[1])[1]
42 }
43
main() -> Result<(), Box<dyn Error>>44 fn main() -> Result<(), Box<dyn Error>> {
45 // Terminal initialization
46 let stdout = io::stdout().into_raw_mode()?;
47 let stdout = MouseTerminal::from(stdout);
48 let stdout = AlternateScreen::from(stdout);
49 let backend = TermionBackend::new(stdout);
50 let mut terminal = Terminal::new(backend)?;
51
52 let events = Events::new();
53
54 loop {
55 terminal.draw(|f| {
56 let size = f.size();
57
58 let chunks = Layout::default()
59 .direction(Direction::Horizontal)
60 .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
61 .split(size);
62
63 let s = "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. ";
64 let mut long_line = s.repeat(usize::from(size.width)*usize::from(size.height)/300);
65 long_line.push('\n');
66
67 let text = vec![
68 Spans::from("This is a line "),
69 Spans::from(Span::styled("This is a line ", Style::default().fg(Color::Red))),
70 Spans::from(Span::styled("This is a line", Style::default().bg(Color::Blue))),
71 Spans::from(Span::styled(
72 "This is a longer line\n",
73 Style::default().add_modifier(Modifier::CROSSED_OUT),
74 )),
75 Spans::from(Span::styled(&long_line, Style::default().bg(Color::Green))),
76 Spans::from(Span::styled(
77 "This is a line\n",
78 Style::default().fg(Color::Green).add_modifier(Modifier::ITALIC),
79 )),
80 ];
81
82 let paragraph = Paragraph::new(text.clone())
83 .block(Block::default().title("Left Block").borders(Borders::ALL))
84 .alignment(Alignment::Left).wrap(Wrap { trim: true });
85 f.render_widget(paragraph, chunks[0]);
86
87 let paragraph = Paragraph::new(text)
88 .block(Block::default().title("Right Block").borders(Borders::ALL))
89 .alignment(Alignment::Left).wrap(Wrap { trim: true });
90 f.render_widget(paragraph, chunks[1]);
91
92 let block = Block::default().title("Popup").borders(Borders::ALL);
93 let area = centered_rect(60, 20, size);
94 f.render_widget(Clear, area); //this clears out the background
95 f.render_widget(block, area);
96 })?;
97
98 if let Event::Input(input) = events.next()? {
99 if let Key::Char('q') = input {
100 break;
101 }
102 }
103 }
104
105 Ok(())
106 }
107