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