Pull new color editor/picker API from 0.1-dev

This commit is contained in:
Joonas Javanainen 2019-07-12 20:03:17 +03:00
parent 6ad52c517b
commit 11b6932714
No known key found for this signature in database
GPG Key ID: D39CCA5CB19B9179
7 changed files with 809 additions and 682 deletions

View File

@ -2,8 +2,150 @@ use imgui::*;
mod support;
fn main() {
let mut state = State::default();
let system = support::init(file!());
system.main_loop(|run, ui| {
example_selector(run, ui, &mut state);
match state.example {
1 => example_1(ui, &mut state),
2 => example_2(ui),
3 => example_3(ui),
_ => (),
}
});
}
fn example_selector(run: &mut bool, ui: &mut Ui, state: &mut State) {
let w = Window::new(im_str!("Color button examples"))
.opened(run)
.position([20.0, 20.0], Condition::Appearing)
.size([700.0, 100.0], Condition::Appearing)
.resizable(false);
w.build(ui, || {
let ex1 = ui.radio_button(im_str!("Example 1: Basics"), &mut state.example, 1);
let ex2 = ui.radio_button(im_str!("Example 2: Alpha component"), &mut state.example, 2);
let ex3 = ui.radio_button(im_str!("Example 3: Input format"), &mut state.example, 3);
if ex1 || ex2 || ex3 {
state.reset();
}
});
}
fn example_1(ui: &Ui, state: &mut State) {
let w = Window::new(im_str!("Example 1: Basics"))
.size([700.0, 300.0], Condition::Appearing)
.position([20.0, 140.0], Condition::Appearing);
w.build(ui, || {
ui.text_wrapped(im_str!(
"Color button is a widget that displays a color value as a clickable rectangle. \
It also supports a tooltip with detailed information about the color value. \
Try hovering over and clicking these buttons!"
));
ui.text(state.notify_text);
ui.text("This button is black:");
if ColorButton::new(im_str!("Black color"), [0.0, 0.0, 0.0, 1.0]).build(ui) {
state.notify_text = "*** Black button was clicked";
}
ui.text("This button is red:");
if ColorButton::new(im_str!("Red color"), [1.0, 0.0, 0.0, 1.0]).build(ui) {
state.notify_text = "*** Red button was clicked";
}
ui.text("This button is BIG because it has a custom size:");
if ColorButton::new(im_str!("Green color"), [0.0, 1.0, 0.0, 1.0])
.size([100.0, 50.0])
.build(ui)
{
state.notify_text = "*** BIG button was clicked";
}
ui.text("This button doesn't use the tooltip at all:");
if ColorButton::new(im_str!("No tooltip"), [0.0, 0.0, 1.0, 1.0])
.tooltip(false)
.build(ui)
{
state.notify_text = "*** No tooltip button was clicked";
}
});
}
fn example_2(ui: &Ui) {
let w = Window::new(im_str!("Example 2: Alpha component"))
.size([700.0, 320.0], Condition::Appearing)
.position([20.0, 140.0], Condition::Appearing);
w.build(ui, || {
ui.text_wrapped(im_str!(
"The displayed color is passed to the button as four float values between \
0.0 - 1.0 (RGBA). If you don't care about the alpha component, it can be \
disabled and it won't show up in the tooltip"
));
ui.text("This button ignores the alpha component:");
ColorButton::new(im_str!("Red color"), [1.0, 0.0, 0.0, 0.5])
.alpha(false)
.build(ui);
ui.spacing();
ui.spacing();
ui.spacing();
ui.text_wrapped(im_str!(
"If you *do* care about the alpha component, you can choose how it's \
displayed in the button and the tooltip"
));
ui.separator();
ui.text_wrapped(im_str!(
"ColorPreview::Opaque (default) doesn't show the alpha component at all"
));
ColorButton::new(im_str!("Red + ColorPreview::Opaque"), [1.0, 0.0, 0.0, 0.5])
.preview(ColorPreview::Opaque)
.build(ui);
ui.separator();
ui.text_wrapped(im_str!(
"ColorPreview::HalfAlpha divides the color area into two halves and uses a \
checkerboard pattern in one half to illustrate the alpha component"
));
ColorButton::new(
im_str!("Red + ColorPreview::HalfAlpha"),
[1.0, 0.0, 0.0, 0.5],
)
.preview(ColorPreview::HalfAlpha)
.build(ui);
ui.separator();
ui.text_wrapped(im_str!(
"ColorPreview::Alpha uses a checkerboard pattern in the entire color area to \
illustrate the alpha component"
));
ColorButton::new(im_str!("Red + ColorPreview::Alpha"), [1.0, 0.0, 0.0, 0.5])
.preview(ColorPreview::Alpha)
.build(ui);
});
}
fn example_3(ui: &Ui) {
let w = Window::new(im_str!("Example 3: Input format"))
.size([700.0, 320.0], Condition::Appearing)
.position([20.0, 140.0], Condition::Appearing);
w.build(ui, || {
ui.text("This button interprets the input value [1.0, 0.0, 0.0, 1.0] as RGB(A) (default):");
ColorButton::new(im_str!("RGBA red"), [1.0, 0.0, 0.0, 1.0]).build(ui);
ui.separator();
ui.text("This button interprets the input value [1.0, 0.0, 0.0, 1.0] as HSV(A):");
ColorButton::new(im_str!("HSVA black"), [1.0, 0.0, 0.0, 1.0])
.input_mode(ColorEditInputMode::HSV)
.build(ui);
});
}
#[derive(Default)]
struct State {
example: i32,
example: u32,
notify_text: &'static str,
}
@ -12,142 +154,3 @@ impl State {
self.notify_text = "";
}
}
impl Default for State {
fn default() -> State {
State {
example: 0,
notify_text: "",
}
}
}
fn main() {
let system = support::init(file!());
let mut state = State::default();
system.main_loop(|_, ui| {
example_selector(&mut state, ui);
match state.example {
1 => example_1(&mut state, ui),
2 => example_2(ui),
_ => (),
}
});
}
fn example_selector(state: &mut State, ui: &Ui) {
Window::new(im_str!("Color button examples"))
.position([20.0, 20.0], Condition::Appearing)
.size([700.0, 80.0], Condition::Appearing)
.resizable(false)
.build(ui, || {
let ex1 = ui.radio_button(im_str!("Example 1: Basics"), &mut state.example, 1);
let ex2 = ui.radio_button(im_str!("Example 2: Alpha component"), &mut state.example, 2);
if ex1 || ex2 {
state.reset();
}
});
}
fn example_1(state: &mut State, ui: &Ui) {
Window::new(im_str!("Example 1: Basics"))
.size([700.0, 300.0], Condition::Appearing)
.position([20.0, 120.0], Condition::Appearing)
.build(ui, || {
ui.text_wrapped(im_str!(
"Color button is a widget that displays a color value as a clickable rectangle. \
It also supports a tooltip with detailed information about the color value. \
Try hovering over and clicking these buttons!"
));
ui.text(state.notify_text);
ui.text("This button is black:");
if ui
.color_button(im_str!("Black color"), [0.0, 0.0, 0.0, 1.0])
.build()
{
state.notify_text = "*** Black button was clicked";
}
ui.text("This button is red:");
if ui
.color_button(im_str!("Red color"), [1.0, 0.0, 0.0, 1.0])
.build()
{
state.notify_text = "*** Red button was clicked";
}
ui.text("This button is BIG because it has a custom size:");
if ui
.color_button(im_str!("Green color"), [0.0, 1.0, 0.0, 1.0])
.size([100.0, 50.0])
.build()
{
state.notify_text = "*** BIG button was clicked";
}
ui.text("This button doesn't use the tooltip at all:");
if ui
.color_button(im_str!("No tooltip"), [0.0, 0.0, 1.0, 1.0])
.tooltip(false)
.build()
{
state.notify_text = "*** No tooltip button was clicked";
}
});
}
fn example_2(ui: &Ui) {
Window::new(im_str!("Example 2: Alpha component"))
.size([700.0, 320.0], Condition::Appearing)
.position([20.0, 140.0], Condition::Appearing)
.build(ui, || {
ui.text_wrapped(im_str!(
"The displayed color is passed to the button as four float values between \
0.0 - 1.0 (RGBA). If you don't care about the alpha component, it can be \
disabled and it won't show up in the tooltip"
));
ui.text("This button ignores the alpha component:");
ui.color_button(im_str!("Red color"), [1.0, 0.0, 0.0, 0.5])
.alpha(false)
.build();
ui.spacing();
ui.spacing();
ui.spacing();
ui.text_wrapped(im_str!(
"If you *do* care about the alpha component, you can choose how it's \
displayed in the button and the tooltip"
));
ui.separator();
ui.text_wrapped(im_str!(
"ColorPreview::Opaque (default) doesn't show the alpha component at all"
));
ui.color_button(im_str!("Red + ColorPreview::Opaque"), [1.0, 0.0, 0.0, 0.5])
.preview(ColorPreview::Opaque)
.build();
ui.separator();
ui.text_wrapped(im_str!(
"ColorPreview::HalfAlpha divides the color area into two halves and uses a \
checkerboard pattern in one half to illustrate the alpha component"
));
ui.color_button(
im_str!("Red + ColorPreview::HalfAlpha"),
[1.0, 0.0, 0.0, 0.5],
)
.preview(ColorPreview::HalfAlpha)
.build();
ui.separator();
ui.text_wrapped(im_str!(
"ColorPreview::Alpha uses a checkerboard pattern in the entire color area to \
illustrate the alpha component"
));
ui.color_button(im_str!("Red + ColorPreview::Alpha"), [1.0, 0.0, 0.0, 0.5])
.preview(ColorPreview::Alpha)
.build();
});
}

