102 lines
2.9 KiB
Rust
102 lines
2.9 KiB
Rust
// src/components/common/dialog.rs
|
|
use ratatui::{
|
|
layout::{Constraint, Direction, Layout, Rect, Margin},
|
|
style::{Modifier, Style},
|
|
widgets::{Block, BorderType, Borders, Paragraph},
|
|
Frame,
|
|
text::{Text, Line, Span}
|
|
};
|
|
use ratatui::prelude::Alignment;
|
|
use crate::config::colors::themes::Theme;
|
|
|
|
pub fn render_dialog(
|
|
f: &mut Frame,
|
|
area: Rect,
|
|
theme: &Theme,
|
|
title: &str,
|
|
message: &str,
|
|
is_active: bool,
|
|
) {
|
|
// Create a centered rect for the dialog
|
|
let dialog_area = centered_rect(60, 25, area);
|
|
|
|
// Main dialog container
|
|
let block = Block::default()
|
|
.borders(Borders::ALL)
|
|
.border_type(BorderType::Rounded)
|
|
.border_style(Style::default().fg(theme.accent))
|
|
.title(title)
|
|
.style(Style::default().bg(theme.bg));
|
|
|
|
f.render_widget(&block, dialog_area);
|
|
|
|
// Inner content area
|
|
let inner_area = block.inner(dialog_area).inner(Margin {
|
|
horizontal: 2,
|
|
vertical: 1,
|
|
});
|
|
|
|
// Split into message and button areas
|
|
let chunks = Layout::default()
|
|
.direction(Direction::Vertical)
|
|
.constraints([
|
|
Constraint::Min(3), // Message content
|
|
Constraint::Length(3), // Button
|
|
])
|
|
.split(inner_area);
|
|
|
|
// Message text
|
|
let message_text = Text::from(message.lines().map(|l| Line::from(Span::styled(
|
|
l,
|
|
Style::default().fg(theme.fg)
|
|
))).collect::<Vec<_>>());
|
|
|
|
let message_paragraph = Paragraph::new(message_text)
|
|
.alignment(Alignment::Center);
|
|
f.render_widget(message_paragraph, chunks[0]);
|
|
|
|
// OK Button
|
|
let button_style = if is_active {
|
|
Style::default()
|
|
.fg(theme.highlight)
|
|
.add_modifier(Modifier::BOLD)
|
|
} else {
|
|
Style::default().fg(theme.fg)
|
|
};
|
|
|
|
let button_block = Block::default()
|
|
.borders(Borders::ALL)
|
|
.border_type(BorderType::Plain)
|
|
.border_style(Style::default().fg(theme.accent))
|
|
.style(Style::default().bg(theme.bg));
|
|
|
|
f.render_widget(
|
|
Paragraph::new("OK")
|
|
.block(button_block)
|
|
.style(button_style)
|
|
.alignment(Alignment::Center),
|
|
chunks[1],
|
|
);
|
|
}
|
|
|
|
/// Helper function to center a rect with given percentage values
|
|
fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
|
|
let popup_layout = Layout::default()
|
|
.direction(Direction::Vertical)
|
|
.constraints([
|
|
Constraint::Percentage((100 - percent_y) / 2),
|
|
Constraint::Percentage(percent_y),
|
|
Constraint::Percentage((100 - percent_y) / 2),
|
|
])
|
|
.split(r);
|
|
|
|
Layout::default()
|
|
.direction(Direction::Horizontal)
|
|
.constraints([
|
|
Constraint::Percentage((100 - percent_x) / 2),
|
|
Constraint::Percentage(percent_x),
|
|
Constraint::Percentage((100 - percent_x) / 2),
|
|
])
|
|
.split(popup_layout[1])[1]
|
|
}
|