agent_core_tui/widgets/
mod.rs1use crossterm::event::KeyEvent;
21use ratatui::{layout::Rect, Frame};
22use std::any::Any;
23
24use crate::controller::{AskUserQuestionsResponse, PermissionPanelResponse};
25use crate::permissions::BatchPermissionResponse;
26use crate::keys::NavigationHelper;
27use crate::themes::Theme;
28
29pub mod batch_permission_panel;
30pub mod chat;
31pub mod chat_helpers;
32pub mod conversation;
33pub mod input;
34pub mod permission_panel;
35pub mod question_panel;
36pub mod session_picker;
37pub mod slash_popup;
38pub mod status_bar;
39
40pub use batch_permission_panel::{
41 BatchKeyAction, BatchPermissionOption, BatchPermissionPanel, BatchPermissionPanelConfig,
42};
43pub use chat::{ChatView, ChatViewConfig, MessageRole, ToolMessageData, ToolStatus};
44pub use chat_helpers::RenderFn;
45pub use conversation::{ConversationView, ConversationViewFactory};
46pub use input::TextInput;
47pub use permission_panel::{
48 KeyAction as PermissionKeyAction, PermissionOption, PermissionPanel, PermissionPanelConfig,
49};
50pub use question_panel::{
51 AnswerState, EnterAction, FocusItem, KeyAction as QuestionKeyAction, QuestionPanel,
52 QuestionPanelConfig,
53};
54pub use session_picker::{render_session_picker, SessionInfo, SessionPickerConfig, SessionPickerState};
55pub use slash_popup::{
56 render_slash_popup, SimpleCommand, SlashCommandDisplay, SlashPopupConfig,
57 SlashPopupState,
58};
59pub use status_bar::{StatusBar, StatusBarConfig, StatusBarData};
60
61pub mod widget_ids {
63 pub const CHAT_VIEW: &str = "chat_view";
65 pub const TEXT_INPUT: &str = "text_input";
66
67 pub const BATCH_PERMISSION_PANEL: &str = "batch_permission_panel";
69 pub const PERMISSION_PANEL: &str = "permission_panel";
70 pub const QUESTION_PANEL: &str = "question_panel";
71 pub const SESSION_PICKER: &str = "session_picker";
72 pub const SLASH_POPUP: &str = "slash_popup";
73 pub const THEME_PICKER: &str = "theme_picker";
74 pub const STATUS_BAR: &str = "status_bar";
75}
76
77pub struct WidgetKeyContext<'a> {
82 pub theme: &'a Theme,
84 pub nav: NavigationHelper<'a>,
86}
87
88#[derive(Debug, Clone)]
90pub enum WidgetKeyResult {
91 NotHandled,
93 Handled,
95 Action(WidgetAction),
97}
98
99#[derive(Debug, Clone)]
101pub enum WidgetAction {
102 SubmitQuestion {
104 tool_use_id: String,
105 response: AskUserQuestionsResponse,
106 },
107 CancelQuestion { tool_use_id: String },
109 SubmitPermission {
111 tool_use_id: String,
112 response: PermissionPanelResponse,
113 },
114 CancelPermission { tool_use_id: String },
116 SubmitBatchPermission {
118 batch_id: String,
119 response: BatchPermissionResponse,
120 },
121 CancelBatchPermission { batch_id: String },
123 SwitchSession { session_id: i64 },
125 ExecuteCommand { command: String },
127 Close,
129}
130
131pub trait Widget: Send + 'static {
136 fn id(&self) -> &'static str;
138
139 fn priority(&self) -> u8 {
144 100
145 }
146
147 fn is_active(&self) -> bool;
149
150 fn handle_key(&mut self, key: KeyEvent, ctx: &WidgetKeyContext) -> WidgetKeyResult;
155
156 fn render(&mut self, frame: &mut Frame, area: Rect, theme: &Theme);
158
159 fn required_height(&self, available: u16) -> u16 {
163 let _ = available;
164 0
165 }
166
167 fn blocks_input(&self) -> bool {
169 false
170 }
171
172 fn is_overlay(&self) -> bool {
176 false
177 }
178
179 fn as_any(&self) -> &dyn Any;
181
182 fn as_any_mut(&mut self) -> &mut dyn Any;
184
185 fn into_any(self: Box<Self>) -> Box<dyn Any>;
187}