From c27e53a7b2918eefab53aee7f2fea31216b9810f Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 29 Aug 2020 16:58:01 +0200 Subject: [PATCH] [color] Rename Color to Srgba + sRGBA correct fading of thin lines Also remove the extra large `aa_size` hack, so everything now looks slightly crispier. I also took the opportunity to tweak some colors. --- egui/src/containers/frame.rs | 10 +- egui/src/context.rs | 1 - egui/src/demos/app.rs | 33 ++++-- egui/src/demos/fractal_clock.rs | 14 ++- egui/src/lib.rs | 2 +- egui/src/paint.rs | 2 +- egui/src/paint/color.rs | 176 ++++++++++++++++++++++++-------- egui/src/paint/command.rs | 20 ++-- egui/src/paint/tessellator.rs | 25 ++--- egui/src/painter.rs | 10 +- egui/src/style.rs | 30 +++--- egui/src/ui.rs | 2 +- egui/src/widgets.rs | 26 ++--- egui/src/widgets/slider.rs | 6 +- egui/src/widgets/text_edit.rs | 4 +- egui_web/src/webgl.rs | 4 +- 16 files changed, 235 insertions(+), 130 deletions(-) diff --git a/egui/src/containers/frame.rs b/egui/src/containers/frame.rs index d4e597ba..b4db3101 100644 --- a/egui/src/containers/frame.rs +++ b/egui/src/containers/frame.rs @@ -8,7 +8,7 @@ pub struct Frame { // On each side pub margin: Vec2, pub corner_radius: f32, - pub fill: Option, + pub fill: Option, pub outline: Option, } @@ -27,7 +27,7 @@ impl Frame { margin: Vec2::splat(1.0), corner_radius: 0.0, fill: None, - outline: Some(LineStyle::new(0.5, color::white(128))), + outline: Some(LineStyle::new(0.5, Srgba::gray(128))), } } @@ -36,7 +36,7 @@ impl Frame { margin: Vec2::splat(1.0), corner_radius: 2.0, fill: Some(style.background_fill), - outline: Some(LineStyle::new(1.0, color::white(128))), + outline: Some(LineStyle::new(1.0, Srgba::gray(128))), } } @@ -45,11 +45,11 @@ impl Frame { margin: style.window_padding, corner_radius: 5.0, fill: Some(style.background_fill), - outline: Some(LineStyle::new(1.0, color::white(128))), + outline: Some(LineStyle::new(1.0, Srgba::gray(128))), } } - pub fn fill(mut self, fill: Option) -> Self { + pub fn fill(mut self, fill: Option) -> Self { self.fill = fill; self } diff --git a/egui/src/context.rs b/egui/src/context.rs index beb52485..1f58fa89 100644 --- a/egui/src/context.rs +++ b/egui/src/context.rs @@ -208,7 +208,6 @@ impl Context { fn paint(&self) -> PaintJobs { let mut paint_options = *self.paint_options.lock(); paint_options.aa_size = 1.0 / self.pixels_per_point(); - paint_options.aa_size *= 1.5; // Looks better, but TODO: should not be needed let paint_commands = self.drain_paint_lists(); let num_primitives = paint_commands.len(); let paint_jobs = diff --git a/egui/src/demos/app.rs b/egui/src/demos/app.rs index f35ccd81..8f6c9302 100644 --- a/egui/src/demos/app.rs +++ b/egui/src/demos/app.rs @@ -274,7 +274,7 @@ fn show_menu_bar(ui: &mut Ui, windows: &mut OpenWindows) { } = windows; ui.add(Checkbox::new(demo, "Demo")); ui.add(Checkbox::new(fractal_clock, "Fractal Clock")); - ui.add(Separator::new()); + ui.separator(); ui.add(Checkbox::new(settings, "Settings")); ui.add(Checkbox::new(inspection, "Inspection")); ui.add(Checkbox::new(memory, "Memory")); @@ -560,12 +560,12 @@ impl BoxPainting { for i in 0..self.num_boxes { cmds.push(PaintCmd::Rect { corner_radius: self.corner_radius, - fill: Some(gray(136, 255)), + fill: Some(Srgba::gray(64)), rect: Rect::from_min_size( pos2(10.0 + pos.x + (i as f32) * (self.size.x * 1.1), pos.y), self.size, ), - outline: Some(LineStyle::new(self.stroke_width, gray(255, 255))), + outline: Some(LineStyle::new(self.stroke_width, WHITE)), }); } ui.painter().extend(cmds); @@ -574,19 +574,32 @@ impl BoxPainting { // ---------------------------------------------------------------------------- -#[derive(Default)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[cfg_attr(feature = "serde", serde(default))] struct Painting { lines: Vec>, + line_width: f32, +} + +impl Default for Painting { + fn default() -> Self { + Self { + lines: Default::default(), + line_width: 1.0, + } + } } impl Painting { pub fn ui(&mut self, ui: &mut Ui) { ui.label("Draw with your mouse to paint"); - if ui.add(Button::new("Clear")).clicked { - self.lines.clear(); - } + + ui.horizontal(|ui| { + ui.add(Slider::f32(&mut self.line_width, 0.0..=3.0).text("Line width")); + if ui.add(Button::new("Clear")).clicked { + self.lines.clear(); + } + }); Resize::default() .default_size([200.0, 200.0]) @@ -623,7 +636,7 @@ impl Painting { painter.add(PaintCmd::Path { path: Path::from_open_points(&points), closed: false, - outline: Some(LineStyle::new(2.0, LIGHT_GRAY)), + outline: Some(LineStyle::new(self.line_width, LIGHT_GRAY)), fill: None, }); } @@ -672,7 +685,7 @@ impl LayoutDemo { if ui.add(Button::new("Reset")).clicked { *self = Default::default(); } - ui.add(Separator::new()); + ui.separator(); ui.add(label!("Direction:")); // TODO: enum iter @@ -688,7 +701,7 @@ impl LayoutDemo { ui.add(Checkbox::new(&mut self.reversed, "Reversed")); - ui.add(Separator::new()); + ui.separator(); ui.add(label!("Align:")); diff --git a/egui/src/demos/fractal_clock.rs b/egui/src/demos/fractal_clock.rs index 1aaf0e2e..ef56d3b4 100644 --- a/egui/src/demos/fractal_clock.rs +++ b/egui/src/demos/fractal_clock.rs @@ -37,7 +37,7 @@ impl FractalClock { .default_rect(ctx.rect().expand(-42.0)) .scroll(false) // Dark background frame to make it pop: - .frame(Frame::window(&ctx.style()).fill(Some(color::black(250)))) + .frame(Frame::window(&ctx.style()).fill(Some(Srgba::black_alpha(250)))) .show(ctx, |ui| self.ui(ui)); } @@ -54,7 +54,7 @@ impl FractalClock { self.fractal_ui(&painter); Frame::popup(ui.style()) - .fill(Some(color::gray(34, 160))) + .fill(Some(Rgba::luminance_alpha(0.02, 0.5).into())) .outline(None) .show(&mut ui.left_column(320.0), |ui| { CollapsingHeader::new("Settings").show(ui, |ui| self.options_ui(ui)); @@ -128,7 +128,7 @@ impl FractalClock { ]; let scale = self.zoom * rect.width().min(rect.height()); - let paint_line = |points: [Pos2; 2], color: Color, width: f32| { + let paint_line = |points: [Pos2; 2], color: Srgba, width: f32| { let line = [ rect.center() + scale * points[0].to_vec2(), rect.center() + scale * points[1].to_vec2(), @@ -160,7 +160,7 @@ impl FractalClock { for (i, hand) in hands.iter().enumerate() { let center = pos2(0.0, 0.0); let end = center + hand.vec; - paint_line([center, end], color::additive_gray(255), width); + paint_line([center, end], Srgba::additive_luminance(255), width); if i < 2 { nodes.push(Node { pos: end, @@ -188,7 +188,11 @@ impl FractalClock { pos: a.pos + new_dir, dir: new_dir, }; - paint_line([a.pos, b.pos], color::additive_gray(luminance_u8), width); + paint_line( + [a.pos, b.pos], + Srgba::additive_luminance(luminance_u8), + width, + ); new_nodes.push(b); } } diff --git a/egui/src/lib.rs b/egui/src/lib.rs index f8b83cf3..de19167e 100644 --- a/egui/src/lib.rs +++ b/egui/src/lib.rs @@ -73,7 +73,7 @@ pub use { layout::*, math::*, memory::Memory, - paint::{color, Color, PaintJobs, TextStyle, Texture}, + paint::{color, PaintJobs, Rgba, Srgba, TextStyle, Texture}, painter::Painter, style::Style, types::*, diff --git a/egui/src/paint.rs b/egui/src/paint.rs index 17ec19e2..c40e65a2 100644 --- a/egui/src/paint.rs +++ b/egui/src/paint.rs @@ -10,7 +10,7 @@ pub mod tessellator; mod texture_atlas; pub use { - color::Color, + color::{Rgba, Srgba}, command::{LineStyle, PaintCmd}, fonts::{FontDefinitions, Fonts, TextStyle}, tessellator::{PaintJobs, PaintOptions, Path, Triangles, Vertex}, diff --git a/egui/src/paint/color.rs b/egui/src/paint/color.rs index d3788e8b..ab613242 100644 --- a/egui/src/paint/color.rs +++ b/egui/src/paint/color.rs @@ -1,61 +1,155 @@ -// TODO: rename `Color` to `sRGBA` for clarity. -/// 0-255 `sRGBA`. Uses premultiplied alpha. -#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] +use crate::math::clamp; + +/// 0-255 gamma space `sRGBA` color with premultiplied alpha. +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] -pub struct Color { +pub struct Srgba { pub r: u8, pub g: u8, pub b: u8, + /// Linear space (not subject to sRGBA gamma conversion) pub a: u8, } - -pub const fn srgba(r: u8, g: u8, b: u8, a: u8) -> Color { - Color { r, g, b, a } +/// 0-1 linear space `RGBA` color with premultiplied alpha. +#[derive(Clone, Copy, Debug, Default, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub struct Rgba { + pub r: f32, + pub g: f32, + pub b: f32, + pub a: f32, } -pub const fn gray(l: u8, a: u8) -> Color { - Color { - r: l, - g: l, - b: l, - a, +// ---------------------------------------------------------------------------- +// Color conversion: + +impl From for Rgba { + fn from(srgba: Srgba) -> Rgba { + Rgba { + r: linear_from_srgb_byte(srgba.r), + g: linear_from_srgb_byte(srgba.g), + b: linear_from_srgb_byte(srgba.b), + a: srgba.a as f32 / 255.0, + } } } -pub const fn black(a: u8) -> Color { - Color { - r: 0, - g: 0, - b: 0, - a, +impl From for Srgba { + fn from(rgba: Rgba) -> Srgba { + Srgba { + r: srgb_byte_from_linear(rgba.r), + g: srgb_byte_from_linear(rgba.g), + b: srgb_byte_from_linear(rgba.b), + a: clamp(rgba.a * 255.0, 0.0..=255.0).round() as u8, + } } } -pub const fn white(a: u8) -> Color { - Color { - r: a, - g: a, - b: a, - a, +fn linear_from_srgb_byte(s: u8) -> f32 { + if s <= 10 { + s as f32 / 3294.6 + } else { + ((s as f32 + 14.025) / 269.025).powf(2.4) } } -pub const fn additive_gray(l: u8) -> Color { - Color { - r: l, - g: l, - b: l, - a: 0, +fn srgb_byte_from_linear(l: f32) -> u8 { + if l <= 0.0 { + 0 + } else if l <= 0.0031308 { + (3294.6 * l).round() as u8 + } else if l <= 1.0 { + (269.025 * l.powf(1.0 / 2.4) - 14.025).round() as u8 + } else { + 255 } } -pub const TRANSPARENT: Color = srgba(0, 0, 0, 0); -pub const BLACK: Color = srgba(0, 0, 0, 255); -pub const LIGHT_GRAY: Color = srgba(220, 220, 220, 255); -pub const GRAY: Color = srgba(160, 160, 160, 255); -pub const WHITE: Color = srgba(255, 255, 255, 255); -pub const RED: Color = srgba(255, 0, 0, 255); -pub const GREEN: Color = srgba(0, 255, 0, 255); -pub const BLUE: Color = srgba(0, 0, 255, 255); -pub const YELLOW: Color = srgba(255, 255, 0, 255); -pub const LIGHT_BLUE: Color = srgba(140, 160, 255, 255); +#[test] +fn test_srgba_conversion() { + #![allow(clippy::float_cmp)] + for b in 0..=255 { + let l = linear_from_srgb_byte(b); + assert!(0.0 <= l && l <= 1.0); + assert_eq!(srgb_byte_from_linear(l), b); + } +} + +// ---------------------------------------------------------------------------- + +pub const fn srgba(r: u8, g: u8, b: u8, a: u8) -> Srgba { + Srgba { r, g, b, a } +} + +impl Srgba { + pub const fn gray(l: u8) -> Self { + Self { + r: l, + g: l, + b: l, + a: 255, + } + } + + pub const fn black_alpha(a: u8) -> Self { + Self { + r: 0, + g: 0, + b: 0, + a, + } + } + + pub const fn additive_luminance(l: u8) -> Self { + Self { + r: l, + g: l, + b: l, + a: 0, + } + } +} + +impl Rgba { + pub fn luminance_alpha(l: f32, a: f32) -> Self { + debug_assert!(0.0 <= l && l <= 1.0); + debug_assert!(0.0 <= a && a <= 1.0); + Self { + r: l * a, + g: l * a, + b: l * a, + a, + } + } + + pub fn white_alpha(l: f32) -> Self { + debug_assert!(0.0 <= l && l <= 1.0); + Self { + r: l, + g: l, + b: l, + a: l, + } + } + + /// Multiply with e.g. 0.5 to make us half transparent + pub fn multiply(self, alpha: f32) -> Self { + Self { + r: alpha * self.r, + g: alpha * self.g, + b: alpha * self.b, + a: alpha * self.a, + } + } +} + +pub const TRANSPARENT: Srgba = srgba(0, 0, 0, 0); +pub const BLACK: Srgba = srgba(0, 0, 0, 255); +pub const LIGHT_GRAY: Srgba = srgba(220, 220, 220, 255); +pub const GRAY: Srgba = srgba(160, 160, 160, 255); +pub const WHITE: Srgba = srgba(255, 255, 255, 255); +pub const RED: Srgba = srgba(255, 0, 0, 255); +pub const GREEN: Srgba = srgba(0, 255, 0, 255); +pub const BLUE: Srgba = srgba(0, 0, 255, 255); +pub const YELLOW: Srgba = srgba(255, 255, 0, 255); +pub const LIGHT_BLUE: Srgba = srgba(140, 160, 255, 255); diff --git a/egui/src/paint/command.rs b/egui/src/paint/command.rs index 3392cd0c..80af4d60 100644 --- a/egui/src/paint/command.rs +++ b/egui/src/paint/command.rs @@ -1,5 +1,5 @@ use { - super::{font::Galley, fonts::TextStyle, Color, Path, Triangles}, + super::{font::Galley, fonts::TextStyle, Path, Srgba, Triangles}, crate::math::{Pos2, Rect}, }; @@ -11,7 +11,7 @@ pub enum PaintCmd { Circle { center: Pos2, radius: f32, - fill: Option, + fill: Option, outline: Option, }, LineSegment { @@ -21,13 +21,13 @@ pub enum PaintCmd { Path { path: Path, closed: bool, - fill: Option, + fill: Option, outline: Option, }, Rect { rect: Rect, corner_radius: f32, - fill: Option, + fill: Option, outline: Option, }, Text { @@ -36,24 +36,24 @@ pub enum PaintCmd { /// The layed out text galley: Galley, text_style: TextStyle, // TODO: Font? - color: Color, + color: Srgba, }, Triangles(Triangles), } impl PaintCmd { - pub fn line_segment(points: [Pos2; 2], width: f32, color: Color) -> Self { + pub fn line_segment(points: [Pos2; 2], width: f32, color: impl Into) -> Self { Self::LineSegment { points, style: LineStyle::new(width, color), } } - pub fn circle_filled(center: Pos2, radius: f32, fill_color: Color) -> Self { + pub fn circle_filled(center: Pos2, radius: f32, fill_color: impl Into) -> Self { Self::Circle { center, radius, - fill: Some(fill_color), + fill: Some(fill_color.into()), outline: None, } } @@ -72,11 +72,11 @@ impl PaintCmd { #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct LineStyle { pub width: f32, - pub color: Color, + pub color: Srgba, } impl LineStyle { - pub fn new(width: impl Into, color: impl Into) -> Self { + pub fn new(width: impl Into, color: impl Into) -> Self { Self { width: width.into(), color: color.into(), diff --git a/egui/src/paint/tessellator.rs b/egui/src/paint/tessellator.rs index 1c9fc276..7a856fbe 100644 --- a/egui/src/paint/tessellator.rs +++ b/egui/src/paint/tessellator.rs @@ -7,7 +7,7 @@ use { super::{ - color::{self, srgba, Color}, + color::{self, srgba, Rgba, Srgba}, fonts::Fonts, LineStyle, PaintCmd, }, @@ -29,7 +29,7 @@ pub struct Vertex { /// Texel coordinates in the texture pub uv: (u16, u16), // 32 bit /// sRGBA with premultiplied alpha - pub color: Color, // 32 bit + pub color: Srgba, // 32 bit } /// Textured triangles. @@ -182,7 +182,7 @@ pub struct PathPoint { normal: Vec2, } -/// A connected line (without thickness or gaps) which can be tesselated +/// A connected line (without thickness or gaps) which can be tessellated /// to either to an outline (with thickness) or a filled convex area. #[derive(Clone, Debug, Default)] pub struct Path(Vec); @@ -376,7 +376,7 @@ impl Default for PaintOptions { /// Tesselate the given convex area into a polygon. pub fn fill_closed_path( path: &[PathPoint], - color: Color, + color: Srgba, options: PaintOptions, out: &mut Triangles, ) { @@ -568,15 +568,10 @@ pub fn paint_path_outline( } } -fn mul_color(color: Color, factor: f32) -> Color { - // TODO: sRGBA correct fading +fn mul_color(color: Srgba, factor: f32) -> Srgba { debug_assert!(0.0 <= factor && factor <= 1.0); - Color { - r: (f32::from(color.r) * factor).round() as u8, - g: (f32::from(color.g) * factor).round() as u8, - b: (f32::from(color.b) * factor).round() as u8, - a: (f32::from(color.a) * factor).round() as u8, - } + // sRGBA correct fading requires conversion to linear space and back again because of premultiplied alpha + Rgba::from(color).multiply(factor).into() } // ---------------------------------------------------------------------------- @@ -585,7 +580,7 @@ fn mul_color(color: Color, factor: f32) -> Color { /// /// * `command`: the command to tesselate /// * `options`: tesselation quality -/// * `fonts`: font source when tesselating text +/// * `fonts`: font source when tessellating text /// * `out`: where the triangles are put /// * `scratchpad_path`: if you plan to run `tessellate_paint_command` /// many times, pass it a reference to the same `Path` to avoid excessive allocations. @@ -651,7 +646,7 @@ pub fn tessellate_paint_command( outline, } => { if !rect.is_empty() { - // It is common to (sometimes accidentally) create an infinitely sized ractangle. + // It is common to (sometimes accidentally) create an infinitely sized rectangle. // Make sure we can handle that: rect.min = rect.min.max(pos2(-1e7, -1e7)); rect.max = rect.max.min(pos2(1e7, 1e7)); @@ -713,7 +708,7 @@ pub fn tessellate_paint_command( /// /// * `commands`: the command to tesselate /// * `options`: tesselation quality -/// * `fonts`: font source when tesselating text +/// * `fonts`: font source when tessellating text /// /// ## Returns /// A list of clip rectangles with matching `Triangles`. diff --git a/egui/src/painter.rs b/egui/src/painter.rs index 1089600f..1a2e3d3a 100644 --- a/egui/src/painter.rs +++ b/egui/src/painter.rs @@ -5,7 +5,7 @@ use crate::{ layers::PaintCmdIdx, math::{Pos2, Rect, Vec2}, paint::{font, Fonts, LineStyle, PaintCmd, TextStyle}, - Align, Color, Context, Layer, + Align, Context, Layer, Srgba, }; /// Helper to paint shapes and text to a specific region on a specific layer. @@ -114,7 +114,7 @@ impl Painter { /// ## Debug painting impl Painter { - pub fn debug_rect(&mut self, rect: Rect, color: Color, text: impl Into) { + pub fn debug_rect(&mut self, rect: Rect, color: Srgba, text: impl Into) { self.add(PaintCmd::Rect { corner_radius: 0.0, fill: None, @@ -135,7 +135,7 @@ impl Painter { let rect = anchor_rect(Rect::from_min_size(pos, galley.size), anchor); self.add(PaintCmd::Rect { corner_radius: 0.0, - fill: Some(color::gray(0, 240)), + fill: Some(Srgba::black_alpha(240)), outline: Some(LineStyle::new(1.0, color::RED)), rect: rect.expand(2.0), }); @@ -156,7 +156,7 @@ impl Painter { anchor: (Align, Align), text: impl Into, text_style: TextStyle, - text_color: Color, + text_color: Srgba, ) -> Rect { let font = &self.fonts()[text_style]; let galley = font.layout_multiline(text.into(), f32::INFINITY); @@ -166,7 +166,7 @@ impl Painter { } /// Paint text that has already been layed out in a `Galley`. - pub fn galley(&self, pos: Pos2, galley: font::Galley, text_style: TextStyle, color: Color) { + pub fn galley(&self, pos: Pos2, galley: font::Galley, text_style: TextStyle, color: Srgba) { self.add(PaintCmd::Text { pos, galley, diff --git a/egui/src/style.rs b/egui/src/style.rs index 4d9e9f28..6bfd05da 100644 --- a/egui/src/style.rs +++ b/egui/src/style.rs @@ -39,7 +39,7 @@ pub struct Style { pub interact: Interact, // TODO: an WidgetStyle ? - pub text_color: Color, + pub text_color: Srgba, /// For stuff like check marks in check boxes. pub line_width: f32, @@ -47,10 +47,10 @@ pub struct Style { pub thin_outline: LineStyle, /// e.g. the background of windows - pub background_fill: Color, + pub background_fill: Srgba, /// e.g. the background of the slider or text edit - pub dark_bg_color: Color, + pub dark_bg_color: Srgba, /// Blink text cursor by this frequency. If None, always show the cursor. pub cursor_blink_hz: Option, @@ -86,11 +86,11 @@ impl Default for Style { resize_interact_radius_corner: 10.0, resize_corner_size: 16.0, interact: Default::default(), - text_color: gray(160, 255), + text_color: Srgba::gray(160), line_width: 1.0, thin_outline: LineStyle::new(0.5, GRAY), - background_fill: gray(32, 250), - dark_bg_color: gray(0, 140), + background_fill: Rgba::luminance_alpha(0.013, 0.95).into(), + dark_bg_color: Srgba::black_alpha(140), cursor_blink_hz: None, // Some(1.0) text_cursor_width: 2.0, animation_time: 1.0 / 15.0, @@ -116,7 +116,7 @@ impl Default for Interact { fn default() -> Self { Self { active: WidgetStyle { - bg_fill: Some(gray(0, 128)), + bg_fill: Some(Srgba::black_alpha(128)), fill: srgba(120, 120, 200, 255), stroke_color: WHITE, stroke_width: 2.0, @@ -126,7 +126,7 @@ impl Default for Interact { hovered: WidgetStyle { bg_fill: None, fill: srgba(100, 100, 150, 255), - stroke_color: gray(240, 255), + stroke_color: Srgba::gray(240), stroke_width: 1.5, rect_outline: Some(LineStyle::new(1.0, WHITE)), corner_radius: 2.0, @@ -134,17 +134,17 @@ impl Default for Interact { inactive: WidgetStyle { bg_fill: None, fill: srgba(60, 60, 80, 255), - stroke_color: gray(210, 255), // Mustn't look grayed out! + stroke_color: Srgba::gray(200), // Mustn't look grayed out! stroke_width: 1.0, - rect_outline: Some(LineStyle::new(1.0, white(128))), + rect_outline: Some(LineStyle::new(1.0, Srgba::gray(128))), corner_radius: 4.0, }, disabled: WidgetStyle { bg_fill: None, fill: srgba(50, 50, 50, 255), - stroke_color: gray(128, 255), // Should look grayed out + stroke_color: Srgba::gray(128), // Should look grayed out stroke_width: 0.5, - rect_outline: Some(LineStyle::new(0.5, white(128))), + rect_outline: Some(LineStyle::new(0.5, Srgba::gray(128))), corner_radius: 4.0, }, } @@ -169,14 +169,14 @@ impl Interact { #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct WidgetStyle { /// Background color of widget - pub bg_fill: Option, + pub bg_fill: Option, /// Fill color of the interactive part of a component (slider grab, checkbox, ...) /// When you need a fill. - pub fill: Color, + pub fill: Srgba, /// Stroke and text color of the interactive part of a component (button, slider grab, checkbox, ...) - pub stroke_color: Color, + pub stroke_color: Srgba, /// For lines etc pub stroke_width: f32, diff --git a/egui/src/ui.rs b/egui/src/ui.rs index 1d05472c..1b2d37d3 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -584,7 +584,7 @@ impl Ui { self.painter.add(PaintCmd::line_segment( [line_start, line_end], self.style.line_width, - gray(150, 255), + Srgba::gray(150), )); (ret, self.allocate_space(indent + size)) diff --git a/egui/src/widgets.rs b/egui/src/widgets.rs index 89f82d1b..6e00d11e 100644 --- a/egui/src/widgets.rs +++ b/egui/src/widgets.rs @@ -31,7 +31,7 @@ pub struct Label { pub(crate) multiline: bool, auto_shrink: bool, pub(crate) text_style: TextStyle, // TODO: Option, where None means "use the default for the ui" - pub(crate) text_color: Option, + pub(crate) text_color: Option, } impl Label { @@ -71,7 +71,7 @@ impl Label { self.text_style(TextStyle::Heading) } - pub fn text_color(mut self, text_color: Color) -> Self { + pub fn text_color(mut self, text_color: Srgba) -> Self { self.text_color = Some(text_color); self } @@ -219,10 +219,10 @@ impl Widget for Hyperlink { /// Clickable button with text pub struct Button { text: String, - text_color: Option, + text_color: Option, text_style: TextStyle, /// None means default for interact - fill: Option, + fill: Option, sense: Sense, } @@ -237,7 +237,7 @@ impl Button { } } - pub fn text_color(mut self, text_color: Color) -> Self { + pub fn text_color(mut self, text_color: Srgba) -> Self { self.text_color = Some(text_color); self } @@ -247,7 +247,7 @@ impl Button { self } - pub fn fill(mut self, fill: Option) -> Self { + pub fn fill(mut self, fill: Option) -> Self { self.fill = fill; self } @@ -311,7 +311,7 @@ impl Widget for Button { pub struct Checkbox<'a> { checked: &'a mut bool, text: String, - text_color: Option, + text_color: Option, } impl<'a> Checkbox<'a> { @@ -323,7 +323,7 @@ impl<'a> Checkbox<'a> { } } - pub fn text_color(mut self, text_color: Color) -> Self { + pub fn text_color(mut self, text_color: Srgba) -> Self { self.text_color = Some(text_color); self } @@ -389,7 +389,7 @@ impl<'a> Widget for Checkbox<'a> { pub struct RadioButton { checked: bool, text: String, - text_color: Option, + text_color: Option, } impl RadioButton { @@ -401,7 +401,7 @@ impl RadioButton { } } - pub fn text_color(mut self, text_color: Color) -> Self { + pub fn text_color(mut self, text_color: Srgba) -> Self { self.text_color = Some(text_color); self } @@ -463,7 +463,7 @@ pub struct Separator { line_width: Option, spacing: f32, extra: f32, - color: Color, + color: Srgba, } impl Separator { @@ -472,7 +472,7 @@ impl Separator { line_width: None, spacing: 6.0, extra: 0.0, - color: color::WHITE, + color: Srgba::gray(128), // TODO: from style } } @@ -493,7 +493,7 @@ impl Separator { self } - pub fn color(mut self, color: Color) -> Self { + pub fn color(mut self, color: Srgba) -> Self { self.color = color; self } diff --git a/egui/src/widgets/slider.rs b/egui/src/widgets/slider.rs index 2594553a..8b6d9b05 100644 --- a/egui/src/widgets/slider.rs +++ b/egui/src/widgets/slider.rs @@ -13,7 +13,7 @@ pub struct Slider<'a> { // TODO: label: Option