Skip to content

Commit

Permalink
Add DragValues for RGB(A) in the color picker (#2734)
Browse files Browse the repository at this point in the history
Added some DragValue widgets in the color_picker widget as input fields
for managing the RGBA values.
In case the provided values result in a not valid premultiplied alpha
RGBA color, a button will appear next to the input fields, to be used to
multiply the values with the alpha channel.


![image](https://user-images.githubusercontent.com/68190772/218438019-8b46936f-d025-4287-ac27-2b937f8f3d7c.png)

Closes <#2716>.

---------

Co-authored-by: IVANMK-7 <[email protected]>
Co-authored-by: Emil Ernerfeldt <[email protected]>
Co-authored-by: Brian Janssen <[email protected]>
  • Loading branch information
4 people authored Jan 7, 2024
1 parent 51e5d28 commit bfed2b4
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 58 deletions.
32 changes: 22 additions & 10 deletions crates/ecolor/src/hsva.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ impl Hsva {

/// From `sRGBA` with premultiplied alpha
#[inline]
pub fn from_srgba_premultiplied(srgba: [u8; 4]) -> Self {
pub fn from_srgba_premultiplied([r, g, b, a]: [u8; 4]) -> Self {
Self::from_rgba_premultiplied(
linear_f32_from_gamma_u8(srgba[0]),
linear_f32_from_gamma_u8(srgba[1]),
linear_f32_from_gamma_u8(srgba[2]),
linear_f32_from_linear_u8(srgba[3]),
linear_f32_from_gamma_u8(r),
linear_f32_from_gamma_u8(g),
linear_f32_from_gamma_u8(b),
linear_f32_from_linear_u8(a),
)
}

/// From `sRGBA` without premultiplied alpha
#[inline]
pub fn from_srgba_unmultiplied(srgba: [u8; 4]) -> Self {
pub fn from_srgba_unmultiplied([r, g, b, a]: [u8; 4]) -> Self {
Self::from_rgba_unmultiplied(
linear_f32_from_gamma_u8(srgba[0]),
linear_f32_from_gamma_u8(srgba[1]),
linear_f32_from_gamma_u8(srgba[2]),
linear_f32_from_linear_u8(srgba[3]),
linear_f32_from_gamma_u8(r),
linear_f32_from_gamma_u8(g),
linear_f32_from_gamma_u8(b),
linear_f32_from_linear_u8(a),
)
}

Expand Down Expand Up @@ -83,6 +83,15 @@ impl Hsva {
}
}

#[inline]
pub fn from_additive_srgb([r, g, b]: [u8; 3]) -> Self {
Self::from_additive_rgb([
linear_f32_from_gamma_u8(r),
linear_f32_from_gamma_u8(g),
linear_f32_from_gamma_u8(b),
])
}

#[inline]
pub fn from_rgb(rgb: [f32; 3]) -> Self {
let (h, s, v) = hsv_from_rgb(rgb);
Expand Down Expand Up @@ -131,6 +140,8 @@ impl Hsva {
}
}

/// To linear space rgba in 0-1 range.
///
/// Represents additive colors using a negative alpha.
#[inline]
pub fn to_rgba_unmultiplied(&self) -> [f32; 4] {
Expand All @@ -150,6 +161,7 @@ impl Hsva {
]
}

/// To gamma-space 0-255.
#[inline]
pub fn to_srgba_unmultiplied(&self) -> [u8; 4] {
let [r, g, b, a] = self.to_rgba_unmultiplied();
Expand Down
54 changes: 54 additions & 0 deletions crates/egui/src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,9 @@ pub struct Visuals {

/// Show a spinner when loading an image.
pub image_loading_spinners: bool,

/// How to display numeric color values.
pub numeric_color_space: NumericColorSpace,
}

impl Visuals {
Expand Down Expand Up @@ -1149,6 +1152,8 @@ impl Visuals {
interact_cursor: None,

image_loading_spinners: true,

numeric_color_space: NumericColorSpace::GammaByte,
}
}

Expand Down Expand Up @@ -1711,6 +1716,8 @@ impl Visuals {
interact_cursor,

image_loading_spinners,

numeric_color_space,
} = self;

ui.collapsing("Background Colors", |ui| {
Expand Down Expand Up @@ -1791,6 +1798,11 @@ impl Visuals {
ui.checkbox(image_loading_spinners, "Image loading spinners")
.on_hover_text("Show a spinner when an Image is loading");

ui.horizontal(|ui| {
ui.label("Color picker type:");
numeric_color_space.toggle_button_ui(ui);
});

ui.vertical_centered(|ui| reset_button(ui, self));
}
}
Expand Down Expand Up @@ -1918,3 +1930,45 @@ impl HandleShape {
});
}
}

/// How to display numeric color values.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum NumericColorSpace {
/// RGB is 0-255 in gamma space.
///
/// Alpha is 0-255 in linear space .
GammaByte,

/// 0-1 in linear space.
Linear,
// TODO(emilk): add Hex as an option
}

impl NumericColorSpace {
pub fn toggle_button_ui(&mut self, ui: &mut Ui) -> crate::Response {
let tooltip = match self {
Self::GammaByte => "Showing color values in 0-255 gamma space",
Self::Linear => "Showing color values in 0-1 linear space",
};

let mut response = ui.button(self.to_string()).on_hover_text(tooltip);
if response.clicked() {
*self = match self {
Self::GammaByte => Self::Linear,
Self::Linear => Self::GammaByte,
};
response.mark_changed();
}
response
}
}

impl std::fmt::Display for NumericColorSpace {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
NumericColorSpace::GammaByte => write!(f, "U8"),
NumericColorSpace::Linear => write!(f, "F"),
}
}
}
Loading

0 comments on commit bfed2b4

Please sign in to comment.