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