Smaller and nicer color picker
This commit is contained in:
parent
76cdbe2cf8
commit
981b812f68
2 changed files with 82 additions and 75 deletions
|
@ -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.
|
||||
|
|
|
@ -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() {
|
||||
ui.output().copied_text = format!("{}, {}, {}, {}", r, g, b, a);
|
||||
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,82 +257,53 @@ 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"
|
||||
let opaque = HsvaGamma { a: 1.0, ..*hsva };
|
||||
|
||||
if alpha == Alpha::Opaque {
|
||||
hsva.a = 1.0;
|
||||
} else {
|
||||
"hsva_color_picker_normal"
|
||||
};
|
||||
let a = &mut hsva.a;
|
||||
|
||||
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 {
|
||||
hsva.a = 1.0;
|
||||
} else {
|
||||
let a = &mut hsva.a;
|
||||
|
||||
if alpha == Alpha::OnlyBlend {
|
||||
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();
|
||||
} else if !additive {
|
||||
color_slider_1d(ui, a, |a| HsvaGamma { a, ..opaque }.into());
|
||||
ui.label("Alpha");
|
||||
ui.end_row();
|
||||
if alpha == Alpha::OnlyBlend {
|
||||
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()).on_hover_text("Alpha");
|
||||
} else if !additive {
|
||||
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();
|
||||
let HsvaGamma { h, s, v, a: _ } = hsva;
|
||||
|
||||
ui.separator(); // TODO: fix ever-expansion
|
||||
ui.end_row();
|
||||
color_slider_1d(ui, h, |h| {
|
||||
HsvaGamma {
|
||||
h,
|
||||
s: 1.0,
|
||||
v: 1.0,
|
||||
a: 1.0,
|
||||
}
|
||||
.into()
|
||||
})
|
||||
.on_hover_text("Hue");
|
||||
|
||||
let HsvaGamma { h, s, v, a: _ } = hsva;
|
||||
if false {
|
||||
color_slider_1d(ui, s, |s| HsvaGamma { s, ..opaque }.into()).on_hover_text("Saturation");
|
||||
}
|
||||
|
||||
color_slider_1d(ui, h, |h| {
|
||||
HsvaGamma {
|
||||
h,
|
||||
s: 1.0,
|
||||
v: 1.0,
|
||||
a: 1.0,
|
||||
}
|
||||
.into()
|
||||
});
|
||||
ui.label("Hue");
|
||||
ui.end_row();
|
||||
if false {
|
||||
color_slider_1d(ui, v, |v| HsvaGamma { v, ..opaque }.into()).on_hover_text("Value");
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
color_slider_2d(ui, v, s, |v, s| HsvaGamma { s, v, ..opaque }.into());
|
||||
}
|
||||
|
||||
/// return true on change
|
||||
/// Returns `true` on change.
|
||||
fn color_picker_hsva_2d(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> bool {
|
||||
let mut hsvag = HsvaGamma::from(*hsva);
|
||||
color_picker_hsvag_2d(ui, &mut hsvag, alpha);
|
||||
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();
|
||||
|
|
Loading…
Reference in a new issue