dear_imgui_rs/widget/
button.rs1use crate::Ui;
6use crate::sys;
7use std::borrow::Cow;
8
9fn assert_finite_vec2(caller: &str, name: &str, value: [f32; 2]) {
10 assert!(
11 value[0].is_finite() && value[1].is_finite(),
12 "{caller} {name} must contain finite values"
13 );
14}
15
16impl Ui {
17 #[doc(alias = "Button")]
19 pub fn button(&self, label: impl AsRef<str>) -> bool {
20 self.button_config(label.as_ref()).build()
21 }
22
23 #[doc(alias = "Button")]
25 pub fn button_with_size(&self, label: impl AsRef<str>, size: impl Into<[f32; 2]>) -> bool {
26 self.button_config(label.as_ref()).size(size).build()
27 }
28
29 pub fn button_config<'ui>(&'ui self, label: impl Into<Cow<'ui, str>>) -> Button<'ui> {
31 Button::new(self, label)
32 }
33}
34
35impl Ui {
36 #[doc(alias = "Checkbox")]
38 pub fn checkbox(&self, label: impl AsRef<str>, value: &mut bool) -> bool {
39 let label_ptr = self.scratch_txt(label);
40 unsafe { sys::igCheckbox(label_ptr, value) }
41 }
42
43 #[doc(alias = "RadioButton")]
45 pub fn radio_button(&self, label: impl AsRef<str>, active: bool) -> bool {
46 let label_ptr = self.scratch_txt(label);
47 unsafe { sys::igRadioButton_Bool(label_ptr, active) }
48 }
49
50 #[doc(alias = "RadioButton")]
52 pub fn radio_button_int(&self, label: impl AsRef<str>, v: &mut i32, v_button: i32) -> bool {
53 let label_ptr = self.scratch_txt(label);
54 unsafe { sys::igRadioButton_IntPtr(label_ptr, v, v_button) }
55 }
56
57 #[doc(alias = "RadioButtonBool")]
61 pub fn radio_button_bool(&self, label: impl AsRef<str>, active: bool) -> bool {
62 let label_ptr = self.scratch_txt(label);
63 unsafe { sys::igRadioButton_Bool(label_ptr, active) }
64 }
65
66 #[doc(alias = "CheckboxFlags")]
74 pub fn checkbox_flags<T>(&self, label: impl AsRef<str>, flags: &mut T, mask: T) -> bool
75 where
76 T: Copy
77 + PartialEq
78 + std::ops::BitOrAssign
79 + std::ops::BitAndAssign
80 + std::ops::BitAnd<Output = T>
81 + std::ops::Not<Output = T>,
82 {
83 let mut value = *flags & mask == mask;
84 let pressed = self.checkbox(label, &mut value);
85 if pressed {
86 if value {
87 *flags |= mask;
88 } else {
89 *flags &= !mask;
90 }
91 }
92 pressed
93 }
94}
95
96pub struct Button<'ui> {
98 ui: &'ui Ui,
99 label: Cow<'ui, str>,
100 size: Option<[f32; 2]>,
101}
102
103impl<'ui> Button<'ui> {
104 pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>) -> Self {
106 Self {
107 ui,
108 label: label.into(),
109 size: None,
110 }
111 }
112
113 pub fn size(mut self, size: impl Into<[f32; 2]>) -> Self {
115 self.size = Some(size.into());
116 self
117 }
118
119 pub fn build(self) -> bool {
121 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
122 let size = self.size.unwrap_or([0.0, 0.0]);
123 assert_finite_vec2("Button::build()", "size", size);
124 let size_vec: sys::ImVec2 = size.into();
125 unsafe { sys::igButton(label_ptr, size_vec) }
126 }
127}