Use Grid to add labels to the color picker sliders
Also improve the color preview in the color picker
This commit is contained in:
parent
63d3e9e70b
commit
73d16eb771
3 changed files with 104 additions and 53 deletions
|
@ -19,6 +19,8 @@ fn contrast_color(color: impl Into<Rgba>) -> Color32 {
|
||||||
const N: u32 = 6 * 6;
|
const N: u32 = 6 * 6;
|
||||||
|
|
||||||
fn background_checkers(painter: &Painter, rect: Rect) {
|
fn background_checkers(painter: &Painter, rect: Rect) {
|
||||||
|
let rect = rect.shrink(0.5); // Small hack to avoid the checkers from peeking through the sides
|
||||||
|
|
||||||
let mut top_color = Color32::from_gray(128);
|
let mut top_color = Color32::from_gray(128);
|
||||||
let mut bottom_color = Color32::from_gray(32);
|
let mut bottom_color = Color32::from_gray(32);
|
||||||
let checker_size = Vec2::splat(rect.height() / 2.0);
|
let checker_size = Vec2::splat(rect.height() / 2.0);
|
||||||
|
@ -40,19 +42,26 @@ fn background_checkers(painter: &Painter, rect: Rect) {
|
||||||
painter.add(Shape::triangles(triangles));
|
painter.add(Shape::triangles(triangles));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_color(ui: &mut Ui, color: impl Into<Color32>, desired_size: Vec2) -> Response {
|
pub fn show_color(ui: &mut Ui, color: impl Into<Hsva>, desired_size: Vec2) -> Response {
|
||||||
show_srgba(ui, color.into(), desired_size)
|
show_hsva(ui, color.into(), desired_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_srgba(ui: &mut Ui, srgba: Color32, desired_size: Vec2) -> Response {
|
fn show_hsva(ui: &mut Ui, color: Hsva, desired_size: Vec2) -> Response {
|
||||||
let (rect, response) = ui.allocate_at_least(desired_size, Sense::hover());
|
let (rect, response) = ui.allocate_at_least(desired_size, Sense::hover());
|
||||||
background_checkers(ui.painter(), rect);
|
background_checkers(ui.painter(), rect);
|
||||||
ui.painter().add(Shape::Rect {
|
if true {
|
||||||
rect,
|
let left = Rect::from_min_max(rect.left_top(), rect.center_bottom());
|
||||||
corner_radius: 2.0,
|
let right = Rect::from_min_max(rect.center_top(), rect.right_bottom());
|
||||||
fill: srgba,
|
ui.painter().rect_filled(left, 0.0, color);
|
||||||
stroke: Stroke::new(3.0, srgba.to_opaque()),
|
ui.painter().rect_filled(right, 0.0, color.to_opaque());
|
||||||
});
|
} else {
|
||||||
|
ui.painter().add(Shape::Rect {
|
||||||
|
rect,
|
||||||
|
corner_radius: 2.0,
|
||||||
|
fill: color.into(),
|
||||||
|
stroke: Stroke::new(3.0, color.to_opaque()),
|
||||||
|
});
|
||||||
|
}
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,12 +71,22 @@ fn color_button(ui: &mut Ui, color: Color32) -> Response {
|
||||||
let visuals = ui.style().interact(&response);
|
let visuals = ui.style().interact(&response);
|
||||||
let rect = rect.expand(visuals.expansion);
|
let rect = rect.expand(visuals.expansion);
|
||||||
background_checkers(ui.painter(), rect);
|
background_checkers(ui.painter(), rect);
|
||||||
ui.painter().add(Shape::Rect {
|
let corner_radius = visuals.corner_radius.at_most(2.0);
|
||||||
rect,
|
if true {
|
||||||
corner_radius: visuals.corner_radius.at_most(2.0),
|
let left = Rect::from_min_max(rect.left_top(), rect.center_bottom());
|
||||||
fill: color,
|
let right = Rect::from_min_max(rect.center_top(), rect.right_bottom());
|
||||||
stroke: visuals.fg_stroke,
|
ui.painter().rect_filled(left, 0.0, color);
|
||||||
});
|
ui.painter().rect_filled(right, 0.0, color.to_opaque());
|
||||||
|
ui.painter()
|
||||||
|
.rect_stroke(rect, corner_radius, visuals.fg_stroke);
|
||||||
|
} else {
|
||||||
|
ui.painter().add(Shape::Rect {
|
||||||
|
rect,
|
||||||
|
corner_radius,
|
||||||
|
fill: color,
|
||||||
|
stroke: visuals.fg_stroke,
|
||||||
|
});
|
||||||
|
}
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +214,37 @@ pub enum Alpha {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_picker_hsvag_2d(ui: &mut Ui, hsva: &mut HsvaGamma, alpha: Alpha) {
|
fn color_picker_hsvag_2d(ui: &mut Ui, hsva: &mut HsvaGamma, alpha: Alpha) {
|
||||||
ui.vertical(|ui| {
|
if alpha == Alpha::BlendOrAdditive {
|
||||||
|
// We signal additive blending by storing a negative alpha (a bit ironic).
|
||||||
|
let a = &mut hsva.a;
|
||||||
|
let mut additive = *a < 0.0;
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Blending:");
|
||||||
|
ui.radio_value(&mut additive, false, "Normal");
|
||||||
|
ui.radio_value(&mut additive, true, "Additive");
|
||||||
|
|
||||||
|
if additive {
|
||||||
|
*a = -a.abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if !additive {
|
||||||
|
*a = a.abs();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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(
|
let current_color_size = vec2(
|
||||||
ui.style().spacing.slider_width,
|
ui.style().spacing.slider_width,
|
||||||
ui.style().spacing.interact_size.y * 2.0,
|
ui.style().spacing.interact_size.y * 2.0,
|
||||||
|
@ -205,53 +254,51 @@ fn color_picker_hsvag_2d(ui: &mut Ui, hsva: &mut HsvaGamma, alpha: Alpha) {
|
||||||
|
|
||||||
if alpha == Alpha::Opaque {
|
if alpha == Alpha::Opaque {
|
||||||
hsva.a = 1.0;
|
hsva.a = 1.0;
|
||||||
show_color(ui, *hsva, current_color_size).on_hover_text("Current color");
|
show_color(ui, *hsva, current_color_size);
|
||||||
|
ui.label("Current color");
|
||||||
|
ui.end_row();
|
||||||
} else {
|
} else {
|
||||||
let a = &mut hsva.a;
|
let a = &mut hsva.a;
|
||||||
|
|
||||||
// We signal additive blending by storing a negative alpha (a bit ironic).
|
|
||||||
let mut additive = *a < 0.0;
|
|
||||||
|
|
||||||
if alpha == Alpha::OnlyBlend {
|
if alpha == Alpha::OnlyBlend {
|
||||||
if additive {
|
if *a < 0.0 {
|
||||||
*a = 0.5;
|
*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 {
|
|
||||||
ui.horizontal(|ui| {
|
|
||||||
ui.label("Blending:");
|
|
||||||
ui.radio_value(&mut additive, false, "Normal");
|
|
||||||
ui.radio_value(&mut additive, true, "Additive");
|
|
||||||
|
|
||||||
if additive {
|
|
||||||
*a = -a.abs();
|
|
||||||
}
|
|
||||||
|
|
||||||
if !additive {
|
|
||||||
*a = a.abs();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if !additive {
|
|
||||||
color_slider_1d(ui, a, |a| HsvaGamma { a, ..opaque }.into())
|
|
||||||
.on_hover_text("Alpha");
|
|
||||||
}
|
}
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
show_color(ui, *hsva, current_color_size).on_hover_text("Current color");
|
show_color(ui, *hsva, current_color_size);
|
||||||
show_color(ui, opaque, current_color_size).on_hover_text("Current color (opaque)");
|
ui.label("Current color");
|
||||||
|
ui.end_row();
|
||||||
}
|
}
|
||||||
|
|
||||||
let HsvaGamma { h, s, v, a: _ } = hsva;
|
let HsvaGamma { h, s, v, a: _ } = hsva;
|
||||||
|
|
||||||
color_slider_2d(ui, h, s, |h, s| HsvaGamma::new(h, s, 1.0, 1.0).into())
|
color_slider_2d(ui, h, s, |h, s| HsvaGamma::new(h, s, 1.0, 1.0).into());
|
||||||
.on_hover_text("Hue - Saturation");
|
ui.label("Hue / Saturation");
|
||||||
color_slider_2d(ui, v, s, |v, s| HsvaGamma { v, s, ..opaque }.into())
|
ui.end_row();
|
||||||
.on_hover_text("Value - Saturation");
|
|
||||||
color_slider_1d(ui, h, |h| HsvaGamma { h, ..opaque }.into()).on_hover_text("Hue");
|
color_slider_2d(ui, v, s, |v, s| HsvaGamma { v, s, ..opaque }.into());
|
||||||
color_slider_1d(ui, s, |s| HsvaGamma { s, ..opaque }.into()).on_hover_text("Saturation");
|
ui.label("Value / Saturation");
|
||||||
color_slider_1d(ui, v, |v| HsvaGamma { v, ..opaque }.into()).on_hover_text("Value");
|
ui.end_row();
|
||||||
|
|
||||||
|
color_slider_1d(ui, h, |h| HsvaGamma { h, ..opaque }.into());
|
||||||
|
ui.label("Hue");
|
||||||
|
ui.end_row();
|
||||||
|
|
||||||
|
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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl Default for WidgetGallery {
|
||||||
radio: Enum::First,
|
radio: Enum::First,
|
||||||
scalar: 42.0,
|
scalar: 42.0,
|
||||||
string: "Hello World!".to_owned(),
|
string: "Hello World!".to_owned(),
|
||||||
color: egui::Color32::LIGHT_BLUE,
|
color: (egui::Rgba::from(egui::Color32::LIGHT_BLUE) * 0.5).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,6 +436,10 @@ impl Hsva {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub fn to_opaque(self) -> Self {
|
||||||
|
Self { a: 1.0, ..self }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_rgb(&self) -> [f32; 3] {
|
pub fn to_rgb(&self) -> [f32; 3] {
|
||||||
rgb_from_hsv((self.h, self.s, self.v))
|
rgb_from_hsv((self.h, self.s, self.v))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue