1#![cfg_attr(test, allow(clippy::float_cmp))]
2#![deny(rust_2018_idioms)]
3pub extern crate imgui_sys as sys;
6
7use std::cell;
8use std::ffi::CStr;
9use std::os::raw::{c_char, c_void};
10use std::ptr;
11use std::str;
12use std::thread;
13
14pub use self::clipboard::*;
15pub use self::color::ImColor32;
16pub use self::context::*;
17pub use self::drag_drop::{DragDropFlags, DragDropSource, DragDropTarget};
18pub use self::draw_list::{ChannelsSplit, DrawListMut};
19pub use self::fonts::atlas::*;
20pub use self::fonts::font::*;
21pub use self::fonts::glyph::*;
22pub use self::fonts::glyph_ranges::*;
23pub use self::input::keyboard::*;
24pub use self::input::mouse::*;
25pub use self::input_widget::*;
26pub use self::io::*;
27pub use self::layout::*;
28pub use self::list_clipper::ListClipper;
29pub use self::plothistogram::PlotHistogram;
30pub use self::plotlines::PlotLines;
31pub use self::popups::*;
32pub use self::render::draw_data::*;
33pub use self::render::renderer::*;
34pub use self::stacks::*;
35pub use self::string::*;
36pub use self::style::*;
37
38#[cfg(feature = "tables-api")]
39pub use self::tables::*;
40pub use self::utils::*;
41pub use self::widget::color_editors::*;
42pub use self::widget::combo_box::*;
43pub use self::widget::drag::*;
44pub use self::widget::image::*;
45pub use self::widget::list_box::*;
46pub use self::widget::menu::*;
47pub use self::widget::misc::*;
48pub use self::widget::progress_bar::*;
49pub use self::widget::selectable::*;
50pub use self::widget::slider::*;
51pub use self::widget::tab::*;
52pub use self::widget::tree::*;
53pub use self::window::child_window::*;
54pub use self::window::*;
55use internal::RawCast;
56
57#[macro_use]
58mod string;
59
60#[macro_use]
61mod tokens;
62
63mod clipboard;
64pub mod color;
65mod columns;
66mod context;
67pub mod drag_drop;
68pub mod draw_list;
69mod fonts;
70mod input;
71mod input_widget;
72pub mod internal;
73mod io;
74mod layout;
75mod list_clipper;
76mod plothistogram;
77mod plotlines;
78mod popups;
79mod render;
80mod stacks;
81mod style;
82#[cfg(feature = "tables-api")]
83mod tables;
84#[cfg(test)]
85mod test;
86mod utils;
87mod widget;
88mod window;
89
90#[doc(hidden)]
93pub use core as __core;
94
95#[doc(alias = "GetVersion")]
97pub fn dear_imgui_version() -> &'static str {
98 unsafe {
99 let bytes = CStr::from_ptr(sys::igGetVersion()).to_bytes();
100 str::from_utf8_unchecked(bytes)
101 }
102}
103
104impl Context {
105 #[doc(alias = "GetTime")]
109 pub fn time(&self) -> f64 {
110 unsafe { sys::igGetTime() }
111 }
112 #[doc(alias = "GetFrameCount")]
116 pub fn frame_count(&self) -> i32 {
117 unsafe { sys::igGetFrameCount() }
118 }
119}
120
121#[derive(Debug)]
123pub struct Ui<'ui> {
124 ctx: &'ui Context,
125 font_atlas: Option<cell::RefMut<'ui, SharedFontAtlas>>,
126 buffer: cell::UnsafeCell<string::UiBuffer>,
128}
129
130impl<'ui> Ui<'ui> {
131 pub fn from_ctx(ctx: &'ui Context) -> Self {
133 Self {
134 ctx,
135 font_atlas: None,
136 buffer: crate::UiBuffer::new(1024).into(),
137 }
138 }
139
140 fn scratch_txt(&self, txt: impl AsRef<str>) -> *const sys::cty::c_char {
142 unsafe {
143 let handle = &mut *self.buffer.get();
144 handle.scratch_txt(txt)
145 }
146 }
147
148 fn scratch_txt_opt(&self, txt: Option<impl AsRef<str>>) -> *const sys::cty::c_char {
150 unsafe {
151 let handle = &mut *self.buffer.get();
152 handle.scratch_txt_opt(txt)
153 }
154 }
155
156 fn scratch_txt_two(
157 &self,
158 txt_0: impl AsRef<str>,
159 txt_1: impl AsRef<str>,
160 ) -> (*const sys::cty::c_char, *const sys::cty::c_char) {
161 unsafe {
162 let handle = &mut *self.buffer.get();
163 handle.scratch_txt_two(txt_0, txt_1)
164 }
165 }
166
167 fn scratch_txt_with_opt(
168 &self,
169 txt_0: impl AsRef<str>,
170 txt_1: Option<impl AsRef<str>>,
171 ) -> (*const sys::cty::c_char, *const sys::cty::c_char) {
172 unsafe {
173 let handle = &mut *self.buffer.get();
174 handle.scratch_txt_with_opt(txt_0, txt_1)
175 }
176 }
177
178 #[doc(alias = "GetIO")]
180 pub fn io(&self) -> &Io {
181 unsafe { &*(sys::igGetIO() as *const Io) }
182 }
183
184 pub fn fonts(&self) -> FontAtlasRef<'_> {
186 match self.font_atlas {
187 Some(ref font_atlas) => FontAtlasRef::Shared(font_atlas),
188 None => unsafe {
189 let fonts = &*(self.io().fonts as *const FontAtlas);
190 FontAtlasRef::Owned(fonts)
191 },
192 }
193 }
194 pub fn clone_style(&self) -> Style {
196 *self.ctx.style()
197 }
198 #[doc(alias = "Render", alias = "GetDrawData")]
200 pub fn render(self) -> &'ui DrawData {
201 unsafe {
202 sys::igRender();
203 &*(sys::igGetDrawData() as *mut DrawData)
204 }
205 }
206}
207
208impl<'a> Drop for Ui<'a> {
209 #[doc(alias = "EndFrame")]
210 fn drop(&mut self) {
211 if !thread::panicking() {
212 unsafe {
213 sys::igEndFrame();
214 }
215 }
216 }
217}
218
219impl<'ui> Ui<'ui> {
221 #[doc(alias = "ShowDemoWindow")]
224 pub fn show_demo_window(&self, opened: &mut bool) {
225 unsafe {
226 sys::igShowDemoWindow(opened);
227 }
228 }
229 #[doc(alias = "ShowAboutWindow")]
233 pub fn show_about_window(&self, opened: &mut bool) {
234 unsafe {
235 sys::igShowAboutWindow(opened);
236 }
237 }
238 #[doc(alias = "ShowMetricsWindow")]
243 pub fn show_metrics_window(&self, opened: &mut bool) {
244 unsafe {
245 sys::igShowMetricsWindow(opened);
246 }
247 }
248 #[doc(alias = "ShowStyleEditor")]
250 pub fn show_style_editor(&self, style: &mut Style) {
251 unsafe {
252 sys::igShowStyleEditor(style.raw_mut());
253 }
254 }
255 #[doc(alias = "ShowStyleEditor")]
257 pub fn show_default_style_editor(&self) {
258 unsafe { sys::igShowStyleEditor(ptr::null_mut()) };
259 }
260 #[doc(alias = "ShowUserGuide")]
262 pub fn show_user_guide(&self) {
263 unsafe { sys::igShowUserGuide() };
264 }
265}
266
267#[derive(Copy, Clone, Debug, Eq, PartialEq)]
269pub enum Id<'a> {
270 Int(i32),
271 Str(&'a str),
272 Ptr(*const c_void),
273}
274
275impl From<i32> for Id<'static> {
276 #[inline]
277 fn from(i: i32) -> Self {
278 Id::Int(i)
279 }
280}
281
282impl<'a, T: ?Sized + AsRef<str>> From<&'a T> for Id<'a> {
283 #[inline]
284 fn from(s: &'a T) -> Self {
285 Id::Str(s.as_ref())
286 }
287}
288
289impl<T> From<*const T> for Id<'static> {
290 #[inline]
291 fn from(p: *const T) -> Self {
292 Id::Ptr(p as *const c_void)
293 }
294}
295
296impl<T> From<*mut T> for Id<'static> {
297 #[inline]
298 fn from(p: *mut T) -> Self {
299 Id::Ptr(p as *const T as *const c_void)
300 }
301}
302
303impl<'a> Id<'a> {
304 #[allow(dead_code)]
307 fn as_imgui_id(&self) -> sys::ImGuiID {
308 unsafe {
309 match self {
310 Id::Ptr(p) => sys::igGetID_Ptr(*p),
311 Id::Str(s) => {
312 let s1 = s.as_ptr() as *const std::os::raw::c_char;
313 let s2 = s1.add(s.len());
314 sys::igGetID_StrStr(s1, s2)
315 }
316 Id::Int(i) => {
317 let p = *i as *const std::os::raw::c_void;
318 sys::igGetID_Ptr(p)
319 } }
321 }
322 }
323}
324
325impl<'a> Default for Id<'a> {
326 fn default() -> Self {
327 Self::Int(0)
328 }
329}
330
331impl<'ui> Ui<'ui> {
333 #[doc(alias = "InputText", alias = "InputTextWithHint")]
334 pub fn input_text<'p, L: AsRef<str>>(
335 &'ui self,
336 label: L,
337 buf: &'p mut String,
338 ) -> InputText<'ui, 'p, L> {
339 InputText::new(self, label, buf)
340 }
341 #[doc(alias = "InputText", alias = "InputTextMultiline")]
342 pub fn input_text_multiline<'p, L: AsRef<str>>(
343 &'ui self,
344 label: L,
345 buf: &'p mut String,
346 size: [f32; 2],
347 ) -> InputTextMultiline<'ui, 'p, L> {
348 InputTextMultiline::new(self, label, buf, size)
349 }
350 #[doc(alias = "InputFloat2")]
351 pub fn input_float<'p, L: AsRef<str>>(
352 &'ui self,
353 label: L,
354 value: &'p mut f32,
355 ) -> InputFloat<'ui, 'p, L> {
356 InputFloat::new(self, label, value)
357 }
358 pub fn input_float2<'p, L: AsRef<str>>(
359 &'ui self,
360 label: L,
361 value: &'p mut [f32; 2],
362 ) -> InputFloat2<'ui, 'p, L> {
363 InputFloat2::new(self, label, value)
364 }
365 #[doc(alias = "InputFloat3")]
366 pub fn input_float3<'p, L: AsRef<str>>(
367 &'ui self,
368 label: L,
369 value: &'p mut [f32; 3],
370 ) -> InputFloat3<'ui, 'p, L> {
371 InputFloat3::new(self, label, value)
372 }
373 #[doc(alias = "InputFloat4")]
374 pub fn input_float4<'p, L: AsRef<str>>(
375 &'ui self,
376 label: L,
377 value: &'p mut [f32; 4],
378 ) -> InputFloat4<'ui, 'p, L> {
379 InputFloat4::new(self, label, value)
380 }
381 #[doc(alias = "InputInt")]
382 pub fn input_int<'p, L: AsRef<str>>(
383 &'ui self,
384 label: L,
385 value: &'p mut i32,
386 ) -> InputInt<'ui, 'p, L> {
387 InputInt::new(self, label, value)
388 }
389 #[doc(alias = "InputInt2")]
390 pub fn input_int2<'p, L: AsRef<str>>(
391 &'ui self,
392 label: L,
393 value: &'p mut [i32; 2],
394 ) -> InputInt2<'ui, 'p, L> {
395 InputInt2::new(self, label, value)
396 }
397 #[doc(alias = "InputInt3")]
398 pub fn input_int3<'p, L: AsRef<str>>(
399 &'ui self,
400 label: L,
401 value: &'p mut [i32; 3],
402 ) -> InputInt3<'ui, 'p, L> {
403 InputInt3::new(self, label, value)
404 }
405 #[doc(alias = "InputInt4")]
406 pub fn input_int4<'p, L: AsRef<str>>(
407 &'ui self,
408 label: L,
409 value: &'p mut [i32; 4],
410 ) -> InputInt4<'ui, 'p, L> {
411 InputInt4::new(self, label, value)
412 }
413}
414
415create_token!(
416 pub struct TooltipToken<'ui>;
418
419 drop { sys::igEndTooltip() }
422);
423
424impl<'ui> Ui<'ui> {
426 #[doc(alias = "BeginTooltip", alias = "EndTootip")]
444 pub fn tooltip<F: FnOnce()>(&self, f: F) {
445 unsafe { sys::igBeginTooltip() };
446 f();
447 unsafe { sys::igEndTooltip() };
448 }
449 #[doc(alias = "BeginTooltip")]
453 pub fn begin_tooltip(&self) -> TooltipToken<'_> {
454 unsafe { sys::igBeginTooltip() };
455 TooltipToken::new(self)
456 }
457 #[doc(alias = "BeginTooltip", alias = "EndTootip")]
473 pub fn tooltip_text<T: AsRef<str>>(&self, text: T) {
474 self.tooltip(|| self.text(text));
475 }
476}
477
478impl<'ui> Ui<'ui> {
480 #[doc(alias = "ListBox")]
481 pub fn list_box<'p, StringType: AsRef<str> + ?Sized>(
482 &self,
483 label: impl AsRef<str>,
484 current_item: &mut i32,
485 items: &'p [&'p StringType],
486 height_in_items: i32,
487 ) -> bool {
488 let (label_ptr, items_inner) = unsafe {
489 let handle = &mut *self.buffer.get();
490
491 handle.refresh_buffer();
492 let label_ptr = handle.push(label);
493
494 let items_inner: Vec<_> = items.iter().map(|&v| handle.push(v)).collect();
495
496 (label_ptr, items_inner)
497 };
498
499 unsafe {
500 sys::igListBox_Str_arr(
501 label_ptr,
502 current_item,
503 items_inner.as_ptr() as *mut *const c_char,
504 items_inner.len() as i32,
505 height_in_items,
506 )
507 }
508 }
509
510 }
545
546impl<'ui> Ui<'ui> {
547 #[doc(alias = "PlotLines")]
548 pub fn plot_lines<'p, Label: AsRef<str>>(
549 &'ui self,
550 label: Label,
551 values: &'p [f32],
552 ) -> PlotLines<'ui, 'p, Label> {
553 PlotLines::new(self, label, values)
554 }
555}
556
557impl<'ui> Ui<'ui> {
558 #[doc(alias = "PlotHistogram")]
559 pub fn plot_histogram<'p, Label: AsRef<str>>(
560 &'ui self,
561 label: Label,
562 values: &'p [f32],
563 ) -> PlotHistogram<'ui, 'p, Label> {
564 PlotHistogram::new(self, label, values)
565 }
566}
567
568impl<'ui> Ui<'ui> {
569 #[doc(alias = "CalcTextSize")]
574 pub fn calc_text_size<T: AsRef<str>>(&self, text: T) -> [f32; 2] {
575 self.calc_text_size_with_opts(text, false, -1.0)
576 }
577
578 #[doc(alias = "CalcTextSize")]
585 pub fn calc_text_size_with_opts<T: AsRef<str>>(
586 &self,
587 text: T,
588 hide_text_after_double_hash: bool,
589 wrap_width: f32,
590 ) -> [f32; 2] {
591 let mut out = sys::ImVec2::zero();
592 let text = text.as_ref();
593
594 unsafe {
595 let start = text.as_ptr();
596 let end = start.add(text.len());
597
598 sys::igCalcTextSize(
599 &mut out,
600 start as *const c_char,
601 end as *const c_char,
602 hide_text_after_double_hash,
603 wrap_width,
604 )
605 };
606 out.into()
607 }
608}
609
610impl<'ui> Ui<'ui> {
612 #[must_use]
642 #[doc(alias = "GetWindowDrawList")]
643 pub fn get_window_draw_list(&'ui self) -> DrawListMut<'ui> {
644 DrawListMut::window(self)
645 }
646
647 #[must_use]
648 #[doc(alias = "GetBackgroundDrawList")]
649 pub fn get_background_draw_list(&'ui self) -> DrawListMut<'ui> {
650 DrawListMut::background(self)
651 }
652
653 #[must_use]
654 #[doc(alias = "GetForegroundDrawList")]
655 pub fn get_foreground_draw_list(&'ui self) -> DrawListMut<'ui> {
656 DrawListMut::foreground(self)
657 }
658}
659
660#[repr(i8)]
662#[derive(Copy, Clone, Debug, Eq, PartialEq)]
663pub enum Condition {
664 Never = -1,
666 Always = sys::ImGuiCond_Always as i8,
668 Once = sys::ImGuiCond_Once as i8,
670 FirstUseEver = sys::ImGuiCond_FirstUseEver as i8,
673 Appearing = sys::ImGuiCond_Appearing as i8,
676}
677
678#[repr(i32)]
680#[derive(Copy, Clone, Debug, Eq, PartialEq)]
681pub enum Direction {
682 None = sys::ImGuiDir_None,
683 Left = sys::ImGuiDir_Left,
684 Right = sys::ImGuiDir_Right,
685 Up = sys::ImGuiDir_Up,
686 Down = sys::ImGuiDir_Down,
687}