Thanks to visit codestin.com
Credit goes to lib.rs

6 releases (breaking)

Uses new Rust 2024

new 0.5.1 Oct 1, 2025
0.5.0 Sep 30, 2025
0.4.0 Sep 9, 2025
0.3.0 Sep 7, 2025
0.1.0 Feb 10, 2025

#1386 in Command-line interface

Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App

298 downloads per month
Used in mdedit

MIT/Apache

1MB
21K SLoC

alpha 2 crates.io Documentation License License

unstable

This crate is a part of rat-salsa.

Rat Dialog

This crates provides a DialogStack that can be used with rat-salsa apps. It can stack and render any number of dialog-windows on top of the main application.

It uses the rat-salsa traits for AppWidget/AppState for rendering and event handling.


# use std::path::PathBuf;
use anyhow::Error;
use rat_dialog::DialogStackState;
use crate::rat_dialog::DialogWidget;
use rat_dialog::widgets::{FileDialog, FileDialogState};
# use rat_salsa::{AppState, Control};
# use rat_theme2::DarkTheme;
# use rat_widget::event::FileOutcome;
# struct GlobalState { dialogs: DialogStackState<GlobalState, MyEvent, Error>, theme: DarkTheme }
# enum MyEvent { Event(crossterm::event::Event), Status(u16, String) }
# impl TryFrom<&MyEvent> for &crossterm::event::Event {
#   type Error = ();
#   fn try_from(value: &MyEvent) -> Result<Self, Self::Error> {
#       match self {
#           MyEvent::Event(event) => Ok(event),
#           _ => Err(())    
#       }
#   }
# }
# struct MyAppState {}

impl AppState<GlobalState, MyEvent, Error> for MyAppState {
    fn event(
        &mut self,
        event: &MyEvent,
        ctx: &mut rat_salsa::AppContext<'_, GlobalState, MyEvent, Error>,
    ) -> Result<Control<MyEvent>, Error> {
        if matches!(event, MyEvent::Event(event)) {
            let mut state = FileDialogState::new();
            state.save_dialog_ext(PathBuf::from("."), "", "pas")?;
            state.map_outcome(|r| match r {
                FileOutcome::Ok(f) => {
                    Control::Event(MyEvent::Status(0, format!("New file {:?}", f)))
                }
                r => r.into(),
            });
            
            ctx.g.dialogs.push_dialog(
                |area, buf, state, ctx| {
                    FileDialog::new()
                        .styles(ctx.g.theme.file_dialog_style())
                        .render(area, buf, state, ctx)
                },
                state                    
            );
            
            Ok(Control::Changed)
        } else {
            Ok(Control::Continue)
        }
    }
}

During rendering of the application:

# use anyhow::Error;
# use ratatui::buffer::Buffer;
# use ratatui::layout::Rect;
use rat_dialog::{DialogStack, DialogStackState};
# use rat_salsa::{AppWidget,AppState, RenderContext};
# use rat_theme2::DarkTheme;
# struct MainApp;
# struct GlobalState { dialogs: DialogStackState<GlobalState, MyEvent, Error>, theme: DarkTheme }
# enum MyEvent { Event(crossterm::event::Event), Status(u16, String) }
# struct MainAppState {}
# impl AppState<GlobalState, MyEvent, Error> for MainAppState {}


impl AppWidget<GlobalState, MyEvent, Error> for MainApp {
    type State = MainAppState;

    fn render(
            &self,
            area: Rect,
            buf: &mut Buffer,
            state: &mut Self::State,
            ctx: &mut RenderContext<'_, GlobalState>,
    ) -> Result<(), Error> {

        // ... do all the rendering ...

        DialogStack.render(area, buf, &mut ctx.g.dialogs.clone(), ctx)?;

        Ok(())
   }
}   

Dependencies

~13–24MB
~332K SLoC