Add ColorPicker widget

This commit is contained in:
Joonas Javanainen 2017-11-04 10:07:48 +02:00
parent b9e0de93b0
commit c9e5db5aa5
No known key found for this signature in database
GPG Key ID: D39CCA5CB19B9179
4 changed files with 202 additions and 7 deletions

View File

@ -5,6 +5,7 @@
### Added
- Namespaced flags (e.g. `ImGuiWindowFlags`)
- Color picker widget
### Changed

View File

@ -43,25 +43,35 @@ struct State {
auto_resize_state: AutoResizeState,
file_menu: FileMenuState,
radio_button: i32,
color_picker: ColorPickerState,
color_edit: ColorEditState,
}
struct ColorPickerState {
struct ColorEditState {
color: [f32; 4],
hdr: bool,
alpha_preview: bool,
alpha_half_preview: bool,
options_menu: bool,
alpha: bool,
alpha_bar: bool,
side_preview: bool,
ref_color: bool,
ref_color_v: [f32; 4],
}
impl Default for ColorPickerState {
impl Default for ColorEditState {
fn default() -> Self {
ColorPickerState {
ColorEditState {
color: [114.0 / 255.0, 144.0 / 255.0, 154.0 / 255.0, 200.0 / 255.0],
hdr: false,
alpha_preview: true,
alpha_half_preview: false,
options_menu: true,
alpha: true,
alpha_bar: true,
side_preview: true,
ref_color: false,
ref_color_v: [1.0, 0.0, 1.0, 0.5],
}
}
}
@ -108,7 +118,7 @@ impl Default for State {
auto_resize_state: Default::default(),
file_menu: Default::default(),
radio_button: 0,
color_picker: ColorPickerState::default(),
color_edit: ColorEditState::default(),
}
}
}
@ -422,7 +432,7 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
});
ui.tree_node(im_str!("Color/Picker Widgets")).build(|| {
let ref mut s = state.color_picker;
let ref mut s = state.color_edit;
ui.checkbox(im_str!("With HDR"), &mut s.hdr);
ui.same_line(0.0);
show_help_marker(ui, im_str!("Currently all this does is to lift the 0..1 limits on dragging widgets."));
@ -471,6 +481,33 @@ fn show_test_window<'a>(ui: &Ui<'a>, state: &mut State, opened: &mut bool) {
.inputs(false)
.label(false)
.build();
ui.text(im_str!("Color picker:"));
ui.checkbox(im_str!("With Alpha"), &mut s.alpha);
ui.checkbox(im_str!("With Alpha Bar"), &mut s.alpha_bar);
ui.checkbox(im_str!("With Side Preview"), &mut s.side_preview);
if s.side_preview {
ui.same_line(0.0);
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)
.flags(misc_flags)
.inputs(false)
.build();
}
}
let mut b = ui.color_picker(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);
if s.ref_color {
b = b.reference_color(s.ref_color_v)
}
b.build();
});
}
if ui.collapsing_header(im_str!("Popups & Modal windows"))

View File

@ -1,5 +1,6 @@
use imgui_sys;
use std::marker::PhantomData;
use std::ptr;
use {ImGuiColorEditFlags, ImStr, Ui};
@ -9,6 +10,15 @@ pub enum EditableColor<'p> {
Float4(&'p mut [f32; 4]),
}
impl<'p> EditableColor<'p> {
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) }
}
@ -24,6 +34,12 @@ pub enum ColorEditMode {
HEX,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum ColorPickerMode {
HueBar,
HueWheel,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum EditableColorFormat {
U8,
@ -155,3 +171,137 @@ impl<'ui, 'p> ColorEdit<'ui, 'p> {
}
}
}
#[must_use]
pub struct ColorPicker<'ui, 'p> {
label: &'p ImStr,
value: EditableColor<'p>,
flags: ImGuiColorEditFlags,
ref_color: Option<[f32; 4]>,
_phantom: PhantomData<&'ui Ui<'ui>>,
}
impl<'ui, 'p> ColorPicker<'ui, 'p> {
pub fn new(_: &Ui<'ui>, label: &'p ImStr, value: EditableColor<'p>) -> Self {
ColorPicker {
label,
value,
flags: ImGuiColorEditFlags::empty(),
ref_color: None,
_phantom: PhantomData,
}
}
#[inline]
pub fn flags(mut self, flags: ImGuiColorEditFlags) -> Self {
self.flags = flags;
self
}
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoAlpha, !value);
self
}
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoSmallPreview, !value);
self
}
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoInputs, !value);
self
}
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoTooltip, !value);
self
}
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoLabel, !value);
self
}
#[inline]
pub fn side_preview(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::NoSidePreview, !value);
self
}
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::AlphaBar, value);
self
}
#[inline]
pub fn preview(mut self, preview: EditableColorPreview) -> Self {
self.flags.set(
ImGuiColorEditFlags::AlphaPreviewHalf,
preview == EditableColorPreview::HalfAlpha,
);
self.flags.set(
ImGuiColorEditFlags::AlphaPreview,
preview == EditableColorPreview::Alpha,
);
self
}
#[inline]
pub fn rgb(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::RGB, value);
self
}
#[inline]
pub fn hsv(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::HSV, value);
self
}
#[inline]
pub fn hex(mut self, value: bool) -> Self {
self.flags.set(ImGuiColorEditFlags::HEX, value);
self
}
#[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
}
#[inline]
pub fn format(mut self, format: EditableColorFormat) -> Self {
self.flags.set(
ImGuiColorEditFlags::Uint8,
format == EditableColorFormat::U8,
);
self.flags.set(
ImGuiColorEditFlags::Float,
format == EditableColorFormat::Float,
);
self
}
#[inline]
pub fn reference_color(mut self, ref_color: [f32; 4]) -> Self {
self.ref_color = Some(ref_color);
self
}
pub fn build(mut self) -> bool {
if let EditableColor::Float3(_) = self.value {
self.flags.insert(ImGuiColorEditFlags::NoAlpha);
}
let ref_color = self.ref_color.as_ref().map(|c| c.as_ptr()).unwrap_or(
ptr::null(),
);
unsafe {
imgui_sys::igColorPicker4(
self.label.as_ptr(),
self.value.as_mut_ptr(),
self.flags,
ref_color,
)
}
}
}

View File

@ -41,7 +41,7 @@ pub use imgui_sys::{ImDrawIdx, ImDrawVert, ImGuiColorEditFlags, ImGuiInputTextFl
ImGuiSelectableFlags, ImGuiCond, ImGuiCol, ImGuiStyle, ImGuiTreeNodeFlags,
ImGuiWindowFlags, ImVec2, ImVec4};
pub use child_frame::ChildFrame;
pub use color_editors::{ColorEdit, ColorEditMode, EditableColor, EditableColorFormat};
pub use color_editors::{ColorEdit, ColorEditMode, ColorPicker, EditableColor, EditableColorFormat};
pub use input::{InputFloat, InputFloat2, InputFloat3, InputFloat4, InputInt, InputInt2, InputInt3,
InputInt4, InputText};
pub use menus::{Menu, MenuItem};
@ -657,6 +657,13 @@ impl<'ui> Ui<'ui> {
pub fn color_edit4<'p>(&self, label: &'p ImStr, value: &'p mut [f32; 4]) -> ColorEdit<'ui, 'p> {
self.color_edit(label, value)
}
pub fn color_picker<'p, V: Into<EditableColor<'p>>>(
&self,
label: &'p ImStr,
value: V,
) -> ColorPicker<'ui, 'p> {
ColorPicker::new(self, label, value.into())
}
}
// Widgets: Trees