dear_imgui/window/
child_window.rs1#![allow(
2 clippy::cast_possible_truncation,
3 clippy::cast_sign_loss,
4 clippy::as_conversions
5)]
6use crate::sys;
7use crate::{Ui, WindowFlags};
8use std::ffi::CString;
9
10bitflags::bitflags! {
11 #[repr(transparent)]
13 pub struct ChildFlags: u32 {
14 const NONE = 0;
16 const BORDERS = 1 << 0;
18 const ALWAYS_USE_WINDOW_PADDING = 1 << 1;
20 const RESIZE_X = 1 << 2;
22 const RESIZE_Y = 1 << 3;
24 const AUTO_RESIZE_X = 1 << 4;
26 const AUTO_RESIZE_Y = 1 << 5;
28 const ALWAYS_AUTO_RESIZE = 1 << 6;
30 const FRAME_STYLE = 1 << 7;
32 const NAV_FLATTENED = 1 << 8;
34 }
35}
36
37pub struct ChildWindow<'ui> {
39 name: String,
40 size: [f32; 2],
41 child_flags: ChildFlags,
42 flags: WindowFlags,
43 _phantom: std::marker::PhantomData<&'ui ()>,
44}
45
46impl<'ui> ChildWindow<'ui> {
47 pub fn new(name: impl Into<String>) -> Self {
49 Self {
50 name: name.into(),
51 size: [0.0, 0.0],
52 child_flags: ChildFlags::NONE,
53 flags: WindowFlags::empty(),
54 _phantom: std::marker::PhantomData,
55 }
56 }
57
58 pub fn size(mut self, size: [f32; 2]) -> Self {
60 self.size = size;
61 self
62 }
63
64 pub fn border(mut self, border: bool) -> Self {
66 self.child_flags.set(ChildFlags::BORDERS, border);
67 self
68 }
69
70 pub fn child_flags(mut self, child_flags: ChildFlags) -> Self {
72 self.child_flags = child_flags;
73 self
74 }
75
76 pub fn flags(mut self, flags: WindowFlags) -> Self {
78 self.flags = flags;
79 self
80 }
81
82 pub fn build<F, R>(self, ui: &'ui Ui, f: F) -> Option<R>
84 where
85 F: FnOnce() -> R,
86 {
87 let token = self.begin(ui)?;
88 let result = f();
89 drop(token); Some(result)
91 }
92
93 fn begin(self, _ui: &'ui Ui) -> Option<ChildWindowToken<'ui>> {
95 let name_cstr = CString::new(self.name).ok()?;
96
97 let result = unsafe {
98 let size_vec = sys::ImVec2 {
99 x: self.size[0],
100 y: self.size[1],
101 };
102 sys::igBeginChild_Str(
103 name_cstr.as_ptr(),
104 size_vec,
105 self.child_flags.bits() as i32,
106 self.flags.bits(),
107 )
108 };
109
110 if result {
115 Some(ChildWindowToken {
116 _phantom: std::marker::PhantomData,
117 })
118 } else {
119 unsafe {
121 sys::igEndChild();
122 }
123 None
124 }
125 }
126}
127
128pub struct ChildWindowToken<'ui> {
130 _phantom: std::marker::PhantomData<&'ui ()>,
131}
132
133impl<'ui> Drop for ChildWindowToken<'ui> {
134 fn drop(&mut self) {
135 unsafe {
136 sys::igEndChild();
137 }
138 }
139}
140
141impl Ui {
142 pub fn child_window(&self, name: impl Into<String>) -> ChildWindow<'_> {
144 ChildWindow::new(name)
145 }
146}