1use crossterm::{
2 event::{self, Event, KeyCode, KeyModifiers},
3 execute,
4 terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
5};
6use std::io::{self, Result};
7use tui::{
8 backend::{Backend, CrosstermBackend},
9 widgets::{Block, Borders},
10 Frame, Terminal,
11};
12
13use tui_file_dialog::{bind_keys, FileDialog};
14
15struct App {
16 file_dialog: FileDialog,
18}
19
20impl App {
21 pub fn new(file_dialog: FileDialog) -> Self {
22 Self { file_dialog }
23 }
24}
25
26fn main() -> Result<()> {
27 enable_raw_mode()?;
28 let mut stdout = io::stdout();
29 execute!(stdout, EnterAlternateScreen)?;
30 let backend = CrosstermBackend::new(stdout);
31 let mut terminal = Terminal::new(backend)?;
32
33 let res = run_app(&mut terminal, App::new(FileDialog::new(60, 40)?));
34
35 disable_raw_mode()?;
36 execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
37 terminal.show_cursor()?;
38
39 if let Err(err) = res {
40 println!("{:?}", err)
41 }
42
43 Ok(())
44}
45
46fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<()> {
47 loop {
48 terminal.draw(|f| ui(f, &mut app))?;
49
50 bind_keys!(
54 app.file_dialog,
55 if let Event::Key(key) = event::read()? {
56 match key.code {
57 KeyCode::Char('o') if key.modifiers == KeyModifiers::CONTROL => {
58 app.file_dialog.open()
59 }
60 KeyCode::Char('q') | KeyCode::Esc => {
61 return Ok(());
62 }
63 _ => {}
64 }
65 }
66 )
67 }
68}
69
70fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
71 let block = Block::default()
72 .title(format!(
73 "Selected file: {}",
74 app.file_dialog
75 .selected_file
76 .as_ref()
77 .map_or("None".to_string(), |f| f.to_string_lossy().to_string())
78 ))
79 .borders(Borders::ALL);
80 f.render_widget(block, f.size());
81
82 app.file_dialog.draw(f);
84}