Skip to main content

gled_model/asset/
palette.rs

1use super::AssetTrait;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
5#[serde(default)]
6pub struct Palette {
7    pub primary: Color,
8    pub secondary: Color,
9    pub gradient: [Color; 16],
10}
11
12impl AssetTrait for Palette {
13    const DIR_NAME: &'static str = "palettes";
14    const NAME: &'static str = "Palette";
15    const SHOW_NAME_IF_SELECTED: bool = false;
16}
17
18impl Palette {
19    /// must be aligned by 16 bytes
20    pub fn write_data(&self, data: &mut [u8]) {
21        for (i, color) in std::iter::once(self.primary)
22            .chain(std::iter::once(self.secondary))
23            .chain(self.gradient.iter().copied())
24            .enumerate()
25        {
26            let rgb = color.rgb();
27            data[i * 16..i * 16 + 4].copy_from_slice(&rgb[0].to_le_bytes());
28            data[i * 16 + 4..i * 16 + 8].copy_from_slice(&rgb[1].to_le_bytes());
29            data[i * 16 + 8..i * 16 + 12].copy_from_slice(&rgb[2].to_le_bytes());
30        }
31    }
32
33    /// must be a multiple of 16
34    pub const fn size() -> usize {
35        18 * 16
36    }
37}
38
39#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
40pub struct Color {
41    rgb: [f32; 3],
42}
43
44impl PartialOrd for Color {
45    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
46        Some(self.cmp(other))
47    }
48}
49impl Ord for Color {
50    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
51        self.rgb_u32().cmp(&other.rgb_u32())
52    }
53}
54impl PartialEq for Color {
55    fn eq(&self, other: &Self) -> bool {
56        self.rgb_u32() == other.rgb_u32()
57    }
58}
59impl Eq for Color {}
60
61impl Color {
62    pub fn new(red: f32, green: f32, blue: f32) -> Self {
63        Self {
64            rgb: [red, green, blue],
65        }
66    }
67
68    pub fn rgb(&self) -> [f32; 3] {
69        self.rgb
70    }
71
72    pub fn rgb_mut(&mut self) -> &mut [f32; 3] {
73        &mut self.rgb
74    }
75
76    /// 8 bit RGB, as the UI shows it.
77    pub fn rgb8(&self) -> [u8; 3] {
78        [
79            (self.rgb[0] * 254.0) as u8,
80            (self.rgb[1] * 254.0) as u8,
81            (self.rgb[2] * 254.0) as u8,
82        ]
83    }
84
85    fn rgb_u32(&self) -> [u32; 3] {
86        [
87            (self.rgb[0] * 10000.0).round() as u32,
88            (self.rgb[1] * 10000.0).round() as u32,
89            (self.rgb[2] * 10000.0).round() as u32,
90        ]
91    }
92}