hyperion/models/
layouts.rs1use super::{ClassicLedConfig, Led, Leds};
2
3pub trait ToLeds {
5 fn to_leds(&self) -> Leds;
6}
7
8struct ClassicLedParams {
9 ledstop: u32,
10 ledsbottom: u32,
11 ledsleft: u32,
12 ledsright: u32,
13 ledsglength: u32,
14 ledsgpos: u32,
15 position: i32,
16 reverse: bool,
17 ledsvdepth: f32,
18 ledshdepth: f32,
19 edgehgap: f32,
20 edgevgap: f32,
21 overlap: f32,
22 ptblh: f32,
23 ptblv: f32,
24 ptbrh: f32,
25 ptbrv: f32,
26 pttlh: f32,
27 pttlv: f32,
28 pttrh: f32,
29 pttrv: f32,
30}
31
32impl From<&ClassicLedConfig> for ClassicLedParams {
33 fn from(c: &ClassicLedConfig) -> Self {
34 Self {
35 ledstop: c.top,
36 ledsbottom: c.bottom,
37 ledsleft: c.left,
38 ledsright: c.right,
39 ledsglength: c.glength,
40 ledsgpos: c.gpos,
41 position: c.position,
42 reverse: c.reverse,
43 ledsvdepth: c.vdepth as f32 / 100.,
44 ledshdepth: c.hdepth as f32 / 100.,
45 edgehgap: (c.edgegap as f32 / 200.) / (16. / 9.),
46 edgevgap: c.edgegap as f32 / 200.,
47 overlap: c.overlap as f32 / 100.,
48 ptblh: c.pblh as f32 / 100.,
49 ptblv: c.pblv as f32 / 100.,
50 ptbrh: c.pbrh as f32 / 100.,
51 ptbrv: c.pbrv as f32 / 100.,
52 pttlh: c.ptlh as f32 / 100.,
53 pttlv: c.ptlv as f32 / 100.,
54 pttrh: c.ptrh as f32 / 100.,
55 pttrv: c.ptrv as f32 / 100.,
56 }
57 }
58}
59
60impl ClassicLedParams {
61 fn round(x: f32) -> f32 {
62 let factor = 1e4;
63 (x * factor).round() / factor
64 }
65
66 fn create_led(hmin: f32, hmax: f32, vmin: f32, vmax: f32) -> Led {
67 Led {
68 hmin: Self::round(hmin),
69 hmax: Self::round(hmax),
70 vmin: Self::round(vmin),
71 vmax: Self::round(vmax),
72 color_order: None,
73 name: None,
74 }
75 }
76
77 fn ovl_plus(&self, x: f32) -> f32 {
78 (x + self.overlap).clamp(0., 1.)
79 }
80
81 fn ovl_minus(&self, x: f32) -> f32 {
82 (x - self.overlap).clamp(0., 1.)
83 }
84
85 fn create_top_leds(&self, leds: &mut Vec<Led>) {
86 let steph = (self.pttrh - self.pttlh - (2. * self.edgehgap)) / self.ledstop as f32;
87 let stepv = (self.pttrv - self.pttlv) / self.ledstop as f32;
88
89 leds.reserve(self.ledstop as _);
90 for i in 0..self.ledstop {
91 let i = i as f32;
92 let hmin = self.ovl_minus(self.pttlh + (steph * i) + self.edgehgap);
93 let hmax = self.ovl_plus(self.pttlh + (steph * (i + 1.)) + self.edgehgap);
94 let vmin = self.pttlv + (stepv * i);
95 let vmax = vmin + self.ledshdepth;
96
97 leds.push(Self::create_led(hmin, hmax, vmin, vmax));
98 }
99 }
100
101 fn create_right_leds(&self, leds: &mut Vec<Led>) {
102 let steph = (self.ptbrh - self.pttrh) / self.ledsright as f32;
103 let stepv = (self.ptbrv - self.pttrv - (2. * self.edgevgap)) / self.ledsright as f32;
104
105 leds.reserve(self.ledsright as _);
106 for i in 0..self.ledsright {
107 let i = i as f32;
108 let hmax = self.pttrh + (steph * (i + 1.));
109 let hmin = hmax - self.ledsvdepth;
110 let vmin = self.ovl_minus(self.pttrv + (stepv * i) + self.edgevgap);
111 let vmax = self.ovl_plus(self.pttrv + (stepv * (i + 1.)) + self.edgevgap);
112
113 leds.push(Self::create_led(hmin, hmax, vmin, vmax));
114 }
115 }
116
117 fn create_bottom_leds(&self, leds: &mut Vec<Led>) {
118 let steph = (self.ptbrh - self.ptblh - (2. * self.edgehgap)) / self.ledsbottom as f32;
119 let stepv = (self.ptbrv - self.ptblv) / self.ledsbottom as f32;
120
121 leds.reserve(self.ledsbottom as _);
122 for i in 0..self.ledsbottom {
123 let i = i as f32;
124 let hmin = self.ovl_minus(self.ptblh + (steph * i) + self.edgehgap);
125 let hmax = self.ovl_plus(self.ptblh + (steph * (i + 1.)) + self.edgehgap);
126 let vmax = self.ptblv + (stepv * i);
127 let vmin = vmax - self.ledshdepth;
128
129 leds.push(Self::create_led(hmin, hmax, vmin, vmax));
130 }
131 }
132
133 fn create_left_leds(&self, leds: &mut Vec<Led>) {
134 let steph = (self.ptblh - self.pttlh) / self.ledsleft as f32;
135 let stepv = (self.ptblv - self.pttlv - (2. * self.edgevgap)) / self.ledsleft as f32;
136
137 leds.reserve(self.ledsleft as _);
138 for i in 0..self.ledsleft {
139 let i = i as f32;
140 let hmin = self.pttlh + (steph * i);
141 let hmax = hmin + self.ledsvdepth;
142 let vmin = self.ovl_minus(self.pttlv + (stepv * i) + self.edgevgap);
143 let vmax = self.ovl_plus(self.pttlv + (stepv * (i + 1.)) + self.edgevgap);
144
145 leds.push(Self::create_led(hmin, hmax, vmin, vmax));
146 }
147 }
148}
149
150impl ToLeds for ClassicLedParams {
151 fn to_leds(&self) -> Leds {
152 let mut leds = Vec::with_capacity(
153 (self.ledstop + self.ledsbottom + self.ledsleft + self.ledsright) as usize,
154 );
155
156 self.create_top_leds(&mut leds);
157 self.create_right_leds(&mut leds);
158 self.create_bottom_leds(&mut leds);
159 self.create_left_leds(&mut leds);
160
161 let ledsgpos = if self.ledsgpos + self.ledsglength > leds.len() as u32 {
163 (leds.len() as isize - self.ledsglength as isize).max(0) as usize
164 } else {
165 self.ledsglength as usize
166 };
167
168 let ledsglength = if self.ledsglength >= leds.len() as u32 {
170 leds.len() as isize - self.ledsglength as isize - 1
171 } else {
172 self.ledsglength as _
173 };
174
175 if ledsglength > 0 {
176 leds.splice(
177 ledsgpos..(ledsgpos + ledsglength as usize),
178 std::iter::empty(),
179 );
180 }
181
182 if self.position < 0 {
183 leds.rotate_left(-self.position as _);
184 } else if self.position > 0 {
185 leds.rotate_right(self.position as _);
186 }
187
188 if self.reverse {
189 leds.reverse();
190 }
191
192 Leds { leds }
193 }
194}
195
196impl ToLeds for ClassicLedConfig {
197 fn to_leds(&self) -> Leds {
198 ClassicLedParams::from(self).to_leds()
199 }
200}