1use crate::sys;
7use crate::ui::Ui;
8use std::borrow::Cow;
9
10#[repr(transparent)]
12#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
13pub struct ColorEditFlags(u32);
14
15impl ColorEditFlags {
16 pub const NONE: Self = Self(0);
18 pub const NO_ALPHA: Self = Self(sys::ImGuiColorEditFlags_NoAlpha as u32);
20 pub const NO_PICKER: Self = Self(sys::ImGuiColorEditFlags_NoPicker as u32);
22 pub const NO_OPTIONS: Self = Self(sys::ImGuiColorEditFlags_NoOptions as u32);
24 pub const NO_SMALL_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_NoSmallPreview as u32);
26 pub const NO_INPUTS: Self = Self(sys::ImGuiColorEditFlags_NoInputs as u32);
28 pub const NO_TOOLTIP: Self = Self(sys::ImGuiColorEditFlags_NoTooltip as u32);
30 pub const NO_LABEL: Self = Self(sys::ImGuiColorEditFlags_NoLabel as u32);
32 pub const NO_SIDE_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_NoSidePreview as u32);
34 pub const NO_DRAG_DROP: Self = Self(sys::ImGuiColorEditFlags_NoDragDrop as u32);
36 pub const NO_BORDER: Self = Self(sys::ImGuiColorEditFlags_NoBorder as u32);
38 pub const NO_COLOR_MARKERS: Self = Self(sys::ImGuiColorEditFlags_NoColorMarkers as u32);
40
41 pub const ALPHA_BAR: Self = Self(sys::ImGuiColorEditFlags_AlphaBar as u32);
43 pub const ALPHA_OPAQUE: Self = Self(sys::ImGuiColorEditFlags_AlphaOpaque as u32);
45 pub const ALPHA_NO_BG: Self = Self(sys::ImGuiColorEditFlags_AlphaNoBg as u32);
47 pub const ALPHA_PREVIEW: Self = Self::ALPHA_NO_BG;
49 pub const ALPHA_PREVIEW_HALF: Self = Self(sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32);
51 pub const HDR: Self = Self(sys::ImGuiColorEditFlags_HDR as u32);
53
54 pub const fn bits(self) -> u32 {
56 self.0
57 }
58
59 pub const fn contains(self, other: Self) -> bool {
61 (self.0 & other.0) == other.0
62 }
63
64 pub const fn all() -> Self {
66 Self(
67 Self::NO_ALPHA.0
68 | Self::NO_PICKER.0
69 | Self::NO_OPTIONS.0
70 | Self::NO_SMALL_PREVIEW.0
71 | Self::NO_INPUTS.0
72 | Self::NO_TOOLTIP.0
73 | Self::NO_LABEL.0
74 | Self::NO_SIDE_PREVIEW.0
75 | Self::NO_DRAG_DROP.0
76 | Self::NO_BORDER.0
77 | Self::NO_COLOR_MARKERS.0
78 | Self::ALPHA_BAR.0
79 | Self::ALPHA_OPAQUE.0
80 | Self::ALPHA_NO_BG.0
81 | Self::ALPHA_PREVIEW_HALF.0
82 | Self::HDR.0,
83 )
84 }
85}
86
87impl Default for ColorEditFlags {
88 fn default() -> Self {
89 Self::NONE
90 }
91}
92
93#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
95pub enum ColorDisplayMode {
96 Rgb,
97 Hsv,
98 Hex,
99}
100
101impl ColorDisplayMode {
102 const fn raw(self) -> u32 {
103 match self {
104 Self::Rgb => sys::ImGuiColorEditFlags_DisplayRGB as u32,
105 Self::Hsv => sys::ImGuiColorEditFlags_DisplayHSV as u32,
106 Self::Hex => sys::ImGuiColorEditFlags_DisplayHex as u32,
107 }
108 }
109}
110
111#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
113pub enum ColorDataType {
114 Uint8,
115 Float,
116}
117
118impl ColorDataType {
119 const fn raw(self) -> u32 {
120 match self {
121 Self::Uint8 => sys::ImGuiColorEditFlags_Uint8 as u32,
122 Self::Float => sys::ImGuiColorEditFlags_Float as u32,
123 }
124 }
125}
126
127#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
129pub enum ColorPickerMode {
130 HueBar,
131 HueWheel,
132}
133
134impl ColorPickerMode {
135 const fn raw(self) -> u32 {
136 match self {
137 Self::HueBar => sys::ImGuiColorEditFlags_PickerHueBar as u32,
138 Self::HueWheel => sys::ImGuiColorEditFlags_PickerHueWheel as u32,
139 }
140 }
141}
142
143#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
145pub enum ColorInputMode {
146 Rgb,
147 Hsv,
148}
149
150impl ColorInputMode {
151 const fn raw(self) -> u32 {
152 match self {
153 Self::Rgb => sys::ImGuiColorEditFlags_InputRGB as u32,
154 Self::Hsv => sys::ImGuiColorEditFlags_InputHSV as u32,
155 }
156 }
157}
158
159bitflags::bitflags! {
160 #[repr(transparent)]
162 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
163 pub struct ColorPickerDisplayFlags: u32 {
164 const RGB = sys::ImGuiColorEditFlags_DisplayRGB as u32;
165 const HSV = sys::ImGuiColorEditFlags_DisplayHSV as u32;
166 const HEX = sys::ImGuiColorEditFlags_DisplayHex as u32;
167 }
168}
169
170#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
173pub struct ColorEditOptions {
174 pub flags: ColorEditFlags,
175 pub display_mode: Option<ColorDisplayMode>,
176 pub data_type: Option<ColorDataType>,
177 pub picker_mode: Option<ColorPickerMode>,
178 pub input_mode: Option<ColorInputMode>,
179}
180
181impl ColorEditOptions {
182 pub const fn new() -> Self {
183 Self {
184 flags: ColorEditFlags::NONE,
185 display_mode: None,
186 data_type: None,
187 picker_mode: None,
188 input_mode: None,
189 }
190 }
191
192 pub fn flags(mut self, flags: ColorEditFlags) -> Self {
193 self.flags = flags;
194 self
195 }
196
197 pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
198 self.display_mode = Some(mode);
199 self
200 }
201
202 pub fn data_type(mut self, data_type: ColorDataType) -> Self {
203 self.data_type = Some(data_type);
204 self
205 }
206
207 pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
208 self.picker_mode = Some(mode);
209 self
210 }
211
212 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
213 self.input_mode = Some(mode);
214 self
215 }
216
217 pub fn bits(self) -> u32 {
218 self.flags.bits()
219 | self.display_mode.map_or(0, ColorDisplayMode::raw)
220 | self.data_type.map_or(0, ColorDataType::raw)
221 | self.picker_mode.map_or(0, ColorPickerMode::raw)
222 | self.input_mode.map_or(0, ColorInputMode::raw)
223 }
224
225 pub(crate) fn validate(self, caller: &str) {
226 validate_color_independent_flags(caller, self.flags);
227 validate_color_supported_bits(caller, self.bits(), color_edit_supported_mask());
228 assert_color_single_choice_mask(caller, self.bits(), color_display_mask(), "display mode");
229 assert_color_single_choice_mask(caller, self.bits(), color_data_type_mask(), "data type");
230 assert_color_single_choice_mask(caller, self.bits(), color_picker_mask(), "picker mode");
231 assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
232 }
233}
234
235impl Default for ColorEditOptions {
236 fn default() -> Self {
237 Self::new()
238 }
239}
240
241impl From<ColorEditFlags> for ColorEditOptions {
242 fn from(flags: ColorEditFlags) -> Self {
243 Self::new().flags(flags)
244 }
245}
246
247#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
249pub struct ColorPickerOptions {
250 pub flags: ColorEditFlags,
251 pub display_flags: ColorPickerDisplayFlags,
252 pub data_type: Option<ColorDataType>,
253 pub picker_mode: Option<ColorPickerMode>,
254 pub input_mode: Option<ColorInputMode>,
255}
256
257impl ColorPickerOptions {
258 pub const fn new() -> Self {
259 Self {
260 flags: ColorEditFlags::NONE,
261 display_flags: ColorPickerDisplayFlags::empty(),
262 data_type: None,
263 picker_mode: None,
264 input_mode: None,
265 }
266 }
267
268 pub fn flags(mut self, flags: ColorEditFlags) -> Self {
269 self.flags = flags;
270 self
271 }
272
273 pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
274 self.display_flags = flags;
275 self
276 }
277
278 pub fn data_type(mut self, data_type: ColorDataType) -> Self {
279 self.data_type = Some(data_type);
280 self
281 }
282
283 pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
284 self.picker_mode = Some(mode);
285 self
286 }
287
288 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
289 self.input_mode = Some(mode);
290 self
291 }
292
293 pub fn bits(self) -> u32 {
294 self.flags.bits()
295 | self.display_flags.bits()
296 | self.data_type.map_or(0, ColorDataType::raw)
297 | self.picker_mode.map_or(0, ColorPickerMode::raw)
298 | self.input_mode.map_or(0, ColorInputMode::raw)
299 }
300
301 pub(crate) fn validate(self, caller: &str) {
302 validate_color_independent_flags(caller, self.flags);
303 let unsupported_display =
304 self.display_flags.bits() & !ColorPickerDisplayFlags::all().bits();
305 assert!(
306 unsupported_display == 0,
307 "{caller} received unsupported ColorPickerDisplayFlags bits: 0x{unsupported_display:X}"
308 );
309 validate_color_supported_bits(caller, self.bits(), color_picker_supported_mask());
310 assert_color_single_choice_mask(caller, self.bits(), color_data_type_mask(), "data type");
311 assert_color_single_choice_mask(caller, self.bits(), color_picker_mask(), "picker mode");
312 assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
313 }
314}
315
316impl Default for ColorPickerOptions {
317 fn default() -> Self {
318 Self::new()
319 }
320}
321
322impl From<ColorEditFlags> for ColorPickerOptions {
323 fn from(flags: ColorEditFlags) -> Self {
324 Self::new().flags(flags)
325 }
326}
327
328#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
330pub struct ColorButtonOptions {
331 pub flags: ColorEditFlags,
332 pub input_mode: Option<ColorInputMode>,
333}
334
335impl ColorButtonOptions {
336 pub const fn new() -> Self {
337 Self {
338 flags: ColorEditFlags::NONE,
339 input_mode: None,
340 }
341 }
342
343 pub fn flags(mut self, flags: ColorEditFlags) -> Self {
344 self.flags = flags;
345 self
346 }
347
348 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
349 self.input_mode = Some(mode);
350 self
351 }
352
353 pub fn bits(self) -> u32 {
354 self.flags.bits() | self.input_mode.map_or(0, ColorInputMode::raw)
355 }
356
357 pub(crate) fn validate(self, caller: &str) {
358 validate_color_independent_flags(caller, self.flags);
359 validate_color_supported_bits(caller, self.bits(), color_button_supported_mask());
360 assert_color_single_choice_mask(caller, self.bits(), color_input_mask(), "input mode");
361 }
362}
363
364impl Default for ColorButtonOptions {
365 fn default() -> Self {
366 Self::new()
367 }
368}
369
370impl From<ColorEditFlags> for ColorButtonOptions {
371 fn from(flags: ColorEditFlags) -> Self {
372 Self::new().flags(flags)
373 }
374}
375
376#[inline]
377const fn color_display_mask() -> u32 {
378 sys::ImGuiColorEditFlags_DisplayMask_ as u32
379}
380
381#[inline]
382const fn color_data_type_mask() -> u32 {
383 sys::ImGuiColorEditFlags_DataTypeMask_ as u32
384}
385
386#[inline]
387const fn color_picker_mask() -> u32 {
388 sys::ImGuiColorEditFlags_PickerMask_ as u32
389}
390
391#[inline]
392const fn color_input_mask() -> u32 {
393 sys::ImGuiColorEditFlags_InputMask_ as u32
394}
395
396#[inline]
397const fn color_choice_mask() -> u32 {
398 color_display_mask() | color_data_type_mask() | color_picker_mask() | color_input_mask()
399}
400
401#[inline]
402const fn color_edit_supported_mask() -> u32 {
403 ColorEditFlags::all().bits() | color_choice_mask()
404}
405
406#[inline]
407const fn color_picker_supported_mask() -> u32 {
408 ColorEditFlags::all().bits()
409 | color_display_mask()
410 | color_data_type_mask()
411 | color_picker_mask()
412 | color_input_mask()
413}
414
415#[inline]
416const fn color_button_supported_mask() -> u32 {
417 ColorEditFlags::all().bits() | color_input_mask()
418}
419
420fn validate_color_independent_flags(caller: &str, flags: ColorEditFlags) {
421 let unsupported = flags.bits() & !ColorEditFlags::all().bits();
422 assert!(
423 unsupported == 0,
424 "{caller} received non-independent ImGuiColorEditFlags bits: 0x{unsupported:X}"
425 );
426}
427
428fn validate_color_supported_bits(caller: &str, bits: u32, supported: u32) {
429 let unsupported = bits & !supported;
430 assert!(
431 unsupported == 0,
432 "{caller} received unsupported ImGuiColorEditFlags bits: 0x{unsupported:X}"
433 );
434}
435
436fn assert_color_single_choice_mask(caller: &str, bits: u32, mask: u32, name: &str) {
437 assert!(
438 (bits & mask).count_ones() <= 1,
439 "{caller} accepts at most one color {name}"
440 );
441}
442
443fn assert_finite_color3(caller: &str, name: &str, color: &[f32; 3]) {
444 assert!(
445 color.iter().all(|component| component.is_finite()),
446 "{caller} {name} must contain finite values"
447 );
448}
449
450fn assert_finite_color4(caller: &str, name: &str, color: &[f32; 4]) {
451 assert!(
452 color.iter().all(|component| component.is_finite()),
453 "{caller} {name} must contain finite values"
454 );
455}
456
457fn assert_non_negative_finite_vec2(caller: &str, name: &str, value: [f32; 2]) {
458 assert!(
459 value[0].is_finite() && value[1].is_finite(),
460 "{caller} {name} must contain finite values"
461 );
462 assert!(
463 value[0] >= 0.0 && value[1] >= 0.0,
464 "{caller} {name} must contain non-negative values"
465 );
466}
467
468impl std::ops::BitOr for ColorEditFlags {
469 type Output = Self;
470 fn bitor(self, rhs: Self) -> Self::Output {
471 Self(self.0 | rhs.0)
472 }
473}
474
475impl std::ops::BitOrAssign for ColorEditFlags {
476 fn bitor_assign(&mut self, rhs: Self) {
477 self.0 |= rhs.0;
478 }
479}
480
481impl std::ops::BitAnd for ColorEditFlags {
482 type Output = Self;
483 fn bitand(self, rhs: Self) -> Self::Output {
484 Self(self.0 & rhs.0)
485 }
486}
487
488impl std::ops::BitAndAssign for ColorEditFlags {
489 fn bitand_assign(&mut self, rhs: Self) {
490 self.0 &= rhs.0;
491 }
492}
493
494impl std::ops::BitXor for ColorEditFlags {
495 type Output = Self;
496 fn bitxor(self, rhs: Self) -> Self::Output {
497 Self(self.0 ^ rhs.0)
498 }
499}
500
501impl std::ops::BitXorAssign for ColorEditFlags {
502 fn bitxor_assign(&mut self, rhs: Self) {
503 self.0 ^= rhs.0;
504 }
505}
506
507impl std::ops::Not for ColorEditFlags {
508 type Output = Self;
509 fn not(self) -> Self::Output {
510 Self(!self.0)
511 }
512}
513
514impl Ui {
516 #[doc(alias = "SetColorEditOptions")]
522 pub fn set_color_edit_options(&self, options: impl Into<ColorEditOptions>) {
523 let options = options.into();
524 options.validate("Ui::set_color_edit_options()");
525 unsafe { sys::igSetColorEditOptions(options.bits() as i32) }
526 }
527
528 #[doc(alias = "ColorEdit3")]
530 pub fn color_edit3(&self, label: impl AsRef<str>, color: &mut [f32; 3]) -> bool {
531 self.color_edit3_config(label.as_ref(), color).build()
532 }
533
534 #[doc(alias = "ColorEdit4")]
536 pub fn color_edit4(&self, label: impl AsRef<str>, color: &mut [f32; 4]) -> bool {
537 self.color_edit4_config(label.as_ref(), color).build()
538 }
539
540 #[doc(alias = "ColorPicker3")]
542 pub fn color_picker3(&self, label: impl AsRef<str>, color: &mut [f32; 3]) -> bool {
543 self.color_picker3_config(label.as_ref(), color).build()
544 }
545
546 #[doc(alias = "ColorPicker4")]
548 pub fn color_picker4(&self, label: impl AsRef<str>, color: &mut [f32; 4]) -> bool {
549 self.color_picker4_config(label.as_ref(), color).build()
550 }
551
552 #[doc(alias = "ColorButton")]
554 pub fn color_button(&self, desc_id: impl AsRef<str>, color: [f32; 4]) -> bool {
555 self.color_button_config(desc_id.as_ref(), color).build()
556 }
557
558 pub fn color_edit3_config<'ui, 'p>(
560 &'ui self,
561 label: impl Into<Cow<'ui, str>>,
562 color: &'p mut [f32; 3],
563 ) -> ColorEdit3<'ui, 'p> {
564 ColorEdit3::new(self, label, color)
565 }
566
567 pub fn color_edit4_config<'ui, 'p>(
569 &'ui self,
570 label: impl Into<Cow<'ui, str>>,
571 color: &'p mut [f32; 4],
572 ) -> ColorEdit4<'ui, 'p> {
573 ColorEdit4::new(self, label, color)
574 }
575
576 pub fn color_picker3_config<'ui, 'p>(
578 &'ui self,
579 label: impl Into<Cow<'ui, str>>,
580 color: &'p mut [f32; 3],
581 ) -> ColorPicker3<'ui, 'p> {
582 ColorPicker3::new(self, label, color)
583 }
584
585 pub fn color_picker4_config<'ui, 'p>(
587 &'ui self,
588 label: impl Into<Cow<'ui, str>>,
589 color: &'p mut [f32; 4],
590 ) -> ColorPicker4<'ui, 'p> {
591 ColorPicker4::new(self, label, color)
592 }
593
594 pub fn color_button_config<'ui>(
596 &'ui self,
597 desc_id: impl Into<Cow<'ui, str>>,
598 color: [f32; 4],
599 ) -> ColorButton<'ui> {
600 ColorButton::new(self, desc_id, color)
601 }
602}
603
604#[derive(Debug)]
606#[must_use]
607pub struct ColorEdit3<'ui, 'p> {
608 ui: &'ui Ui,
609 label: Cow<'ui, str>,
610 color: &'p mut [f32; 3],
611 flags: ColorEditOptions,
612}
613
614impl<'ui, 'p> ColorEdit3<'ui, 'p> {
615 pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 3]) -> Self {
617 Self {
618 ui,
619 label: label.into(),
620 color,
621 flags: ColorEditOptions::new(),
622 }
623 }
624
625 pub fn flags(mut self, flags: impl Into<ColorEditOptions>) -> Self {
627 self.flags = flags.into();
628 self
629 }
630
631 pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
633 self.flags.display_mode = Some(mode);
634 self
635 }
636
637 pub fn data_type(mut self, data_type: ColorDataType) -> Self {
639 self.flags.data_type = Some(data_type);
640 self
641 }
642
643 pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
645 self.flags.picker_mode = Some(mode);
646 self
647 }
648
649 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
651 self.flags.input_mode = Some(mode);
652 self
653 }
654
655 pub fn build(self) -> bool {
657 self.flags.validate("ColorEdit3::build()");
658 assert_finite_color3("ColorEdit3::build()", "color", &*self.color);
659 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
660 unsafe { sys::igColorEdit3(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
661 }
662}
663
664#[derive(Debug)]
666#[must_use]
667pub struct ColorEdit4<'ui, 'p> {
668 ui: &'ui Ui,
669 label: Cow<'ui, str>,
670 color: &'p mut [f32; 4],
671 flags: ColorEditOptions,
672}
673
674impl<'ui, 'p> ColorEdit4<'ui, 'p> {
675 pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 4]) -> Self {
677 Self {
678 ui,
679 label: label.into(),
680 color,
681 flags: ColorEditOptions::new(),
682 }
683 }
684
685 pub fn flags(mut self, flags: impl Into<ColorEditOptions>) -> Self {
687 self.flags = flags.into();
688 self
689 }
690
691 pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
693 self.flags.display_mode = Some(mode);
694 self
695 }
696
697 pub fn data_type(mut self, data_type: ColorDataType) -> Self {
699 self.flags.data_type = Some(data_type);
700 self
701 }
702
703 pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
705 self.flags.picker_mode = Some(mode);
706 self
707 }
708
709 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
711 self.flags.input_mode = Some(mode);
712 self
713 }
714
715 pub fn build(self) -> bool {
717 self.flags.validate("ColorEdit4::build()");
718 assert_finite_color4("ColorEdit4::build()", "color", &*self.color);
719 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
720 unsafe { sys::igColorEdit4(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
721 }
722}
723
724#[derive(Debug)]
726#[must_use]
727pub struct ColorPicker3<'ui, 'p> {
728 ui: &'ui Ui,
729 label: Cow<'ui, str>,
730 color: &'p mut [f32; 3],
731 flags: ColorPickerOptions,
732}
733
734impl<'ui, 'p> ColorPicker3<'ui, 'p> {
735 pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 3]) -> Self {
737 Self {
738 ui,
739 label: label.into(),
740 color,
741 flags: ColorPickerOptions::new(),
742 }
743 }
744
745 pub fn flags(mut self, flags: impl Into<ColorPickerOptions>) -> Self {
747 self.flags = flags.into();
748 self
749 }
750
751 pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
753 self.flags.display_flags = flags;
754 self
755 }
756
757 pub fn data_type(mut self, data_type: ColorDataType) -> Self {
759 self.flags.data_type = Some(data_type);
760 self
761 }
762
763 pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
765 self.flags.picker_mode = Some(mode);
766 self
767 }
768
769 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
771 self.flags.input_mode = Some(mode);
772 self
773 }
774
775 pub fn build(self) -> bool {
777 self.flags.validate("ColorPicker3::build()");
778 assert_finite_color3("ColorPicker3::build()", "color", &*self.color);
779 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
780 unsafe { sys::igColorPicker3(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
781 }
782}
783
784#[derive(Debug)]
786#[must_use]
787pub struct ColorPicker4<'ui, 'p> {
788 ui: &'ui Ui,
789 label: Cow<'ui, str>,
790 color: &'p mut [f32; 4],
791 flags: ColorPickerOptions,
792 ref_color: Option<[f32; 4]>,
793}
794
795impl<'ui, 'p> ColorPicker4<'ui, 'p> {
796 pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 4]) -> Self {
798 Self {
799 ui,
800 label: label.into(),
801 color,
802 flags: ColorPickerOptions::new(),
803 ref_color: None,
804 }
805 }
806
807 pub fn flags(mut self, flags: impl Into<ColorPickerOptions>) -> Self {
809 self.flags = flags.into();
810 self
811 }
812
813 pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
815 self.flags.display_flags = flags;
816 self
817 }
818
819 pub fn data_type(mut self, data_type: ColorDataType) -> Self {
821 self.flags.data_type = Some(data_type);
822 self
823 }
824
825 pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
827 self.flags.picker_mode = Some(mode);
828 self
829 }
830
831 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
833 self.flags.input_mode = Some(mode);
834 self
835 }
836
837 pub fn reference_color(mut self, ref_color: [f32; 4]) -> Self {
839 self.ref_color = Some(ref_color);
840 self
841 }
842
843 pub fn build(self) -> bool {
845 self.flags.validate("ColorPicker4::build()");
846 assert_finite_color4("ColorPicker4::build()", "color", &*self.color);
847 if let Some(ref_color) = &self.ref_color {
848 assert_finite_color4("ColorPicker4::build()", "reference color", ref_color);
849 }
850 let label_ptr = self.ui.scratch_txt(self.label.as_ref());
851 let ref_color_ptr = self
852 .ref_color
853 .as_ref()
854 .map_or(std::ptr::null(), |c| c.as_ptr());
855
856 unsafe {
857 sys::igColorPicker4(
858 label_ptr,
859 self.color.as_mut_ptr(),
860 self.flags.bits() as i32,
861 ref_color_ptr,
862 )
863 }
864 }
865}
866
867#[derive(Debug)]
869#[must_use]
870pub struct ColorButton<'ui> {
871 ui: &'ui Ui,
872 desc_id: Cow<'ui, str>,
873 color: [f32; 4],
874 flags: ColorButtonOptions,
875 size: [f32; 2],
876}
877
878impl<'ui> ColorButton<'ui> {
879 pub fn new(ui: &'ui Ui, desc_id: impl Into<Cow<'ui, str>>, color: [f32; 4]) -> Self {
881 Self {
882 ui,
883 desc_id: desc_id.into(),
884 color,
885 flags: ColorButtonOptions::new(),
886 size: [0.0, 0.0],
887 }
888 }
889
890 pub fn flags(mut self, flags: impl Into<ColorButtonOptions>) -> Self {
892 self.flags = flags.into();
893 self
894 }
895
896 pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
898 self.flags.input_mode = Some(mode);
899 self
900 }
901
902 pub fn size(mut self, size: [f32; 2]) -> Self {
904 self.size = size;
905 self
906 }
907
908 pub fn build(self) -> bool {
910 self.flags.validate("ColorButton::build()");
911 assert_finite_color4("ColorButton::build()", "color", &self.color);
912 assert_non_negative_finite_vec2("ColorButton::build()", "size", self.size);
913 let desc_id_ptr = self.ui.scratch_txt(self.desc_id.as_ref());
914 let size_vec: sys::ImVec2 = self.size.into();
915
916 unsafe {
917 sys::igColorButton(
918 desc_id_ptr,
919 sys::ImVec4 {
920 x: self.color[0],
921 y: self.color[1],
922 z: self.color[2],
923 w: self.color[3],
924 },
925 self.flags.bits() as i32,
926 size_vec,
927 )
928 }
929 }
930}