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 if !self.has_mouse_focus() {
141 return TableOutcome::Continue;
142 }
143
144 let mut sas = ScrollAreaState::new()
145 .area(self.inner)
146 .h_scroll(&mut self.hscroll)
147 .v_scroll(&mut self.vscroll);
148
149 match sas.handle(event, MouseOnly) {
150 ScrollOutcome::Up(v) => {
151 if self.scroll_up(v) {
152 TableOutcome::Changed
153 } else {
154 TableOutcome::Unchanged
155 }
156 }
157 ScrollOutcome::Down(v) => {
158 if self.scroll_down(v) {
159 TableOutcome::Changed
160 } else {
161 TableOutcome::Unchanged
162 }
163 }
164 ScrollOutcome::VPos(v) => {
165 if self.set_row_offset(v) {
166 TableOutcome::Changed
167 } else {
168 TableOutcome::Unchanged
169 }
170 }
171 ScrollOutcome::Left(v) => {
172 if self.scroll_left(v) {
173 TableOutcome::Changed
174 } else {
175 TableOutcome::Unchanged
176 }
177 }
178 ScrollOutcome::Right(v) => {
179 if self.scroll_right(v) {
180 TableOutcome::Changed
181 } else {
182 TableOutcome::Unchanged
183 }
184 }
185 ScrollOutcome::HPos(v) => {
186 if self.set_x_offset(v) {
187 TableOutcome::Changed
188 } else {
189 TableOutcome::Unchanged
190 }
191 }
192 ScrollOutcome::Continue => TableOutcome::Continue,
193 ScrollOutcome::Unchanged => TableOutcome::Unchanged,
194 ScrollOutcome::Changed => TableOutcome::Changed,
195 }
196 }
197}
198
199pub fn handle_events(
203 state: &mut TableState<NoSelection>,
204 focus: bool,
205 event: &Event,
206) -> TableOutcome {
207 state.focus.set(focus);
208 state.handle(event, Regular)
209}
210
211pub fn handle_mouse_events(state: &mut TableState<NoSelection>, event: &Event) -> TableOutcome {
213 state.handle(event, MouseOnly)
214}