Skip to main content

rat_ftable2/selection/
rowsetselection.rs

1use crate::TableSelection;
2use crate::event::TableOutcome;
3use crate::table::TableState;
4use rat_event::{HandleEvent, MouseOnly, Regular, ct_event, flow};
5use rat_focus::HasFocus;
6use rat_ftable::selection::RowSetSelection;
7use rat_scrolled::ScrollAreaState;
8use rat_scrolled::event::ScrollOutcome;
9use ratatui_crossterm::crossterm::event::{Event, KeyModifiers};
10use std::cmp::max;
11
12impl HandleEvent<Event, Regular, TableOutcome> for TableState<RowSetSelection> {
13    fn handle(&mut self, event: &Event, _: Regular) -> TableOutcome {
14        let res = if self.is_focused() {
15            match event {
16                ct_event!(keycode press Up) => {
17                    if self.move_up(1, false) {
18                        TableOutcome::Selected
19                    } else {
20                        TableOutcome::Unchanged
21                    }
22                }
23                ct_event!(keycode press Down) => {
24                    if self.move_down(1, false) {
25                        TableOutcome::Selected
26                    } else {
27                        TableOutcome::Unchanged
28                    }
29                }
30                ct_event!(keycode press CONTROL-Up)
31                | ct_event!(keycode press CONTROL-Home)
32                | ct_event!(keycode press Home) => {
33                    if self.move_to(0, false) {
34                        TableOutcome::Selected
35                    } else {
36                        TableOutcome::Unchanged
37                    }
38                }
39                ct_event!(keycode press CONTROL-Down)
40                | ct_event!(keycode press CONTROL-End)
41                | ct_event!(keycode press End) => {
42                    if self.move_to(self.rows.saturating_sub(1), false) {
43                        TableOutcome::Selected
44                    } else {
45                        TableOutcome::Unchanged
46                    }
47                }
48                ct_event!(keycode press PageUp) => {
49                    if self.move_up(max(1, self.page_len().saturating_sub(1)), false) {
50                        TableOutcome::Selected
51                    } else {
52                        TableOutcome::Unchanged
53                    }
54                }
55                ct_event!(keycode press PageDown) => {
56                    if self.move_down(max(1, self.page_len().saturating_sub(1)), false) {
57                        TableOutcome::Selected
58                    } else {
59                        TableOutcome::Unchanged
60                    }
61                }
62                ct_event!(keycode press SHIFT-Up) => {
63                    if self.move_up(1, true) {
64                        TableOutcome::Selected
65                    } else {
66                        TableOutcome::Unchanged
67                    }
68                }
69                ct_event!(keycode press SHIFT-Down) => {
70                    if self.move_down(1, true) {
71                        TableOutcome::Selected
72                    } else {
73                        TableOutcome::Unchanged
74                    }
75                }
76                ct_event!(keycode press CONTROL_SHIFT-Up)
77                | ct_event!(keycode press CONTROL_SHIFT-Home)
78                | ct_event!(keycode press SHIFT-Home) => {
79                    if self.move_to(0, true) {
80                        TableOutcome::Selected
81                    } else {
82                        TableOutcome::Unchanged
83                    }
84                }
85                ct_event!(keycode press CONTROL_SHIFT-Down)
86                | ct_event!(keycode press CONTROL_SHIFT-End)
87                | ct_event!(keycode press SHIFT-End) => {
88                    if self.move_to(self.rows.saturating_sub(1), true) {
89                        TableOutcome::Selected
90                    } else {
91                        TableOutcome::Unchanged
92                    }
93                }
94                ct_event!(keycode press SHIFT-PageUp) => {
95                    if self.move_up(max(1, self.page_len().saturating_sub(1)), true) {
96                        TableOutcome::Selected
97                    } else {
98                        TableOutcome::Unchanged
99                    }
100                }
101                ct_event!(keycode press SHIFT-PageDown) => {
102                    if self.move_down(max(1, self.page_len().saturating_sub(1)), true) {
103                        TableOutcome::Selected
104                    } else {
105                        TableOutcome::Unchanged
106                    }
107                }
108                ct_event!(keycode press Left) => {
109                    if self.scroll_left(1) {
110                        TableOutcome::Changed
111                    } else {
112                        TableOutcome::Unchanged
113                    }
114                }
115                ct_event!(keycode press Right) => {
116                    if self.scroll_right(1) {
117                        TableOutcome::Changed
118                    } else {
119                        TableOutcome::Unchanged
120                    }
121                }
122                ct_event!(keycode press CONTROL-Left) => {
123                    if self.scroll_to_x(0) {
124                        TableOutcome::Changed
125                    } else {
126                        TableOutcome::Unchanged
127                    }
128                }
129                ct_event!(keycode press CONTROL-Right) => {
130                    if self.scroll_to_x(self.x_max_offset()) {
131                        TableOutcome::Changed
132                    } else {
133                        TableOutcome::Unchanged
134                    }
135                }
136                _ => TableOutcome::Continue,
137            }
138        } else {
139            TableOutcome::Continue
140        };
141
142        if res == TableOutcome::Continue {
143            self.handle(event, MouseOnly)
144        } else {
145            res
146        }
147    }
148}
149
150impl HandleEvent<Event, MouseOnly, TableOutcome> for TableState<RowSetSelection> {
151    fn handle(&mut self, event: &Event, _: MouseOnly) -> TableOutcome {
152        if self.is_obscured() {
153            return TableOutcome::Continue;
154        }
155
156        flow!(match event {
157            ct_event!(mouse any for m) | ct_event!(mouse any CONTROL for m)
158                if self.mouse.drag(self.table_area, m)
159                    || self.mouse.drag2(self.table_area, m, KeyModifiers::CONTROL) =>
160            {
161                if self.move_to(self.row_at_drag((m.column, m.row)), true) {
162                    TableOutcome::Selected
163                } else {
164                    TableOutcome::Unchanged
165                }
166            }
167            ct_event!(mouse down Left for column, row) => {
168                let pos = (*column, *row);
169                if self.table_area.contains(pos.into()) {
170                    if let Some(new_row) = self.row_at_clicked(pos) {
171                        if self.move_to(new_row, false) {
172                            TableOutcome::Selected
173                        } else {
174                            TableOutcome::Unchanged
175                        }
176                    } else {
177                        TableOutcome::Continue
178                    }
179                } else if self.header_area.contains((*column, *row).into()) {
180                    if let Some(col) = self.column_at_clicked((*column, *row)) {
181                        TableOutcome::Header(col)
182                    } else {
183                        TableOutcome::Continue
184                    }
185                } else if self.footer_area.contains((*column, *row).into()) {
186                    if let Some(col) = self.column_at_clicked((*column, *row)) {
187                        TableOutcome::Footer(col)
188                    } else {
189                        TableOutcome::Continue
190                    }
191                } else {
192                    TableOutcome::Continue
193                }
194            }
195            ct_event!(mouse down ALT-Left for column, row) => {
196                let pos = (*column, *row);
197                if self.area.contains(pos.into()) {
198                    if let Some(new_row) = self.row_at_clicked(pos) {
199                        if self.move_to(new_row, true) {
200                            TableOutcome::Selected
201                        } else {
202                            TableOutcome::Unchanged
203                        }
204                    } else {
205                        TableOutcome::Continue
206                    }
207                } else {
208                    TableOutcome::Continue
209                }
210            }
211            ct_event!(mouse down CONTROL-Left for column, row) => {
212                let pos = (*column, *row);
213                if self.area.contains(pos.into()) {
214                    if let Some(new_row) = self.row_at_clicked(pos) {
215                        self.retire_selection();
216                        if self.selection.is_selected_row(new_row) {
217                            self.selection.remove(new_row);
218                        } else {
219                            self.move_to(new_row, true);
220                        }
221                        TableOutcome::Selected
222                    } else {
223                        TableOutcome::Continue
224                    }
225                } else {
226                    TableOutcome::Continue
227                }
228            }
229            _ => TableOutcome::Continue,
230        });
231
232        let mut sas = ScrollAreaState::new()
233            .area(self.inner)
234            .h_scroll(&mut self.hscroll)
235            .v_scroll(&mut self.vscroll);
236
237        match sas.handle(event, MouseOnly) {
238            ScrollOutcome::Up(v) => {
239                if self.scroll_up(v) {
240                    TableOutcome::Changed
241                } else {
242                    TableOutcome::Unchanged
243                }
244            }
245            ScrollOutcome::Down(v) => {
246                if self.scroll_down(v) {
247                    TableOutcome::Changed
248                } else {
249                    TableOutcome::Unchanged
250                }
251            }
252            ScrollOutcome::VPos(v) => {
253                if self.set_row_offset(self.vscroll.limited_offset(v)) {
254                    TableOutcome::Changed
255                } else {
256                    TableOutcome::Unchanged
257                }
258            }
259            ScrollOutcome::Left(v) => {
260                if self.scroll_left(v) {
261                    TableOutcome::Changed
262                } else {
263                    TableOutcome::Unchanged
264                }
265            }
266            ScrollOutcome::Right(v) => {
267                if self.scroll_right(v) {
268                    TableOutcome::Changed
269                } else {
270                    TableOutcome::Unchanged
271                }
272            }
273            ScrollOutcome::HPos(v) => {
274                if self.set_x_offset(self.hscroll.limited_offset(v)) {
275                    TableOutcome::Changed
276                } else {
277                    TableOutcome::Unchanged
278                }
279            }
280
281            ScrollOutcome::Continue => TableOutcome::Continue,
282            ScrollOutcome::Unchanged => TableOutcome::Unchanged,
283            ScrollOutcome::Changed => TableOutcome::Changed,
284        }
285    }
286}