Krolyxon
Commit 957ffc9

rmptuisrcpopupsmod.rs

60 lines · 1.6 KB · Rust

1//! Modal popups drawn above the screens. The topmost popup receives all
2//! keys until it closes.
3
4mod add_to_playlist;
5mod confirm;
6mod help;
7mod input;
8
9use ratatui::{
10 Frame,
11 layout::{Constraint, Flex, Layout, Rect},
12 text::Line,
13 widgets::{Block, BorderType, Clear},
14};
15
16pub use add_to_playlist::AddToPlaylistPopup;
17pub use confirm::ConfirmPopup;
18pub use help::HelpPopup;
19pub use input::{InputPopup, InputPurpose};
20
21use crate::{config::KeyCombo, screens::Ctx};
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum PopupState {
25 Open,
26 Closed,
27}
28
29pub trait Popup {
30 /// Draws the popup; `area` is the whole terminal.
31 fn draw(&mut self, frame: &mut Frame, area: Rect, ctx: &Ctx);
32
33 fn handle_key(&mut self, key: KeyCombo, ctx: &mut Ctx) -> PopupState;
34}
35
36/// Clears a centered rectangle and draws a titled frame around it,
37/// returning the inner area.
38fn frame_popup(
39 frame: &mut Frame,
40 area: Rect,
41 width: u16,
42 height: u16,
43 title: &str,
44 ctx: &Ctx,
45) -> Rect {
46 let [area] = Layout::horizontal([Constraint::Length(width.min(area.width))])
47 .flex(Flex::Center)
48 .areas(area);
49 let [area] = Layout::vertical([Constraint::Length(height.min(area.height))])
50 .flex(Flex::Center)
51 .areas(area);
52 let block = Block::bordered()
53 .border_type(BorderType::Plain)
54 .border_style(ctx.theme().border())
55 .title(Line::from(format!(" {title} ")).style(ctx.theme().header()));
56 let inner = block.inner(area);
57 frame.render_widget(Clear, area);
58 frame.render_widget(block, area);
59 inner
60}