light_and_dark_theme/
light_and_dark_theme.rs

1use std::io::{self, stdout};
2
3use crossterm::{
4    event::{read, Event, KeyCode},
5    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
6    ExecutableCommand,
7};
8use ratatui::{
9    prelude::*,
10    widgets::{Block, BorderType, Borders},
11};
12
13use fpicker::{FileExplorer, Theme};
14
15fn main() -> io::Result<()> {
16    enable_raw_mode()?;
17    stdout().execute(EnterAlternateScreen)?;
18
19    let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
20
21    // Create a new file explorer with the light theme.
22    let mut dark_theme = false;
23    let mut file_explorer = FileExplorer::with_theme(get_light_theme())?;
24
25    loop {
26        // Render the file explorer widget.
27        terminal.draw(|f| {
28            f.render_widget(&file_explorer.widget(), f.area());
29        })?;
30
31        // Read the next event from the terminal.
32        let event = read()?;
33        // If the user presses `Ctrl + s`, switch the theme.
34        // If the user presses `Ctrl + q`, quit the application.
35        if let Event::Key(key) = event {
36            if key.modifiers == crossterm::event::KeyModifiers::CONTROL {
37                match key.code {
38                    KeyCode::Char('s') => {
39                        dark_theme = !dark_theme;
40                        if dark_theme {
41                            file_explorer.set_theme(get_dark_theme());
42                        } else {
43                            file_explorer.set_theme(get_light_theme());
44                        }
45                    }
46                    KeyCode::Char('q') => {
47                        break;
48                    }
49                    _ => {}
50                }
51            }
52        }
53        // Handle the event in the file explorer.
54        file_explorer.handle(&event)?;
55    }
56
57    disable_raw_mode()?;
58    stdout().execute(LeaveAlternateScreen)?;
59    Ok(())
60}
61
62fn get_light_theme() -> Theme {
63    Theme::new()
64        .with_block(
65            Block::default()
66                .borders(Borders::ALL)
67                .border_type(BorderType::Rounded)
68                .style(Style::default().fg(Color::Black).bg(Color::White)),
69        )
70        .with_item_style(Style::default().fg(Color::Yellow))
71        .with_dir_style(
72            Style::default()
73                .fg(Color::Cyan)
74                .add_modifier(Modifier::BOLD),
75        )
76        .with_highlight_symbol("> ")
77        .add_default_title()
78        .with_title_top(|_| Line::from(" ☀ Theme ").right_aligned())
79        .with_title_bottom(|_| " ^q Quit | ^s Switch theme ".into())
80}
81
82fn get_dark_theme() -> Theme {
83    Theme::new()
84        .with_block(
85            Block::default()
86                .borders(Borders::ALL)
87                .border_type(BorderType::Rounded)
88                .style(Style::default().fg(Color::White).bg(Color::Black)),
89        )
90        .with_item_style(Style::default().fg(Color::Yellow))
91        .with_dir_style(
92            Style::default()
93                .fg(Color::Cyan)
94                .add_modifier(Modifier::BOLD),
95        )
96        .with_highlight_symbol("> ")
97        .add_default_title()
98        .with_title_top(|_| Line::from(" ☾ Theme ").right_aligned())
99        .with_title_bottom(|_| " ^q Quit | ^s Switch theme ".into())
100}