use ratatui::{
layout::{Alignment, Rect},
style::{Color, Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, Paragraph},
Frame,
};
use tuiserial_core::{i18n::t, AppState, Parity};
use crate::areas::{update_area, UiAreaField};
pub fn draw_status_panel(f: &mut Frame, app: &AppState, area: Rect) {
update_area(UiAreaField::StatusPanel, area);
let status_color = if app.is_connected {
Color::Green
} else {
Color::Red
};
let status_icon = if app.is_connected { "✓" } else { "✗" };
let status_text = if app.is_connected {
t("status.connected", app.language)
} else {
t("status.disconnected", app.language)
};
let config_status = if app.config_locked {
("🔒", t("status.locked", app.language), Color::Yellow)
} else {
("🔓", t("status.modifiable", app.language), Color::Green)
};
let parity_str = match app.config.parity {
Parity::None => t("parity.none", app.language).chars().next().unwrap_or('N'),
Parity::Even => t("parity.even", app.language).chars().next().unwrap_or('E'),
Parity::Odd => t("parity.odd", app.language).chars().next().unwrap_or('O'),
};
let text = vec![
Line::from(vec![
Span::styled(
status_icon,
Style::default()
.fg(status_color)
.add_modifier(Modifier::BOLD),
),
Span::raw(" "),
Span::styled(
status_text,
Style::default()
.fg(status_color)
.add_modifier(Modifier::BOLD),
),
]),
Line::from(vec![
Span::styled(config_status.0, Style::default().fg(config_status.2)),
Span::raw(" "),
Span::styled(config_status.1, Style::default().fg(config_status.2)),
]),
Line::raw(""),
Line::from(vec![
Span::styled(
format!("{}: ", t("label.port", app.language)),
Style::default().fg(Color::Cyan),
),
Span::raw(if app.config.port.is_empty() {
t("status.not_connected", app.language)
.split('-')
.next()
.unwrap_or("Not selected")
.trim()
} else {
&app.config.port
}),
]),
Line::from(vec![
Span::styled(
format!("{}: ", t("label.baud_rate", app.language)),
Style::default().fg(Color::Cyan),
),
Span::raw(format!("{}", app.config.baud_rate)),
]),
Line::from(vec![
Span::styled(
format!("{}: ", t("label.data_bits", app.language)),
Style::default().fg(Color::Cyan),
),
Span::raw(format!(
"{}-{}-{}",
app.config.data_bits, parity_str, app.config.stop_bits
)),
]),
Line::raw(""),
Line::from(vec![
Span::styled(
"o",
Style::default()
.fg(Color::Green)
.add_modifier(Modifier::BOLD),
),
Span::raw(format!(" {} ", t("hint.select", app.language))),
Span::styled(
"r",
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
),
Span::raw(format!(" {}", t("hint.refresh", app.language))),
]),
Line::from(vec![
Span::styled(
"q",
Style::default().fg(Color::Red).add_modifier(Modifier::BOLD),
),
Span::raw(format!(" {} ", t("hint.quit", app.language))),
Span::styled(
"Tab",
Style::default()
.fg(Color::Yellow)
.add_modifier(Modifier::BOLD),
),
Span::raw(format!(" {}", t("hint.switch", app.language))),
]),
];
let para = Paragraph::new(text).block(
Block::default()
.borders(Borders::ALL)
.title(format!(" {} ", t("label.status", app.language)))
.title_alignment(Alignment::Left),
);
f.render_widget(para, area);
}
pub fn draw_control_area(f: &mut Frame, app: &AppState, area: Rect) {
update_area(UiAreaField::ControlArea, area);
let auto_scroll_icon = if app.auto_scroll { "🔄" } else { "⏸" };
let stats = vec![
Span::styled(
format!("{}: ", t("label.tx_count", app.language)),
Style::default()
.fg(Color::Green)
.add_modifier(Modifier::BOLD),
),
Span::styled(
format!("{} ", app.message_log.tx_count),
Style::default().fg(Color::White),
),
Span::raw("│ "),
Span::styled(
format!("{}: ", t("label.rx_count", app.language)),
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
),
Span::styled(
format!("{} ", app.message_log.rx_count),
Style::default().fg(Color::White),
),
Span::raw("│ "),
Span::styled(
format!(
"{} {}",
auto_scroll_icon,
t("hint.auto_scroll", app.language)
),
if app.auto_scroll {
Style::default().fg(Color::Green)
} else {
Style::default().fg(Color::Yellow)
},
),
];
let para = Paragraph::new(Line::from(stats))
.block(
Block::default()
.borders(Borders::ALL)
.title(format!(" {} ", t("label.statistics", app.language)))
.title_alignment(Alignment::Left),
)
.alignment(Alignment::Left);
f.render_widget(para, area);
}