tlc: phase 18c — migrate 7 more dialogs to render_popup
Continue Phase 18 mechanical migration of centered dialogs to the shared terminal::popup::render_popup() shell (MC-matching rounded borders + drop shadow): permission, owner, connection_dialog, config_dialog, compare, sort_dialog, progress All 7 share the same pattern: inline Clear + Block + title replaced with render_popup() + centered_cols_rect()/centered_percent_rect(). Title color now derives from [dialog] dtitle via the unified shell. compare.rs also dropped its local centered_rect helper (used only for the popup shell; the body Block stays inline since it's a sub-frame, not the popup shell). Tree (full-screen directory tree dialog) intentionally skipped — it uses the entire frame area, not a centered popup, so it does not benefit from the popup shell or shadow. Tests: 1112 passed (no regressions).
This commit is contained in:
@@ -9,11 +9,12 @@ use std::path::Path;
|
|||||||
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::{Line, Span};
|
use ratatui::text::{Line, Span};
|
||||||
use ratatui::widgets::{Block, Borders, Clear, Paragraph};
|
use ratatui::widgets::{Block, Borders, Paragraph};
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::key::Key;
|
use crate::key::Key;
|
||||||
use crate::terminal::color::Theme;
|
use crate::terminal::color::Theme;
|
||||||
|
use crate::terminal::popup::{centered_percent_rect, render_popup};
|
||||||
|
|
||||||
/// Maximum lines to read from each file (prevents OOM on huge files).
|
/// Maximum lines to read from each file (prevents OOM on huge files).
|
||||||
const MAX_LINES: usize = 10_000;
|
const MAX_LINES: usize = 10_000;
|
||||||
@@ -121,19 +122,18 @@ impl CompareDialog {
|
|||||||
|
|
||||||
/// Render the dialog.
|
/// Render the dialog.
|
||||||
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
||||||
let popup = centered_rect(area, 90, 80);
|
let popup = centered_percent_rect(area, 0.9, 0.8);
|
||||||
frame.render_widget(Clear, popup);
|
let title = if self.error.is_some() {
|
||||||
|
"Compare: error".to_string()
|
||||||
|
} else {
|
||||||
|
format!("Compare: {} ⟷ {}", self.left_name, self.right_name)
|
||||||
|
};
|
||||||
|
let inner = render_popup(frame, popup, title.as_str(), theme);
|
||||||
|
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(ratatui::layout::Direction::Vertical)
|
.direction(ratatui::layout::Direction::Vertical)
|
||||||
.constraints([Constraint::Length(2), Constraint::Min(1)])
|
.constraints([Constraint::Length(2), Constraint::Min(1)])
|
||||||
.split(popup);
|
.split(inner);
|
||||||
|
|
||||||
let title = if self.error.is_some() {
|
|
||||||
format!(" Compare: error ")
|
|
||||||
} else {
|
|
||||||
format!(" Compare: {} ⟷ {} ", self.left_name, self.right_name)
|
|
||||||
};
|
|
||||||
|
|
||||||
let header = Paragraph::new(Line::from(vec![Span::styled(
|
let header = Paragraph::new(Line::from(vec![Span::styled(
|
||||||
title,
|
title,
|
||||||
@@ -236,25 +236,6 @@ fn compute_diff(a: &[String], b: &[String]) -> Vec<DiffLine> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn centered_rect(area: Rect, pct_x: u16, pct_y: u16) -> Rect {
|
|
||||||
let pop_rect = Layout::default()
|
|
||||||
.direction(ratatui::layout::Direction::Vertical)
|
|
||||||
.constraints([
|
|
||||||
Constraint::Percentage((100 - pct_y) / 2),
|
|
||||||
Constraint::Percentage(pct_y),
|
|
||||||
Constraint::Percentage((100 - pct_y) / 2),
|
|
||||||
])
|
|
||||||
.split(area);
|
|
||||||
Layout::default()
|
|
||||||
.direction(ratatui::layout::Direction::Horizontal)
|
|
||||||
.constraints([
|
|
||||||
Constraint::Percentage((100 - pct_x) / 2),
|
|
||||||
Constraint::Percentage(pct_x),
|
|
||||||
Constraint::Percentage((100 - pct_x) / 2),
|
|
||||||
])
|
|
||||||
.split(pop_rect[1])[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -22,11 +22,12 @@
|
|||||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::{Line, Span};
|
use ratatui::text::{Line, Span};
|
||||||
use ratatui::widgets::{Block, Borders, Clear, Paragraph};
|
use ratatui::widgets::Paragraph;
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::key::Key;
|
use crate::key::Key;
|
||||||
use crate::terminal::color::Theme;
|
use crate::terminal::color::Theme;
|
||||||
|
use crate::terminal::popup::{centered_cols_rect, render_popup};
|
||||||
|
|
||||||
/// The result of the configuration dialog after a key event.
|
/// The result of the configuration dialog after a key event.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@@ -181,25 +182,8 @@ impl ConfigDialog {
|
|||||||
|
|
||||||
/// Render the dialog centered on `area`.
|
/// Render the dialog centered on `area`.
|
||||||
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
||||||
let w = 44u16.min(area.width.saturating_sub(2));
|
let dlg = centered_cols_rect(area, 44, 12);
|
||||||
let h = 12u16.min(area.height.saturating_sub(2));
|
let inner = render_popup(frame, dlg, "Configuration", theme);
|
||||||
let x = area.x + (area.width - w) / 2;
|
|
||||||
let y = area.y + (area.height - h) / 2;
|
|
||||||
let dlg = Rect::new(x, y, w, h);
|
|
||||||
frame.render_widget(Clear, dlg);
|
|
||||||
|
|
||||||
let block = Block::default()
|
|
||||||
.borders(Borders::ALL)
|
|
||||||
.border_style(Style::default().fg(theme.title_fg))
|
|
||||||
.title(Span::styled(
|
|
||||||
" Configuration ",
|
|
||||||
Style::default()
|
|
||||||
.fg(theme.title_fg)
|
|
||||||
.bg(theme.title_bg)
|
|
||||||
.add_modifier(Modifier::BOLD),
|
|
||||||
));
|
|
||||||
let inner = block.inner(dlg);
|
|
||||||
frame.render_widget(block, dlg);
|
|
||||||
|
|
||||||
let rows = Layout::default()
|
let rows = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
|
|||||||
@@ -19,11 +19,12 @@ use std::path::PathBuf;
|
|||||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::{Line, Span};
|
use ratatui::text::{Line, Span};
|
||||||
use ratatui::widgets::{Block, Borders, Clear, Paragraph};
|
use ratatui::widgets::Paragraph;
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::key::Key;
|
use crate::key::Key;
|
||||||
use crate::terminal::color::Theme;
|
use crate::terminal::color::Theme;
|
||||||
|
use crate::terminal::popup::{centered_cols_rect, render_popup};
|
||||||
use crate::vfs::VfsPath;
|
use crate::vfs::VfsPath;
|
||||||
use crate::widget::input::Input;
|
use crate::widget::input::Input;
|
||||||
|
|
||||||
@@ -205,25 +206,8 @@ impl ConnectionDialog {
|
|||||||
|
|
||||||
/// Render the dialog centered on `area`.
|
/// Render the dialog centered on `area`.
|
||||||
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
||||||
let w = 60u16.min(area.width.saturating_sub(2));
|
let dlg = centered_cols_rect(area, 60, 8);
|
||||||
let h = 8u16.min(area.height.saturating_sub(2));
|
let inner = render_popup(frame, dlg, self.kind.title(), theme);
|
||||||
let x = area.x + (area.width.saturating_sub(w)) / 2;
|
|
||||||
let y = area.y + (area.height.saturating_sub(h)) / 2;
|
|
||||||
let dlg = Rect::new(x, y, w, h);
|
|
||||||
frame.render_widget(Clear, dlg);
|
|
||||||
|
|
||||||
let block = Block::default()
|
|
||||||
.borders(Borders::ALL)
|
|
||||||
.border_style(Style::default().fg(theme.title_fg))
|
|
||||||
.title(Span::styled(
|
|
||||||
self.kind.title(),
|
|
||||||
Style::default()
|
|
||||||
.fg(theme.title_fg)
|
|
||||||
.bg(theme.title_bg)
|
|
||||||
.add_modifier(Modifier::BOLD),
|
|
||||||
));
|
|
||||||
let inner = block.inner(dlg);
|
|
||||||
frame.render_widget(block, dlg);
|
|
||||||
|
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ use std::path::PathBuf;
|
|||||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::{Line, Span};
|
use ratatui::text::{Line, Span};
|
||||||
use ratatui::widgets::{Block, Borders, Clear, Paragraph, Wrap};
|
use ratatui::widgets::{Paragraph, Wrap};
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::key::Key;
|
use crate::key::Key;
|
||||||
use crate::terminal::color::Theme;
|
use crate::terminal::color::Theme;
|
||||||
|
use crate::terminal::popup::{centered_percent_rect, render_popup};
|
||||||
use crate::widget::input::Input;
|
use crate::widget::input::Input;
|
||||||
|
|
||||||
/// Which field currently has focus.
|
/// Which field currently has focus.
|
||||||
@@ -170,21 +171,13 @@ impl OwnerDialog {
|
|||||||
/// `theme` supplies the title, body, and hint colours so the
|
/// `theme` supplies the title, body, and hint colours so the
|
||||||
/// dialog follows the active skin.
|
/// dialog follows the active skin.
|
||||||
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
||||||
let popup = centered_rect(area, self.width_pct, self.height_pct);
|
let popup = centered_percent_rect(area, self.width_pct, self.height_pct);
|
||||||
frame.render_widget(Clear, popup);
|
let inner = render_popup(
|
||||||
|
frame,
|
||||||
let block = Block::default()
|
popup,
|
||||||
.borders(Borders::ALL)
|
crate::locale::t("dialog_title_owner"),
|
||||||
.border_style(Style::default().fg(theme.title_fg))
|
theme,
|
||||||
.title(Span::styled(
|
);
|
||||||
format!(" {} ", crate::locale::t("dialog_title_owner")),
|
|
||||||
Style::default()
|
|
||||||
.fg(theme.title_fg)
|
|
||||||
.bg(theme.title_bg)
|
|
||||||
.add_modifier(Modifier::BOLD),
|
|
||||||
));
|
|
||||||
let inner = block.inner(popup);
|
|
||||||
frame.render_widget(block, popup);
|
|
||||||
|
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
|
|||||||
@@ -15,11 +15,12 @@ use std::path::PathBuf;
|
|||||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::{Line, Span};
|
use ratatui::text::{Line, Span};
|
||||||
use ratatui::widgets::{Block, Borders, Clear, Paragraph, Wrap};
|
use ratatui::widgets::{Paragraph, Wrap};
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::key::Key;
|
use crate::key::Key;
|
||||||
use crate::terminal::color::Theme;
|
use crate::terminal::color::Theme;
|
||||||
|
use crate::terminal::popup::{centered_percent_rect, render_popup};
|
||||||
|
|
||||||
/// One cell in the 3x3 permission grid.
|
/// One cell in the 3x3 permission grid.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@@ -211,21 +212,13 @@ impl PermissionDialog {
|
|||||||
/// `theme` supplies the title, border, hint, and button colours so
|
/// `theme` supplies the title, border, hint, and button colours so
|
||||||
/// the dialog follows the active skin.
|
/// the dialog follows the active skin.
|
||||||
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
||||||
let popup = centered_rect(area, self.width_pct, self.height_pct);
|
let popup = centered_percent_rect(area, self.width_pct, self.height_pct);
|
||||||
frame.render_widget(Clear, popup);
|
let inner = render_popup(
|
||||||
|
frame,
|
||||||
let block = Block::default()
|
popup,
|
||||||
.borders(Borders::ALL)
|
crate::locale::t("dialog_title_permission"),
|
||||||
.border_style(Style::default().fg(theme.title_fg))
|
theme,
|
||||||
.title(Span::styled(
|
);
|
||||||
format!(" {} ", crate::locale::t("dialog_title_permission")),
|
|
||||||
Style::default()
|
|
||||||
.fg(theme.title_fg)
|
|
||||||
.bg(theme.title_bg)
|
|
||||||
.add_modifier(Modifier::BOLD),
|
|
||||||
));
|
|
||||||
let inner = block.inner(popup);
|
|
||||||
frame.render_widget(block, popup);
|
|
||||||
|
|
||||||
// Inner split: header line, 3-row grid, hint line.
|
// Inner split: header line, 3-row grid, hint line.
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::Span;
|
use ratatui::text::Span;
|
||||||
use ratatui::widgets::{Block, Borders, Clear, Paragraph};
|
use ratatui::widgets::Paragraph;
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
use crate::filemanager::panel::SortField;
|
use crate::filemanager::panel::SortField;
|
||||||
@@ -130,25 +130,8 @@ impl SortDialog {
|
|||||||
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
||||||
let w = 36u16.min(area.width.saturating_sub(2));
|
let w = 36u16.min(area.width.saturating_sub(2));
|
||||||
let h = 12u16.min(area.height.saturating_sub(2));
|
let h = 12u16.min(area.height.saturating_sub(2));
|
||||||
let x = area.x + (area.width - w) / 2;
|
let dlg = crate::terminal::popup::centered_cols_rect(area, w, h);
|
||||||
let y = area.y + (area.height - h) / 2;
|
let inner = crate::terminal::popup::render_popup(frame, dlg, "Sort Order", theme);
|
||||||
let dlg = Rect::new(x, y, w, h);
|
|
||||||
frame.render_widget(Clear, dlg);
|
|
||||||
|
|
||||||
let block = Block::default()
|
|
||||||
.borders(Borders::ALL)
|
|
||||||
.border_style(Style::default().fg(theme.border))
|
|
||||||
.title(Span::styled(
|
|
||||||
" Sort Order ",
|
|
||||||
Style::default()
|
|
||||||
.fg(theme.title_fg)
|
|
||||||
.bg(theme.title_bg)
|
|
||||||
.add_modifier(Modifier::BOLD),
|
|
||||||
))
|
|
||||||
.style(Style::default().bg(theme.background).fg(theme.foreground));
|
|
||||||
|
|
||||||
let inner = block.inner(dlg);
|
|
||||||
frame.render_widget(block, dlg);
|
|
||||||
|
|
||||||
let mut constraints = vec![Constraint::Length(1)];
|
let mut constraints = vec![Constraint::Length(1)];
|
||||||
for _ in 0..FIELDS.len() {
|
for _ in 0..FIELDS.len() {
|
||||||
|
|||||||
@@ -7,12 +7,13 @@ use std::time::Instant;
|
|||||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
use ratatui::style::{Modifier, Style};
|
use ratatui::style::{Modifier, Style};
|
||||||
use ratatui::text::{Line, Span};
|
use ratatui::text::{Line, Span};
|
||||||
use ratatui::widgets::{Block, Borders, Clear, Paragraph, Wrap};
|
use ratatui::widgets::{Paragraph, Wrap};
|
||||||
use ratatui::Frame;
|
use ratatui::Frame;
|
||||||
|
|
||||||
|
|
||||||
use crate::ops::OpHandle;
|
use crate::ops::OpHandle;
|
||||||
use crate::terminal::color::Theme;
|
use crate::terminal::color::Theme;
|
||||||
|
use crate::terminal::popup::{centered_percent_rect, render_popup};
|
||||||
use crate::widget::ProgressGauge;
|
use crate::widget::ProgressGauge;
|
||||||
|
|
||||||
/// The progress dialog. Renders a running operation with a
|
/// The progress dialog. Renders a running operation with a
|
||||||
@@ -57,21 +58,8 @@ impl ProgressDialog {
|
|||||||
/// `theme` supplies the title, current file, gauge, and cancel
|
/// `theme` supplies the title, current file, gauge, and cancel
|
||||||
/// button colours so the progress dialog follows the active skin.
|
/// button colours so the progress dialog follows the active skin.
|
||||||
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
pub fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme) {
|
||||||
let popup = centered_rect(area, self.width_pct, self.height_pct);
|
let popup = centered_percent_rect(area, self.width_pct, self.height_pct);
|
||||||
frame.render_widget(Clear, popup);
|
let inner = render_popup(frame, popup, self.title.as_str(), theme);
|
||||||
|
|
||||||
let block = Block::default()
|
|
||||||
.borders(Borders::ALL)
|
|
||||||
.border_style(Style::default().fg(theme.title_fg))
|
|
||||||
.title(Span::styled(
|
|
||||||
format!(" {} ", self.title),
|
|
||||||
Style::default()
|
|
||||||
.fg(theme.title_fg)
|
|
||||||
.bg(theme.title_bg)
|
|
||||||
.add_modifier(Modifier::BOLD),
|
|
||||||
));
|
|
||||||
let inner = block.inner(popup);
|
|
||||||
frame.render_widget(block, popup);
|
|
||||||
|
|
||||||
let chunks = Layout::default()
|
let chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
|
|||||||
Reference in New Issue
Block a user