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
use std::io;
use textwrap::{core::Fragment, word_separators::WordSeparator};
use crate::{backend::Backend, events::KeyEvent, layout::Layout};
pub use crate::char_input::CharInput;
pub use crate::prompt::{Delimiter, Prompt};
pub use crate::select::{List, Select};
pub use crate::string_input::StringInput;
pub use crate::text::Text;
pub type FilterMapChar = fn(char) -> Option<char>;
pub(crate) fn no_filter(c: char) -> Option<char> {
Some(c)
}
pub trait Widget {
fn render<B: Backend>(&mut self, layout: &mut Layout, backend: &mut B) -> io::Result<()>;
fn height(&mut self, layout: &mut Layout) -> u16;
fn cursor_pos(&mut self, layout: Layout) -> (u16, u16);
fn handle_key(&mut self, key: KeyEvent) -> bool;
}
impl<T: std::ops::Deref<Target = str>> Widget for T {
fn render<B: Backend>(&mut self, layout: &mut Layout, backend: &mut B) -> io::Result<()> {
let max_width = layout.line_width() as usize;
layout.offset_y += 1;
layout.line_offset = 0;
if max_width <= 3 {
for _ in 0..max_width {
backend.write_all(b".")?;
}
} else if textwrap::core::display_width(self) > max_width {
let mut width = 0;
let mut prev_whitespace_len = 0;
let max_width = max_width - 3;
for word in textwrap::word_separators::UnicodeBreakProperties.find_words(self) {
width += word.width() + prev_whitespace_len;
if width > max_width {
break;
}
for _ in 0..prev_whitespace_len {
backend.write_all(b" ")?;
}
backend.write_all(word.as_bytes())?;
prev_whitespace_len = word.whitespace_width();
}
backend.write_all(b"...")?;
} else {
backend.write_all(self.as_bytes())?;
}
backend
.move_cursor_to(layout.offset_x, layout.offset_y)
.map_err(Into::into)
}
fn height(&mut self, layout: &mut Layout) -> u16 {
layout.offset_y += 1;
layout.line_offset = 0;
1
}
fn cursor_pos(&mut self, layout: Layout) -> (u16, u16) {
(layout.line_offset, 0)
}
fn handle_key(&mut self, _: crate::events::KeyEvent) -> bool {
false
}
}