use super::{
PICKER_MODAL, draw_modal_panel, picker_list_area, picker_modal_list_area, render_picker_list,
};
use crate::tui::state::MissionControlState;
use ratatui::{
Frame,
layout::Rect,
text::{Line, Span},
widgets::{ListItem, Paragraph},
};
pub(crate) fn model_picker_list_area(area: Rect, has_notice: bool) -> Option<Rect> {
let header_rows = 1 + u16::from(has_notice);
picker_modal_list_area(area, "Model Picker", header_rows)
}
pub(in crate::tui::render) fn draw_model_picker(
frame: &mut Frame<'_>,
area: Rect,
state: &MissionControlState,
) {
let Some(picker) = &state.modals.model_picker else {
return;
};
let theme = state.theme;
let Some(text_area) = draw_modal_panel(frame, area, "Model Picker", PICKER_MODAL, theme) else {
return;
};
if text_area.height == 0 {
return;
}
let header = format!("current: {}", picker.current_model_id);
frame.render_widget(
Paragraph::new(header).style(theme.pane()),
Rect::new(text_area.x, text_area.y, text_area.width, 1),
);
let header_rows = 1 + u16::from(picker.notice.is_some());
let notice_y = text_area.y.saturating_add(1);
if let Some(notice) = &picker.notice
&& notice_y < text_area.y.saturating_add(text_area.height)
{
frame.render_widget(
Paragraph::new(notice.clone()).style(theme.muted(false)),
Rect::new(text_area.x, notice_y, text_area.width, 1),
);
}
let Some(list_area) = picker_list_area(text_area, header_rows) else {
return;
};
let items = picker
.entries
.iter()
.map(|entry| {
let current = if entry.id == picker.current_model_id {
"● "
} else {
" "
};
let mut parts = vec![Span::raw(format!("{current}{}", entry.id))];
if let Some(context) = entry.context_window {
parts.push(Span::raw(format!(" ctx:{context}")));
}
if let Some(name) = &entry.display_name {
parts.push(Span::raw(format!(" {name}")));
}
ListItem::new(Line::from(parts))
})
.collect::<Vec<_>>();
render_picker_list(
frame,
list_area,
items,
picker.selected,
&state.scroll_views.model_picker,
theme,
);
}