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
38impl HandleEvent<Event, Regular, TableOutcome> for TableState<NoSelection> {
39 fn handle(&mut self, event: &Event, _keymap: Regular) -> TableOutcome {
40 let res = if self.is_focused() {
41 match event {
42 ct_event!(keycode press Up) => {
43 if self.scroll_up(1) {
44 TableOutcome::Changed
45 } else {
46 TableOutcome::Unchanged
47 }
48 }
49 ct_event!(keycode press Down) => {
50 if self.scroll_down(1) {
51 TableOutcome::Changed
52 } else {
53 TableOutcome::Unchanged
54 }
55 }
56 ct_event!(keycode press CONTROL-Up)
57 | ct_event!(keycode press CONTROL-Home)
58 | ct_event!(keycode press Home) => {
59 if self.scroll_to_row(0) {
60 TableOutcome::Changed
61 } else {
62 TableOutcome::Unchanged
63 }
64 }
65 ct_event!(keycode press CONTROL-Down)
66 | ct_event!(keycode press CONTROL-End)
67 | ct_event!(keycode press End) => {
68 if self.scroll_to_row(self.rows.saturating_sub(1)) {
69 TableOutcome::Changed
70 } else {
71 TableOutcome::Unchanged
72 }
73 }
74 ct_event!(keycode press PageUp) => {
75 if self.scroll_up(max(1, self.page_len().saturating_sub(1))) {
76 TableOutcome::Changed
77 } else {
78 TableOutcome::Unchanged
79 }
80 }
81 ct_event!(keycode press PageDown) => {
82 if self.scroll_down(max(1, self.page_len().saturating_sub(1))) {
83 TableOutcome::Changed
84 } else {
85 TableOutcome::Unchanged
86 }
87 }
88 ct_event!(keycode press Left) => {
89 if self.scroll_left(1) {
90 TableOutcome::Changed
91 } else {
92 TableOutcome::Unchanged
93 }
94 }
95 ct_event!(keycode press Right) => {
96 if self.scroll_right(1) {
97 TableOutcome::Changed
98 } else {
99 TableOutcome::Unchanged
100 }
101 }
102 ct_event!(keycode press CONTROL-Left) => {
103 if self.scroll_to_x(0) {
104 TableOutcome::Changed
105 } else {
106 TableOutcome::Unchanged
107 }
108 }
109 ct_event!(keycode press CONTROL-Right) => {
110 if self.scroll_to_x(self.x_max_offset()) {
111 TableOutcome::Changed
112 } else {
113 TableOutcome::Unchanged
114 }
115 }
116 _ => TableOutcome::Continue,
117 }
118 } else {
119 TableOutcome::Continue
120 };
121
122 if res == TableOutcome::Continue {
123 self.handle(event, MouseOnly)
124 } else {
125 res
126 }
127 }
128}
129
130impl HandleEvent<Event, MouseOnly, TableOutcome> for TableState<NoSelection> {
131 fn handle(&mut self, event: &Event, _keymap: MouseOnly) -> TableOutcome {
132 let mut sas = ScrollAreaState::new()
133 .area(self.inner)
134 .h_scroll(&mut self.hscroll)
135 .v_scroll(&mut self.vscroll);
136
137 match sas.handle(event, MouseOnly) {
138 ScrollOutcome::Up(v) => {
139 if self.scroll_up(v) {
140 TableOutcome::Changed
141 } else {
142 TableOutcome::Unchanged
143 }
144 }
145 ScrollOutcome::Down(v) => {
146 if self.scroll_down(v) {
147 TableOutcome::Changed
148 } else {
149 TableOutcome::Unchanged
150 }
151 }
152 ScrollOutcome::VPos(v) => {
153 if self.set_row_offset(v) {
154 TableOutcome::Changed
155 } else {
156 TableOutcome::Unchanged
157 }
158 }
159 ScrollOutcome::Left(v) => {
160 if self.scroll_left(v) {
161 TableOutcome::Changed
162 } else {
163 TableOutcome::Unchanged
164 }
165 }
166 ScrollOutcome::Right(v) => {
167 if self.scroll_right(v) {
168 TableOutcome::Changed
169 } else {
170 TableOutcome::Unchanged
171 }
172 }
173 ScrollOutcome::HPos(v) => {
174 if self.set_x_offset(v) {
175 TableOutcome::Changed
176 } else {
177 TableOutcome::Unchanged
178 }
179 }
180 ScrollOutcome::Continue => TableOutcome::Continue,
181 ScrollOutcome::Unchanged => TableOutcome::Unchanged,
182 ScrollOutcome::Changed => TableOutcome::Changed,
183 }
184 }
185}
186
187pub fn handle_events(
191 state: &mut TableState<NoSelection>,
192 focus: bool,
193 event: &Event,
194) -> TableOutcome {
195 state.focus.set(focus);
196 state.handle(event, Regular)
197}
198
199pub fn handle_mouse_events(state: &mut TableState<NoSelection>, event: &Event) -> TableOutcome {
201 state.handle(event, MouseOnly)
202}