Render the agent selector popup as an overlay
(&mut self, frame: &mut Frame, area: Rect, theme: &Theme)
| 105 | |
| 106 | /// Render the agent selector popup as an overlay |
| 107 | pub fn render(&mut self, frame: &mut Frame, area: Rect, theme: &Theme) { |
| 108 | if !self.visible || self.items.is_empty() { |
| 109 | self.last_area = None; |
| 110 | return; |
| 111 | } |
| 112 | |
| 113 | let popup_width = area.width.saturating_sub(4).min(60); |
| 114 | let popup_height = (self.items.len() as u16 + 4).min(area.height.saturating_sub(2)); |
| 115 | if popup_height < 5 || popup_width < 20 { |
| 116 | self.last_area = None; |
| 117 | return; |
| 118 | } |
| 119 | |
| 120 | let popup_x = area.x + (area.width.saturating_sub(popup_width)) / 2; |
| 121 | let popup_y = area.y + (area.height.saturating_sub(popup_height)) / 2; |
| 122 | |
| 123 | let popup_area = Rect { |
| 124 | x: popup_x, |
| 125 | y: popup_y, |
| 126 | width: popup_width, |
| 127 | height: popup_height, |
| 128 | }; |
| 129 | self.last_area = Some(popup_area); |
| 130 | |
| 131 | let list_items: Vec<ListItem> = self |
| 132 | .items |
| 133 | .iter() |
| 134 | .map(|agent| { |
| 135 | let is_current = self |
| 136 | .current_agent_id |
| 137 | .as_ref() |
| 138 | .map_or(false, |id| id == &agent.id); |
| 139 | |
| 140 | let marker = if is_current { "● " } else { " " }; |
| 141 | let marker_style = if is_current { |
| 142 | theme.style(StyleKind::Success) |
| 143 | } else { |
| 144 | theme.style(StyleKind::Muted) |
| 145 | }; |
| 146 | |
| 147 | let name_style = theme.style(StyleKind::Primary).add_modifier(Modifier::BOLD); |
| 148 | let desc_style = theme.style(StyleKind::Muted); |
| 149 | |
| 150 | let line = Line::from(vec![ |
| 151 | Span::styled(marker, marker_style), |
| 152 | Span::styled(&agent.id, name_style), |
| 153 | Span::raw(" "), |
| 154 | Span::styled(&agent.description, desc_style), |
| 155 | ]); |
| 156 | ListItem::new(line) |
| 157 | }) |
| 158 | .collect(); |
| 159 | |
| 160 | let block = Block::default() |
| 161 | .borders(Borders::ALL) |
| 162 | .border_style(theme.style(StyleKind::Primary)) |
| 163 | .style(Style::default().bg(theme.background)) |
| 164 | .title(" Select Agent (↑↓ Navigate, Enter Select, Esc Cancel) "); |