use bitflags::bitflags;
use std::ptr;
use crate::string::ImStr;
use crate::sys;
use crate::Ui;
#[derive(Debug)]
pub enum EditableColor<'a> {
Float3(&'a mut [f32; 3]),
Float4(&'a mut [f32; 4]),
}
impl<'a> EditableColor<'a> {
fn as_mut_ptr(&mut self) -> *mut f32 {
match *self {
EditableColor::Float3(ref mut value) => value.as_mut_ptr(),
EditableColor::Float4(ref mut value) => value.as_mut_ptr(),
}
}
}
impl<'a> From<&'a mut [f32; 3]> for EditableColor<'a> {
fn from(value: &'a mut [f32; 3]) -> EditableColor<'a> {
EditableColor::Float3(value)
}
}
impl<'a> From<&'a mut [f32; 4]> for EditableColor<'a> {
fn from(value: &'a mut [f32; 4]) -> EditableColor<'a> {
EditableColor::Float4(value)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorEditInputMode {
RGB,
HSV,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorEditDisplayMode {
RGB,
HSV,
HEX,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorPickerMode {
HueBar,
HueWheel,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorFormat {
U8,
Float,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorPreview {
Opaque,
HalfAlpha,
Alpha,
}
bitflags! {
#[repr(transparent)]
pub struct ColorEditFlags: u32 {
const NO_ALPHA = sys::ImGuiColorEditFlags_NoAlpha;
const NO_PICKER = sys::ImGuiColorEditFlags_NoPicker;
const NO_OPTIONS = sys::ImGuiColorEditFlags_NoOptions;
const NO_SMALL_PREVIEW = sys::ImGuiColorEditFlags_NoSmallPreview;
const NO_INPUTS = sys::ImGuiColorEditFlags_NoInputs;
const NO_TOOLTIP = sys::ImGuiColorEditFlags_NoTooltip;
const NO_LABEL = sys::ImGuiColorEditFlags_NoLabel;
const NO_SIDE_PREVIEW = sys::ImGuiColorEditFlags_NoSidePreview;
const NO_DRAG_DROP = sys::ImGuiColorEditFlags_NoDragDrop;
const ALPHA_BAR = sys::ImGuiColorEditFlags_AlphaBar;
const ALPHA_PREVIEW = sys::ImGuiColorEditFlags_AlphaPreview;
const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf;
const HDR = sys::ImGuiColorEditFlags_HDR;
const DISPLAY_RGB = sys::ImGuiColorEditFlags_DisplayRGB;
const DISPLAY_HSV = sys::ImGuiColorEditFlags_DisplayHSV;
const DISPLAY_HEX = sys::ImGuiColorEditFlags_DisplayHex;
const UINT8 = sys::ImGuiColorEditFlags_Uint8;
const FLOAT = sys::ImGuiColorEditFlags_Float;
const PICKER_HUE_BAR = sys::ImGuiColorEditFlags_PickerHueBar;
const PICKER_HUE_WHEEL = sys::ImGuiColorEditFlags_PickerHueWheel;
const INPUT_RGB = sys::ImGuiColorEditFlags_InputRGB;
const INPUT_HSV = sys::ImGuiColorEditFlags_InputHSV;
}
}
#[derive(Debug)]
#[must_use]
pub struct ColorEdit<'a> {
label: &'a ImStr,
value: EditableColor<'a>,
flags: ColorEditFlags,
}
impl<'a> ColorEdit<'a> {
pub fn new<T: Into<EditableColor<'a>>>(label: &'a ImStr, value: T) -> ColorEdit<'a> {
ColorEdit {
label,
value: value.into(),
flags: ColorEditFlags::empty(),
}
}
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
#[inline]
pub fn picker(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_PICKER, !value);
self
}
#[inline]
pub fn options(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
self
}
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
self
}
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_INPUTS, !value);
self
}
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_LABEL, !value);
self
}
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::ALPHA_BAR, value);
self
}
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW_HALF,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW,
preview == ColorPreview::Alpha,
);
self
}
#[inline]
pub fn hdr(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::HDR, value);
self
}
#[inline]
pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
self.flags.set(
ColorEditFlags::INPUT_RGB,
input_mode == ColorEditInputMode::RGB,
);
self.flags.set(
ColorEditFlags::INPUT_HSV,
input_mode == ColorEditInputMode::HSV,
);
self
}
#[inline]
pub fn display_mode(mut self, mode: ColorEditDisplayMode) -> Self {
self.flags.set(
ColorEditFlags::DISPLAY_RGB,
mode == ColorEditDisplayMode::RGB,
);
self.flags.set(
ColorEditFlags::DISPLAY_HSV,
mode == ColorEditDisplayMode::HSV,
);
self.flags.set(
ColorEditFlags::DISPLAY_HEX,
mode == ColorEditDisplayMode::HEX,
);
self
}
#[inline]
pub fn format(mut self, format: ColorFormat) -> Self {
self.flags
.set(ColorEditFlags::UINT8, format == ColorFormat::U8);
self.flags
.set(ColorEditFlags::FLOAT, format == ColorFormat::Float);
self
}
pub fn build(mut self, _: &Ui) -> bool {
if let EditableColor::Float3(_) = self.value {
self.flags.insert(ColorEditFlags::NO_ALPHA);
}
match self.value {
EditableColor::Float3(value) => unsafe {
sys::igColorEdit3(
self.label.as_ptr(),
value.as_mut_ptr(),
self.flags.bits() as _,
)
},
EditableColor::Float4(value) => unsafe {
sys::igColorEdit4(
self.label.as_ptr(),
value.as_mut_ptr(),
self.flags.bits() as _,
)
},
}
}
}
#[derive(Debug)]
#[must_use]
pub struct ColorPicker<'a> {
label: &'a ImStr,
value: EditableColor<'a>,
flags: ColorEditFlags,
ref_color: Option<&'a [f32; 4]>,
}
impl<'a> ColorPicker<'a> {
pub fn new<T: Into<EditableColor<'a>>>(label: &'a ImStr, value: T) -> ColorPicker<'a> {
ColorPicker {
label,
value: value.into(),
flags: ColorEditFlags::empty(),
ref_color: None,
}
}
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
#[inline]
pub fn options(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
self
}
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
self
}
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_INPUTS, !value);
self
}
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_LABEL, !value);
self
}
#[inline]
pub fn side_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SIDE_PREVIEW, !value);
self
}
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::ALPHA_BAR, value);
self
}
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW_HALF,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW,
preview == ColorPreview::Alpha,
);
self
}
#[inline]
pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
self.flags.set(
ColorEditFlags::INPUT_RGB,
input_mode == ColorEditInputMode::RGB,
);
self.flags.set(
ColorEditFlags::INPUT_HSV,
input_mode == ColorEditInputMode::HSV,
);
self
}
#[inline]
pub fn display_rgb(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_RGB, value);
self
}
#[inline]
pub fn display_hsv(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_HSV, value);
self
}
#[inline]
pub fn display_hex(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_HEX, value);
self
}
#[inline]
pub fn mode(mut self, mode: ColorPickerMode) -> Self {
self.flags.set(
ColorEditFlags::PICKER_HUE_BAR,
mode == ColorPickerMode::HueBar,
);
self.flags.set(
ColorEditFlags::PICKER_HUE_WHEEL,
mode == ColorPickerMode::HueWheel,
);
self
}
#[inline]
pub fn format(mut self, format: ColorFormat) -> Self {
self.flags
.set(ColorEditFlags::UINT8, format == ColorFormat::U8);
self.flags
.set(ColorEditFlags::FLOAT, format == ColorFormat::Float);
self
}
#[inline]
pub fn reference_color(mut self, ref_color: &'a [f32; 4]) -> Self {
self.ref_color = Some(ref_color);
self
}
pub fn build(mut self, _: &Ui) -> bool {
if let EditableColor::Float3(_) = self.value {
self.flags.insert(ColorEditFlags::NO_ALPHA);
}
let ref_color = self.ref_color.map(|c| c.as_ptr()).unwrap_or(ptr::null());
unsafe {
sys::igColorPicker4(
self.label.as_ptr(),
self.value.as_mut_ptr(),
self.flags.bits() as _,
ref_color,
)
}
}
}
#[derive(Copy, Clone, Debug)]
#[must_use]
pub struct ColorButton<'a> {
desc_id: &'a ImStr,
color: [f32; 4],
flags: ColorEditFlags,
size: [f32; 2],
}
impl<'a> ColorButton<'a> {
pub fn new(desc_id: &ImStr, color: [f32; 4]) -> ColorButton {
ColorButton {
desc_id,
color,
flags: ColorEditFlags::empty(),
size: [0.0, 0.0],
}
}
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW_HALF,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW,
preview == ColorPreview::Alpha,
);
self
}
#[inline]
pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
self.flags.set(
ColorEditFlags::INPUT_RGB,
input_mode == ColorEditInputMode::RGB,
);
self.flags.set(
ColorEditFlags::INPUT_HSV,
input_mode == ColorEditInputMode::HSV,
);
self
}
pub fn drag_drop(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_DRAG_DROP, !value);
self
}
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
self
}
pub fn build(self, _: &Ui) -> bool {
unsafe {
sys::igColorButton(
self.desc_id.as_ptr(),
self.color.into(),
self.flags.bits() as _,
self.size.into(),
)
}
}
}
impl<'ui> Ui<'ui> {
pub fn set_color_edit_options(&self, flags: ColorEditFlags) {
unsafe {
sys::igSetColorEditOptions(flags.bits() as i32);
}
}
}