picterm/
lib.rs

1pub mod app;
2pub mod image;
3pub mod inputs;
4pub mod io;
5pub mod utils;
6
7use crate::{
8    app::{ui, App, AppReturn},
9    io::IoEvent,
10};
11use crossterm::{
12    event::{DisableMouseCapture, EnableMouseCapture},
13    execute,
14    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
15};
16use eyre::Result;
17use inputs::{events::Events, InputEvent};
18use std::{io::stdout, sync::Arc, time::Duration};
19use tui::{backend::CrosstermBackend, Terminal};
20
21pub async fn start_ui<'a>(app: &Arc<tokio::sync::Mutex<App<'a>>>, path: String) -> Result<()> {
22    let mut stdout = stdout();
23    enable_raw_mode()?;
24    execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
25    let backend = CrosstermBackend::new(stdout);
26    let mut terminal = Terminal::new(backend)?;
27    terminal.clear()?;
28    terminal.hide_cursor()?;
29
30    let tick_rate = Duration::from_millis(100);
31    let mut events = Events::new(tick_rate);
32
33    {
34        let mut app = app.lock().await;
35        app.dispatch(IoEvent::Initialize(path)).await;
36    }
37
38    loop {
39        let mut app = app.lock().await;
40
41        terminal.draw(|rect| ui::draw(rect, &mut app))?;
42
43        let result = match events.next().await {
44            InputEvent::Input(key) => app.do_action(key).await,
45            InputEvent::Tick => app.update_on_tick().await,
46        };
47
48        if result == AppReturn::Exit {
49            events.close();
50            break;
51        }
52    }
53
54    disable_raw_mode()?;
55    execute!(
56        terminal.backend_mut(),
57        LeaveAlternateScreen,
58        DisableMouseCapture
59    )?;
60    terminal.show_cursor()?;
61
62    Ok(())
63}