dear_imgui/widget/
color.rs

1use crate::sys;
2use crate::ui::Ui;
3
4/// Flags for color edit widgets
5#[repr(transparent)]
6#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
7pub struct ColorEditFlags(u32);
8
9impl ColorEditFlags {
10    /// No flags
11    pub const NONE: Self = Self(0);
12    /// ColorEdit, ColorPicker, ColorButton: ignore Alpha component (will only read 3 components from the input pointer).
13    pub const NO_ALPHA: Self = Self(sys::ImGuiColorEditFlags_NoAlpha as u32);
14    /// ColorEdit: disable picker when clicking on color square.
15    pub const NO_PICKER: Self = Self(sys::ImGuiColorEditFlags_NoPicker as u32);
16    /// ColorEdit: disable toggling options menu when right-clicking on inputs/small preview.
17    pub const NO_OPTIONS: Self = Self(sys::ImGuiColorEditFlags_NoOptions as u32);
18    /// ColorEdit, ColorPicker: disable color square preview next to the inputs. (e.g. to show only the inputs)
19    pub const NO_SMALL_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_NoSmallPreview as u32);
20    /// ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview color square).
21    pub const NO_INPUTS: Self = Self(sys::ImGuiColorEditFlags_NoInputs as u32);
22    /// ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview.
23    pub const NO_TOOLTIP: Self = Self(sys::ImGuiColorEditFlags_NoTooltip as u32);
24    /// ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker).
25    pub const NO_LABEL: Self = Self(sys::ImGuiColorEditFlags_NoLabel as u32);
26    /// ColorPicker: disable bigger color preview on right side of the picker, use small color square preview instead.
27    pub const NO_SIDE_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_NoSidePreview as u32);
28    /// ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
29    pub const NO_DRAG_DROP: Self = Self(sys::ImGuiColorEditFlags_NoDragDrop as u32);
30    /// ColorButton: disable border (which is enforced by default)
31    pub const NO_BORDER: Self = Self(sys::ImGuiColorEditFlags_NoBorder as u32);
32
33    /// ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
34    pub const ALPHA_BAR: Self = Self(sys::ImGuiColorEditFlags_AlphaBar as u32);
35    /// ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque.
36    pub const ALPHA_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_AlphaNoBg as u32);
37    /// ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque.
38    pub const ALPHA_PREVIEW_HALF: Self = Self(sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32);
39    /// (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
40    pub const HDR: Self = Self(sys::ImGuiColorEditFlags_HDR as u32);
41    /// ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
42    pub const DISPLAY_RGB: Self = Self(sys::ImGuiColorEditFlags_DisplayRGB as u32);
43    /// ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
44    pub const DISPLAY_HSV: Self = Self(sys::ImGuiColorEditFlags_DisplayHSV as u32);
45    /// ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
46    pub const DISPLAY_HEX: Self = Self(sys::ImGuiColorEditFlags_DisplayHex as u32);
47    /// ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255.
48    pub const UINT8: Self = Self(sys::ImGuiColorEditFlags_Uint8 as u32);
49    /// ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers.
50    pub const FLOAT: Self = Self(sys::ImGuiColorEditFlags_Float as u32);
51    /// ColorPicker: bar for Hue, rectangle for Sat/Value.
52    pub const PICKER_HUE_BAR: Self = Self(sys::ImGuiColorEditFlags_PickerHueBar as u32);
53    /// ColorPicker: wheel for Hue, triangle for Sat/Value.
54    pub const PICKER_HUE_WHEEL: Self = Self(sys::ImGuiColorEditFlags_PickerHueWheel as u32);
55    /// ColorEdit, ColorPicker: input and output data in RGB format.
56    pub const INPUT_RGB: Self = Self(sys::ImGuiColorEditFlags_InputRGB as u32);
57    /// ColorEdit, ColorPicker: input and output data in HSV format.
58    pub const INPUT_HSV: Self = Self(sys::ImGuiColorEditFlags_InputHSV as u32);
59
60    /// Returns the underlying bits
61    pub const fn bits(self) -> u32 {
62        self.0
63    }
64
65    /// Returns true if all flags are set
66    pub const fn contains(self, other: Self) -> bool {
67        (self.0 & other.0) == other.0
68    }
69}
70
71impl std::ops::BitOr for ColorEditFlags {
72    type Output = Self;
73    fn bitor(self, rhs: Self) -> Self::Output {
74        Self(self.0 | rhs.0)
75    }
76}
77
78impl std::ops::BitOrAssign for ColorEditFlags {
79    fn bitor_assign(&mut self, rhs: Self) {
80        self.0 |= rhs.0;
81    }
82}
83
84impl std::ops::BitAnd for ColorEditFlags {
85    type Output = Self;
86    fn bitand(self, rhs: Self) -> Self::Output {
87        Self(self.0 & rhs.0)
88    }
89}
90
91impl std::ops::BitAndAssign for ColorEditFlags {
92    fn bitand_assign(&mut self, rhs: Self) {
93        self.0 &= rhs.0;
94    }
95}
96
97impl std::ops::BitXor for ColorEditFlags {
98    type Output = Self;
99    fn bitxor(self, rhs: Self) -> Self::Output {
100        Self(self.0 ^ rhs.0)
101    }
102}
103
104impl std::ops::BitXorAssign for ColorEditFlags {
105    fn bitxor_assign(&mut self, rhs: Self) {
106        self.0 ^= rhs.0;
107    }
108}
109
110impl std::ops::Not for ColorEditFlags {
111    type Output = Self;
112    fn not(self) -> Self::Output {
113        Self(!self.0)
114    }
115}
116
117/// # Color Edit Widgets
118impl Ui {
119    /// Creates a color edit widget for 3 components (RGB)
120    #[doc(alias = "ColorEdit3")]
121    pub fn color_edit3(&self, label: impl AsRef<str>, color: &mut [f32; 3]) -> bool {
122        self.color_edit3_config(label, color).build()
123    }
124
125    /// Creates a color edit widget for 4 components (RGBA)
126    #[doc(alias = "ColorEdit4")]
127    pub fn color_edit4(&self, label: impl AsRef<str>, color: &mut [f32; 4]) -> bool {
128        self.color_edit4_config(label, color).build()
129    }
130
131    /// Creates a color picker widget for 3 components (RGB)
132    #[doc(alias = "ColorPicker3")]
133    pub fn color_picker3(&self, label: impl AsRef<str>, color: &mut [f32; 3]) -> bool {
134        self.color_picker3_config(label, color).build()
135    }
136
137    /// Creates a color picker widget for 4 components (RGBA)
138    #[doc(alias = "ColorPicker4")]
139    pub fn color_picker4(&self, label: impl AsRef<str>, color: &mut [f32; 4]) -> bool {
140        self.color_picker4_config(label, color).build()
141    }
142
143    /// Creates a color button widget
144    #[doc(alias = "ColorButton")]
145    pub fn color_button(&self, desc_id: impl AsRef<str>, color: [f32; 4]) -> bool {
146        self.color_button_config(desc_id, color).build()
147    }
148
149    /// Creates a color edit builder for 3 components
150    pub fn color_edit3_config<'p>(
151        &self,
152        label: impl AsRef<str>,
153        color: &'p mut [f32; 3],
154    ) -> ColorEdit3<'_, 'p> {
155        ColorEdit3::new(self, label, color)
156    }
157
158    /// Creates a color edit builder for 4 components
159    pub fn color_edit4_config<'p>(
160        &self,
161        label: impl AsRef<str>,
162        color: &'p mut [f32; 4],
163    ) -> ColorEdit4<'_, 'p> {
164        ColorEdit4::new(self, label, color)
165    }
166
167    /// Creates a color picker builder for 3 components
168    pub fn color_picker3_config<'p>(
169        &self,
170        label: impl AsRef<str>,
171        color: &'p mut [f32; 3],
172    ) -> ColorPicker3<'_, 'p> {
173        ColorPicker3::new(self, label, color)
174    }
175
176    /// Creates a color picker builder for 4 components
177    pub fn color_picker4_config<'p>(
178        &self,
179        label: impl AsRef<str>,
180        color: &'p mut [f32; 4],
181    ) -> ColorPicker4<'_, 'p> {
182        ColorPicker4::new(self, label, color)
183    }
184
185    /// Creates a color button builder
186    pub fn color_button_config(
187        &self,
188        desc_id: impl AsRef<str>,
189        color: [f32; 4],
190    ) -> ColorButton<'_> {
191        ColorButton::new(self, desc_id, color)
192    }
193}
194
195/// Builder for a 3-component color edit widget
196#[derive(Debug)]
197#[must_use]
198pub struct ColorEdit3<'ui, 'p> {
199    ui: &'ui Ui,
200    label: String,
201    color: &'p mut [f32; 3],
202    flags: ColorEditFlags,
203}
204
205impl<'ui, 'p> ColorEdit3<'ui, 'p> {
206    /// Creates a new color edit builder
207    pub fn new(ui: &'ui Ui, label: impl AsRef<str>, color: &'p mut [f32; 3]) -> Self {
208        Self {
209            ui,
210            label: label.as_ref().to_string(),
211            color,
212            flags: ColorEditFlags::NONE,
213        }
214    }
215
216    /// Sets the flags for the color edit
217    pub fn flags(mut self, flags: ColorEditFlags) -> Self {
218        self.flags = flags;
219        self
220    }
221
222    /// Builds the color edit widget
223    pub fn build(self) -> bool {
224        let label_ptr = self.ui.scratch_txt(&self.label);
225        unsafe { sys::igColorEdit3(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
226    }
227}
228
229/// Builder for a 4-component color edit widget
230#[derive(Debug)]
231#[must_use]
232pub struct ColorEdit4<'ui, 'p> {
233    ui: &'ui Ui,
234    label: String,
235    color: &'p mut [f32; 4],
236    flags: ColorEditFlags,
237}
238
239impl<'ui, 'p> ColorEdit4<'ui, 'p> {
240    /// Creates a new color edit builder
241    pub fn new(ui: &'ui Ui, label: impl AsRef<str>, color: &'p mut [f32; 4]) -> Self {
242        Self {
243            ui,
244            label: label.as_ref().to_string(),
245            color,
246            flags: ColorEditFlags::NONE,
247        }
248    }
249
250    /// Sets the flags for the color edit
251    pub fn flags(mut self, flags: ColorEditFlags) -> Self {
252        self.flags = flags;
253        self
254    }
255
256    /// Builds the color edit widget
257    pub fn build(self) -> bool {
258        let label_ptr = self.ui.scratch_txt(&self.label);
259        unsafe { sys::igColorEdit4(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
260    }
261}
262
263/// Builder for a 3-component color picker widget
264#[derive(Debug)]
265#[must_use]
266pub struct ColorPicker3<'ui, 'p> {
267    ui: &'ui Ui,
268    label: String,
269    color: &'p mut [f32; 3],
270    flags: ColorEditFlags,
271}
272
273impl<'ui, 'p> ColorPicker3<'ui, 'p> {
274    /// Creates a new color picker builder
275    pub fn new(ui: &'ui Ui, label: impl AsRef<str>, color: &'p mut [f32; 3]) -> Self {
276        Self {
277            ui,
278            label: label.as_ref().to_string(),
279            color,
280            flags: ColorEditFlags::NONE,
281        }
282    }
283
284    /// Sets the flags for the color picker
285    pub fn flags(mut self, flags: ColorEditFlags) -> Self {
286        self.flags = flags;
287        self
288    }
289
290    /// Builds the color picker widget
291    pub fn build(self) -> bool {
292        let label_ptr = self.ui.scratch_txt(&self.label);
293        unsafe { sys::igColorPicker3(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
294    }
295}
296
297/// Builder for a 4-component color picker widget
298#[derive(Debug)]
299#[must_use]
300pub struct ColorPicker4<'ui, 'p> {
301    ui: &'ui Ui,
302    label: String,
303    color: &'p mut [f32; 4],
304    flags: ColorEditFlags,
305    ref_color: Option<[f32; 4]>,
306}
307
308impl<'ui, 'p> ColorPicker4<'ui, 'p> {
309    /// Creates a new color picker builder
310    pub fn new(ui: &'ui Ui, label: impl AsRef<str>, color: &'p mut [f32; 4]) -> Self {
311        Self {
312            ui,
313            label: label.as_ref().to_string(),
314            color,
315            flags: ColorEditFlags::NONE,
316            ref_color: None,
317        }
318    }
319
320    /// Sets the flags for the color picker
321    pub fn flags(mut self, flags: ColorEditFlags) -> Self {
322        self.flags = flags;
323        self
324    }
325
326    /// Sets the reference color for comparison
327    pub fn reference_color(mut self, ref_color: [f32; 4]) -> Self {
328        self.ref_color = Some(ref_color);
329        self
330    }
331
332    /// Builds the color picker widget
333    pub fn build(self) -> bool {
334        let label_ptr = self.ui.scratch_txt(&self.label);
335        let ref_color_ptr = self
336            .ref_color
337            .as_ref()
338            .map_or(std::ptr::null(), |c| c.as_ptr());
339
340        unsafe {
341            sys::igColorPicker4(
342                label_ptr,
343                self.color.as_mut_ptr(),
344                self.flags.bits() as i32,
345                ref_color_ptr,
346            )
347        }
348    }
349}
350
351/// Builder for a color button widget
352#[derive(Debug)]
353#[must_use]
354pub struct ColorButton<'ui> {
355    ui: &'ui Ui,
356    desc_id: String,
357    color: [f32; 4],
358    flags: ColorEditFlags,
359    size: [f32; 2],
360}
361
362impl<'ui> ColorButton<'ui> {
363    /// Creates a new color button builder
364    pub fn new(ui: &'ui Ui, desc_id: impl AsRef<str>, color: [f32; 4]) -> Self {
365        Self {
366            ui,
367            desc_id: desc_id.as_ref().to_string(),
368            color,
369            flags: ColorEditFlags::NONE,
370            size: [0.0, 0.0],
371        }
372    }
373
374    /// Sets the flags for the color button
375    pub fn flags(mut self, flags: ColorEditFlags) -> Self {
376        self.flags = flags;
377        self
378    }
379
380    /// Sets the size of the color button
381    pub fn size(mut self, size: [f32; 2]) -> Self {
382        self.size = size;
383        self
384    }
385
386    /// Builds the color button widget
387    pub fn build(self) -> bool {
388        let desc_id_ptr = self.ui.scratch_txt(&self.desc_id);
389        let size_vec: sys::ImVec2 = self.size.into();
390
391        unsafe {
392            sys::igColorButton(
393                desc_id_ptr,
394                sys::ImVec4 {
395                    x: self.color[0],
396                    y: self.color[1],
397                    z: self.color[2],
398                    w: self.color[3],
399                },
400                self.flags.bits() as i32,
401                size_vec,
402            )
403        }
404    }
405}