Smaller and nicer color picker

This commit is contained in:
Emil Ernerfeldt 2021-10-01 19:24:36 +02:00
parent 76cdbe2cf8
commit 981b812f68
2 changed files with 82 additions and 75 deletions

View file

@ -21,6 +21,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md), [`eg
* `Painter`/`Fonts`: text layout now expect a color when creating a `Galley`. You may override that color with `Painter::galley_with_color`.
* MSRV (Minimum Supported Rust Version) is now `1.54.0`.
* By default, `DragValue`:s no longer show a tooltip when hovered. Change with `Style::explanation_tooltips`.
* Smaller and nicer color picker.
### Fixed 🐛
* Fix wrongly sized multiline `TextEdit` in justified layouts.

View file

@ -95,10 +95,7 @@ fn color_button(ui: &mut Ui, color: Color32, open: bool) -> Response {
fn color_slider_1d(ui: &mut Ui, value: &mut f32, color_at: impl Fn(f32) -> Color32) -> Response {
#![allow(clippy::identity_op)]
let desired_size = vec2(
ui.spacing().slider_width,
ui.spacing().interact_size.y * 2.0,
);
let desired_size = vec2(ui.spacing().slider_width, ui.spacing().interact_size.y);
let (rect, response) = ui.allocate_at_least(desired_size, Sense::click_and_drag());
if let Some(mpos) = response.interact_pointer_pos() {
@ -211,23 +208,34 @@ pub enum Alpha {
BlendOrAdditive,
}
fn color_text_ui(ui: &mut Ui, color: impl Into<Color32>) {
fn color_text_ui(ui: &mut Ui, color: impl Into<Color32>, alpha: Alpha) {
let color = color.into();
ui.horizontal(|ui| {
let [r, g, b, a] = color.to_array();
ui.label(format!(
"RGBA (premultiplied): rgba({}, {}, {}, {})",
r, g, b, a
));
if ui.button("📋").on_hover_text("Click to copy").clicked() {
if alpha == Alpha::Opaque {
ui.output().copied_text = format!("{}, {}, {}", r, g, b);
} else {
ui.output().copied_text = format!("{}, {}, {}, {}", r, g, b, a);
}
}
if alpha == Alpha::Opaque {
ui.label(format!("rgb({}, {}, {})", r, g, b))
.on_hover_text("Red Green Blue");
} else {
ui.label(format!("rgba({}, {}, {}, {})", r, g, b, a))
.on_hover_text("Red Green Blue with premultiplied Alpha");
}
});
}
fn color_picker_hsvag_2d(ui: &mut Ui, hsva: &mut HsvaGamma, alpha: Alpha) {
color_text_ui(ui, *hsva);
let current_color_size = vec2(ui.spacing().slider_width, ui.spacing().interact_size.y);
show_color(ui, *hsva, current_color_size).on_hover_text("Selected color");
color_text_ui(ui, *hsva, alpha);
if alpha == Alpha::BlendOrAdditive {
// We signal additive blending by storing a negative alpha (a bit ironic).
@ -249,22 +257,6 @@ fn color_picker_hsvag_2d(ui: &mut Ui, hsva: &mut HsvaGamma, alpha: Alpha) {
}
let additive = hsva.a < 0.0;
// Using different grid ids avoid some flickering when switching between
// (the grid remembers the sizes of its contents).
let grid_id = if alpha == Alpha::Opaque {
"hsva_color_picker_opaque"
} else if additive {
"hsva_color_picker_additive"
} else {
"hsva_color_picker_normal"
};
crate::Grid::new(grid_id).show(ui, |ui| {
let current_color_size = vec2(
ui.spacing().slider_width,
ui.spacing().interact_size.y * 2.0,
);
let opaque = HsvaGamma { a: 1.0, ..*hsva };
if alpha == Alpha::Opaque {
@ -276,23 +268,12 @@ fn color_picker_hsvag_2d(ui: &mut Ui, hsva: &mut HsvaGamma, alpha: Alpha) {
if *a < 0.0 {
*a = 0.5; // was additive, but isn't allowed to be
}
color_slider_1d(ui, a, |a| HsvaGamma { a, ..opaque }.into());
ui.label("Alpha");
ui.end_row();
color_slider_1d(ui, a, |a| HsvaGamma { a, ..opaque }.into()).on_hover_text("Alpha");
} else if !additive {
color_slider_1d(ui, a, |a| HsvaGamma { a, ..opaque }.into());
ui.label("Alpha");
ui.end_row();
color_slider_1d(ui, a, |a| HsvaGamma { a, ..opaque }.into()).on_hover_text("Alpha");
}
}
show_color(ui, *hsva, current_color_size);
ui.label("Selected color");
ui.end_row();
ui.separator(); // TODO: fix ever-expansion
ui.end_row();
let HsvaGamma { h, s, v, a: _ } = hsva;
color_slider_1d(ui, h, |h| {
@ -303,28 +284,26 @@ fn color_picker_hsvag_2d(ui: &mut Ui, hsva: &mut HsvaGamma, alpha: Alpha) {
a: 1.0,
}
.into()
});
ui.label("Hue");
ui.end_row();
})
.on_hover_text("Hue");
color_slider_1d(ui, s, |s| HsvaGamma { s, ..opaque }.into());
ui.label("Saturation");
ui.end_row();
color_slider_1d(ui, v, |v| HsvaGamma { v, ..opaque }.into());
ui.label("Value");
ui.end_row();
color_slider_2d(ui, v, s, |v, s| HsvaGamma { s, v, ..opaque }.into());
ui.label("Value / Saturation");
ui.end_row();
});
if false {
color_slider_1d(ui, s, |s| HsvaGamma { s, ..opaque }.into()).on_hover_text("Saturation");
}
/// return true on change
if false {
color_slider_1d(ui, v, |v| HsvaGamma { v, ..opaque }.into()).on_hover_text("Value");
}
color_slider_2d(ui, v, s, |v, s| HsvaGamma { s, v, ..opaque }.into());
}
/// Returns `true` on change.
fn color_picker_hsva_2d(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> bool {
let mut hsvag = HsvaGamma::from(*hsva);
ui.vertical(|ui| {
color_picker_hsvag_2d(ui, &mut hsvag, alpha);
});
let new_hasva = Hsva::from(hsvag);
if *hsva == new_hasva {
false
@ -334,6 +313,33 @@ fn color_picker_hsva_2d(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> bool {
}
}
/// Returns `true` on change.
pub fn color_picker_color32(ui: &mut Ui, srgba: &mut Color32, alpha: Alpha) -> bool {
// To ensure we keep hue slider when `srgba` is gray we store the
// full `Hsva` in a cache:
let mut hsva = ui
.ctx()
.memory()
.data_temp
.get_or_default::<Cache<Color32, Hsva>>()
.get(srgba)
.cloned()
.unwrap_or_else(|| Hsva::from(*srgba));
let response = color_picker_hsva_2d(ui, &mut hsva, alpha);
*srgba = Color32::from(hsva);
ui.ctx()
.memory()
.data_temp
.get_mut_or_default::<Cache<Color32, Hsva>>()
.set(*srgba, hsva);
response
}
pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Response {
let pupup_id = ui.auto_id_with("popup");
let open = ui.memory().is_popup_open(pupup_id);
@ -351,7 +357,7 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res
.order(Order::Foreground)
.default_pos(button_response.rect.max)
.show(ui.ctx(), |ui| {
ui.spacing_mut().slider_width = 256.0;
ui.spacing_mut().slider_width = 210.0;
Frame::popup(ui.style()).show(ui, |ui| {
if color_picker_hsva_2d(ui, hsva, alpha) {
button_response.mark_changed();