dear_imgui/widget/
misc.rs

1#![allow(
2    clippy::cast_possible_truncation,
3    clippy::cast_sign_loss,
4    clippy::as_conversions
5)]
6use crate::Ui;
7use crate::sys;
8
9bitflags::bitflags! {
10    /// Flags for invisible buttons
11    #[repr(transparent)]
12    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
13    pub struct ButtonFlags: i32 {
14        /// No flags
15        const NONE = 0;
16        /// React on left mouse button
17        const MOUSE_BUTTON_LEFT = sys::ImGuiButtonFlags_MouseButtonLeft as i32;
18        /// React on right mouse button
19        const MOUSE_BUTTON_RIGHT = sys::ImGuiButtonFlags_MouseButtonRight as i32;
20        /// React on middle mouse button
21        const MOUSE_BUTTON_MIDDLE = sys::ImGuiButtonFlags_MouseButtonMiddle as i32;
22    }
23}
24
25/// Direction for arrow buttons (alias for Direction)
26pub use crate::Direction as ArrowDirection;
27
28impl Ui {
29    /// Creates a bullet point
30    #[doc(alias = "Bullet")]
31    pub fn bullet(&self) {
32        unsafe {
33            sys::igBullet();
34        }
35    }
36
37    /// Creates a bullet point with text
38    #[doc(alias = "BulletText")]
39    pub fn bullet_text(&self, text: impl AsRef<str>) {
40        let text_ptr = self.scratch_txt(text);
41        unsafe {
42            sys::igBulletText(text_ptr);
43        }
44    }
45}
46
47impl Ui {
48    /// Creates a small button
49    #[doc(alias = "SmallButton")]
50    pub fn small_button(&self, label: impl AsRef<str>) -> bool {
51        let label_ptr = self.scratch_txt(label);
52        unsafe { sys::igSmallButton(label_ptr) }
53    }
54
55    /// Creates an invisible button
56    #[doc(alias = "InvisibleButton")]
57    pub fn invisible_button(&self, str_id: impl AsRef<str>, size: impl Into<[f32; 2]>) -> bool {
58        self.invisible_button_flags(str_id, size, crate::widget::ButtonFlags::NONE)
59    }
60
61    /// Creates an invisible button with flags
62    #[doc(alias = "InvisibleButton")]
63    pub fn invisible_button_flags(
64        &self,
65        str_id: impl AsRef<str>,
66        size: impl Into<[f32; 2]>,
67        flags: crate::widget::ButtonFlags,
68    ) -> bool {
69        let id_ptr = self.scratch_txt(str_id);
70        let size_vec: sys::ImVec2 = size.into().into();
71        unsafe { sys::igInvisibleButton(id_ptr, size_vec, flags.bits()) }
72    }
73
74    /// Creates an arrow button
75    #[doc(alias = "ArrowButton")]
76    pub fn arrow_button(&self, str_id: impl AsRef<str>, dir: crate::Direction) -> bool {
77        let id_ptr = self.scratch_txt(str_id);
78        unsafe { sys::igArrowButton(id_ptr, dir as i32) }
79    }
80}
81
82// ============================================================================
83// Disabled scope (RAII)
84// ============================================================================
85
86/// Tracks a disabled scope begun with [`Ui::begin_disabled`] and ended on drop.
87#[must_use]
88pub struct DisabledToken<'ui> {
89    _ui: &'ui Ui,
90}
91
92impl<'ui> DisabledToken<'ui> {
93    fn new(ui: &'ui Ui) -> Self {
94        DisabledToken { _ui: ui }
95    }
96
97    /// Ends the disabled scope explicitly.
98    pub fn end(self) {
99        // Drop will call EndDisabled
100    }
101}
102
103impl<'ui> Drop for DisabledToken<'ui> {
104    fn drop(&mut self) {
105        unsafe { sys::igEndDisabled() }
106    }
107}
108
109impl Ui {
110    /// Begin a disabled scope for subsequent items.
111    ///
112    /// All following widgets will be disabled (grayed out and non-interactive)
113    /// until the returned token is dropped.
114    #[doc(alias = "BeginDisabled")]
115    pub fn begin_disabled(&self) -> DisabledToken<'_> {
116        unsafe { sys::igBeginDisabled(true) }
117        DisabledToken::new(self)
118    }
119
120    /// Begin a conditionally disabled scope for subsequent items.
121    ///
122    /// If `disabled` is false, this still needs to be paired with the returned
123    /// token being dropped to correctly balance the internal stack.
124    #[doc(alias = "BeginDisabled")]
125    pub fn begin_disabled_with_cond(&self, disabled: bool) -> DisabledToken<'_> {
126        unsafe { sys::igBeginDisabled(disabled) }
127        DisabledToken::new(self)
128    }
129}
130
131// ============================================================================
132// Button repeat (convenience over item flag)
133// ============================================================================
134
135impl Ui {
136    /// Enable/disable repeating behavior for subsequent buttons.
137    ///
138    /// Internally uses `PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat)`.
139    #[doc(alias = "PushButtonRepeat")]
140    pub fn push_button_repeat(&self, repeat: bool) {
141        unsafe { sys::igPushItemFlag(sys::ImGuiItemFlags_ButtonRepeat as i32, repeat) }
142    }
143
144    /// Pop the button repeat item flag.
145    #[doc(alias = "PopButtonRepeat")]
146    pub fn pop_button_repeat(&self) {
147        unsafe { sys::igPopItemFlag() }
148    }
149}
150
151// ============================================================================
152// Item key ownership
153// ============================================================================
154
155impl Ui {
156    /// Set the key owner for the last item, without flags.
157    #[doc(alias = "SetItemKeyOwner")]
158    pub fn set_item_key_owner(&self, key: crate::input::Key) {
159        let k: sys::ImGuiKey = key as sys::ImGuiKey;
160        unsafe { sys::igSetItemKeyOwner_Nil(k) }
161    }
162
163    /// Set the key owner for the last item with input flags.
164    /// Pass a combination of `ImGuiInputFlags_*` from `dear_imgui_sys`.
165    #[doc(alias = "SetItemKeyOwner")]
166    pub fn set_item_key_owner_with_flags(
167        &self,
168        key: crate::input::Key,
169        flags: sys::ImGuiInputFlags,
170    ) {
171        let k: sys::ImGuiKey = key as sys::ImGuiKey;
172        unsafe { sys::igSetItemKeyOwner_InputFlags(k, flags) }
173    }
174}