use ratatui::{
Frame,
layout::{Constraint, Direction, Layout},
};
use crate::tui::state::FormState;
use super::components::{
render_body, render_composite_overlay, render_footer, render_help_overlay, render_popup,
};
pub struct UiContext<'a> {
pub status_message: &'a str,
pub dirty: bool,
pub error_count: usize,
pub help: Option<&'a str>,
pub global_errors: &'a [String],
pub focus_label: Option<String>,
pub popup: Option<PopupRender<'a>>,
pub composite_overlay: Option<CompositeOverlay>,
pub help_overlay: Option<HelpOverlayRender<'a>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HelpShortcutRender {
pub scope: String,
pub keys: String,
pub action: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HelpErrorRender {
pub index: usize,
pub pointer: String,
pub message: String,
}
#[derive(Debug, Clone)]
pub struct HelpOverlayPage {
pub summary: String,
pub current_page: usize,
pub total_pages: usize,
pub shortcuts: Vec<HelpShortcutRender>,
pub errors: Vec<HelpErrorRender>,
pub total_errors: usize,
}
pub struct PopupRender<'a> {
pub title: &'a str,
pub options: &'a [String],
pub selected: usize,
pub multi: bool,
pub active: Option<&'a [bool]>,
}
#[derive(Debug, Clone, Copy)]
pub struct HelpOverlayRender<'a> {
pub page: &'a HelpOverlayPage,
pub shortcut_offset: usize,
}
#[derive(Debug, Clone)]
pub struct CompositeOverlay {
pub title: String,
pub description: Option<String>,
pub dirty: bool,
pub instructions: String,
pub list_entries: Option<Vec<String>>,
pub list_selected: Option<usize>,
pub entry_label: Option<String>,
pub level: usize,
}
pub fn draw(
frame: &mut Frame<'_>,
form_state: &mut FormState,
overlay_form: Option<&mut FormState>,
ctx: UiContext<'_>,
) {
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Min(7), Constraint::Length(4)])
.split(frame.area());
let cursor_enabled = ctx.popup.is_none() && ctx.composite_overlay.is_none();
render_body(frame, chunks[0], form_state, cursor_enabled);
render_footer(frame, chunks[1], &ctx);
if let (Some(meta), Some(overlay_state)) = (ctx.composite_overlay.as_ref(), overlay_form) {
render_composite_overlay(frame, meta, overlay_state);
}
if let Some(popup) = ctx.popup {
render_popup(frame, popup);
}
if let Some(help) = ctx.help_overlay {
render_help_overlay(frame, help);
}
}