rat_ftable2/selection/
rowselection.rs1use 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}