1use bitflags::bitflags;
2use std::ptr;
3
4use crate::sys;
5use crate::Ui;
6
7#[derive(Debug)]
9pub enum EditableColor<'a> {
10 Float3(&'a mut [f32; 3]),
12 Float4(&'a mut [f32; 4]),
14}
15
16impl<'a> EditableColor<'a> {
17 fn as_mut_ptr(&mut self) -> *mut f32 {
19 match *self {
20 EditableColor::Float3(ref mut value) => value.as_mut_ptr(),
21 EditableColor::Float4(ref mut value) => value.as_mut_ptr(),
22 }
23 }
24}
25
26impl<'a> From<&'a mut [f32; 3]> for EditableColor<'a> {
27 #[inline]
28 fn from(value: &'a mut [f32; 3]) -> EditableColor<'a> {
29 EditableColor::Float3(value)
30 }
31}
32
33impl<'a> From<&'a mut [f32; 4]> for EditableColor<'a> {
34 #[inline]
35 fn from(value: &'a mut [f32; 4]) -> EditableColor<'a> {
36 EditableColor::Float4(value)
37 }
38}
39
40#[derive(Copy, Clone, Debug, PartialEq, Eq)]
42pub enum ColorEditInputMode {
43 Rgb,
45 Hsv,
47}
48
49impl ColorEditInputMode {
50 pub const RGB: Self = Self::Rgb;
53 pub const HSV: Self = Self::Hsv;
55}
56
57#[derive(Copy, Clone, Debug, PartialEq, Eq)]
59pub enum ColorEditDisplayMode {
60 Rgb,
62 Hsv,
64 Hex,
66}
67
68impl ColorEditDisplayMode {
69 pub const RGB: Self = Self::Rgb;
72 pub const HSV: Self = Self::Hsv;
74 pub const HEX: Self = Self::Hex;
76}
77
78#[derive(Copy, Clone, Debug, PartialEq, Eq)]
80pub enum ColorPickerMode {
81 HueBar,
83 HueWheel,
85}
86
87#[derive(Copy, Clone, Debug, PartialEq, Eq)]
89pub enum ColorFormat {
90 U8,
92 Float,
94}
95
96#[derive(Copy, Clone, Debug, PartialEq, Eq)]
98pub enum ColorPreview {
99 Opaque,
101 HalfAlpha,
103 Alpha,
105}
106
107bitflags! {
108 #[repr(transparent)]
110 pub struct ColorEditFlags: u32 {
111 const NO_ALPHA = sys::ImGuiColorEditFlags_NoAlpha;
114 const NO_PICKER = sys::ImGuiColorEditFlags_NoPicker;
116 const NO_OPTIONS = sys::ImGuiColorEditFlags_NoOptions;
118 const NO_SMALL_PREVIEW = sys::ImGuiColorEditFlags_NoSmallPreview;
121 const NO_INPUTS = sys::ImGuiColorEditFlags_NoInputs;
124 const NO_TOOLTIP = sys::ImGuiColorEditFlags_NoTooltip;
126 const NO_LABEL = sys::ImGuiColorEditFlags_NoLabel;
129 const NO_SIDE_PREVIEW = sys::ImGuiColorEditFlags_NoSidePreview;
132 const NO_DRAG_DROP = sys::ImGuiColorEditFlags_NoDragDrop;
134 const NO_BORDER = sys::ImGuiColorEditFlags_NoBorder;
136
137 const ALPHA_BAR = sys::ImGuiColorEditFlags_AlphaBar;
139 const ALPHA_PREVIEW = sys::ImGuiColorEditFlags_AlphaPreview;
142 const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf;
145 const HDR = sys::ImGuiColorEditFlags_HDR;
148 const DISPLAY_RGB = sys::ImGuiColorEditFlags_DisplayRGB;
150 const DISPLAY_HSV = sys::ImGuiColorEditFlags_DisplayHSV;
152 const DISPLAY_HEX = sys::ImGuiColorEditFlags_DisplayHex;
154 const UINT8 = sys::ImGuiColorEditFlags_Uint8;
156 const FLOAT = sys::ImGuiColorEditFlags_Float;
159 const PICKER_HUE_BAR = sys::ImGuiColorEditFlags_PickerHueBar;
161 const PICKER_HUE_WHEEL = sys::ImGuiColorEditFlags_PickerHueWheel;
163 const INPUT_RGB = sys::ImGuiColorEditFlags_InputRGB;
165 const INPUT_HSV = sys::ImGuiColorEditFlags_InputHSV;
167 }
168}
169
170#[derive(Debug)]
185#[must_use]
186pub struct ColorEdit<'a, T: AsRef<str> + 'a> {
187 label: T,
188 value: EditableColor<'a>,
189 flags: ColorEditFlags,
190}
191
192impl<'a, T: AsRef<str> + 'a> ColorEdit<'a, T> {
193 #[doc(alias = "ColorEdit3", alias = "ColorEdit4")]
195 pub fn new(label: T, value: impl Into<EditableColor<'a>>) -> ColorEdit<'a, T> {
196 ColorEdit {
197 label,
198 value: value.into(),
199 flags: ColorEditFlags::empty(),
200 }
201 }
202 #[inline]
204 pub fn flags(mut self, flags: ColorEditFlags) -> Self {
205 self.flags = flags;
206 self
207 }
208 #[inline]
210 pub fn alpha(mut self, value: bool) -> Self {
211 self.flags.set(ColorEditFlags::NO_ALPHA, !value);
212 self
213 }
214 #[inline]
216 pub fn picker(mut self, value: bool) -> Self {
217 self.flags.set(ColorEditFlags::NO_PICKER, !value);
218 self
219 }
220 #[inline]
223 pub fn options(mut self, value: bool) -> Self {
224 self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
225 self
226 }
227 #[inline]
229 pub fn small_preview(mut self, value: bool) -> Self {
230 self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
231 self
232 }
233 #[inline]
235 pub fn inputs(mut self, value: bool) -> Self {
236 self.flags.set(ColorEditFlags::NO_INPUTS, !value);
237 self
238 }
239 #[inline]
241 pub fn tooltip(mut self, value: bool) -> Self {
242 self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
243 self
244 }
245 #[inline]
248 pub fn label(mut self, value: bool) -> Self {
249 self.flags.set(ColorEditFlags::NO_LABEL, !value);
250 self
251 }
252 #[inline]
254 pub fn alpha_bar(mut self, value: bool) -> Self {
255 self.flags.set(ColorEditFlags::ALPHA_BAR, value);
256 self
257 }
258 #[inline]
260 pub fn preview(mut self, preview: ColorPreview) -> Self {
261 self.flags.set(
262 ColorEditFlags::ALPHA_PREVIEW_HALF,
263 preview == ColorPreview::HalfAlpha,
264 );
265 self.flags.set(
266 ColorEditFlags::ALPHA_PREVIEW,
267 preview == ColorPreview::Alpha,
268 );
269 self
270 }
271 #[inline]
275 pub fn hdr(mut self, value: bool) -> Self {
276 self.flags.set(ColorEditFlags::HDR, value);
277 self
278 }
279 #[inline]
281 pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
282 self.flags.set(
283 ColorEditFlags::INPUT_RGB,
284 input_mode == ColorEditInputMode::RGB,
285 );
286 self.flags.set(
287 ColorEditFlags::INPUT_HSV,
288 input_mode == ColorEditInputMode::HSV,
289 );
290 self
291 }
292 #[inline]
294 pub fn display_mode(mut self, mode: ColorEditDisplayMode) -> Self {
295 self.flags.set(
296 ColorEditFlags::DISPLAY_RGB,
297 mode == ColorEditDisplayMode::RGB,
298 );
299 self.flags.set(
300 ColorEditFlags::DISPLAY_HSV,
301 mode == ColorEditDisplayMode::HSV,
302 );
303 self.flags.set(
304 ColorEditFlags::DISPLAY_HEX,
305 mode == ColorEditDisplayMode::HEX,
306 );
307 self
308 }
309 #[inline]
311 pub fn format(mut self, format: ColorFormat) -> Self {
312 self.flags
313 .set(ColorEditFlags::UINT8, format == ColorFormat::U8);
314 self.flags
315 .set(ColorEditFlags::FLOAT, format == ColorFormat::Float);
316 self
317 }
318 pub fn build(mut self, ui: &Ui<'_>) -> bool {
322 if let EditableColor::Float3(_) = self.value {
323 self.flags.insert(ColorEditFlags::NO_ALPHA);
324 }
325 match self.value {
326 EditableColor::Float3(value) => unsafe {
327 sys::igColorEdit3(
328 ui.scratch_txt(self.label),
329 value.as_mut_ptr(),
330 self.flags.bits() as _,
331 )
332 },
333 EditableColor::Float4(value) => unsafe {
334 sys::igColorEdit4(
335 ui.scratch_txt(self.label),
336 value.as_mut_ptr(),
337 self.flags.bits() as _,
338 )
339 },
340 }
341 }
342}
343
344#[derive(Debug)]
359#[must_use]
360pub struct ColorPicker<'a, T: AsRef<str> + 'a> {
361 label: T,
362 value: EditableColor<'a>,
363 flags: ColorEditFlags,
364 ref_color: Option<&'a [f32; 4]>,
365}
366
367impl<'a, T: AsRef<str>> ColorPicker<'a, T> {
368 #[doc(alias = "ColorButton")]
370 pub fn new(label: T, value: impl Into<EditableColor<'a>>) -> Self {
371 ColorPicker {
372 label,
373 value: value.into(),
374 flags: ColorEditFlags::empty(),
375 ref_color: None,
376 }
377 }
378 #[inline]
380 pub fn flags(mut self, flags: ColorEditFlags) -> Self {
381 self.flags = flags;
382 self
383 }
384 #[inline]
386 pub fn alpha(mut self, value: bool) -> Self {
387 self.flags.set(ColorEditFlags::NO_ALPHA, !value);
388 self
389 }
390 #[inline]
393 pub fn options(mut self, value: bool) -> Self {
394 self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
395 self
396 }
397 #[inline]
399 pub fn small_preview(mut self, value: bool) -> Self {
400 self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
401 self
402 }
403 #[inline]
405 pub fn inputs(mut self, value: bool) -> Self {
406 self.flags.set(ColorEditFlags::NO_INPUTS, !value);
407 self
408 }
409 #[inline]
411 pub fn tooltip(mut self, value: bool) -> Self {
412 self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
413 self
414 }
415 #[inline]
418 pub fn label(mut self, value: bool) -> Self {
419 self.flags.set(ColorEditFlags::NO_LABEL, !value);
420 self
421 }
422 #[inline]
424 pub fn side_preview(mut self, value: bool) -> Self {
425 self.flags.set(ColorEditFlags::NO_SIDE_PREVIEW, !value);
426 self
427 }
428 #[inline]
430 pub fn alpha_bar(mut self, value: bool) -> Self {
431 self.flags.set(ColorEditFlags::ALPHA_BAR, value);
432 self
433 }
434 #[inline]
436 pub fn preview(mut self, preview: ColorPreview) -> Self {
437 self.flags.set(
438 ColorEditFlags::ALPHA_PREVIEW_HALF,
439 preview == ColorPreview::HalfAlpha,
440 );
441 self.flags.set(
442 ColorEditFlags::ALPHA_PREVIEW,
443 preview == ColorPreview::Alpha,
444 );
445 self
446 }
447 #[inline]
449 pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
450 self.flags.set(
451 ColorEditFlags::INPUT_RGB,
452 input_mode == ColorEditInputMode::RGB,
453 );
454 self.flags.set(
455 ColorEditFlags::INPUT_HSV,
456 input_mode == ColorEditInputMode::HSV,
457 );
458 self
459 }
460 #[inline]
462 pub fn display_rgb(mut self, value: bool) -> Self {
463 self.flags.set(ColorEditFlags::DISPLAY_RGB, value);
464 self
465 }
466 #[inline]
468 pub fn display_hsv(mut self, value: bool) -> Self {
469 self.flags.set(ColorEditFlags::DISPLAY_HSV, value);
470 self
471 }
472 #[inline]
474 pub fn display_hex(mut self, value: bool) -> Self {
475 self.flags.set(ColorEditFlags::DISPLAY_HEX, value);
476 self
477 }
478 #[inline]
480 pub fn mode(mut self, mode: ColorPickerMode) -> Self {
481 self.flags.set(
482 ColorEditFlags::PICKER_HUE_BAR,
483 mode == ColorPickerMode::HueBar,
484 );
485 self.flags.set(
486 ColorEditFlags::PICKER_HUE_WHEEL,
487 mode == ColorPickerMode::HueWheel,
488 );
489 self
490 }
491 #[inline]
493 pub fn format(mut self, format: ColorFormat) -> Self {
494 self.flags
495 .set(ColorEditFlags::UINT8, format == ColorFormat::U8);
496 self.flags
497 .set(ColorEditFlags::FLOAT, format == ColorFormat::Float);
498 self
499 }
500 #[inline]
502 pub fn reference_color(mut self, ref_color: &'a [f32; 4]) -> Self {
503 self.ref_color = Some(ref_color);
504 self
505 }
506 pub fn build(mut self, ui: &Ui<'_>) -> bool {
510 if let EditableColor::Float3(_) = self.value {
511 self.flags.insert(ColorEditFlags::NO_ALPHA);
512 }
513 let ref_color = self.ref_color.map(|c| c.as_ptr()).unwrap_or(ptr::null());
514 unsafe {
515 sys::igColorPicker4(
516 ui.scratch_txt(self.label),
517 self.value.as_mut_ptr(),
518 self.flags.bits() as _,
519 ref_color,
520 )
521 }
522 }
523}
524
525#[derive(Copy, Clone, Debug)]
537#[must_use]
538pub struct ColorButton<T> {
539 desc_id: T,
540 color: [f32; 4],
541 flags: ColorEditFlags,
542 size: [f32; 2],
543}
544
545impl<T: AsRef<str>> ColorButton<T> {
546 pub fn new(desc_id: T, color: [f32; 4]) -> Self {
548 ColorButton {
549 desc_id,
550 color,
551 flags: ColorEditFlags::empty(),
552 size: [0.0, 0.0],
553 }
554 }
555 #[inline]
557 pub fn flags(mut self, flags: ColorEditFlags) -> Self {
558 self.flags = flags;
559 self
560 }
561 #[inline]
563 pub fn alpha(mut self, value: bool) -> Self {
564 self.flags.set(ColorEditFlags::NO_ALPHA, !value);
565 self
566 }
567 #[inline]
569 pub fn tooltip(mut self, value: bool) -> Self {
570 self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
571 self
572 }
573 #[inline]
575 pub fn preview(mut self, preview: ColorPreview) -> Self {
576 self.flags.set(
577 ColorEditFlags::ALPHA_PREVIEW_HALF,
578 preview == ColorPreview::HalfAlpha,
579 );
580 self.flags.set(
581 ColorEditFlags::ALPHA_PREVIEW,
582 preview == ColorPreview::Alpha,
583 );
584 self
585 }
586 #[inline]
588 pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
589 self.flags.set(
590 ColorEditFlags::INPUT_RGB,
591 input_mode == ColorEditInputMode::RGB,
592 );
593 self.flags.set(
594 ColorEditFlags::INPUT_HSV,
595 input_mode == ColorEditInputMode::HSV,
596 );
597 self
598 }
599 pub fn drag_drop(mut self, value: bool) -> Self {
603 self.flags.set(ColorEditFlags::NO_DRAG_DROP, !value);
604 self
605 }
606 pub fn border(mut self, value: bool) -> Self {
610 self.flags.set(ColorEditFlags::NO_BORDER, !value);
611 self
612 }
613 #[inline]
617 pub fn size(mut self, size: [f32; 2]) -> Self {
618 self.size = size;
619 self
620 }
621 pub fn build(self, ui: &Ui<'_>) -> bool {
625 unsafe {
626 sys::igColorButton(
627 ui.scratch_txt(self.desc_id),
628 self.color.into(),
629 self.flags.bits() as _,
630 self.size.into(),
631 )
632 }
633 }
634}
635
636impl<'ui> Ui<'ui> {
638 #[doc(alias = "SetColorEditOptions")]
642 pub fn set_color_edit_options(&self, flags: ColorEditFlags) {
643 unsafe {
644 sys::igSetColorEditOptions(flags.bits() as i32);
645 }
646 }
647}