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