use crossterm::event::KeyEvent;
use oxi_tui::Theme;
use ratatui::{layout::Rect, Frame};
pub mod anchor;
pub mod factories;
pub mod fork_select;
pub mod questionnaire;
pub mod router_integration;
pub mod router_setup;
pub mod settings;
pub mod tree_navigator;
#[allow(unused_imports)]
pub use factories::{logout_select, model_select, resume_select, routing_status};
#[allow(unused_imports)]
pub use fork_select::ForkSelectOverlay;
pub use router_setup::{router_setup, RouterSetupData};
#[allow(unused_imports)]
pub use settings::settings_overlay;
#[allow(unused_imports)]
pub use tree_navigator::{tree_navigator, TreeNavigatorOverlay};
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum OverlayAction {
None,
Close,
SwitchSession(String),
NewSession,
ExecuteSlashCommand(String),
SendPrompt(String),
OpenRouterSetup {
initial: crate::tui::overlay::RouterSetupData,
models: Vec<String>,
},
ForkFromEntry { entry_id: String },
NavigateToEntry { entry_id: String },
}
pub trait OverlayComponent: std::fmt::Debug {
fn handle_key(&mut self, key: KeyEvent) -> OverlayAction;
fn render(&mut self, frame: &mut Frame, area: Rect, theme: &Theme);
fn hint(&self) -> &str;
}
#[allow(dead_code)]
pub fn centered_popup(area: Rect, width_pct: f32, height_pct: f32) -> Rect {
let w = (area.width as f32 * width_pct) as u16;
let h = (area.height as f32 * height_pct) as u16;
Rect {
x: area.x + area.width.saturating_sub(w) / 2,
y: area.y + area.height.saturating_sub(h) / 2,
width: w.min(area.width),
height: h.min(area.height),
}
}
pub fn centered_layout(area: Rect, width_pct: f32, height_pct: f32) -> Rect {
use oxi_tui::overlay_anchor::{
resolve_overlay_layout, OverlayAnchor, OverlayLayout, SizeValue,
};
let layout = OverlayLayout {
anchor: OverlayAnchor::Center,
width: SizeValue::Percent(width_pct),
max_height: Some((area.height as f32 * height_pct) as u16),
min_width: None,
margin: 0,
..Default::default()
};
resolve_overlay_layout(&layout, area.width, area.height)
}