Skip to main content

dear_imgui_rs/widget/color/
flags.rs

1use super::validation::{
2    assert_color_single_choice_mask, color_button_supported_mask, color_data_type_mask,
3    color_display_mask, color_edit_supported_mask, color_input_mask, color_picker_mask,
4    color_picker_supported_mask, validate_color_button_flags, validate_color_edit_flags,
5    validate_color_picker_flags, validate_color_supported_bits,
6};
7use crate::sys;
8
9bitflags::bitflags! {
10    /// Independently composable flags accepted by `ColorEdit3()`,
11    /// `ColorEdit4()`, and `Io::set_color_edit_options()`.
12    #[repr(transparent)]
13    #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
14    pub struct ColorEditFlags: u32 {
15        /// No flags.
16        const NONE = 0;
17        /// Ignore Alpha component (will only read 3 components from the input pointer).
18        const NO_ALPHA = sys::ImGuiColorEditFlags_NoAlpha as u32;
19        /// Disable picker when clicking on color square.
20        const NO_PICKER = sys::ImGuiColorEditFlags_NoPicker as u32;
21        /// Disable toggling options menu when right-clicking on inputs/small preview.
22        const NO_OPTIONS = sys::ImGuiColorEditFlags_NoOptions as u32;
23        /// Disable color square preview next to the inputs.
24        const NO_SMALL_PREVIEW = sys::ImGuiColorEditFlags_NoSmallPreview as u32;
25        /// Disable inputs sliders/text widgets.
26        const NO_INPUTS = sys::ImGuiColorEditFlags_NoInputs as u32;
27        /// Disable tooltip when hovering the preview.
28        const NO_TOOLTIP = sys::ImGuiColorEditFlags_NoTooltip as u32;
29        /// Disable display of inline text label.
30        const NO_LABEL = sys::ImGuiColorEditFlags_NoLabel as u32;
31        /// Disable drag and drop target/source.
32        const NO_DRAG_DROP = sys::ImGuiColorEditFlags_NoDragDrop as u32;
33        /// Disable rendering R/G/B/A color markers.
34        const NO_COLOR_MARKERS = sys::ImGuiColorEditFlags_NoColorMarkers as u32;
35        /// Show vertical alpha bar/gradient in the picker.
36        const ALPHA_BAR = sys::ImGuiColorEditFlags_AlphaBar as u32;
37        /// Disable alpha in the preview.
38        const ALPHA_OPAQUE = sys::ImGuiColorEditFlags_AlphaOpaque as u32;
39        /// Disable the checkerboard background behind transparent colors.
40        const ALPHA_NO_BG = sys::ImGuiColorEditFlags_AlphaNoBg as u32;
41        /// Display half opaque / half checkerboard, instead of opaque.
42        const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32;
43        /// Disable 0.0f..1.0f limits in RGBA edition.
44        const HDR = sys::ImGuiColorEditFlags_HDR as u32;
45        /// Disable rotation of the saturation/value triangle in the color picker.
46        const PICKER_NO_ROTATE = sys::ImGuiColorEditFlags_PickerNoRotate as u32;
47    }
48}
49
50bitflags::bitflags! {
51    /// Independently composable flags accepted by `ColorPicker3()` and
52    /// `ColorPicker4()`.
53    #[repr(transparent)]
54    #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
55    pub struct ColorPickerFlags: u32 {
56        /// No flags.
57        const NONE = 0;
58        /// Ignore Alpha component (will only read 3 components from the input pointer).
59        const NO_ALPHA = sys::ImGuiColorEditFlags_NoAlpha as u32;
60        /// Disable toggling options menu when right-clicking.
61        const NO_OPTIONS = sys::ImGuiColorEditFlags_NoOptions as u32;
62        /// Disable color square preview next to the inputs.
63        const NO_SMALL_PREVIEW = sys::ImGuiColorEditFlags_NoSmallPreview as u32;
64        /// Disable inputs sliders/text widgets.
65        const NO_INPUTS = sys::ImGuiColorEditFlags_NoInputs as u32;
66        /// Disable tooltip when hovering the preview.
67        const NO_TOOLTIP = sys::ImGuiColorEditFlags_NoTooltip as u32;
68        /// Disable display of inline text label.
69        const NO_LABEL = sys::ImGuiColorEditFlags_NoLabel as u32;
70        /// Disable bigger color preview on right side of the picker.
71        const NO_SIDE_PREVIEW = sys::ImGuiColorEditFlags_NoSidePreview as u32;
72        /// Show vertical alpha bar/gradient in the picker.
73        const ALPHA_BAR = sys::ImGuiColorEditFlags_AlphaBar as u32;
74        /// Disable alpha in the preview.
75        const ALPHA_OPAQUE = sys::ImGuiColorEditFlags_AlphaOpaque as u32;
76        /// Disable the checkerboard background behind transparent colors.
77        const ALPHA_NO_BG = sys::ImGuiColorEditFlags_AlphaNoBg as u32;
78        /// Display half opaque / half checkerboard, instead of opaque.
79        const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32;
80        /// Disable 0.0f..1.0f limits in RGBA edition.
81        const HDR = sys::ImGuiColorEditFlags_HDR as u32;
82        /// Disable rotation of the saturation/value triangle.
83        const PICKER_NO_ROTATE = sys::ImGuiColorEditFlags_PickerNoRotate as u32;
84    }
85}
86
87bitflags::bitflags! {
88    /// Independently composable flags accepted by `ColorButton()`.
89    #[repr(transparent)]
90    #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
91    pub struct ColorButtonFlags: u32 {
92        /// No flags.
93        const NONE = 0;
94        /// Ignore Alpha component. For `ColorButton()` this does the same as [`Self::ALPHA_OPAQUE`].
95        const NO_ALPHA = sys::ImGuiColorEditFlags_NoAlpha as u32;
96        /// Disable tooltip when hovering the preview.
97        const NO_TOOLTIP = sys::ImGuiColorEditFlags_NoTooltip as u32;
98        /// Disable drag and drop source.
99        const NO_DRAG_DROP = sys::ImGuiColorEditFlags_NoDragDrop as u32;
100        /// Disable border (which is enforced by default).
101        const NO_BORDER = sys::ImGuiColorEditFlags_NoBorder as u32;
102        /// Disable alpha in the preview.
103        const ALPHA_OPAQUE = sys::ImGuiColorEditFlags_AlphaOpaque as u32;
104        /// Disable the checkerboard background behind transparent colors.
105        const ALPHA_NO_BG = sys::ImGuiColorEditFlags_AlphaNoBg as u32;
106        /// Display half opaque / half checkerboard, instead of opaque.
107        const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32;
108    }
109}
110
111/// Single display mode for color edit widgets.
112#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
113pub enum ColorDisplayMode {
114    Rgb,
115    Hsv,
116    Hex,
117}
118
119impl ColorDisplayMode {
120    const fn raw(self) -> u32 {
121        match self {
122            Self::Rgb => sys::ImGuiColorEditFlags_DisplayRGB as u32,
123            Self::Hsv => sys::ImGuiColorEditFlags_DisplayHSV as u32,
124            Self::Hex => sys::ImGuiColorEditFlags_DisplayHex as u32,
125        }
126    }
127}
128
129/// Single numeric representation for color edit widgets and defaults.
130#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
131pub enum ColorDataType {
132    Uint8,
133    Float,
134}
135
136impl ColorDataType {
137    const fn raw(self) -> u32 {
138        match self {
139            Self::Uint8 => sys::ImGuiColorEditFlags_Uint8 as u32,
140            Self::Float => sys::ImGuiColorEditFlags_Float as u32,
141        }
142    }
143}
144
145/// Single picker implementation for color picker widgets and defaults.
146#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
147pub enum ColorPickerMode {
148    HueBar,
149    HueWheel,
150}
151
152impl ColorPickerMode {
153    const fn raw(self) -> u32 {
154        match self {
155            Self::HueBar => sys::ImGuiColorEditFlags_PickerHueBar as u32,
156            Self::HueWheel => sys::ImGuiColorEditFlags_PickerHueWheel as u32,
157        }
158    }
159}
160
161/// Single input/output color space for color edit and picker widgets.
162#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
163pub enum ColorInputMode {
164    Rgb,
165    Hsv,
166}
167
168impl ColorInputMode {
169    const fn raw(self) -> u32 {
170        match self {
171            Self::Rgb => sys::ImGuiColorEditFlags_InputRGB as u32,
172            Self::Hsv => sys::ImGuiColorEditFlags_InputHSV as u32,
173        }
174    }
175}
176
177bitflags::bitflags! {
178    /// Display sub-editors visible inside `ColorPicker*()`.
179    #[repr(transparent)]
180    #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
181    pub struct ColorPickerDisplayFlags: u32 {
182        const RGB = sys::ImGuiColorEditFlags_DisplayRGB as u32;
183        const HSV = sys::ImGuiColorEditFlags_DisplayHSV as u32;
184        const HEX = sys::ImGuiColorEditFlags_DisplayHex as u32;
185    }
186}
187
188/// Options accepted by `ColorEdit3()`, `ColorEdit4()`, and
189/// `Io::set_color_edit_options()`.
190#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
191pub struct ColorEditOptions {
192    pub flags: ColorEditFlags,
193    pub display_mode: Option<ColorDisplayMode>,
194    pub data_type: Option<ColorDataType>,
195    pub picker_mode: Option<ColorPickerMode>,
196    pub input_mode: Option<ColorInputMode>,
197}
198
199impl ColorEditOptions {
200    pub const fn new() -> Self {
201        Self {
202            flags: ColorEditFlags::NONE,
203            display_mode: None,
204            data_type: None,
205            picker_mode: None,
206            input_mode: None,
207        }
208    }
209
210    pub fn flags(mut self, flags: ColorEditFlags) -> Self {
211        self.flags = flags;
212        self
213    }
214
215    pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
216        self.display_mode = Some(mode);
217        self
218    }
219
220    pub fn data_type(mut self, data_type: ColorDataType) -> Self {
221        self.data_type = Some(data_type);
222        self
223    }
224
225    pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
226        self.picker_mode = Some(mode);
227        self
228    }
229
230    pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
231        self.input_mode = Some(mode);
232        self
233    }
234
235    pub fn bits(self) -> u32 {
236        self.flags.bits()
237            | self.display_mode.map_or(0, ColorDisplayMode::raw)
238            | self.data_type.map_or(0, ColorDataType::raw)
239            | self.picker_mode.map_or(0, ColorPickerMode::raw)
240            | self.input_mode.map_or(0, ColorInputMode::raw)
241    }
242
243    pub(crate) fn from_bits(bits: u32, caller: &str) -> Self {
244        let options = Self {
245            flags: ColorEditFlags::from_bits_retain(bits & ColorEditFlags::all().bits()),
246            display_mode: match bits & color_display_mask() {
247                0 => None,
248                value if value == ColorDisplayMode::Rgb.raw() => Some(ColorDisplayMode::Rgb),
249                value if value == ColorDisplayMode::Hsv.raw() => Some(ColorDisplayMode::Hsv),
250                value if value == ColorDisplayMode::Hex.raw() => Some(ColorDisplayMode::Hex),
251                _ => panic!("{caller} contains an invalid color display mode"),
252            },
253            data_type: match bits & color_data_type_mask() {
254                0 => None,
255                value if value == ColorDataType::Uint8.raw() => Some(ColorDataType::Uint8),
256                value if value == ColorDataType::Float.raw() => Some(ColorDataType::Float),
257                _ => panic!("{caller} contains an invalid color data type"),
258            },
259            picker_mode: match bits & color_picker_mask() {
260                0 => None,
261                value if value == ColorPickerMode::HueBar.raw() => Some(ColorPickerMode::HueBar),
262                value if value == ColorPickerMode::HueWheel.raw() => {
263                    Some(ColorPickerMode::HueWheel)
264                }
265                _ => panic!("{caller} contains an invalid color picker mode"),
266            },
267            input_mode: match bits & color_input_mask() {
268                0 => None,
269                value if value == ColorInputMode::Rgb.raw() => Some(ColorInputMode::Rgb),
270                value if value == ColorInputMode::Hsv.raw() => Some(ColorInputMode::Hsv),
271                _ => panic!("{caller} contains an invalid color input mode"),
272            },
273        };
274        options.validate(caller);
275        options
276    }
277
278    pub(crate) fn with_default_choices(self) -> Self {
279        let mut bits = self.bits();
280        let defaults = sys::ImGuiColorEditFlags_DefaultOptions_ as u32;
281        for mask in [
282            color_display_mask(),
283            color_data_type_mask(),
284            color_picker_mask(),
285            color_input_mask(),
286        ] {
287            if bits & mask == 0 {
288                bits |= defaults & mask;
289            }
290        }
291        Self::from_bits(bits, "ColorEditOptions::with_default_choices()")
292    }
293
294    pub(crate) fn validate(self, caller: &str) {
295        validate_color_edit_flags(caller, self.flags);
296        validate_color_supported_bits(caller, self.bits(), color_edit_supported_mask());
297        assert_color_single_choice_mask(caller, self.bits(), color_display_mask(), "display mode");
298        assert_color_single_choice_mask(caller, self.bits(), color_data_type_mask(), "data type");
299        assert_color_single_choice_mask(caller, self.bits(), color_picker_mask(), "picker mode");
300        assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
301    }
302}
303
304impl Default for ColorEditOptions {
305    fn default() -> Self {
306        Self::new()
307    }
308}
309
310impl From<ColorEditFlags> for ColorEditOptions {
311    fn from(flags: ColorEditFlags) -> Self {
312        Self::new().flags(flags)
313    }
314}
315
316/// Options accepted by `ColorPicker3()` and `ColorPicker4()`.
317#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
318pub struct ColorPickerOptions {
319    pub flags: ColorPickerFlags,
320    pub display_flags: ColorPickerDisplayFlags,
321    pub data_type: Option<ColorDataType>,
322    pub picker_mode: Option<ColorPickerMode>,
323    pub input_mode: Option<ColorInputMode>,
324}
325
326impl ColorPickerOptions {
327    pub const fn new() -> Self {
328        Self {
329            flags: ColorPickerFlags::NONE,
330            display_flags: ColorPickerDisplayFlags::empty(),
331            data_type: None,
332            picker_mode: None,
333            input_mode: None,
334        }
335    }
336
337    pub fn flags(mut self, flags: ColorPickerFlags) -> Self {
338        self.flags = flags;
339        self
340    }
341
342    pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
343        self.display_flags = flags;
344        self
345    }
346
347    pub fn data_type(mut self, data_type: ColorDataType) -> Self {
348        self.data_type = Some(data_type);
349        self
350    }
351
352    pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
353        self.picker_mode = Some(mode);
354        self
355    }
356
357    pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
358        self.input_mode = Some(mode);
359        self
360    }
361
362    pub fn bits(self) -> u32 {
363        self.flags.bits()
364            | self.display_flags.bits()
365            | self.data_type.map_or(0, ColorDataType::raw)
366            | self.picker_mode.map_or(0, ColorPickerMode::raw)
367            | self.input_mode.map_or(0, ColorInputMode::raw)
368    }
369
370    pub(crate) fn validate(self, caller: &str) {
371        validate_color_picker_flags(caller, self.flags);
372        let unsupported_display =
373            self.display_flags.bits() & !ColorPickerDisplayFlags::all().bits();
374        assert!(
375            unsupported_display == 0,
376            "{caller} received unsupported ColorPickerDisplayFlags bits: 0x{unsupported_display:X}"
377        );
378        validate_color_supported_bits(caller, self.bits(), color_picker_supported_mask());
379        assert_color_single_choice_mask(caller, self.bits(), color_data_type_mask(), "data type");
380        assert_color_single_choice_mask(caller, self.bits(), color_picker_mask(), "picker mode");
381        assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
382    }
383}
384
385impl Default for ColorPickerOptions {
386    fn default() -> Self {
387        Self::new()
388    }
389}
390
391impl From<ColorPickerFlags> for ColorPickerOptions {
392    fn from(flags: ColorPickerFlags) -> Self {
393        Self::new().flags(flags)
394    }
395}
396
397/// Options accepted by `ColorButton()`.
398#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
399pub struct ColorButtonOptions {
400    pub flags: ColorButtonFlags,
401    pub input_mode: Option<ColorInputMode>,
402}
403
404impl ColorButtonOptions {
405    pub const fn new() -> Self {
406        Self {
407            flags: ColorButtonFlags::NONE,
408            input_mode: None,
409        }
410    }
411
412    pub fn flags(mut self, flags: ColorButtonFlags) -> Self {
413        self.flags = flags;
414        self
415    }
416
417    pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
418        self.input_mode = Some(mode);
419        self
420    }
421
422    pub fn bits(self) -> u32 {
423        self.flags.bits() | self.input_mode.map_or(0, ColorInputMode::raw)
424    }
425
426    pub(crate) fn validate(self, caller: &str) {
427        validate_color_button_flags(caller, self.flags);
428        validate_color_supported_bits(caller, self.bits(), color_button_supported_mask());
429        assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
430    }
431}
432
433impl Default for ColorButtonOptions {
434    fn default() -> Self {
435        Self::new()
436    }
437}
438
439impl From<ColorButtonFlags> for ColorButtonOptions {
440    fn from(flags: ColorButtonFlags) -> Self {
441        Self::new().flags(flags)
442    }
443}