Color provenance hack via f32 next_up / next_down

Michael Sloan created

Change summary

crates/theme/src/theme.rs | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)

Detailed changes

crates/theme/src/theme.rs 🔗

@@ -238,6 +238,14 @@ impl ThemeFamily {
             .map(Into::into)
             .unwrap_or_default();
 
+        #[cfg(debug_assertions)]
+        {
+            use collections::HashMap;
+            let mut color_to_count: HashMap<Hsla, u32> = HashMap::default();
+            make_colors_unique(&mut refined_status_colors, &mut color_to_count);
+            make_colors_unique(&mut refined_theme_colors, &mut color_to_count);
+        }
+
         Theme {
             id: uuid::Uuid::new_v4().to_string(),
             name: theme.name.clone().into(),
@@ -280,6 +288,33 @@ pub fn refine_theme_family(theme_family_content: ThemeFamilyContent) -> ThemeFam
     theme_family
 }
 
+/// Make theme colors unique via tiny adjustments to luminance. This is a hack to provide color
+/// provenance information to the inspector (which is only available in debug builds).
+///
+/// Since luminance is an f32, `next_down` / `next_up` should rarely affect RGB.
+#[cfg(debug_assertions)]
+fn make_colors_unique<T, F>(colors: &mut T, color_to_count: &mut collections::HashMap<Hsla, u32>)
+where
+    F: Copy + strum::IntoEnumIterator,
+    T: util::FieldAccessByEnum<Field = F, FieldValue = Hsla>,
+{
+    for field in F::iter() {
+        let mut color = *colors.get_field_by_enum(field);
+        let count = color_to_count.entry(color).or_default();
+        *count += 1;
+        if color.l > 0.5 {
+            for _ in 0..*count {
+                color.l = color.l.next_down();
+            }
+        } else {
+            for _ in 0..*count {
+                color.l = color.l.next_up();
+            }
+        }
+        colors.set_field_by_enum(field, color);
+    }
+}
+
 /// A theme is the primary mechanism for defining the appearance of the UI.
 #[derive(Clone, Debug, PartialEq)]
 pub struct Theme {