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