1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! Key handling for the multi-select widget
use crate::event::Key;
use crate::widget::traits::{EventResult, Interactive};
use super::types::MultiSelect;
impl Interactive for MultiSelect {
fn handle_key(&mut self, event: &crate::event::KeyEvent) -> EventResult {
// When closed and Tab pressed, let the focus manager handle navigation
if event.key == Key::Tab && !self.open {
return EventResult::Ignored;
}
let changed = self.handle_key(&event.key);
if changed {
EventResult::ConsumedAndRender
} else {
EventResult::Ignored
}
}
crate::impl_focus_handlers!(state, no_blur);
fn on_blur(&mut self) {
self.state.focused = false;
if self.open {
self.close();
}
}
}
impl MultiSelect {
/// Handle key input, returns true if needs redraw
pub fn handle_key(&mut self, key: &Key) -> bool {
if self.state.disabled {
return false;
}
match key {
// Open/close/select
Key::Enter => {
if self.open {
if let Some(idx) = self.current_option() {
self.toggle_option(idx);
}
} else {
self.open();
}
true
}
Key::Escape => {
if self.open {
self.close();
true
} else if self.tag_cursor.is_some() {
self.tag_cursor = None;
true
} else {
false
}
}
Key::Char(' ') if self.open && !self.searchable => {
if let Some(idx) = self.current_option() {
self.toggle_option(idx);
}
true
}
// Dropdown navigation
Key::Down | Key::Char('j') if self.open => {
self.cursor_down();
true
}
Key::Up | Key::Char('k') if self.open => {
self.cursor_up();
true
}
// Tag navigation
Key::Left if !self.open => {
self.tag_cursor_left();
true
}
Key::Right if !self.open => {
self.tag_cursor_right();
true
}
// Delete tag
Key::Backspace if !self.open => {
if self.tag_cursor.is_some() {
self.remove_tag_at_cursor();
} else if !self.selected.is_empty() {
self.remove_last_tag();
}
true
}
Key::Backspace if self.open && self.searchable => {
self.query.pop();
self.update_filter();
true
}
Key::Delete if !self.open && self.tag_cursor.is_some() => {
self.remove_tag_at_cursor();
true
}
// Search typing
Key::Char(c) if self.open && self.searchable => {
self.query.push(*c);
self.update_filter();
true
}
// Select all
Key::Char('a') if !self.open => {
self.select_all();
true
}
// Clear selection
Key::Char('c') if !self.open => {
self.clear_selection();
true
}
// Close dropdown on Tab when open
Key::Tab if self.open => {
self.close();
true
}
_ => false,
}
}
}