use crate::app::{AppState, GraveyardMode};
use crate::theme::{BONE_WHITE, NEON_PURPLE, TOXIC_GREEN};
use ratatui::{
layout::{Alignment, Rect},
style::{Color, Modifier, Style},
text::{Line, Span},
widgets::{Block, BorderType, Borders, Paragraph},
Frame,
};
pub fn render_status_bar(f: &mut Frame, area: Rect, app: &AppState) {
let mode_hint = match app.graveyard_mode {
GraveyardMode::Host => "Focus Process | ",
GraveyardMode::Process => "Back to Host | ",
};
let available_width = area.width.saturating_sub(4);
struct Hint {
priority: u8,
key: &'static str,
desc: String,
color: Color,
}
let hints = vec![
Hint {
priority: 1,
key: "Q:",
desc: "R.I.P ".to_string(),
color: Color::Red,
},
Hint {
priority: 1,
key: "↑↓:",
desc: "Navigate | ".to_string(),
color: NEON_PURPLE,
},
Hint {
priority: 1,
key: "P:",
desc: mode_hint.to_string(),
color: NEON_PURPLE,
},
Hint {
priority: 2,
key: "+/-:",
desc: "Speed | ".to_string(),
color: NEON_PURPLE,
},
Hint {
priority: 2,
key: "A:",
desc: "Anim | ".to_string(),
color: NEON_PURPLE,
},
Hint {
priority: 2,
key: "H:",
desc: "Theme | ".to_string(),
color: NEON_PURPLE,
},
Hint {
priority: 2,
key: "t:",
desc: "Labels | ".to_string(),
color: NEON_PURPLE,
},
Hint {
priority: 3,
key: "⇆ TAB:",
desc: "Switch Pane | ".to_string(),
color: NEON_PURPLE,
},
Hint {
priority: 3,
key: "F1:",
desc: "Help | ".to_string(),
color: NEON_PURPLE,
},
];
let mut spans = vec![Span::styled(" 💀 ", Style::default().fg(NEON_PURPLE))];
let mut current_length = 4;
for priority in 1..=3 {
for hint in &hints {
if hint.priority == priority {
let hint_length = hint.key.len() + hint.desc.len();
if current_length + hint_length <= available_width as usize {
spans.push(Span::styled(
hint.key,
Style::default().fg(hint.color).add_modifier(Modifier::BOLD),
));
spans.push(Span::raw(hint.desc.clone()));
current_length += hint_length;
}
}
}
}
let toggle_indicators = build_toggle_indicators(app);
let toggle_length: usize = toggle_indicators.iter().map(|s| s.content.len()).sum();
if current_length + toggle_length < available_width as usize {
spans.push(Span::raw(" "));
spans.extend(toggle_indicators);
}
let status_text = Line::from(spans);
let status_bar = Paragraph::new(status_text)
.block(
Block::default()
.borders(Borders::ALL)
.border_type(BorderType::Double)
.border_style(Style::default().fg(NEON_PURPLE)),
)
.alignment(Alignment::Left);
f.render_widget(status_bar, area);
}
pub fn build_toggle_indicators(app: &AppState) -> Vec<Span<'static>> {
let mut spans = Vec::new();
let anim_state = if app.graveyard_settings.animations_enabled {
"ON"
} else {
"OFF"
};
let anim_color = if app.graveyard_settings.animations_enabled {
TOXIC_GREEN
} else {
BONE_WHITE
};
spans.push(Span::styled("[A:", Style::default().fg(BONE_WHITE)));
spans.push(Span::styled(
anim_state,
Style::default().fg(anim_color).add_modifier(Modifier::BOLD),
));
spans.push(Span::styled("] ", Style::default().fg(BONE_WHITE)));
let overdrive_state = if app.graveyard_settings.overdrive_enabled {
"ON"
} else {
"OFF"
};
let overdrive_color = if app.graveyard_settings.overdrive_enabled {
TOXIC_GREEN
} else {
BONE_WHITE
};
spans.push(Span::styled("[H:", Style::default().fg(BONE_WHITE)));
spans.push(Span::styled(
overdrive_state,
Style::default()
.fg(overdrive_color)
.add_modifier(Modifier::BOLD),
));
spans.push(Span::styled("] ", Style::default().fg(BONE_WHITE)));
let labels_state = if app.graveyard_settings.labels_enabled {
"ON"
} else {
"OFF"
};
let labels_color = if app.graveyard_settings.labels_enabled {
TOXIC_GREEN
} else {
BONE_WHITE
};
spans.push(Span::styled("[t:", Style::default().fg(BONE_WHITE)));
spans.push(Span::styled(
labels_state,
Style::default()
.fg(labels_color)
.add_modifier(Modifier::BOLD),
));
spans.push(Span::styled("]", Style::default().fg(BONE_WHITE)));
spans
}