From d701e179ae31c6c8e0be5ce8b08b642eccec8390 Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Thu, 11 Jan 2024 07:10:45 -0800 Subject: [PATCH] Fixing ComponentPicker's loupe coloring The previous fix was a fix in contrast_between. However, I then convinced myself that the selected color was changing when it wasn't purely because the alpha picker utilizes a checkeboard pattern, and I was specifically testing grayscale values. Aka, I was reproducing the "different grays" optical illusion using the loupe outline color and driving myself crazy trying to figure out what my code was doing, when in reality it wasn't doing anything. The real fix? Don't ask for contrast between two similar colors. OutlineColor and TextColor are both meant to be contrasting colors to SurfaceColor, which is the background color. The loupe color really should have switched between any surface-type color and any foreground-type color, but it instead was asking for two different foreground colors. --- src/widgets/color.rs | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/widgets/color.rs b/src/widgets/color.rs index f6cc408..496ee2b 100644 --- a/src/widgets/color.rs +++ b/src/widgets/color.rs @@ -10,7 +10,7 @@ use kludgine::{Color, DrawableExt, Origin}; use crate::animation::{LinearInterpolate, PercentBetween, ZeroToOne}; use crate::context::{EventContext, GraphicsContext, LayoutContext}; -use crate::styles::components::{HighlightColor, OutlineColor, TextColor}; +use crate::styles::components::{HighlightColor, OutlineColor, SurfaceColor, TextColor}; use crate::styles::{ColorExt, ColorSource, Hsl, Hsla}; use crate::value::{ Destination, Dynamic, ForEachCloned, IntoDynamic, IntoReadOnly, IntoValue, MapEach, ReadOnly, @@ -149,7 +149,6 @@ impl MakeWidgetWithTag for HslaPicker { .and(ComponentPicker::lightness(self.lightness)) .and(ComponentPicker::alpha_f32(self.alpha, preview_color)) .into_rows() - .gutter(Px::ZERO) .make_widget() } } @@ -543,19 +542,32 @@ where Point::new(value_x - loupe_size / 2, options.line_width / 2), Size::new(loupe_size, size.height - options.line_width), ); - let selected_color = self.component.loupe_color(value); - let loupe_color = if let Some(selected_color) = selected_color { - context.gfx.draw_shape(&Shape::filled_round_rect( - loupe_rect, - CornerRadii::from(loupe_size), - selected_color, - )); - - selected_color.most_contrasting(&[context.get(&OutlineColor), context.get(&TextColor)]) - } else { - context.get(&OutlineColor) + let selected_color = self + .component + .loupe_color(value) + .ok_or_else(|| self.component.interpolate_color(value)); + let mut selected_color = match selected_color { + Ok(selected_color) => { + context.gfx.draw_shape(&Shape::filled_round_rect( + loupe_rect, + CornerRadii::from(loupe_size), + selected_color, + )); + selected_color + } + Err(selected_color) => selected_color, }; + let alpha = selected_color.alpha(); + if alpha < 255 { + let alpha_f32 = alpha.percent_between(&0, &255); + let surface = context.theme().surface.color; + selected_color = surface.lerp(&selected_color.with_alpha(255), *alpha_f32); + } + + let loupe_color = + selected_color.most_contrasting(&[context.get(&SurfaceColor), context.get(&TextColor)]); + context.gfx.draw_shape(&Shape::stroked_round_rect( loupe_rect, CornerRadii::from(loupe_size),