View File

@ -479,8 +479,8 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
.build();
ui.input_float3(im_str!("input float3"), &mut state.vec3f)
.build();
ui.color_edit(im_str!("color 1"), &mut state.col1).build();
ui.color_edit(im_str!("color 2"), &mut state.col2).build();
ColorEdit::new(im_str!("color 1"), &mut state.col1).build(ui);
ColorEdit::new(im_str!("color 2"), &mut state.col2).build(ui);
ui.tree_node(im_str!("Multi-component Widgets")).build(|| {
ui.input_float2(im_str!("input float2"), &mut state.vec2f)
@ -519,13 +519,13 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
show options.",
);
let misc_flags = {
let mut f = ImGuiColorEditFlags::empty();
f.set(ImGuiColorEditFlags::HDR, s.hdr);
f.set(ImGuiColorEditFlags::AlphaPreviewHalf, s.alpha_half_preview);
let mut f = ColorEditFlags::empty();
f.set(ColorEditFlags::HDR, s.hdr);
f.set(ColorEditFlags::ALPHA_PREVIEW_HALF, s.alpha_half_preview);
if !s.alpha_half_preview {
f.set(ImGuiColorEditFlags::AlphaPreview, s.alpha_preview);
f.set(ColorEditFlags::ALPHA_PREVIEW, s.alpha_preview);
}
f.set(ImGuiColorEditFlags::NoOptions, !s.options_menu);
f.set(ColorEditFlags::NO_OPTIONS, !s.options_menu);
f
};
@ -536,22 +536,22 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
"Click on the colored square to open a color picker.
CTRL+click on individual component to input value.\n",
);
ui.color_edit(im_str!("MyColor##1"), &mut s.color)
ColorEdit::new(im_str!("MyColor##1"), &mut s.color)
.flags(misc_flags)
.alpha(false)
.build();
.build(ui);
ui.text(im_str!("Color widget HSV with Alpha:"));
ui.color_edit(im_str!("MyColor##2"), &mut s.color)
ColorEdit::new(im_str!("MyColor##2"), &mut s.color)
.flags(misc_flags)
.mode(ColorEditMode::HSV)
.build();
.input_mode(ColorEditInputMode::HSV)
.build(ui);
ui.text(im_str!("Color widget with Float Display:"));
ui.color_edit(im_str!("MyColor##2f"), &mut s.color)
ColorEdit::new(im_str!("MyColor##2f"), &mut s.color)
.flags(misc_flags)
.format(ColorFormat::Float)
.build();
.build(ui);
ui.text(im_str!("Color button with Picker:"));
ui.same_line(0.0);
@ -562,11 +562,11 @@ CTRL+click on individual component to input value.\n",
With the label(false) function you can pass a non-empty label which \
will only be used for the tooltip and picker popup.",
);
ui.color_edit(im_str!("MyColor##3"), &mut s.color)
ColorEdit::new(im_str!("MyColor##3"), &mut s.color)
.flags(misc_flags)
.inputs(false)
.label(false)
.build();
.build(ui);
ui.text(im_str!("Color picker:"));
ui.checkbox(im_str!("With Alpha"), &mut s.alpha);
@ -577,24 +577,24 @@ CTRL+click on individual component to input value.\n",
ui.checkbox(im_str!("With Ref Color"), &mut s.ref_color);
if s.ref_color {
ui.same_line(0.0);
ui.color_edit(im_str!("##RefColor"), &mut s.ref_color_v)
ColorEdit::new(im_str!("##RefColor"), &mut s.ref_color_v)
.flags(misc_flags)
.inputs(false)
.build();
.build(ui);
}
}
let mut b = ui
.color_picker(im_str!("MyColor##4"), &mut s.color)
let mut b = ColorPicker::new
(im_str!("MyColor##4"), &mut s.color)
.flags(misc_flags)
.alpha(s.alpha)
.alpha_bar(s.alpha_bar)
.side_preview(s.side_preview)
.rgb(true);
.display_rgb(true);
if s.ref_color {
b = b.reference_color(&s.ref_color_v)
}
b.build();
b.build(ui);
});
}
if ui
@ -674,7 +674,7 @@ CTRL+click on individual component to input value.\n",
let items = &[im_str!("aaaa"), im_str!("bbbb"), im_str!("cccc"), im_str!("dddd"), im_str!("eeee")];
ui.combo(im_str!("Combo"), &mut state.stacked_modals_item, items, -1);
ui.color_edit(im_str!("color"), &mut state.stacked_modals_color).build();
ColorEdit::new(im_str!("color"), &mut state.stacked_modals_color).build(ui);
if ui.button(im_str!("Add another modal.."), [0.0, 0.0]) {
ui.open_popup(im_str!("Stacked 2")) ;
@ -855,7 +855,7 @@ fn show_example_app_custom_rendering(ui: &Ui, state: &mut CustomRenderingState,
.build(ui, || {
ui.text("Primitives");
// TODO: Add DragFloat to change value of sz
ui.color_edit(im_str!("Color"), &mut state.col).build();
ColorEdit::new(im_str!("Color"), &mut state.col).build(ui);
let draw_list = ui.get_window_draw_list();
let p = ui.get_cursor_screen_pos();
let spacing = 8.0;

View File

@ -1,426 +0,0 @@
#![warn(missing_docs)]
use std::marker::PhantomData;
use std::ptr;
use crate::legacy::ImGuiColorEditFlags;
use crate::sys;
use crate::{ImStr, Ui};
/// Mutable reference to an editable color value.
#[derive(Debug)]
pub enum EditableColor<'p> {
/// Color value with three float components (e.g. RGB).
Float3(&'p mut [f32; 3]),
/// Color value with four float components (e.g. RGBA).
Float4(&'p mut [f32; 4]),
}
impl<'p> EditableColor<'p> {
/// Returns an unsafe mutable pointer to the color slice's buffer.
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<'p> From<&'p mut [f32; 3]> for EditableColor<'p> {
fn from(value: &'p mut [f32; 3]) -> EditableColor<'p> {
EditableColor::Float3(value)
}
}
impl<'p> From<&'p mut [f32; 4]> for EditableColor<'p> {
fn from(value: &'p mut [f32; 4]) -> EditableColor<'p> {
EditableColor::Float4(value)
}
}
/// Color editor mode.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorEditMode {
/// Edit as RGB(A).
RGB,
/// Edit as HSV(A).
HSV,
/// Edit as hex (e.g. #AABBCC(DD))
HEX,
}
/// Color picker hue/saturation/value editor mode.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorPickerMode {
/// Use a bar for hue, rectangle for saturation/value.
HueBar,
/// Use a wheel for hue, triangle for saturation/value.
HueWheel,
}
/// Color component formatting.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorFormat {
/// Display values formatted as 0..255.
U8,
/// Display values formatted as 0.0..1.0.
Float,
}
/// Color editor preview style.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorPreview {
/// Don't show the alpha component.
Opaque,
/// Half of the preview area shows the alpha component using a checkerboard pattern.
HalfAlpha,
/// Show the alpha component using a checkerboard pattern.
Alpha,
}
/// Builder for a color editor widget.
#[must_use]
pub struct ColorEdit<'ui, 'p> {
label: &'p ImStr,
value: EditableColor<'p>,
flags: ImGuiColorEditFlags,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
impl<'ui, 'p> ColorEdit<'ui, 'p> {
/// Constructs a new color editor builder.
pub fn new(_: &Ui<'ui>, label: &'p ImStr, value: EditableColor<'p>) -> Self {
ColorEdit {
label,
value,
flags: ImGuiColorEditFlags::empty(),
_phantom: PhantomData,
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ImGuiColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoAlpha, !value);
self
}
/// Enables/disables the picker that appears when clicking on colored square.
#[inline]
pub fn picker(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoPicker, !value);
self
}
/// Enables/disables toggling of the options menu when right-clicking on inputs or the small
/// preview.
#[inline]
pub fn options(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoOptions, !value);
self
}
/// Enables/disables the colored square preview next to the inputs.
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoSmallPreview, !value);
self
}
/// Enables/disables the input sliders/text widgets.
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoInputs, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoTooltip, !value);
self
}
/// Enables/disables display of the inline text label (the label is in any case forwarded to
/// the tooltip and picker).
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoLabel, !value);
self
}
/// Enables/disables the vertical alpha bar/gradient in the color picker.
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::AlphaBar, value);
self
}
/// Sets the preview style.
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ImGuiColorEditFlags::AlphaPreviewHalf,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ImGuiColorEditFlags::AlphaPreview,
preview == ColorPreview::Alpha,
);
self
}
/// (WIP) Currently only disables 0.0..1.0 limits in RGBA edition.
///
/// Note: you probably want to use ColorFormat::Float as well.
#[inline]
pub fn hdr(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::HDR, value);
self
}
/// Sets the color editor mode.
#[inline]
pub fn mode(mut self, mode: ColorEditMode) -> Self {
self.flags
.set(ImGuiColorEditFlags::RGB, mode == ColorEditMode::RGB);
self.flags
.set(ImGuiColorEditFlags::HSV, mode == ColorEditMode::HSV);
self.flags
.set(ImGuiColorEditFlags::HEX, mode == ColorEditMode::HEX);
self
}
/// Sets the formatting style of color components.
#[inline]
pub fn format(mut self, format: ColorFormat) -> Self {
self.flags
.set(ImGuiColorEditFlags::Uint8, format == ColorFormat::U8);
self.flags
.set(ImGuiColorEditFlags::Float, format == ColorFormat::Float);
self
}
/// Builds the color editor.
pub fn build(self) -> bool {
match self.value {
EditableColor::Float3(value) => unsafe {
sys::igColorEdit3(self.label.as_ptr(), value.as_mut_ptr(), self.flags.bits())
},
EditableColor::Float4(value) => unsafe {
sys::igColorEdit4(self.label.as_ptr(), value.as_mut_ptr(), self.flags.bits())
},
}
}
}
/// Builder for a color picker widget.
#[must_use]
pub struct ColorPicker<'ui, 'p> {
label: &'p ImStr,
value: EditableColor<'p>,
flags: ImGuiColorEditFlags,
ref_color: Option<&'p [f32; 4]>,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
impl<'ui, 'p> ColorPicker<'ui, 'p> {
/// Constructs a new color picker builder.
pub fn new(_: &Ui<'ui>, label: &'p ImStr, value: EditableColor<'p>) -> Self {
ColorPicker {
label,
value,
flags: ImGuiColorEditFlags::empty(),
ref_color: None,
_phantom: PhantomData,
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ImGuiColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoAlpha, !value);
self
}
/// Enables/disables the colored square preview next to the inputs.
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoSmallPreview, !value);
self
}
/// Enables/disables the input sliders/text widgets.
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoInputs, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoTooltip, !value);
self
}
/// Enables/disables display of the inline text label (the label is in any case forwarded to
/// the tooltip and picker).
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoLabel, !value);
self
}
/// Enables/disables the bigger color preview on the right side of the picker.
#[inline]
pub fn side_preview(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoSidePreview, !value);
self
}
/// Enables/disables the vertical alpha bar/gradient in the color picker.
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::AlphaBar, value);
self
}
/// Sets the preview style.
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ImGuiColorEditFlags::AlphaPreviewHalf,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ImGuiColorEditFlags::AlphaPreview,
preview == ColorPreview::Alpha,
);
self
}
/// Enables/disables the RGB inputs.
#[inline]
pub fn rgb(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::RGB, value);
self
}
/// Enables/disables the HSV inputs.
#[inline]
pub fn hsv(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::HSV, value);
self
}
/// Enables/disables the HEX input.
#[inline]
pub fn hex(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::HEX, value);
self
}
/// Sets the hue/saturation/value editor mode.
#[inline]
pub fn mode(mut self, mode: ColorPickerMode) -> Self {
self.flags.set(
ImGuiColorEditFlags::PickerHueBar,
mode == ColorPickerMode::HueBar,
);
self.flags.set(
ImGuiColorEditFlags::PickerHueWheel,
mode == ColorPickerMode::HueWheel,
);
self
}
/// Sets the formatting style of color components.
#[inline]
pub fn format(mut self, format: ColorFormat) -> Self {
self.flags
.set(ImGuiColorEditFlags::Uint8, format == ColorFormat::U8);
self.flags
.set(ImGuiColorEditFlags::Float, format == ColorFormat::Float);
self
}
/// Sets the shown reference color.
#[inline]
pub fn reference_color(mut self, ref_color: &'p [f32; 4]) -> Self {
self.ref_color = Some(ref_color);
self
}
/// Builds the color picker.
pub fn build(mut self) -> bool {
if let EditableColor::Float3(_) = self.value {
self.flags.insert(ImGuiColorEditFlags::NoAlpha);
}
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(),
ref_color,
)
}
}
}
/// Builder for a color button widget.
#[must_use]
pub struct ColorButton<'ui, 'p> {
desc_id: &'p ImStr,
color: [f32; 4],
flags: ImGuiColorEditFlags,
size: [f32; 2],
_phantom: PhantomData<&'ui Ui<'ui>>,
}
impl<'ui, 'p> ColorButton<'ui, 'p> {
/// Constructs a new color button builder.
pub fn new(_: &Ui<'ui>, desc_id: &'p ImStr, color: [f32; 4]) -> Self {
ColorButton {
desc_id,
color,
flags: ImGuiColorEditFlags::empty(),
size: [0.0, 0.0],
_phantom: PhantomData,
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ImGuiColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoAlpha, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoTooltip, !value);
self
}
/// Sets the preview style.
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ImGuiColorEditFlags::AlphaPreviewHalf,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ImGuiColorEditFlags::AlphaPreview,
preview == ColorPreview::Alpha,
);
self
}
/// Sets the button size.
///
/// Use 0.0 for width and/or height to use the default size.
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size.into();
self
}
/// Builds the color button.
pub fn build(self) -> bool {
unsafe {
sys::igColorButton(
self.desc_id.as_ptr(),
self.color.into(),
self.flags.bits(),
self.size.into(),
)
}
}
}

