1use std::os::raw::c_void;
2use std::ptr;
3
4use crate::internal::DataTypeKind;
5use crate::sys;
6use crate::widget::slider::SliderFlags;
7use crate::Ui;
8
9#[derive(Copy, Clone, Debug)]
11#[must_use]
12pub struct Drag<T, L, F = &'static str> {
13 label: L,
14 speed: f32,
15 min: Option<T>,
16 max: Option<T>,
17 display_format: Option<F>,
18 flags: SliderFlags,
19}
20
21impl<L: AsRef<str>, T: DataTypeKind> Drag<T, L> {
22 #[doc(alias = "DragScalar", alias = "DragScalarN")]
24 pub fn new(label: L) -> Self {
25 Drag {
26 label,
27 speed: 1.0,
28 min: None,
29 max: None,
30 display_format: None,
31 flags: SliderFlags::empty(),
32 }
33 }
34}
35
36impl<L: AsRef<str>, T: DataTypeKind, F: AsRef<str>> Drag<T, L, F> {
37 pub fn range(mut self, min: T, max: T) -> Self {
39 self.min = Some(min);
40 self.max = Some(max);
41 self
42 }
43 pub fn speed(mut self, speed: f32) -> Self {
47 self.speed = speed;
48 self
49 }
50 pub fn display_format<F2: AsRef<str>>(self, display_format: F2) -> Drag<T, L, F2> {
52 Drag {
53 label: self.label,
54 speed: self.speed,
55 min: self.min,
56 max: self.max,
57 display_format: Some(display_format),
58 flags: self.flags,
59 }
60 }
61 pub fn flags(mut self, flags: SliderFlags) -> Self {
63 self.flags = flags;
64 self
65 }
66 pub fn build(self, ui: &Ui<'_>, value: &mut T) -> bool {
70 unsafe {
71 let (one, two) = ui.scratch_txt_with_opt(self.label, self.display_format);
72
73 sys::igDragScalar(
74 one,
75 T::KIND as i32,
76 value as *mut T as *mut c_void,
77 self.speed,
78 self.min
79 .as_ref()
80 .map(|min| min as *const T)
81 .unwrap_or(ptr::null()) as *const c_void,
82 self.max
83 .as_ref()
84 .map(|max| max as *const T)
85 .unwrap_or(ptr::null()) as *const c_void,
86 two,
87 self.flags.bits() as i32,
88 )
89 }
90 }
91 pub fn build_array(self, ui: &Ui<'_>, values: &mut [T]) -> bool {
95 unsafe {
96 let (one, two) = ui.scratch_txt_with_opt(self.label, self.display_format);
97
98 sys::igDragScalarN(
99 one,
100 T::KIND as i32,
101 values.as_mut_ptr() as *mut c_void,
102 values.len() as i32,
103 self.speed,
104 self.min
105 .as_ref()
106 .map(|min| min as *const T)
107 .unwrap_or(ptr::null()) as *const c_void,
108 self.max
109 .as_ref()
110 .map(|max| max as *const T)
111 .unwrap_or(ptr::null()) as *const c_void,
112 two,
113 self.flags.bits() as i32,
114 )
115 }
116 }
117}
118
119#[derive(Copy, Clone, Debug)]
121#[must_use]
122pub struct DragRange<T, L, F = &'static str, M = &'static str> {
123 label: L,
124 speed: f32,
125 min: Option<T>,
126 max: Option<T>,
127 display_format: Option<F>,
128 max_display_format: Option<M>,
129 flags: SliderFlags,
130}
131
132impl<T: DataTypeKind, L: AsRef<str>> DragRange<T, L> {
133 #[doc(alias = "DragIntRange2", alias = "DragFloatRange2")]
135 pub fn new(label: L) -> DragRange<T, L> {
136 DragRange {
137 label,
138 speed: 1.0,
139 min: None,
140 max: None,
141 display_format: None,
142 max_display_format: None,
143 flags: SliderFlags::empty(),
144 }
145 }
146}
147
148impl<T, L, F, M> DragRange<T, L, F, M>
149where
150 T: DataTypeKind,
151 L: AsRef<str>,
152 F: AsRef<str>,
153 M: AsRef<str>,
154{
155 pub fn range(mut self, min: T, max: T) -> Self {
156 self.min = Some(min);
157 self.max = Some(max);
158 self
159 }
160 pub fn speed(mut self, speed: f32) -> Self {
164 self.speed = speed;
165 self
166 }
167 pub fn display_format<F2: AsRef<str>>(self, display_format: F2) -> DragRange<T, L, F2, M> {
169 DragRange {
170 label: self.label,
171 speed: self.speed,
172 min: self.min,
173 max: self.max,
174 display_format: Some(display_format),
175 max_display_format: self.max_display_format,
176 flags: self.flags,
177 }
178 }
179 pub fn max_display_format<M2: AsRef<str>>(
181 self,
182 max_display_format: M2,
183 ) -> DragRange<T, L, F, M2> {
184 DragRange {
185 label: self.label,
186 speed: self.speed,
187 min: self.min,
188 max: self.max,
189 display_format: self.display_format,
190 max_display_format: Some(max_display_format),
191 flags: self.flags,
192 }
193 }
194 pub fn flags(mut self, flags: SliderFlags) -> Self {
196 self.flags = flags;
197 self
198 }
199}
200
201impl<L, F, M> DragRange<f32, L, F, M>
202where
203 L: AsRef<str>,
204 F: AsRef<str>,
205 M: AsRef<str>,
206{
207 #[doc(alias = "DragFloatRange2")]
211 pub fn build(self, ui: &Ui<'_>, min: &mut f32, max: &mut f32) -> bool {
212 let label;
213 let mut display_format = std::ptr::null();
214 let mut max_display_format = std::ptr::null();
215
216 unsafe {
218 let buffer = &mut *ui.buffer.get();
219 buffer.refresh_buffer();
220
221 label = buffer.push(self.label);
222 if let Some(v) = self.display_format {
223 display_format = buffer.push(v);
224 }
225 if let Some(v) = self.max_display_format {
226 max_display_format = buffer.push(v);
227 }
228
229 sys::igDragFloatRange2(
230 label,
231 min as *mut f32,
232 max as *mut f32,
233 self.speed,
234 self.min.unwrap_or(0.0),
235 self.max.unwrap_or(0.0),
236 display_format,
237 max_display_format,
238 self.flags.bits() as i32,
239 )
240 }
241 }
242}
243
244impl<L, F, M> DragRange<i32, L, F, M>
245where
246 L: AsRef<str>,
247 F: AsRef<str>,
248 M: AsRef<str>,
249{
250 #[doc(alias = "DragIntRange2")]
254 pub fn build(self, ui: &Ui<'_>, min: &mut i32, max: &mut i32) -> bool {
255 unsafe {
256 let label;
257 let mut display_format = std::ptr::null();
258 let mut max_display_format = std::ptr::null();
259
260 let buffer = &mut *ui.buffer.get();
262 buffer.refresh_buffer();
263
264 label = buffer.push(self.label);
265 if let Some(v) = self.display_format {
266 display_format = buffer.push(v);
267 }
268 if let Some(v) = self.max_display_format {
269 max_display_format = buffer.push(v);
270 }
271
272 sys::igDragIntRange2(
273 label,
274 min as *mut i32,
275 max as *mut i32,
276 self.speed,
277 self.min.unwrap_or(0),
278 self.max.unwrap_or(0),
279 display_format,
280 max_display_format,
281 self.flags.bits() as i32,
282 )
283 }
284 }
285}