use crate::sys;
use crate::ui::Ui;
use std::borrow::Cow;
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct ColorEditFlags(u32);
impl ColorEditFlags {
pub const NONE: Self = Self(0);
pub const NO_ALPHA: Self = Self(sys::ImGuiColorEditFlags_NoAlpha as u32);
pub const NO_PICKER: Self = Self(sys::ImGuiColorEditFlags_NoPicker as u32);
pub const NO_OPTIONS: Self = Self(sys::ImGuiColorEditFlags_NoOptions as u32);
pub const NO_SMALL_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_NoSmallPreview as u32);
pub const NO_INPUTS: Self = Self(sys::ImGuiColorEditFlags_NoInputs as u32);
pub const NO_TOOLTIP: Self = Self(sys::ImGuiColorEditFlags_NoTooltip as u32);
pub const NO_LABEL: Self = Self(sys::ImGuiColorEditFlags_NoLabel as u32);
pub const NO_SIDE_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_NoSidePreview as u32);
pub const NO_DRAG_DROP: Self = Self(sys::ImGuiColorEditFlags_NoDragDrop as u32);
pub const NO_BORDER: Self = Self(sys::ImGuiColorEditFlags_NoBorder as u32);
pub const ALPHA_BAR: Self = Self(sys::ImGuiColorEditFlags_AlphaBar as u32);
pub const ALPHA_PREVIEW: Self = Self(sys::ImGuiColorEditFlags_AlphaNoBg as u32);
pub const ALPHA_PREVIEW_HALF: Self = Self(sys::ImGuiColorEditFlags_AlphaPreviewHalf as u32);
pub const HDR: Self = Self(sys::ImGuiColorEditFlags_HDR as u32);
pub const fn bits(self) -> u32 {
self.0
}
pub const fn contains(self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
pub const fn all() -> Self {
Self(
Self::NO_ALPHA.0
| Self::NO_PICKER.0
| Self::NO_OPTIONS.0
| Self::NO_SMALL_PREVIEW.0
| Self::NO_INPUTS.0
| Self::NO_TOOLTIP.0
| Self::NO_LABEL.0
| Self::NO_SIDE_PREVIEW.0
| Self::NO_DRAG_DROP.0
| Self::NO_BORDER.0
| Self::ALPHA_BAR.0
| Self::ALPHA_PREVIEW.0
| Self::ALPHA_PREVIEW_HALF.0
| Self::HDR.0,
)
}
}
impl Default for ColorEditFlags {
fn default() -> Self {
Self::NONE
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum ColorDisplayMode {
Rgb,
Hsv,
Hex,
}
impl ColorDisplayMode {
const fn raw(self) -> u32 {
match self {
Self::Rgb => sys::ImGuiColorEditFlags_DisplayRGB as u32,
Self::Hsv => sys::ImGuiColorEditFlags_DisplayHSV as u32,
Self::Hex => sys::ImGuiColorEditFlags_DisplayHex as u32,
}
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum ColorDataType {
Uint8,
Float,
}
impl ColorDataType {
const fn raw(self) -> u32 {
match self {
Self::Uint8 => sys::ImGuiColorEditFlags_Uint8 as u32,
Self::Float => sys::ImGuiColorEditFlags_Float as u32,
}
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum ColorPickerMode {
HueBar,
HueWheel,
}
impl ColorPickerMode {
const fn raw(self) -> u32 {
match self {
Self::HueBar => sys::ImGuiColorEditFlags_PickerHueBar as u32,
Self::HueWheel => sys::ImGuiColorEditFlags_PickerHueWheel as u32,
}
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum ColorInputMode {
Rgb,
Hsv,
}
impl ColorInputMode {
const fn raw(self) -> u32 {
match self {
Self::Rgb => sys::ImGuiColorEditFlags_InputRGB as u32,
Self::Hsv => sys::ImGuiColorEditFlags_InputHSV as u32,
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct ColorPickerDisplayFlags: u32 {
const RGB = sys::ImGuiColorEditFlags_DisplayRGB as u32;
const HSV = sys::ImGuiColorEditFlags_DisplayHSV as u32;
const HEX = sys::ImGuiColorEditFlags_DisplayHex as u32;
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct ColorEditOptions {
pub flags: ColorEditFlags,
pub display_mode: Option<ColorDisplayMode>,
pub data_type: Option<ColorDataType>,
pub picker_mode: Option<ColorPickerMode>,
pub input_mode: Option<ColorInputMode>,
}
impl ColorEditOptions {
pub const fn new() -> Self {
Self {
flags: ColorEditFlags::NONE,
display_mode: None,
data_type: None,
picker_mode: None,
input_mode: None,
}
}
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
self.display_mode = Some(mode);
self
}
pub fn data_type(mut self, data_type: ColorDataType) -> Self {
self.data_type = Some(data_type);
self
}
pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
self.picker_mode = Some(mode);
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.input_mode = Some(mode);
self
}
pub fn bits(self) -> u32 {
self.flags.bits()
| self.display_mode.map_or(0, ColorDisplayMode::raw)
| self.data_type.map_or(0, ColorDataType::raw)
| self.picker_mode.map_or(0, ColorPickerMode::raw)
| self.input_mode.map_or(0, ColorInputMode::raw)
}
}
impl Default for ColorEditOptions {
fn default() -> Self {
Self::new()
}
}
impl From<ColorEditFlags> for ColorEditOptions {
fn from(flags: ColorEditFlags) -> Self {
Self::new().flags(flags)
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct ColorPickerOptions {
pub flags: ColorEditFlags,
pub display_flags: ColorPickerDisplayFlags,
pub data_type: Option<ColorDataType>,
pub picker_mode: Option<ColorPickerMode>,
pub input_mode: Option<ColorInputMode>,
}
impl ColorPickerOptions {
pub const fn new() -> Self {
Self {
flags: ColorEditFlags::NONE,
display_flags: ColorPickerDisplayFlags::empty(),
data_type: None,
picker_mode: None,
input_mode: None,
}
}
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
self.display_flags = flags;
self
}
pub fn data_type(mut self, data_type: ColorDataType) -> Self {
self.data_type = Some(data_type);
self
}
pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
self.picker_mode = Some(mode);
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.input_mode = Some(mode);
self
}
pub fn bits(self) -> u32 {
self.flags.bits()
| self.display_flags.bits()
| self.data_type.map_or(0, ColorDataType::raw)
| self.picker_mode.map_or(0, ColorPickerMode::raw)
| self.input_mode.map_or(0, ColorInputMode::raw)
}
}
impl Default for ColorPickerOptions {
fn default() -> Self {
Self::new()
}
}
impl From<ColorEditFlags> for ColorPickerOptions {
fn from(flags: ColorEditFlags) -> Self {
Self::new().flags(flags)
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct ColorButtonOptions {
pub flags: ColorEditFlags,
pub input_mode: Option<ColorInputMode>,
}
impl ColorButtonOptions {
pub const fn new() -> Self {
Self {
flags: ColorEditFlags::NONE,
input_mode: None,
}
}
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.input_mode = Some(mode);
self
}
pub fn bits(self) -> u32 {
self.flags.bits() | self.input_mode.map_or(0, ColorInputMode::raw)
}
}
impl Default for ColorButtonOptions {
fn default() -> Self {
Self::new()
}
}
impl From<ColorEditFlags> for ColorButtonOptions {
fn from(flags: ColorEditFlags) -> Self {
Self::new().flags(flags)
}
}
impl std::ops::BitOr for ColorEditFlags {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl std::ops::BitOrAssign for ColorEditFlags {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl std::ops::BitAnd for ColorEditFlags {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0 & rhs.0)
}
}
impl std::ops::BitAndAssign for ColorEditFlags {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
impl std::ops::BitXor for ColorEditFlags {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
Self(self.0 ^ rhs.0)
}
}
impl std::ops::BitXorAssign for ColorEditFlags {
fn bitxor_assign(&mut self, rhs: Self) {
self.0 ^= rhs.0;
}
}
impl std::ops::Not for ColorEditFlags {
type Output = Self;
fn not(self) -> Self::Output {
Self(!self.0)
}
}
impl Ui {
#[doc(alias = "SetColorEditOptions")]
pub fn set_color_edit_options(&self, options: impl Into<ColorEditOptions>) {
unsafe { sys::igSetColorEditOptions(options.into().bits() as i32) }
}
#[doc(alias = "ColorEdit3")]
pub fn color_edit3(&self, label: impl AsRef<str>, color: &mut [f32; 3]) -> bool {
self.color_edit3_config(label.as_ref(), color).build()
}
#[doc(alias = "ColorEdit4")]
pub fn color_edit4(&self, label: impl AsRef<str>, color: &mut [f32; 4]) -> bool {
self.color_edit4_config(label.as_ref(), color).build()
}
#[doc(alias = "ColorPicker3")]
pub fn color_picker3(&self, label: impl AsRef<str>, color: &mut [f32; 3]) -> bool {
self.color_picker3_config(label.as_ref(), color).build()
}
#[doc(alias = "ColorPicker4")]
pub fn color_picker4(&self, label: impl AsRef<str>, color: &mut [f32; 4]) -> bool {
self.color_picker4_config(label.as_ref(), color).build()
}
#[doc(alias = "ColorButton")]
pub fn color_button(&self, desc_id: impl AsRef<str>, color: [f32; 4]) -> bool {
self.color_button_config(desc_id.as_ref(), color).build()
}
pub fn color_edit3_config<'ui, 'p>(
&'ui self,
label: impl Into<Cow<'ui, str>>,
color: &'p mut [f32; 3],
) -> ColorEdit3<'ui, 'p> {
ColorEdit3::new(self, label, color)
}
pub fn color_edit4_config<'ui, 'p>(
&'ui self,
label: impl Into<Cow<'ui, str>>,
color: &'p mut [f32; 4],
) -> ColorEdit4<'ui, 'p> {
ColorEdit4::new(self, label, color)
}
pub fn color_picker3_config<'ui, 'p>(
&'ui self,
label: impl Into<Cow<'ui, str>>,
color: &'p mut [f32; 3],
) -> ColorPicker3<'ui, 'p> {
ColorPicker3::new(self, label, color)
}
pub fn color_picker4_config<'ui, 'p>(
&'ui self,
label: impl Into<Cow<'ui, str>>,
color: &'p mut [f32; 4],
) -> ColorPicker4<'ui, 'p> {
ColorPicker4::new(self, label, color)
}
pub fn color_button_config<'ui>(
&'ui self,
desc_id: impl Into<Cow<'ui, str>>,
color: [f32; 4],
) -> ColorButton<'ui> {
ColorButton::new(self, desc_id, color)
}
}
#[derive(Debug)]
#[must_use]
pub struct ColorEdit3<'ui, 'p> {
ui: &'ui Ui,
label: Cow<'ui, str>,
color: &'p mut [f32; 3],
flags: ColorEditOptions,
}
impl<'ui, 'p> ColorEdit3<'ui, 'p> {
pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 3]) -> Self {
Self {
ui,
label: label.into(),
color,
flags: ColorEditOptions::new(),
}
}
pub fn flags(mut self, flags: impl Into<ColorEditOptions>) -> Self {
self.flags = flags.into();
self
}
pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
self.flags.display_mode = Some(mode);
self
}
pub fn data_type(mut self, data_type: ColorDataType) -> Self {
self.flags.data_type = Some(data_type);
self
}
pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
self.flags.picker_mode = Some(mode);
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.flags.input_mode = Some(mode);
self
}
pub fn build(self) -> bool {
let label_ptr = self.ui.scratch_txt(self.label.as_ref());
unsafe { sys::igColorEdit3(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
}
}
#[derive(Debug)]
#[must_use]
pub struct ColorEdit4<'ui, 'p> {
ui: &'ui Ui,
label: Cow<'ui, str>,
color: &'p mut [f32; 4],
flags: ColorEditOptions,
}
impl<'ui, 'p> ColorEdit4<'ui, 'p> {
pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 4]) -> Self {
Self {
ui,
label: label.into(),
color,
flags: ColorEditOptions::new(),
}
}
pub fn flags(mut self, flags: impl Into<ColorEditOptions>) -> Self {
self.flags = flags.into();
self
}
pub fn display_mode(mut self, mode: ColorDisplayMode) -> Self {
self.flags.display_mode = Some(mode);
self
}
pub fn data_type(mut self, data_type: ColorDataType) -> Self {
self.flags.data_type = Some(data_type);
self
}
pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
self.flags.picker_mode = Some(mode);
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.flags.input_mode = Some(mode);
self
}
pub fn build(self) -> bool {
let label_ptr = self.ui.scratch_txt(self.label.as_ref());
unsafe { sys::igColorEdit4(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
}
}
#[derive(Debug)]
#[must_use]
pub struct ColorPicker3<'ui, 'p> {
ui: &'ui Ui,
label: Cow<'ui, str>,
color: &'p mut [f32; 3],
flags: ColorPickerOptions,
}
impl<'ui, 'p> ColorPicker3<'ui, 'p> {
pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 3]) -> Self {
Self {
ui,
label: label.into(),
color,
flags: ColorPickerOptions::new(),
}
}
pub fn flags(mut self, flags: impl Into<ColorPickerOptions>) -> Self {
self.flags = flags.into();
self
}
pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
self.flags.display_flags = flags;
self
}
pub fn data_type(mut self, data_type: ColorDataType) -> Self {
self.flags.data_type = Some(data_type);
self
}
pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
self.flags.picker_mode = Some(mode);
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.flags.input_mode = Some(mode);
self
}
pub fn build(self) -> bool {
let label_ptr = self.ui.scratch_txt(self.label.as_ref());
unsafe { sys::igColorPicker3(label_ptr, self.color.as_mut_ptr(), self.flags.bits() as i32) }
}
}
#[derive(Debug)]
#[must_use]
pub struct ColorPicker4<'ui, 'p> {
ui: &'ui Ui,
label: Cow<'ui, str>,
color: &'p mut [f32; 4],
flags: ColorPickerOptions,
ref_color: Option<[f32; 4]>,
}
impl<'ui, 'p> ColorPicker4<'ui, 'p> {
pub fn new(ui: &'ui Ui, label: impl Into<Cow<'ui, str>>, color: &'p mut [f32; 4]) -> Self {
Self {
ui,
label: label.into(),
color,
flags: ColorPickerOptions::new(),
ref_color: None,
}
}
pub fn flags(mut self, flags: impl Into<ColorPickerOptions>) -> Self {
self.flags = flags.into();
self
}
pub fn display_flags(mut self, flags: ColorPickerDisplayFlags) -> Self {
self.flags.display_flags = flags;
self
}
pub fn data_type(mut self, data_type: ColorDataType) -> Self {
self.flags.data_type = Some(data_type);
self
}
pub fn picker_mode(mut self, mode: ColorPickerMode) -> Self {
self.flags.picker_mode = Some(mode);
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.flags.input_mode = Some(mode);
self
}
pub fn reference_color(mut self, ref_color: [f32; 4]) -> Self {
self.ref_color = Some(ref_color);
self
}
pub fn build(self) -> bool {
let label_ptr = self.ui.scratch_txt(self.label.as_ref());
let ref_color_ptr = self
.ref_color
.as_ref()
.map_or(std::ptr::null(), |c| c.as_ptr());
unsafe {
sys::igColorPicker4(
label_ptr,
self.color.as_mut_ptr(),
self.flags.bits() as i32,
ref_color_ptr,
)
}
}
}
#[derive(Debug)]
#[must_use]
pub struct ColorButton<'ui> {
ui: &'ui Ui,
desc_id: Cow<'ui, str>,
color: [f32; 4],
flags: ColorButtonOptions,
size: [f32; 2],
}
impl<'ui> ColorButton<'ui> {
pub fn new(ui: &'ui Ui, desc_id: impl Into<Cow<'ui, str>>, color: [f32; 4]) -> Self {
Self {
ui,
desc_id: desc_id.into(),
color,
flags: ColorButtonOptions::new(),
size: [0.0, 0.0],
}
}
pub fn flags(mut self, flags: impl Into<ColorButtonOptions>) -> Self {
self.flags = flags.into();
self
}
pub fn input_mode(mut self, mode: ColorInputMode) -> Self {
self.flags.input_mode = Some(mode);
self
}
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
self
}
pub fn build(self) -> bool {
let desc_id_ptr = self.ui.scratch_txt(self.desc_id.as_ref());
let size_vec: sys::ImVec2 = self.size.into();
unsafe {
sys::igColorButton(
desc_id_ptr,
sys::ImVec4 {
x: self.color[0],
y: self.color[1],
z: self.color[2],
w: self.color[3],
},
self.flags.bits() as i32,
size_vec,
)
}
}
}