Skip to main content

rat_ftable2/selection/
cellselection.rs

1use crate::event::TableOutcome;
2use crate::table::TableState;
3use rat_event::{ConsumedEvent, HandleEvent, MouseOnly, Regular, ct_event};
4use rat_focus::HasFocus;
5use rat_ftable::selection::CellSelection;
6use rat_scrolled::ScrollAreaState;
7use rat_scrolled::event::ScrollOutcome;
8use ratatui_crossterm::crossterm::event::Event;
9use std::cmp::max;
10
11impl HandleEvent<Event, Regular, TableOutcome> for TableState<CellSelection> {
12    fn handle(&mut self, event: &Event, _keymap: Regular) -> TableOutcome {
13        let res = if self.is_focused() {
14            match event {
15                ct_event!(keycode press Up) => {
16                    if self.move_up(1) {
17                        TableOutcome::Selected
18                    } else {
19                        TableOutcome::Unchanged
20                    }
21                }
22                ct_event!(keycode press Down) => {
23                    if self.move_down(1) {
24                        TableOutcome::Selected
25                    } else {
26                        TableOutcome::Unchanged
27                    }
28                }
29                ct_event!(keycode press CONTROL-Up) | ct_event!(keycode press CONTROL-Home) => {
30                    if self.move_to_row(0) {
31                        TableOutcome::Selected
32                    } else {
33                        TableOutcome::Unchanged
34                    }
35                }
36                ct_event!(keycode press CONTROL-Down) | ct_event!(keycode press CONTROL-End) => {
37                    if self.move_to_row(self.rows.saturating_sub(1)) {
38                        TableOutcome::Selected
39                    } else {
40                        TableOutcome::Unchanged
41                    }
42                }
43
44                ct_event!(keycode press PageUp) => {
45                    if self.move_up(max(1, self.page_len().saturating_sub(1))) {
46                        TableOutcome::Selected
47                    } else {
48                        TableOutcome::Unchanged
49                    }
50                }
51                ct_event!(keycode press PageDown) => {
52                    if self.move_down(max(1, self.page_len().saturating_sub(1))) {
53                        TableOutcome::Selected
54                    } else {
55                        TableOutcome::Unchanged
56                    }
57                }
58
59                ct_event!(keycode press Left) => {
60                    if self.move_left(1) {
61                        TableOutcome::Selected
62                    } else {
63                        TableOutcome::Unchanged
64                    }
65                }
66                ct_event!(keycode press Right) => {
67                    if self.move_right(1) {
68                        TableOutcome::Selected
69                    } else {
70                        TableOutcome::Unchanged
71                    }
72                }
73                ct_event!(keycode press CONTROL-Left) | ct_event!(keycode press Home) => {
74                    if self.move_to_col(0) {
75                        TableOutcome::Selected
76                    } else {
77                        TableOutcome::Unchanged
78                    }
79                }
80                ct_event!(keycode press CONTROL-Right) | ct_event!(keycode press End) => {
81                    if self.move_to_col(self.columns.saturating_sub(1)) {
82                        TableOutcome::Selected
83                    } else {
84                        TableOutcome::Unchanged
85                    }
86                }
87
88                _ => TableOutcome::Continue,
89            }
90        } else {
91            TableOutcome::Continue
92        };
93
94        if res == TableOutcome::Continue {
95            self.handle(event, MouseOnly)
96        } else {
97            res
98        }
99    }
100}
101
102impl HandleEvent<Event, MouseOnly, TableOutcome> for TableState<CellSelection> {
103    fn handle(&mut self, event: &Event, _keymap: MouseOnly) -> TableOutcome {
104        if self.is_obscured() {
105            return TableOutcome::Continue;
106        }
107
108        let mut r = match event {
109            ct_event!(mouse any for m) if self.mouse.drag(self.table_area, m) => {
110                if self.move_to(self.cell_at_drag((m.column, m.row))) {
111                    TableOutcome::Selected
112                } else {
113                    TableOutcome::Unchanged
114                }
115            }
116            ct_event!(mouse down Left for column, row) => {
117                if self.area.contains((*column, *row).into()) {
118                    if let Some(new_cell) = self.cell_at_clicked((*column, *row)) {
119                        if self.move_to(new_cell) {
120                            TableOutcome::Selected
121                        } else {
122                            TableOutcome::Unchanged
123                        }
124                    } else {
125                        TableOutcome::Continue
126                    }
127                } else if self.header_area.contains((*column, *row).into()) {
128                    if let Some(col) = self.column_at_clicked((*column, *row)) {
129                        TableOutcome::Header(col)
130                    } else {
131                        TableOutcome::Continue
132                    }
133                } else if self.footer_area.contains((*column, *row).into()) {
134                    if let Some(col) = self.column_at_clicked((*column, *row)) {
135                        TableOutcome::Footer(col)
136                    } else {
137                        TableOutcome::Continue
138                    }
139                } else {
140                    TableOutcome::Continue
141                }
142            }
143            _ => TableOutcome::Continue,
144        };
145
146        r = r.or_else(|| {
147            let mut sas = ScrollAreaState::new()
148                .area(self.inner)
149                .h_scroll(&mut self.hscroll)
150                .v_scroll(&mut self.vscroll);
151            match sas.handle(event, MouseOnly) {
152                ScrollOutcome::Up(v) => {
153                    if self.scroll_up(v) {
154                        TableOutcome::Changed
155                    } else {
156                        TableOutcome::Unchanged
157                    }
158                }
159                ScrollOutcome::Down(v) => {
160                    if self.scroll_down(v) {
161                        TableOutcome::Changed
162                    } else {
163                        TableOutcome::Unchanged
164                    }
165                }
166                ScrollOutcome::VPos(v) => {
167                    if self.set_row_offset(self.vscroll.limited_offset(v)) {
168                        TableOutcome::Changed
169                    } else {
170                        TableOutcome::Unchanged
171                    }
172                }
173                ScrollOutcome::Left(v) => {
174                    if self.scroll_left(v) {
175                        TableOutcome::Changed
176                    } else {
177                        TableOutcome::Unchanged
178                    }
179                }
180                ScrollOutcome::Right(v) => {
181                    if self.scroll_right(v) {
182                        TableOutcome::Changed
183                    } else {
184                        TableOutcome::Unchanged
185                    }
186                }
187                ScrollOutcome::HPos(v) => {
188                    if self.set_x_offset(self.hscroll.limited_offset(v)) {
189                        TableOutcome::Changed
190                    } else {
191                        TableOutcome::Unchanged
192                    }
193                }
194                ScrollOutcome::Continue => TableOutcome::Continue,
195                ScrollOutcome::Unchanged => TableOutcome::Unchanged,
196                ScrollOutcome::Changed => TableOutcome::Changed,
197            }
198        });
199        r
200    }
201}