use mcu_hct::Hct;
use mcu_palettes::TonalPalette;
use mcu_utils::math::sanitize_degrees_double;
use crate::dynamic_scheme_palettes::{
get_piecewise_value, get_rotated_hue, is_blue_hue, DynamicSchemePalettesDelegate, HUES,
SECONDARY_ROTATIONS_EXPRESSIVE, TERTIARY_ROTATIONS_EXPRESSIVE, VIBRANT_SECONDARY_ROTATIONS,
VIBRANT_TERTIARY_ROTATIONS,
};
use crate::impl_palettes_2021::DynamicSchemePalettesDelegateImpl2021;
use crate::{Platform, Variant};
pub struct DynamicSchemePalettesDelegateImpl2025;
impl DynamicSchemePalettesDelegateImpl2025 {
fn delegate_2021() -> &'static DynamicSchemePalettesDelegateImpl2021 {
&DynamicSchemePalettesDelegateImpl2021
}
}
impl DynamicSchemePalettesDelegate for DynamicSchemePalettesDelegateImpl2025 {
fn get_primary_palette(
&self,
variant: Variant,
source: &Hct,
is_dark: bool,
platform: Platform,
contrast: f64,
) -> TonalPalette {
let is_blue = is_blue_hue(source.hue());
match variant {
Variant::Neutral => {
let chroma = if platform == Platform::Phone {
if is_blue {
12.0
} else {
8.0
}
} else {
if is_blue {
16.0
} else {
12.0
}
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
Variant::TonalSpot => {
let chroma = if platform == Platform::Phone && is_dark {
26.0
} else {
32.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
Variant::Expressive => {
let chroma = if platform == Platform::Phone {
if is_dark {
36.0
} else {
48.0
}
} else {
40.0
};
TonalPalette::from_hue_and_chroma(
sanitize_degrees_double(source.hue() + 240.0),
chroma,
)
}
Variant::Vibrant => {
let chroma = if platform == Platform::Phone {
74.0
} else {
56.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
_ => Self::delegate_2021()
.get_primary_palette(variant, source, is_dark, platform, contrast),
}
}
fn get_secondary_palette(
&self,
variant: Variant,
source: &Hct,
is_dark: bool,
platform: Platform,
contrast: f64,
) -> TonalPalette {
match variant {
Variant::TonalSpot => {
let chroma = if platform == Platform::Phone {
if is_dark {
14.0
} else {
16.0
}
} else {
16.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
Variant::Expressive => {
let rotated_hue = get_rotated_hue(source, &HUES, &SECONDARY_ROTATIONS_EXPRESSIVE);
let chroma = if platform == Platform::Phone {
if is_dark {
20.0
} else {
24.0
}
} else {
24.0
};
TonalPalette::from_hue_and_chroma(rotated_hue, chroma)
}
Variant::Vibrant => {
let rotated_hue = get_rotated_hue(source, &HUES, &VIBRANT_SECONDARY_ROTATIONS);
let chroma = if platform == Platform::Phone {
if is_dark {
20.0
} else {
24.0
}
} else {
24.0
};
TonalPalette::from_hue_and_chroma(rotated_hue, chroma)
}
_ => Self::delegate_2021()
.get_secondary_palette(variant, source, is_dark, platform, contrast),
}
}
fn get_tertiary_palette(
&self,
variant: Variant,
source: &Hct,
is_dark: bool,
platform: Platform,
contrast: f64,
) -> TonalPalette {
match variant {
Variant::TonalSpot => {
let chroma = if platform == Platform::Phone {
if is_dark {
20.0
} else {
24.0
}
} else {
24.0
};
TonalPalette::from_hue_and_chroma(
sanitize_degrees_double(source.hue() + 60.0),
chroma,
)
}
Variant::Expressive => {
let rotated_hue = get_rotated_hue(source, &HUES, &TERTIARY_ROTATIONS_EXPRESSIVE);
let chroma = if platform == Platform::Phone {
if is_dark {
28.0
} else {
32.0
}
} else {
32.0
};
TonalPalette::from_hue_and_chroma(rotated_hue, chroma)
}
Variant::Vibrant => {
let rotated_hue = get_rotated_hue(source, &HUES, &VIBRANT_TERTIARY_ROTATIONS);
let chroma = if platform == Platform::Phone {
if is_dark {
28.0
} else {
32.0
}
} else {
32.0
};
TonalPalette::from_hue_and_chroma(rotated_hue, chroma)
}
_ => Self::delegate_2021()
.get_tertiary_palette(variant, source, is_dark, platform, contrast),
}
}
fn get_neutral_palette(
&self,
variant: Variant,
source: &Hct,
is_dark: bool,
platform: Platform,
contrast: f64,
) -> TonalPalette {
match variant {
Variant::TonalSpot => {
let chroma = if platform == Platform::Phone {
if is_dark {
5.0
} else {
6.0
}
} else {
6.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
Variant::Expressive => {
let chroma = if platform == Platform::Phone {
if is_dark {
7.0
} else {
8.0
}
} else {
8.0
};
TonalPalette::from_hue_and_chroma(
sanitize_degrees_double(source.hue() + 15.0),
chroma,
)
}
Variant::Vibrant => {
let chroma = if platform == Platform::Phone {
if is_dark {
8.0
} else {
10.0
}
} else {
10.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
Variant::Neutral => {
let chroma = if platform == Platform::Phone {
if is_dark {
2.0
} else {
2.0
}
} else {
2.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
_ => Self::delegate_2021()
.get_neutral_palette(variant, source, is_dark, platform, contrast),
}
}
fn get_neutral_variant_palette(
&self,
variant: Variant,
source: &Hct,
is_dark: bool,
platform: Platform,
contrast: f64,
) -> TonalPalette {
match variant {
Variant::TonalSpot => {
let chroma = if platform == Platform::Phone {
if is_dark {
7.0
} else {
8.0
}
} else {
8.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
Variant::Expressive => {
let chroma = if platform == Platform::Phone {
if is_dark {
11.0
} else {
12.0
}
} else {
12.0
};
TonalPalette::from_hue_and_chroma(
sanitize_degrees_double(source.hue() + 15.0),
chroma,
)
}
Variant::Vibrant => {
let chroma = if platform == Platform::Phone {
if is_dark {
10.0
} else {
12.0
}
} else {
12.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
Variant::Neutral => {
let chroma = if platform == Platform::Phone {
if is_dark {
2.0
} else {
2.0
}
} else {
2.0
};
TonalPalette::from_hue_and_chroma(source.hue(), chroma)
}
_ => Self::delegate_2021()
.get_neutral_variant_palette(variant, source, is_dark, platform, contrast),
}
}
fn get_error_palette(
&self,
variant: Variant,
source: &Hct,
_is_dark: bool,
_platform: Platform,
_contrast: f64,
) -> Option<TonalPalette> {
match variant {
Variant::Expressive | Variant::Vibrant | Variant::TonalSpot | Variant::Neutral => {
const ERROR_HUES: [f64; 8] = [0.0, 21.0, 51.0, 121.0, 151.0, 191.0, 271.0, 321.0];
const ERROR_ROTATIONS: [f64; 8] = [25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0, 25.0];
let error_hue = get_piecewise_value(source.hue(), &ERROR_HUES, &ERROR_ROTATIONS);
Some(TonalPalette::from_hue_and_chroma(error_hue, 84.0))
}
_ => None,
}
}
}