/
text_callbacks.rs
138 lines (111 loc) · 5.74 KB
/
text_callbacks.rs
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
use imgui::*;
mod support;
fn main() {
let system = support::init(file!());
let mut buffers = vec![String::default(), String::default(), String::default()];
system.main_loop(move |_, ui| {
ui.window("Input text callbacks")
.size([500.0, 300.0], Condition::FirstUseEver)
.build(|| {
ui.text("You can make a variety of buffer callbacks on an Input Text");
ui.text(
"or on an InputTextMultiline. In this example, we'll use \
InputText primarily.",
);
ui.text(
"The only difference is that InputTextMultiline doesn't get \
the `History` callback,",
);
ui.text("since, of course, you need the up/down keys to navigate.");
ui.separator();
ui.text("No callbacks:");
ui.input_text("buf0", &mut buffers[0]).build();
ui.input_text("buf1", &mut buffers[1]).build();
ui.input_text("buf2", &mut buffers[2]).build();
ui.separator();
ui.text("Here's a callback which printlns when each is ran.");
struct AllCallback;
impl InputTextCallbackHandler for AllCallback {
fn char_filter(&mut self, c: char) -> Option<char> {
println!("Char filter fired! This means a char was inputted.");
Some(c)
}
fn on_completion(&mut self, _: TextCallbackData) {
println!("Completion request fired! This means the tab key was hit.");
}
fn on_edit(&mut self, _: TextCallbackData) {
println!("Edit was fired! Any edit will cause this to fire.")
}
fn on_history(&mut self, dir: HistoryDirection, _: TextCallbackData) {
println!("History was fired by pressing {:?}", dir);
}
fn on_always(&mut self, _: TextCallbackData) {
// We don't actually print this out because it will flood your log a lot!
// println!("The always callback fired! It always fires.");
}
}
ui.input_text("All Callbacks logging", buffers.get_mut(0).unwrap())
.callback(InputTextCallback::all(), AllCallback)
.build();
ui.separator();
ui.text("You can also define a callback on structs with data.");
ui.text("Here we implement the callback handler on a wrapper around &mut String");
ui.text("to duplicate edits to buf0 on buf1");
struct Wrapper<'a>(&'a mut String);
impl<'a> InputTextCallbackHandler for Wrapper<'a> {
fn on_always(&mut self, data: TextCallbackData) {
*self.0 = data.str().to_owned();
}
}
let (buf0, brwchk_dance) = buffers.split_first_mut().unwrap();
let buf1 = Wrapper(&mut brwchk_dance[0]);
ui.input_text("Edits copied to buf1", buf0)
.callback(InputTextCallback::ALWAYS, buf1)
.build();
ui.separator();
ui.text("Finally, we'll do some whacky history to show inserting and removing");
ui.text("characters from the buffer.");
ui.text(
"Here, pressing UP (while editing the below widget) will remove the\n\
first and last character from buf2",
);
ui.text("and pressing DOWN will prepend the first char from buf0 AND");
ui.text("append the last char from buf1");
let (buf0, brwchk_dance) = buffers.split_first_mut().unwrap();
let (buf1, buf2_dance) = brwchk_dance.split_first_mut().unwrap();
let buf2 = &mut buf2_dance[0];
struct Wrapper2<'a>(&'a str, &'a str);
impl<'a> InputTextCallbackHandler for Wrapper2<'a> {
fn on_history(&mut self, dir: HistoryDirection, mut data: TextCallbackData) {
match dir {
HistoryDirection::Up => {
// remove first char...
if !data.str().is_empty() {
data.remove_chars(0, 1);
if let Some((idx, _)) = data.str().char_indices().next_back() {
data.remove_chars(idx, 1);
}
}
}
HistoryDirection::Down => {
// insert first char...
if let Some(first_char) = self.0.get(0..1) {
data.insert_chars(0, first_char);
}
// insert last char
if let Some((idx, _)) = self.1.char_indices().next_back() {
data.push_str(&self.1[idx..]);
}
}
}
}
}
ui.input_text("Wild buf2 editor", buf2)
.callback(InputTextCallback::HISTORY, Wrapper2(buf0, buf1))
.build();
ui.text(
"For more examples on how to use callbacks non-chaotically, check the demo",
);
});
});
}