use ratatui::{ layout::{Constraint, Layout, Rect}, style::{Modifier, Style}, text::{Line, Span}, widgets::{Clear, Paragraph}, Frame, }; use super::widgets::{ action_button_row_rects, centered_popup_rect, panel_contrast_fg, render_action_button, render_modal_header, render_modal_shell, render_panel_shell, ActionButtonSpec, }; use crate::app::{AppState, Mode}; pub(crate) fn rename_button_rects(inner: Rect) -> (Rect, Rect, Rect) { let rects = action_button_row_rects( inner, &[ ActionButtonSpec { hint: Some("↵"), label: "save", }, ActionButtonSpec { hint: Some("^c"), label: "clear", }, ActionButtonSpec { hint: Some("esc"), label: "cancel", }, ], 2, 3, ); (rects[0], rects[1], rects[2]) } pub(super) fn render_rename_overlay(app: &AppState, frame: &mut Frame, area: Rect) { super::dim_background(frame, area); let title = match app.mode { Mode::RenameWorkspace => "rename workspace", Mode::RenameTab if app.creating_new_tab => "new tab", Mode::RenameTab => "rename tab", Mode::RenamePane => "rename pane", _ => return, }; let Some(inner) = render_modal_shell(frame, area, 56, 7, &app.palette) else { return; }; if inner.height < 4 { return; } let rows = Layout::vertical([ Constraint::Length(1), Constraint::Length(1), Constraint::Length(1), Constraint::Length(1), Constraint::Min(0), ]) .areas::<5>(inner); render_modal_header(frame, rows[0], title, &app.palette); let input_rect = Rect::new(rows[2].x, rows[2].y, rows[2].width, 1); frame.render_widget(Clear, input_rect); frame.render_widget( Paragraph::new(format!(" {}█", app.name_input)).style( Style::default() .fg(app.palette.text) .bg(app.palette.surface0), ), input_rect, ); let (save_rect, clear_rect, cancel_rect) = rename_button_rects(inner); render_action_button( frame, save_rect, Some("↵"), "save", Style::default() .fg(panel_contrast_fg(&app.palette)) .bg(app.palette.accent) .add_modifier(Modifier::BOLD), ); render_action_button( frame, clear_rect, Some("^c"), "clear", Style::default() .fg(app.palette.text) .bg(app.palette.surface0) .add_modifier(Modifier::BOLD), ); render_action_button( frame, cancel_rect, Some("esc"), "cancel", Style::default() .fg(app.palette.text) .bg(app.palette.surface0) .add_modifier(Modifier::BOLD), ); } pub(super) fn render_confirm_close_overlay(app: &AppState, frame: &mut Frame, area: Rect) { let ws_name = app .workspaces .get(app.selected) .map(|ws| ws.display_name()) .unwrap_or_else(|| "?".to_string()); let pane_count = app .workspaces .get(app.selected) .map(|ws| ws.layout.pane_count()) .unwrap_or(0); let pane_text = if pane_count == 1 { "1 pane".to_string() } else { format!("{pane_count} panes") }; super::dim_background(frame, area); let Some(popup) = confirm_close_popup_rect(area) else { return; }; let warn = Style::default() .fg(app.palette.red) .add_modifier(Modifier::BOLD); let dim = Style::default().fg(app.palette.overlay0); let title_line = Line::from(vec![Span::styled(" Close workspace?", warn)]); let detail_line = Line::from(vec![ Span::styled( format!(" {ws_name}"), Style::default() .fg(app.palette.text) .add_modifier(Modifier::BOLD), ), Span::styled(format!(" — {pane_text}"), dim), ]); let Some(inner) = render_panel_shell(frame, popup, app.palette.red, app.palette.panel_bg) else { return; }; if inner.height >= 3 { let rows = Layout::vertical([ Constraint::Length(1), Constraint::Length(1), Constraint::Length(1), ]) .areas::<3>(inner); frame.render_widget(Paragraph::new(title_line), rows[0]); frame.render_widget(Paragraph::new(detail_line), rows[1]); let (confirm_rect, cancel_rect) = confirm_close_button_rects(inner); render_action_button( frame, confirm_rect, Some("↵"), "confirm", Style::default() .fg(panel_contrast_fg(&app.palette)) .bg(app.palette.red) .add_modifier(Modifier::BOLD), ); render_action_button( frame, cancel_rect, Some("esc"), "cancel", Style::default() .fg(app.palette.text) .bg(app.palette.surface0) .add_modifier(Modifier::BOLD), ); } } pub(crate) fn confirm_close_popup_rect(area: Rect) -> Option { centered_popup_rect(area, 44, 5) } pub(crate) fn confirm_close_button_rects(inner: Rect) -> (Rect, Rect) { let rects = action_button_row_rects( inner, &[ ActionButtonSpec { hint: Some("↵"), label: "confirm", }, ActionButtonSpec { hint: Some("esc"), label: "cancel", }, ], 2, 2, ); (rects[0], rects[1]) }