dear_imgui_rs/widget/
button.rs

1//! Buttons
2//!
3//! Push-button widgets with optional sizing and configuration helpers.
4//!
5use crate::Ui;
6use crate::sys;
7
8impl Ui {
9    /// Creates a button with the given label
10    #[doc(alias = "Button")]
11    pub fn button(&self, label: impl AsRef<str>) -> bool {
12        self.button_config(label).build()
13    }
14
15    /// Creates a button with the given label and size
16    #[doc(alias = "Button")]
17    pub fn button_with_size(&self, label: impl AsRef<str>, size: impl Into<[f32; 2]>) -> bool {
18        self.button_config(label).size(size).build()
19    }
20
21    /// Creates a button builder
22    pub fn button_config(&self, label: impl AsRef<str>) -> Button<'_> {
23        Button::new(self, label)
24    }
25}
26
27impl Ui {
28    /// Creates a checkbox
29    #[doc(alias = "Checkbox")]
30    pub fn checkbox(&self, label: impl AsRef<str>, value: &mut bool) -> bool {
31        let label_ptr = self.scratch_txt(label);
32        unsafe { sys::igCheckbox(label_ptr, value) }
33    }
34
35    /// Creates a radio button
36    #[doc(alias = "RadioButton")]
37    pub fn radio_button(&self, label: impl AsRef<str>, active: bool) -> bool {
38        let label_ptr = self.scratch_txt(label);
39        unsafe { sys::igRadioButton_Bool(label_ptr, active) }
40    }
41
42    /// Creates a radio button with integer value
43    #[doc(alias = "RadioButton")]
44    pub fn radio_button_int(&self, label: impl AsRef<str>, v: &mut i32, v_button: i32) -> bool {
45        let label_ptr = self.scratch_txt(label);
46        unsafe { sys::igRadioButton_IntPtr(label_ptr, v, v_button) }
47    }
48
49    /// Creates a radio button suitable for choosing an arbitrary value.
50    ///
51    /// Returns true if this radio button was clicked.
52    #[doc(alias = "RadioButtonBool")]
53    pub fn radio_button_bool(&self, label: impl AsRef<str>, active: bool) -> bool {
54        let label_ptr = self.scratch_txt(label);
55        unsafe { sys::igRadioButton_Bool(label_ptr, active) }
56    }
57
58    /// Renders a checkbox suitable for toggling bit flags using a mask.
59    ///
60    /// Returns true if this checkbox was clicked.
61    pub fn checkbox_flags<T>(&self, label: impl AsRef<str>, flags: &mut T, mask: T) -> bool
62    where
63        T: Copy
64            + PartialEq
65            + std::ops::BitOrAssign
66            + std::ops::BitAndAssign
67            + std::ops::BitAnd<Output = T>
68            + std::ops::Not<Output = T>,
69    {
70        let mut value = *flags & mask == mask;
71        let pressed = self.checkbox(label, &mut value);
72        if pressed {
73            if value {
74                *flags |= mask;
75            } else {
76                *flags &= !mask;
77            }
78        }
79        pressed
80    }
81}
82
83/// Builder for button widget
84pub struct Button<'ui> {
85    ui: &'ui Ui,
86    label: String,
87    size: Option<[f32; 2]>,
88}
89
90impl<'ui> Button<'ui> {
91    /// Creates a new button builder
92    pub fn new(ui: &'ui Ui, label: impl AsRef<str>) -> Self {
93        Self {
94            ui,
95            label: label.as_ref().to_string(),
96            size: None,
97        }
98    }
99
100    /// Sets the size of the button
101    pub fn size(mut self, size: impl Into<[f32; 2]>) -> Self {
102        self.size = Some(size.into());
103        self
104    }
105
106    /// Builds the button
107    pub fn build(self) -> bool {
108        let label_ptr = self.ui.scratch_txt(&self.label);
109        let size = self.size.unwrap_or([0.0, 0.0]);
110        let size_vec: sys::ImVec2 = size.into();
111        unsafe { sys::igButton(label_ptr, size_vec) }
112    }
113}