1use ratatui::layout::Rect;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum HitTarget {
13 Cards,
15 CardRow {
18 row: usize,
19 col: usize,
20 },
21 Stream,
23 StreamRow(u64),
25 ChatInput,
26 StatusSegment(SegmentId),
28 ModalBody,
31 ModalRow(usize),
32 ModalButton(ModalButtonId),
33 ModalActionButton(ModalAction),
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub enum SegmentId {
39 Instances,
40 Waiting,
41 Model,
42 Backend,
43 LogLevel,
44 WebSearch,
45 Handler,
46 Scripting,
47 Usage,
48 Help,
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum ModalButtonId {
53 Confirm,
54 Cancel,
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60pub enum ModalAction {
61 RoutingAdd,
62 RoutingEdit,
63 RoutingDelete,
64 RoutingMoveUp,
65 RoutingMoveDown,
66 RoutingSave,
67 RoutingCancel,
68 DraftSave,
69 DraftCancel,
70 DraftKind(crate::tui::modal::routing::HandlerKind),
72 FormApply,
73 FormCancel,
74 FormWireshark,
77 InterceptCompose,
80 InterceptSend,
82 InterceptDismiss,
84 ComposerSend,
86 ComposerRaw,
88 ComposerBack,
90 EditorAccept,
92 EditorCancel,
94 ConfirmYes,
96 ConfirmNo,
97}
98
99impl ModalAction {
100 pub fn label(&self) -> &'static str {
101 match self {
102 ModalAction::RoutingAdd => "[ Add ]",
103 ModalAction::RoutingEdit => "[ Edit ]",
104 ModalAction::RoutingDelete => "[ Delete ]",
105 ModalAction::RoutingMoveUp => "[ Move up ]",
106 ModalAction::RoutingMoveDown => "[ Move down ]",
107 ModalAction::RoutingSave => "[ Save ]",
108 ModalAction::RoutingCancel => "[ Cancel ]",
109 ModalAction::DraftSave => "[ Save response ]",
110 ModalAction::DraftCancel => "[ Cancel ]",
111 ModalAction::DraftKind(kind) => kind.label(),
112 ModalAction::FormApply => "[ Apply ]",
113 ModalAction::FormCancel => "[ Cancel ]",
114 ModalAction::FormWireshark => "[ View in Wireshark ]",
115 ModalAction::InterceptCompose => "[ Compose answer… ]",
116 ModalAction::InterceptSend => "[ Answer with nothing ]",
117 ModalAction::InterceptDismiss => "[ Fail closed ]",
118 ModalAction::ComposerSend => "[ Send ]",
119 ModalAction::ComposerRaw => "[ Raw JSON ]",
120 ModalAction::ComposerBack => "[ Back ]",
121 ModalAction::EditorAccept => "[ Accept ]",
122 ModalAction::EditorCancel => "[ Cancel ]",
123 ModalAction::ConfirmYes => "[ Yes ]",
124 ModalAction::ConfirmNo => "[ No ]",
125 }
126 }
127}
128
129#[derive(Default)]
131pub struct HitRegistry {
132 regions: Vec<(Rect, HitTarget)>,
133}
134
135impl HitRegistry {
136 pub fn clear(&mut self) {
137 self.regions.clear();
138 }
139
140 pub fn push(&mut self, area: Rect, target: HitTarget) {
141 self.regions.push((area, target));
142 }
143
144 pub fn hit(&self, column: u16, row: u16) -> Option<&HitTarget> {
146 self.regions
147 .iter()
148 .rev()
149 .find(|(rect, _)| {
150 column >= rect.x
151 && column < rect.x.saturating_add(rect.width)
152 && row >= rect.y
153 && row < rect.y.saturating_add(rect.height)
154 })
155 .map(|(_, target)| target)
156 }
157}