dear_imgui_rs/widget/input/
multiline.rs1use super::buffers::{finish_string_input_buffer, make_string_input_buffer};
2use super::callback_bridge::{
3 StringCallbackState, StringResizeCallbackState, im_string_multiline_resize_callback,
4 string_multiline_callback_router, string_multiline_resize_callback,
5};
6use super::callbacks::{InputTextCallback, InputTextCallbackHandler};
7use super::validation::validate_input_multiline_flags;
8use crate::InputTextMultilineFlags;
9use crate::string::ImString;
10use crate::sys;
11use crate::ui::Ui;
12use std::borrow::Cow;
13use std::ffi::c_void;
14
15#[derive(Debug)]
17#[must_use]
18pub struct InputTextMultiline<'ui, 'p> {
19 ui: &'ui Ui,
20 label: Cow<'ui, str>,
21 buf: &'p mut String,
22 size: [f32; 2],
23 flags: InputTextMultilineFlags,
24 capacity_hint: Option<usize>,
25}
26
27#[derive(Debug)]
29#[must_use]
30pub struct InputTextMultilineImStr<'ui, 'p> {
31 ui: &'ui Ui,
32 label: Cow<'ui, str>,
33 buf: &'p mut ImString,
34 size: [f32; 2],
35 flags: InputTextMultilineFlags,
36}
37
38impl<'ui, 'p> InputTextMultilineImStr<'ui, 'p> {
39 pub fn new(
40 ui: &'ui Ui,
41 label: impl Into<Cow<'ui, str>>,
42 buf: &'p mut ImString,
43 size: impl Into<[f32; 2]>,
44 ) -> Self {
45 Self {
46 ui,
47 label: label.into(),
48 buf,
49 size: size.into(),
50 flags: InputTextMultilineFlags::NONE,
51 }
52 }
53 pub fn flags(mut self, flags: InputTextMultilineFlags) -> Self {
54 self.flags = flags;
55 self
56 }
57 pub fn read_only(mut self, v: bool) -> Self {
58 self.flags.set(InputTextMultilineFlags::READ_ONLY, v);
59 self
60 }
61 pub fn build(self) -> bool {
62 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
63 let buf_size = self.buf.capacity_with_nul().max(1);
64 self.buf.ensure_buf_size(buf_size);
65 let buf_ptr = self.buf.as_mut_ptr();
66 let user_ptr = self.buf as *mut ImString as *mut c_void;
67 let size_vec: sys::ImVec2 = self.size.into();
68
69 validate_input_multiline_flags("InputTextMultilineImStr::build()", self.flags);
70 let flags = self.flags.raw() | sys::ImGuiInputTextFlags_CallbackResize as i32;
71 let result = self.ui.run_with_bound_context(|| unsafe {
72 sys::igInputTextMultiline(
73 label_ptr,
74 buf_ptr,
75 buf_size,
76 size_vec,
77 flags,
78 Some(im_string_multiline_resize_callback),
79 user_ptr,
80 )
81 });
82 unsafe { self.buf.refresh_len() };
84 result
85 }
86}
87impl<'ui, 'p> InputTextMultiline<'ui, 'p> {
88 pub fn new(
90 ui: &'ui Ui,
91 label: impl Into<Cow<'ui, str>>,
92 buf: &'p mut String,
93 size: impl Into<[f32; 2]>,
94 ) -> Self {
95 Self {
96 ui,
97 label: label.into(),
98 buf,
99 size: size.into(),
100 flags: InputTextMultilineFlags::NONE,
101 capacity_hint: None,
102 }
103 }
104
105 pub fn flags(mut self, flags: InputTextMultilineFlags) -> Self {
107 self.flags = flags;
108 self
109 }
110
111 pub fn capacity_hint(mut self, cap: usize) -> Self {
113 self.capacity_hint = Some(cap);
114 self
115 }
116
117 pub fn read_only(mut self, read_only: bool) -> Self {
119 self.flags
120 .set(InputTextMultilineFlags::READ_ONLY, read_only);
121 self
122 }
123
124 pub fn build(self) -> bool {
126 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
127
128 let mut input_buffer = make_string_input_buffer(self.buf, self.capacity_hint);
129 let capacity = input_buffer.len();
130 let buf_ptr = input_buffer.as_mut_ptr() as *mut std::os::raw::c_char;
131
132 let mut callback_state = StringResizeCallbackState::new(&mut input_buffer);
133 let user_ptr = callback_state.user_ptr();
134
135 let size_vec: sys::ImVec2 = self.size.into();
136 validate_input_multiline_flags("InputTextMultiline::build()", self.flags);
137 let flags = self.flags.raw() | sys::ImGuiInputTextFlags_CallbackResize as i32;
138 let result = self.ui.run_with_bound_context(|| unsafe {
139 sys::igInputTextMultiline(
140 label_ptr,
141 buf_ptr,
142 capacity,
143 size_vec,
144 flags,
145 Some(string_multiline_resize_callback),
146 user_ptr,
147 )
148 });
149
150 finish_string_input_buffer(self.buf, input_buffer);
151 result
152 }
153
154 pub fn callback<T2: InputTextCallbackHandler>(
156 mut self,
157 callbacks: InputTextCallback,
158 handler: T2,
159 ) -> InputTextMultilineWithCb<'ui, 'p, T2> {
160 if callbacks.contains(InputTextCallback::ALWAYS) {
163 self.flags |= InputTextMultilineFlags::from_bits_retain(
164 sys::ImGuiInputTextFlags_CallbackAlways as i32,
165 );
166 }
167 if callbacks.contains(InputTextCallback::CHAR_FILTER) {
168 self.flags |= InputTextMultilineFlags::from_bits_retain(
169 sys::ImGuiInputTextFlags_CallbackCharFilter as i32,
170 );
171 }
172 if callbacks.contains(InputTextCallback::EDIT) {
173 self.flags |= InputTextMultilineFlags::from_bits_retain(
174 sys::ImGuiInputTextFlags_CallbackEdit as i32,
175 );
176 }
177
178 InputTextMultilineWithCb {
179 ui: self.ui,
180 label: self.label,
181 buf: self.buf,
182 size: self.size,
183 flags: self.flags,
184 capacity_hint: self.capacity_hint,
185 handler,
186 }
187 }
188}
189
190pub struct InputTextMultilineWithCb<'ui, 'p, T> {
192 ui: &'ui Ui,
193 label: Cow<'ui, str>,
194 buf: &'p mut String,
195 size: [f32; 2],
196 flags: InputTextMultilineFlags,
197 capacity_hint: Option<usize>,
198 handler: T,
199}
200
201impl<'ui, 'p, T: InputTextCallbackHandler> InputTextMultilineWithCb<'ui, 'p, T> {
202 pub fn build(self) -> bool {
203 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
204
205 let mut input_buffer = make_string_input_buffer(self.buf, self.capacity_hint);
206 let capacity = input_buffer.len();
207 let buf_ptr = input_buffer.as_mut_ptr() as *mut std::os::raw::c_char;
208
209 let mut callback_state = StringCallbackState::new(&mut input_buffer, self.handler);
210 let user_ptr = callback_state.user_ptr();
211
212 let size_vec: sys::ImVec2 = self.size.into();
213 validate_input_multiline_flags("InputTextMultilineWithCb::build()", self.flags);
214 let flags = self.flags.raw() | sys::ImGuiInputTextFlags_CallbackResize as i32;
215 let result = self.ui.run_with_bound_context(|| unsafe {
216 sys::igInputTextMultiline(
217 label_ptr,
218 buf_ptr,
219 capacity,
220 size_vec,
221 flags,
222 Some(string_multiline_callback_router::<T>),
223 user_ptr,
224 )
225 });
226
227 finish_string_input_buffer(self.buf, input_buffer);
228 result
229 }
230}