imgui_ext/
color.rs

1//!
2//! It has three variants:
3//!
4//! ## Color Button
5//!
6//! `color(button(...))`
7//!
8//! ### Optional params
9//!
10//! * `label`
11//! * `flags` Function identifier that returns a
12//!   [`ImGuiColorEditFlags`][ImGuiColorEditFlags].
13//! * `preview` Allowed values: `"Opaque"`, `"HalfAlpha"`, `"Alpha"`
14//!   ([`ColorPreview`][ColorPreview] variants).
15//! * `size` Function identifier that returns the button size.
16//! * `catch`
17//! * `map` Applies a mapping function to `&mut Self`.
18//!
19//! ## Color Edit
20//!
21//! `color(edit(...))`
22//!
23//! ### Optional params
24//!
25//! * `label`
26//! * `flags` Function identifier that returns a
27//!   [`ImGuiColorEditFlags`][ImGuiColorEditFlags].
28//! * `preview` Allowed values: `"Opaque"`, `"HalfAlpha"`, `"Alpha"`
29//!   ([`ColorPreview`][ColorPreview] variants).
30//! * `mode` Allowed values: `"RGB"`, `"HSV"`, `"HEX"`
31//!   ([`ColorEditMode`][ColorEditMode] variants).
32//! * `format` Allowed values: `"Float"`, `"U8"` ([`ColorFormat`][ColorFormat]
33//!   variants).
34//! * `catch`
35//! * `map` Applies a mapping function to `&mut Self`.
36//!
37//! ## Color Picker
38//!
39//! `color(picker(...))`
40//!
41//! ### Optional params
42//!
43//! * `label`
44//! * `flags` Function identifier that returns a
45//!   [`ImGuiColorEditFlags`][ImGuiColorEditFlags].
46//! * `preview` Allowed values: `"Opaque"`, `"HalfAlpha"`, `"Alpha"`
47//!   ([`ColorPreview`][ColorPreview] variants).
48//! * `mode` Allowed values: `"HueBar"`, `"HueWheel"`
49//!   ([`ColorPickerMode`][ColorEditMode] variants).
50//! * `format` Allowed values: `"Float"`, `"U8"` ([`ColorFormat`][ColorFormat]
51//!   variants).
52//! * `catch`
53//! * `map` Applies a mapping function to `&mut Self`.
54//!
55//! ## Example
56//!
57//! ```
58//! #[derive(imgui_ext::Gui)]
59//! struct Example {
60//!     // you could also nest all the modes inside of the same `color(...)`
61//!     #[imgui(
62//!         color(button(preview = "Alpha")),
63//!         color(edit(preview = "HalfAlpha")),
64//!         color(picker(mode = "HueWheel"))
65//!     )]
66//!     color: [f32; 4],
67//! }
68//! ```
69//!
70//! ### Result:
71//!
72//! ![][result]
73//!
74//! [result]: https://i.imgur.com/hWD08K0.png?1
75//! [ImGuiColorEditFlags]: https://docs.rs/imgui/0.0/imgui/struct.ImGuiColorEditFlags.html
76//! [ColorPreview]: https://docs.rs/imgui/0.0/imgui/enum.ColorPreview.html
77//! [ColorFormat]: https://docs.rs/imgui/0.0/imgui/enum.ColorFormat.html
78//! [ColorEditMode]: https://docs.rs/imgui/0.0/imgui/enum.ColorEditMode.html
79//! [ColorPickerMode]: https://docs.rs/imgui/0.0/imgui/enum.ColorPickerMode.html
80use imgui::{
81    ColorButton as ImColorButton, ColorEdit as ImColorEdit, ColorEditMode, ColorFormat,
82    ColorPicker as ImColorPicker, ColorPickerMode, ColorPreview, EditableColor,
83    ImGuiColorEditFlags, ImStr, Ui,
84};
85
86pub struct ColorButtonParams<'a> {
87    pub label: &'a ImStr,
88    pub flags: Option<ImGuiColorEditFlags>,
89    pub preview: Option<ColorPreview>,
90    pub size: Option<[f32; 2]>,
91}
92
93pub struct ColorEditParams<'a> {
94    pub label: &'a ImStr,
95    pub flags: Option<ImGuiColorEditFlags>,
96    pub preview: Option<ColorPreview>,
97    pub format: Option<ColorFormat>,
98    pub mode: Option<ColorEditMode>,
99}
100
101pub struct ColorPickerParams<'a> {
102    pub label: &'a ImStr,
103    pub flags: Option<ImGuiColorEditFlags>,
104    pub preview: Option<ColorPreview>,
105    pub format: Option<ColorFormat>,
106    pub mode: Option<ColorPickerMode>,
107}
108
109pub trait ColorButton {
110    fn build(ui: &Ui, elem: Self, params: ColorButtonParams) -> bool;
111}
112
113pub trait ColorEdit {
114    fn build(ui: &Ui, elem: Self, params: ColorEditParams) -> bool;
115}
116
117pub trait ColorPicker {
118    fn build(ui: &Ui, elem: Self, params: ColorPickerParams) -> bool;
119}
120
121impl<C: Into<[f32; 4]>> ColorButton for C {
122    fn build(ui: &Ui, elem: Self, params: ColorButtonParams) -> bool {
123        let mut button = ImColorButton::new(ui, params.label, elem.into());
124        if let Some(flags) = params.flags {
125            button = button.flags(flags);
126        }
127        if let Some(preview) = params.preview {
128            button = button.preview(preview);
129        }
130        if let Some(size) = params.size {
131            button = button.size(size);
132        }
133        button.build()
134    }
135}
136
137impl<'a, C: Into<EditableColor<'a>>> ColorEdit for C {
138    fn build(ui: &Ui, elem: Self, params: ColorEditParams) -> bool {
139        let mut edit = ImColorEdit::new(ui, params.label, elem.into());
140        if let Some(flags) = params.flags {
141            edit = edit.flags(flags);
142        }
143        if let Some(preview) = params.preview {
144            edit = edit.preview(preview);
145        }
146        if let Some(mode) = params.mode {
147            edit = edit.mode(mode);
148        }
149        if let Some(format) = params.format {
150            edit = edit.format(format);
151        }
152        edit.build()
153    }
154}
155
156impl<'a, C: Into<EditableColor<'a>>> ColorPicker for C {
157    fn build(ui: &Ui, elem: Self, params: ColorPickerParams) -> bool {
158        let mut picker = ImColorPicker::new(ui, params.label, elem.into());
159        if let Some(flags) = params.flags {
160            picker = picker.flags(flags);
161        }
162        if let Some(preview) = params.preview {
163            picker = picker.preview(preview);
164        }
165        if let Some(mode) = params.mode {
166            picker = picker.mode(mode);
167        }
168        if let Some(format) = params.format {
169            picker = picker.format(format);
170        }
171        picker.build()
172    }
173}
174
175#[cfg(test)]
176mod tests {
177    #![allow(dead_code)]
178
179    use crate as imgui_ext;
180
181    use imgui::ImGuiColorEditFlags as Flags;
182
183    #[test]
184    fn color_test() {
185        #[derive(imgui_ext::Gui)]
186        struct Example {
187            #[imgui(color(edit), color(picker(flags = "flags")), color(button()))]
188            a: [f32; 4],
189            #[imgui(color(edit(mode = "HSV"), picker, button(size = "size"),))]
190            b: [f32; 4],
191        }
192
193        fn size() -> [f32; 2] {
194            [42.0, 42.0]
195        }
196
197        fn flags() -> Flags {
198            Flags::all()
199        }
200    }
201}