View File

@ -3,65 +3,13 @@ use bitflags::bitflags;
use std::os::raw::c_int;
use crate::string::ImStr;
use crate::widget::color_editors::*;
use crate::widget::progress_bar::ProgressBar;
use crate::window::{Window, WindowFlags};
use crate::Ui;
bitflags!(
/// Color edit flags
#[repr(C)]
pub struct ImGuiColorEditFlags: c_int {
/// ColorEdit, ColorPicker, ColorButton: ignore Alpha component (read 3 components from the
/// input pointer).
const NoAlpha = 1;
/// ColorEdit: disable picker when clicking on colored square.
const NoPicker = 1 << 2;
/// ColorEdit: disable toggling options menu when right-clicking on inputs/small preview.
const NoOptions = 1 << 3;
/// ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to
/// show only the inputs)
const NoSmallPreview = 1 << 4;
/// ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the
/// small preview colored square).
const NoInputs = 1 << 5;
/// ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview.
const NoTooltip = 1 << 6;
/// ColorEdit, ColorPicker: disable display of inline text label (the label is still
/// forwarded to the tooltip and picker).
const NoLabel = 1 << 7;
/// ColorPicker: disable bigger color preview on right side of the picker, use small
/// colored square preview instead.
const NoSidePreview = 1 << 8;
/// ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
const NoDragDrop = 1 << 9;
/// ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
const AlphaBar = 1 << 16;
/// ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a
/// checkerboard, instead of opaque.
const AlphaPreview = 1 << 17;
/// ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead
/// of opaque.
const AlphaPreviewHalf= 1 << 18;
/// (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you
/// probably want to use ImGuiColorEditFlags::Float flag as well).
const HDR = 1 << 19;
/// ColorEdit: choose one among RGB/HSV/HEX. ColorPicker: choose any combination using
/// RGB/HSV/HEX.
const RGB = 1 << 20;
const HSV = 1 << 21;
const HEX = 1 << 22;
/// ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255.
const Uint8 = 1 << 23;
/// ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats
/// instead of 0..255 integers. No round-trip of value via integers.
const Float = 1 << 24;
/// ColorPicker: bar for Hue, rectangle for Sat/Value.
const PickerHueBar = 1 << 25;
/// ColorPicker: wheel for Hue, triangle for Sat/Value.
const PickerHueWheel = 1 << 26;
}
);
#[deprecated(since = "0.2.0", note = "use ColorEditFlags instead")]
pub type ImGuiColorEditFlags = ColorEditFlags;
bitflags!(
/// Flags for combo boxes
@ -360,3 +308,26 @@ impl<'ui> Ui<'ui> {
ProgressBar::new(fraction)
}
}
impl<'ui> Ui<'ui> {
#[deprecated(since = "0.2.0", note = "use imgui::ColorEdit::new(...) instead")]
pub fn color_edit<'p, V: Into<EditableColor<'p>>>(
&self,
label: &'p ImStr,
value: V,
) -> ColorEdit<'p> {
ColorEdit::new(label, value.into())
}
#[deprecated(since = "0.2.0", note = "use imgui::ColorPicker::new(...) instead")]
pub fn color_picker<'p, V: Into<EditableColor<'p>>>(
&self,
label: &'p ImStr,
value: V,
) -> ColorPicker<'p> {
ColorPicker::new(label, value.into())
}
#[deprecated(since = "0.2.0", note = "use imgui::ColorButton::new(...) instead")]
pub fn color_button<'p>(&self, desc_id: &'p ImStr, color: [f32; 4]) -> ColorButton<'p> {
ColorButton::new(desc_id, color.into())
}
}

