Skip to main content

rat_ftable2/selection/
rowselection.rs

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