rat_ftable/
noselection.rs1use crate::event::TableOutcome;
2use crate::{TableSelection, TableState};
3use rat_event::{HandleEvent, MouseOnly, Regular, ct_event};
4use rat_focus::HasFocus;
5use rat_scrolled::ScrollAreaState;
6use rat_scrolled::event::ScrollOutcome;
7use ratatui_crossterm::crossterm::event::Event;
8use std::cmp::max;
9
10#[derive(Debug, Default, Clone)]
14pub struct NoSelection;
15
16impl TableSelection for NoSelection {
17 fn count(&self) -> usize {
18 0
19 }
20
21 fn is_selected_row(&self, _row: usize) -> bool {
22 false
23 }
24
25 fn is_selected_column(&self, _column: usize) -> bool {
26 false
27 }
28
29 fn is_selected_cell(&self, _column: usize, _row: usize) -> bool {
30 false
31 }
32
33 fn lead_selection(&self) -> Option<(usize, usize)> {
34 None
35 }
36
37 fn validate_rows(&mut self, _rows: usize) {}
38
39 fn validate_cols(&mut self, _cols: usize) {}
40
41 fn items_added(&mut self, _pos: usize, _n: usize) {}
42
43 fn items_removed(&mut self, _pos: usize, _n: usize, _rows: usize) {}
44}
45
46impl HandleEvent<Event, Regular, TableOutcome> for TableState<NoSelection> {
47 fn handle(&mut self, event: &Event, _keymap: Regular) -> TableOutcome {
48 let res = if self.is_focused() {
49 match event {
50 ct_event!(keycode press Up) => {
51 if self.scroll_up(1) {
52 TableOutcome::Changed
53 } else {
54 TableOutcome::Unchanged
55 }
56 }
57 ct_event!(keycode press Down) => {
58 if self.scroll_down(1) {
59 TableOutcome::Changed
60 } else {
61 TableOutcome::Unchanged
62 }
63 }
64 ct_event!(keycode press CONTROL-Up)
65 | ct_event!(keycode press CONTROL-Home)
66 | ct_event!(keycode press Home) => {
67 if self.scroll_to_row(0) {
68 TableOutcome::Changed
69 } else {
70 TableOutcome::Unchanged
71 }
72 }
73 ct_event!(keycode press CONTROL-Down)
74 | ct_event!(keycode press CONTROL-End)
75 | ct_event!(keycode press End) => {
76 if self.scroll_to_row(self.rows.saturating_sub(1)) {
77 TableOutcome::Changed
78 } else {
79 TableOutcome::Unchanged
80 }
81 }
82 ct_event!(keycode press PageUp) => {
83 if self.scroll_up(max(1, self.page_len().saturating_sub(1))) {
84 TableOutcome::Changed
85 } else {
86 TableOutcome::Unchanged
87 }
88 }
89 ct_event!(keycode press PageDown) => {
90 if self.scroll_down(max(1, self.page_len().saturating_sub(1))) {
91 TableOutcome::Changed
92 } else {
93 TableOutcome::Unchanged
94 }
95 }
96 ct_event!(keycode press Left) => {
97 if self.scroll_left(1) {
98 TableOutcome::Changed
99 } else {
100 TableOutcome::Unchanged
101 }
102 }
103 ct_event!(keycode press Right) => {
104 if self.scroll_right(1) {
105 TableOutcome::Changed
106 } else {
107 TableOutcome::Unchanged
108 }
109 }
110 ct_event!(keycode press CONTROL-Left) => {
111 if self.scroll_to_x(0) {
112 TableOutcome::Changed
113 } else {
114 TableOutcome::Unchanged
115 }
116 }
117 ct_event!(keycode press CONTROL-Right) => {
118 if self.scroll_to_x(self.x_max_offset()) {
119 TableOutcome::Changed
120 } else {
121 TableOutcome::Unchanged
122 }
123 }
124 _ => TableOutcome::Continue,
125 }
126 } else {
127 TableOutcome::Continue
128 };
129
130 if res == TableOutcome::Continue {
131 self.handle(event, MouseOnly)
132 } else {
133 res
134 }
135 }
136}
137
138impl HandleEvent<Event, MouseOnly, TableOutcome> for TableState<NoSelection> {
139 fn handle(&mut self, event: &Event, _keymap: MouseOnly) -> TableOutcome {
140 let mut sas = ScrollAreaState::new()
141 .area(self.inner)
142 .h_scroll(&mut self.hscroll)
143 .v_scroll(&mut self.vscroll);
144
145 match sas.handle(event, MouseOnly) {
146 ScrollOutcome::Up(v) => {
147 if self.scroll_up(v) {
148 TableOutcome::Changed
149 } else {
150 TableOutcome::Unchanged
151 }
152 }
153 ScrollOutcome::Down(v) => {
154 if self.scroll_down(v) {
155 TableOutcome::Changed
156 } else {
157 TableOutcome::Unchanged
158 }
159 }
160 ScrollOutcome::VPos(v) => {
161 if self.set_row_offset(v) {
162 TableOutcome::Changed
163 } else {
164 TableOutcome::Unchanged
165 }
166 }
167 ScrollOutcome::Left(v) => {
168 if self.scroll_left(v) {
169 TableOutcome::Changed
170 } else {
171 TableOutcome::Unchanged
172 }
173 }
174 ScrollOutcome::Right(v) => {
175 if self.scroll_right(v) {
176 TableOutcome::Changed
177 } else {
178 TableOutcome::Unchanged
179 }
180 }
181 ScrollOutcome::HPos(v) => {
182 if self.set_x_offset(v) {
183 TableOutcome::Changed
184 } else {
185 TableOutcome::Unchanged
186 }
187 }
188 ScrollOutcome::Continue => TableOutcome::Continue,
189 ScrollOutcome::Unchanged => TableOutcome::Unchanged,
190 ScrollOutcome::Changed => TableOutcome::Changed,
191 }
192 }
193}
194
195pub fn handle_events(
199 state: &mut TableState<NoSelection>,
200 focus: bool,
201 event: &Event,
202) -> TableOutcome {
203 state.focus.set(focus);
204 state.handle(event, Regular)
205}
206
207pub fn handle_mouse_events(state: &mut TableState<NoSelection>, event: &Event) -> TableOutcome {
209 state.handle(event, MouseOnly)
210}