1use super::super::{super::Rotation, IcedRenderer, Primitive, style};
2use common::util::srgba_to_linear;
3use iced::{Element, Layout, Point, Rectangle, container};
4use style::container::Border;
5use vek::Rgba;
6
7const BORDER_SIZE: u16 = 8;
9
10impl container::Renderer for IcedRenderer {
11 type Style = style::container::Style;
12
13 fn draw<M>(
14 &mut self,
15 defaults: &Self::Defaults,
16 bounds: Rectangle,
17 cursor_position: Point,
18 viewport: &Rectangle,
19 style_sheet: &Self::Style,
20 content: &Element<'_, M, Self>,
21 content_layout: Layout<'_>,
22 ) -> Self::Output {
23 let (content, mouse_interaction) =
24 content.draw(self, defaults, content_layout, cursor_position, viewport);
25
26 let prim = match style_sheet {
27 Self::Style::Image(handle, color) => {
28 let background = Primitive::Image {
29 handle: (*handle, Rotation::None),
30 bounds,
31 color: *color,
32 source_rect: None,
33 };
34
35 Primitive::Group {
36 primitives: vec![background, content],
37 }
38 },
39 Self::Style::Color(color, border) => {
40 let linear_color = srgba_to_linear(color.map(|e| e as f32 / 255.0));
41
42 let primitives = match border {
43 Border::None => {
44 let background = Primitive::Rectangle {
45 bounds,
46 linear_color,
47 };
48
49 vec![background, content]
50 },
51 Border::DoubleCornerless { inner, outer } => {
52 let border_size = f32::from(BORDER_SIZE)
53 .min(bounds.width / 4.0)
54 .min(bounds.height / 4.0);
55
56 let center = Primitive::Rectangle {
57 bounds: Rectangle {
58 x: bounds.x + border_size * 2.0,
59 y: bounds.y + border_size * 2.0,
60 width: bounds.width - border_size * 4.0,
61 height: bounds.height - border_size * 4.0,
62 },
63 linear_color,
64 };
65
66 let linear_color = srgba_to_linear(outer.map(|e| e as f32 / 255.0));
67 let top = Primitive::Rectangle {
68 bounds: Rectangle {
69 x: bounds.x + border_size,
70 y: bounds.y,
71 width: bounds.width - border_size * 2.0,
72 height: border_size,
73 },
74 linear_color,
75 };
76 let bottom = Primitive::Rectangle {
77 bounds: Rectangle {
78 x: bounds.x + border_size,
79 y: bounds.y + bounds.height - border_size,
80 width: bounds.width - border_size * 2.0,
81 height: border_size,
82 },
83 linear_color,
84 };
85 let left = Primitive::Rectangle {
86 bounds: Rectangle {
87 x: bounds.x,
88 y: bounds.y + border_size,
89 width: border_size,
90 height: bounds.height - border_size * 2.0,
91 },
92 linear_color,
93 };
94 let right = Primitive::Rectangle {
95 bounds: Rectangle {
96 x: bounds.x + bounds.width - border_size,
97 y: bounds.y + border_size,
98 width: border_size,
99 height: bounds.height - border_size * 2.0,
100 },
101 linear_color,
102 };
103
104 let linear_color = srgba_to_linear(inner.map(|e| e as f32 / 255.0));
105 let top_inner = Primitive::Rectangle {
106 bounds: Rectangle {
107 x: bounds.x + border_size,
108 y: bounds.y + border_size,
109 width: bounds.width - border_size * 2.0,
110 height: border_size,
111 },
112 linear_color,
113 };
114 let bottom_inner = Primitive::Rectangle {
115 bounds: Rectangle {
116 x: bounds.x + border_size,
117 y: bounds.y + bounds.height - border_size * 2.0,
118 width: bounds.width - border_size * 2.0,
119 height: border_size,
120 },
121 linear_color,
122 };
123 let left_inner = Primitive::Rectangle {
124 bounds: Rectangle {
125 x: bounds.x + border_size,
126 y: bounds.y + border_size * 2.0,
127 width: border_size,
128 height: bounds.height - border_size * 4.0,
129 },
130 linear_color,
131 };
132 let right_inner = Primitive::Rectangle {
133 bounds: Rectangle {
134 x: bounds.x + bounds.width - border_size * 2.0,
135 y: bounds.y + border_size * 2.0,
136 width: border_size,
137 height: bounds.height - border_size * 4.0,
138 },
139 linear_color,
140 };
141
142 vec![
143 center,
144 top,
145 bottom,
146 left,
147 right,
148 top_inner,
149 bottom_inner,
150 left_inner,
151 right_inner,
152 content,
153 ]
154 },
155 Border::Image { corner, edge } => {
156 let border_size = f32::from(BORDER_SIZE)
157 .min(bounds.width / 4.0)
158 .min(bounds.height / 4.0);
159
160 let center = Primitive::Rectangle {
161 bounds: Rectangle {
162 x: bounds.x + border_size,
163 y: bounds.y + border_size,
164 width: bounds.width - border_size * 2.0,
165 height: bounds.height - border_size * 2.0,
166 },
167 linear_color,
168 };
169
170 let color = Rgba::white();
171
172 let tl_corner = Primitive::Image {
173 handle: (*corner, Rotation::None),
174 bounds: Rectangle {
175 x: bounds.x,
176 y: bounds.y,
177 width: border_size,
178 height: border_size,
179 },
180 color,
181 source_rect: None,
182 };
183
184 let tr_corner = Primitive::Image {
185 handle: (*corner, Rotation::Cw90),
186 bounds: Rectangle {
187 x: bounds.x + bounds.width - border_size,
188 y: bounds.y,
189 width: border_size,
190 height: border_size,
191 },
192 color,
193 source_rect: None,
194 };
195
196 let bl_corner = Primitive::Image {
197 handle: (*corner, Rotation::Cw270),
198 bounds: Rectangle {
199 x: bounds.x,
200 y: bounds.y + bounds.height - border_size,
201 width: border_size,
202 height: border_size,
203 },
204 color,
205 source_rect: None,
206 };
207
208 let br_corner = Primitive::Image {
209 handle: (*corner, Rotation::Cw180),
210 bounds: Rectangle {
211 x: bounds.x + bounds.width - border_size,
212 y: bounds.y + bounds.height - border_size,
213 width: border_size,
214 height: border_size,
215 },
216 color,
217 source_rect: None,
218 };
219
220 let top_edge = Primitive::Image {
221 handle: (*edge, Rotation::None),
222 bounds: Rectangle {
223 x: bounds.x + border_size,
224 y: bounds.y,
225 width: bounds.width - 2.0 * border_size,
226 height: border_size,
227 },
228 color,
229 source_rect: None,
230 };
231
232 let bottom_edge = Primitive::Image {
233 handle: (*edge, Rotation::Cw180),
234 bounds: Rectangle {
235 x: bounds.x + border_size,
236 y: bounds.y + bounds.height - border_size,
237 width: bounds.width - 2.0 * border_size,
238 height: border_size,
239 },
240 color,
241 source_rect: None,
242 };
243
244 let left_edge = Primitive::Image {
245 handle: (*edge, Rotation::Cw270),
246 bounds: Rectangle {
247 x: bounds.x,
248 y: bounds.y + border_size,
249 width: border_size,
250 height: bounds.height - 2.0 * border_size,
251 },
252 color,
253 source_rect: None,
254 };
255
256 let right_edge = Primitive::Image {
257 handle: (*edge, Rotation::Cw90),
258 bounds: Rectangle {
259 x: bounds.x + bounds.width - border_size,
260 y: bounds.y + border_size,
261 width: border_size,
262 height: bounds.height - 2.0 * border_size,
263 },
264 color,
265 source_rect: None,
266 };
267
268 vec![
270 center,
271 tl_corner,
272 tr_corner,
273 bl_corner,
274 br_corner,
275 top_edge,
276 bottom_edge,
277 left_edge,
278 right_edge,
279 content,
280 ]
281 },
282 };
283
284 Primitive::Group { primitives }
285 },
286 Self::Style::None => content,
287 };
288
289 (prim, mouse_interaction)
290 }
291}