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 `SetColorEditOptions()`.
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        /// Compatibility alias for [`Self::ALPHA_NO_BG`].
42        const ALPHA_PREVIEW = Self::ALPHA_NO_BG.bits();
43        /// Display half opaque / half checkerboard, instead of opaque.
44        const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32;
45        /// Disable 0.0f..1.0f limits in RGBA edition.
46        const HDR = sys::ImGuiColorEditFlags_HDR 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        /// Compatibility alias for [`Self::ALPHA_NO_BG`].
79        const ALPHA_PREVIEW = Self::ALPHA_NO_BG.bits();
80        /// Display half opaque / half checkerboard, instead of opaque.
81        const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32;
82        /// Disable 0.0f..1.0f limits in RGBA edition.
83        const HDR = sys::ImGuiColorEditFlags_HDR 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        /// Compatibility alias for [`Self::ALPHA_NO_BG`].
107        const ALPHA_PREVIEW = Self::ALPHA_NO_BG.bits();
108        /// Display half opaque / half checkerboard, instead of opaque.
109        const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32;
110    }
111}
112
113/// Single display mode for color edit widgets.
114#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
115pub enum ColorDisplayMode {
116    Rgb,
117    Hsv,
118    Hex,
119}
120
121impl ColorDisplayMode {
122    const fn raw(self) -> u32 {
123        match self {
124            Self::Rgb => sys::ImGuiColorEditFlags_DisplayRGB as u32,
125            Self::Hsv => sys::ImGuiColorEditFlags_DisplayHSV as u32,
126            Self::Hex => sys::ImGuiColorEditFlags_DisplayHex as u32,
127        }
128    }
129}
130
131/// Single numeric representation for color edit widgets and defaults.
132#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
133pub enum ColorDataType {
134    Uint8,
135    Float,
136}
137
138impl ColorDataType {
139    const fn raw(self) -> u32 {
140        match self {
141            Self::Uint8 => sys::ImGuiColorEditFlags_Uint8 as u32,
142            Self::Float => sys::ImGuiColorEditFlags_Float as u32,
143        }
144    }
145}
146
147/// Single picker implementation for color picker widgets and defaults.
148#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
149pub enum ColorPickerMode {
150    HueBar,
151    HueWheel,
152}
153
154impl ColorPickerMode {
155    const fn raw(self) -> u32 {
156        match self {
157            Self::HueBar => sys::ImGuiColorEditFlags_PickerHueBar as u32,
158            Self::HueWheel => sys::ImGuiColorEditFlags_PickerHueWheel as u32,
159        }
160    }
161}
162
163/// Single input/output color space for color edit and picker widgets.
164#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
165pub enum ColorInputMode {
166    Rgb,
167    Hsv,
168}
169
170impl ColorInputMode {
171    const fn raw(self) -> u32 {
172        match self {
173            Self::Rgb => sys::ImGuiColorEditFlags_InputRGB as u32,
174            Self::Hsv => sys::ImGuiColorEditFlags_InputHSV as u32,
175        }
176    }
177}
178
179bitflags::bitflags! {
180    /// Display sub-editors visible inside `ColorPicker*()`.
181    #[repr(transparent)]
182    #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
183    pub struct ColorPickerDisplayFlags: u32 {
184        const RGB = sys::ImGuiColorEditFlags_DisplayRGB as u32;
185        const HSV = sys::ImGuiColorEditFlags_DisplayHSV as u32;
186        const HEX = sys::ImGuiColorEditFlags_DisplayHex as u32;
187    }
188}
189
190/// Options accepted by `ColorEdit3()`, `ColorEdit4()`, and
191/// `SetColorEditOptions()`.
192#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
193pub struct ColorEditOptions {
194    pub flags: ColorEditFlags,
195    pub display_mode: Option<ColorDisplayMode>,
196    pub data_type: Option<ColorDataType>,
197    pub picker_mode: Option<ColorPickerMode>,
198    pub input_mode: Option<ColorInputMode>,
199}
200
201impl ColorEditOptions {
202    pub const fn new() -> Self {
203        Self {
204            flags: ColorEditFlags::NONE,
205            display_mode: None,
206            data_type: None,
207            picker_mode: None,
208            input_mode: None,
209        }
210    }
211
212    pub fn flags(mut self, flags: ColorEditFlags) -> Self {
213        self.flags = flags;
214        self
215    }
216
217    pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
218        self.display_mode = Some(mode);
219        self
220    }
221
222    pub fn data_type(mut self, data_type: ColorDataType) -> Self {
223        self.data_type = Some(data_type);
224        self
225    }
226
227    pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
228        self.picker_mode = Some(mode);
229        self
230    }
231
232    pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
233        self.input_mode = Some(mode);
234        self
235    }
236
237    pub fn bits(self) -> u32 {
238        self.flags.bits()
239            | self.display_mode.map_or(0, ColorDisplayMode::raw)
240            | self.data_type.map_or(0, ColorDataType::raw)
241            | self.picker_mode.map_or(0, ColorPickerMode::raw)
242            | self.input_mode.map_or(0, ColorInputMode::raw)
243    }
244
245    pub(crate) fn validate(self, caller: &str) {
246        validate_color_edit_flags(caller, self.flags);
247        validate_color_supported_bits(caller, self.bits(), color_edit_supported_mask());
248        assert_color_single_choice_mask(caller, self.bits(), color_display_mask(), "display mode");
249        assert_color_single_choice_mask(caller, self.bits(), color_data_type_mask(), "data type");
250        assert_color_single_choice_mask(caller, self.bits(), color_picker_mask(), "picker mode");
251        assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
252    }
253}
254
255impl Default for ColorEditOptions {
256    fn default() -> Self {
257        Self::new()
258    }
259}
260
261impl From<ColorEditFlags> for ColorEditOptions {
262    fn from(flags: ColorEditFlags) -> Self {
263        Self::new().flags(flags)
264    }
265}
266
267/// Options accepted by `ColorPicker3()` and `ColorPicker4()`.
268#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
269pub struct ColorPickerOptions {
270    pub flags: ColorPickerFlags,
271    pub display_flags: ColorPickerDisplayFlags,
272    pub data_type: Option<ColorDataType>,
273    pub picker_mode: Option<ColorPickerMode>,
274    pub input_mode: Option<ColorInputMode>,
275}
276
277impl ColorPickerOptions {
278    pub const fn new() -> Self {
279        Self {
280            flags: ColorPickerFlags::NONE,
281            display_flags: ColorPickerDisplayFlags::empty(),
282            data_type: None,
283            picker_mode: None,
284            input_mode: None,
285        }
286    }
287
288    pub fn flags(mut self, flags: ColorPickerFlags) -> Self {
289        self.flags = flags;
290        self
291    }
292
293    pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
294        self.display_flags = flags;
295        self
296    }
297
298    pub fn data_type(mut self, data_type: ColorDataType) -> Self {
299        self.data_type = Some(data_type);
300        self
301    }
302
303    pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
304        self.picker_mode = Some(mode);
305        self
306    }
307
308    pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
309        self.input_mode = Some(mode);
310        self
311    }
312
313    pub fn bits(self) -> u32 {
314        self.flags.bits()
315            | self.display_flags.bits()
316            | self.data_type.map_or(0, ColorDataType::raw)
317            | self.picker_mode.map_or(0, ColorPickerMode::raw)
318            | self.input_mode.map_or(0, ColorInputMode::raw)
319    }
320
321    pub(crate) fn validate(self, caller: &str) {
322        validate_color_picker_flags(caller, self.flags);
323        let unsupported_display =
324            self.display_flags.bits() & !ColorPickerDisplayFlags::all().bits();
325        assert!(
326            unsupported_display == 0,
327            "{caller} received unsupported ColorPickerDisplayFlags bits: 0x{unsupported_display:X}"
328        );
329        validate_color_supported_bits(caller, self.bits(), color_picker_supported_mask());
330        assert_color_single_choice_mask(caller, self.bits(), color_data_type_mask(), "data type");
331        assert_color_single_choice_mask(caller, self.bits(), color_picker_mask(), "picker mode");
332        assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
333    }
334}
335
336impl Default for ColorPickerOptions {
337    fn default() -> Self {
338        Self::new()
339    }
340}
341
342impl From<ColorPickerFlags> for ColorPickerOptions {
343    fn from(flags: ColorPickerFlags) -> Self {
344        Self::new().flags(flags)
345    }
346}
347
348/// Options accepted by `ColorButton()`.
349#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
350pub struct ColorButtonOptions {
351    pub flags: ColorButtonFlags,
352    pub input_mode: Option<ColorInputMode>,
353}
354
355impl ColorButtonOptions {
356    pub const fn new() -> Self {
357        Self {
358            flags: ColorButtonFlags::NONE,
359            input_mode: None,
360        }
361    }
362
363    pub fn flags(mut self, flags: ColorButtonFlags) -> Self {
364        self.flags = flags;
365        self
366    }
367
368    pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
369        self.input_mode = Some(mode);
370        self
371    }
372
373    pub fn bits(self) -> u32 {
374        self.flags.bits() | self.input_mode.map_or(0, ColorInputMode::raw)
375    }
376
377    pub(crate) fn validate(self, caller: &str) {
378        validate_color_button_flags(caller, self.flags);
379        validate_color_supported_bits(caller, self.bits(), color_button_supported_mask());
380        assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
381    }
382}
383
384impl Default for ColorButtonOptions {
385    fn default() -> Self {
386        Self::new()
387    }
388}
389
390impl From<ColorButtonFlags> for ColorButtonOptions {
391    fn from(flags: ColorButtonFlags) -> Self {
392        Self::new().flags(flags)
393    }
394}