View File

@ -11,10 +11,6 @@ use std::thread;
pub use self::child_frame::ChildFrame;
pub use self::clipboard::*;
pub use self::color_editors::{
ColorButton, ColorEdit, ColorEditMode, ColorFormat, ColorPicker, ColorPickerMode, ColorPreview,
EditableColor,
};
pub use self::context::*;
pub use self::drag::{
DragFloat, DragFloat2, DragFloat3, DragFloat4, DragFloatRange2, DragInt, DragInt2, DragInt3,
@ -47,6 +43,7 @@ pub use self::stacks::*;
pub use self::string::*;
pub use self::style::*;
pub use self::trees::{CollapsingHeader, TreeNode};
pub use self::widget::color_editors::*;
pub use self::widget::progress_bar::*;
pub use self::window::*;
pub use self::window_draw_list::{ChannelsSplit, ImColor, WindowDrawList};
@ -54,7 +51,6 @@ use internal::RawCast;
mod child_frame;
mod clipboard;
mod color_editors;
mod context;
mod drag;
mod fonts;
@ -514,38 +510,6 @@ impl<'ui> Ui<'ui> {
}
}
// Widgets: Color Editor/Picker
impl<'ui> Ui<'ui> {
/// Constructs a new color editor builder.
pub fn color_edit<'p, V: Into<EditableColor<'p>>>(
&self,
label: &'p ImStr,
value: V,
) -> ColorEdit<'ui, 'p> {
ColorEdit::new(self, label, value.into())
}
/// Constructs a new color picker builder.
pub fn color_picker<'p, V: Into<EditableColor<'p>>>(
&self,
label: &'p ImStr,
value: V,
) -> ColorPicker<'ui, 'p> {
ColorPicker::new(self, label, value.into())
}
/// Constructs a new color button builder.
pub fn color_button<'p>(&self, desc_id: &'p ImStr, color: [f32; 4]) -> ColorButton<'ui, 'p> {
ColorButton::new(self, desc_id, color.into())
}
/// Initialize current options (generally on application startup) if you want to select a
/// default format, picker type, etc. Users will be able to change many settings, unless you
/// use .options(false) in your widget builders.
pub fn set_color_edit_options(&self, flags: ImGuiColorEditFlags) {
unsafe {
sys::igSetColorEditOptions(flags.bits());
}
}
}
// Widgets: Trees
impl<'ui> Ui<'ui> {
pub fn tree_node<'p>(&self, id: &'p ImStr) -> TreeNode<'ui, 'p> {

614
src/widget/color_editors.rs Normal file
View File

@ -0,0 +1,614 @@
use bitflags::bitflags;
use std::ptr;
use crate::string::ImStr;
use crate::sys;
use crate::Ui;
/// Mutable reference to an editable color value.
#[derive(Debug)]
pub enum EditableColor<'a> {
/// Color value with three float components (e.g. RGB).
Float3(&'a mut [f32; 3]),
/// Color value with four float components (e.g. RGBA).
Float4(&'a mut [f32; 4]),
}
impl<'a> EditableColor<'a> {
/// Returns an unsafe mutable pointer to the color slice's buffer.
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)
}
}
/// Color editor input mode.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorEditInputMode {
/// Edit as RGB(A).
RGB,
/// Edit as HSV(A).
HSV,
}
/// Color editor display mode.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorEditDisplayMode {
/// Display as RGB(A).
RGB,
/// Display as HSV(A).
HSV,
/// Display as hex (e.g. #AABBCC(DD))
HEX,
}
/// Color picker hue/saturation/value editor mode
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorPickerMode {
/// Use a bar for hue, rectangle for saturation/value.
HueBar,
/// Use a wheel for hue, triangle for saturation/value.
HueWheel,
}
/// Color component formatting
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorFormat {
/// Display values formatted as 0..255.
U8,
/// Display values formatted as 0.0..1.0.
Float,
}
/// Color editor preview style
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorPreview {
/// Don't show the alpha component.
Opaque,
/// Half of the preview area shows the alpha component using a checkerboard pattern.
HalfAlpha,
/// Show the alpha component using a checkerboard pattern.
Alpha,
}
bitflags! {
/// Color edit flags
#[repr(transparent)]
pub struct ColorEditFlags: u32 {
/// ColorEdit, ColorPicker, ColorButton: ignore Alpha component (read only 3 components of
/// the value).
const NO_ALPHA = sys::ImGuiColorEditFlags_NoAlpha;
/// ColorEdit: disable picker when clicking on colored square.
const NO_PICKER = sys::ImGuiColorEditFlags_NoPicker;
/// ColorEdit: disable toggling options menu when right-clicking on inputs/small preview.
const NO_OPTIONS = sys::ImGuiColorEditFlags_NoOptions;
/// ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to
/// show only the inputs)
const NO_SMALL_PREVIEW = sys::ImGuiColorEditFlags_NoSmallPreview;
/// ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the
/// small preview colored square).
const NO_INPUTS = sys::ImGuiColorEditFlags_NoInputs;
/// ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview.
const NO_TOOLTIP = sys::ImGuiColorEditFlags_NoTooltip;
/// ColorEdit, ColorPicker: disable display of inline text label (the label is still
/// forwarded to the tooltip and picker).
const NO_LABEL = sys::ImGuiColorEditFlags_NoLabel;
/// ColorPicker: disable bigger color preview on right side of the picker, use small
/// colored square preview instead.
const NO_SIDE_PREVIEW = sys::ImGuiColorEditFlags_NoSidePreview;
/// ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
const NO_DRAG_DROP = sys::ImGuiColorEditFlags_NoDragDrop;
/// ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
const ALPHA_BAR = sys::ImGuiColorEditFlags_AlphaBar;
/// ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a
/// checkerboard, instead of opaque.
const ALPHA_PREVIEW = sys::ImGuiColorEditFlags_AlphaPreview;
/// ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead
/// of opaque.
const ALPHA_PREVIEW_HALF = sys::ImGuiColorEditFlags_AlphaPreviewHalf;
/// (WIP) ColorEdit: Currently onlys disable 0.0f..1.0f limits in RGBA editing (note: you
/// probably want to use `ColorEditFlags::FLOAT` as well).
const HDR = sys::ImGuiColorEditFlags_HDR;
/// ColorEdit: display only as RGB. ColorPicker: Enable RGB display.
const DISPLAY_RGB = sys::ImGuiColorEditFlags_DisplayRGB;
/// ColorEdit: display only as HSV. ColorPicker: Enable HSV display.
const DISPLAY_HSV = sys::ImGuiColorEditFlags_DisplayHSV;
/// ColorEdit: display only as HEX. ColorPicker: Enable Hex display.
const DISPLAY_HEX = sys::ImGuiColorEditFlags_DisplayHex;
/// ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255.
const UINT8 = sys::ImGuiColorEditFlags_Uint8;
/// ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats
/// instead of 0..255 integers. No round-trip of value via integers.
const FLOAT = sys::ImGuiColorEditFlags_Float;
/// ColorPicker: bar for Hue, rectangle for Sat/Value.
const PICKER_HUE_BAR = sys::ImGuiColorEditFlags_PickerHueBar;
/// ColorPicker: wheel for Hue, triangle for Sat/Value.
const PICKER_HUE_WHEEL = sys::ImGuiColorEditFlags_PickerHueWheel;
/// ColorEdit, ColorPicker: input and output data in RGB format.
const INPUT_RGB = sys::ImGuiColorEditFlags_InputRGB;
/// ColorEdit, ColorPicker: input and output data in HSV format.
const INPUT_HSV = sys::ImGuiColorEditFlags_InputHSV;
}
}
/// Builder for a color editor widget.
///
/// # Examples
///
/// ```no_run
/// # use imgui::*;
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame();
/// # let mut color = [0.0, 0.0, 0.0, 1.0];
/// let ce = ColorEdit::new(im_str!("color_edit"), &mut color);
/// if ce.build(&ui) {
/// println!("The color was changed");
/// }
/// ```
#[derive(Debug)]
#[must_use]
pub struct ColorEdit<'a> {
label: &'a ImStr,
value: EditableColor<'a>,
flags: ColorEditFlags,
}
impl<'a> ColorEdit<'a> {
/// Constructs a new color editor builder.
pub fn new<T: Into<EditableColor<'a>>>(label: &'a ImStr, value: T) -> ColorEdit<'a> {
ColorEdit {
label,
value: value.into(),
flags: ColorEditFlags::empty(),
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
/// Enables/disables the picker that appears when clicking on colored square.
#[inline]
pub fn picker(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_PICKER, !value);
self
}
/// Enables/disables toggling of the options menu when right-clicking on inputs or the small
/// preview.
#[inline]
pub fn options(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
self
}
/// Enables/disables the colored square preview next to the inputs.
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
self
}
/// Enables/disables the input sliders/text widgets.
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_INPUTS, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
/// Enables/disables display of the inline text label (the label is in any case forwarded to
/// the tooltip and picker).
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_LABEL, !value);
self
}
/// Enables/disables the vertical alpha bar/gradient in the color picker.
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::ALPHA_BAR, value);
self
}
/// Sets the preview style.
#[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
}
/// (WIP) Currently only disables 0.0..1.0 limits in RGBA edition.
///
/// Note: you probably want to use ColorFormat::Float as well.
#[inline]
pub fn hdr(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::HDR, value);
self
}
/// Sets the data format for input and output data.
#[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
}
/// Sets the color editor display mode.
#[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
}
/// Sets the formatting style of color components.
#[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
}
/// Builds the color editor.
///
/// Returns true if the color value was changed.
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 _,
)
},
}
}
}
/// Builder for a color picker widget.
///
/// # Examples
///
/// ```no_run
/// # use imgui::*;
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame();
/// # let mut color = [0.0, 0.0, 0.0, 1.0];
/// let cp = ColorPicker::new(im_str!("color_picker"), &mut color);
/// if cp.build(&ui) {
/// println!("A color was picked");
/// }
/// ```
#[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> {
/// Constructs a new color picker builder.
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,
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
/// Enables/disables toggling of the options menu when right-clicking on inputs or the small
/// preview.
#[inline]
pub fn options(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
self
}
/// Enables/disables the colored square preview next to the inputs.
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
self
}
/// Enables/disables the input sliders/text widgets.
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_INPUTS, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
/// Enables/disables display of the inline text label (the label is in any case forwarded to
/// the tooltip and picker).
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_LABEL, !value);
self
}
/// Enables/disables the bigger color preview on the right side of the picker.
#[inline]
pub fn side_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SIDE_PREVIEW, !value);
self
}
/// Enables/disables the vertical alpha bar/gradient in the color picker.
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::ALPHA_BAR, value);
self
}
/// Sets the preview style.
#[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
}
/// Sets the data format for input and output data.
#[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
}
/// Enables/disables displaying the value as RGB.
#[inline]
pub fn display_rgb(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_RGB, value);
self
}
/// Enables/disables displaying the value as HSV.
#[inline]
pub fn display_hsv(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_HSV, value);
self
}
/// Enables/disables displaying the value as hex.
#[inline]
pub fn display_hex(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_HEX, value);
self
}
/// Sets the hue/saturation/value editor mode.
#[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
}
/// Sets the formatting style of color components.
#[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
}
/// Sets the shown reference color.
#[inline]
pub fn reference_color(mut self, ref_color: &'a [f32; 4]) -> Self {
self.ref_color = Some(ref_color);
self
}
/// Builds the color picker.
///
/// Returns true if the color value was changed.
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,
)
}
}
}
/// Builder for a color button widget.
///
/// # Examples
///
/// ```no_run
/// # use imgui::*;
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame();
/// ColorButton::new(im_str!("color_button"), [1.0, 0.0, 0.0, 1.0])
/// .build(&ui);
/// ```
#[derive(Debug, Clone)]
#[must_use]
pub struct ColorButton<'a> {
desc_id: &'a ImStr,
color: [f32; 4],
flags: ColorEditFlags,
size: [f32; 2],
}
impl<'a> ColorButton<'a> {
/// Constructs a new color button builder.
pub fn new(desc_id: &ImStr, color: [f32; 4]) -> ColorButton {
ColorButton {
desc_id,
color,
flags: ColorEditFlags::empty(),
size: [0.0, 0.0],
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
/// Sets the preview style.
#[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
}
/// Sets the data format for input data.
#[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
}
/// Enables/disables using the button as drag&drop source.
pub fn drag_drop(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_DRAG_DROP, !value);
self
}
/// Sets the button size.
///
/// Use 0.0 for width and/or height to use the default size.
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
self
}
/// Builds the color button.
///
/// Returns true if this color button was clicked.
pub fn build(self, _: &Ui) -> bool {
unsafe {
sys::igColorButton(
self.desc_id.as_ptr(),
self.color.into(),
self.flags.bits() as _,
self.size.into(),
)
}
}
}
/// # Widgets: Color Editor/Picker
impl<'ui> Ui<'ui> {
/// Initialize current options (generally on application startup) if you want to select a
/// default format, picker type, etc. Users will be able to change many settings, unless you
/// use .options(false) in your widget builders.
pub fn set_color_edit_options(&self, flags: ColorEditFlags) {
unsafe {
sys::igSetColorEditOptions(flags.bits() as i32);
}
}
}

View File

@ -1,3 +1,4 @@
pub mod color_editors;
pub mod misc;
pub mod progress_bar;
pub mod text;