1use crate::layout;
2use crate::mouse;
3use crate::overlay;
4use crate::renderer;
5use crate::widget;
6use crate::widget::tree::{self, Tree};
7use crate::{
8 Border, Clipboard, Color, Event, Layout, Length, Rectangle, Shell, Size,
9 Vector, Widget,
10};
11
12use std::borrow::Borrow;
13
14#[allow(missing_debug_implementations)]
24pub struct Element<'a, Message, Theme, Renderer> {
25 widget: Box<dyn Widget<Message, Theme, Renderer> + 'a>,
26}
27
28impl<'a, Message, Theme, Renderer> Element<'a, Message, Theme, Renderer> {
29 pub fn new(widget: impl Widget<Message, Theme, Renderer> + 'a) -> Self
31 where
32 Renderer: crate::Renderer,
33 {
34 Self {
35 widget: Box::new(widget),
36 }
37 }
38
39 pub fn as_widget(&self) -> &dyn Widget<Message, Theme, Renderer> {
41 self.widget.as_ref()
42 }
43
44 pub fn as_widget_mut(
46 &mut self,
47 ) -> &mut dyn Widget<Message, Theme, Renderer> {
48 self.widget.as_mut()
49 }
50
51 pub fn map<B>(
191 self,
192 f: impl Fn(Message) -> B + 'a,
193 ) -> Element<'a, B, Theme, Renderer>
194 where
195 Message: 'a,
196 Theme: 'a,
197 Renderer: crate::Renderer + 'a,
198 B: 'a,
199 {
200 Element::new(Map::new(self.widget, f))
201 }
202
203 pub fn explain<C: Into<Color>>(
210 self,
211 color: C,
212 ) -> Element<'a, Message, Theme, Renderer>
213 where
214 Message: 'a,
215 Theme: 'a,
216 Renderer: crate::Renderer + 'a,
217 {
218 Element {
219 widget: Box::new(Explain::new(self, color.into())),
220 }
221 }
222}
223
224impl<'a, Message, Theme, Renderer>
225 Borrow<dyn Widget<Message, Theme, Renderer> + 'a>
226 for Element<'a, Message, Theme, Renderer>
227{
228 fn borrow(&self) -> &(dyn Widget<Message, Theme, Renderer> + 'a) {
229 self.widget.borrow()
230 }
231}
232
233impl<'a, Message, Theme, Renderer>
234 Borrow<dyn Widget<Message, Theme, Renderer> + 'a>
235 for &Element<'a, Message, Theme, Renderer>
236{
237 fn borrow(&self) -> &(dyn Widget<Message, Theme, Renderer> + 'a) {
238 self.widget.borrow()
239 }
240}
241
242struct Map<'a, A, B, Theme, Renderer> {
243 widget: Box<dyn Widget<A, Theme, Renderer> + 'a>,
244 mapper: Box<dyn Fn(A) -> B + 'a>,
245}
246
247impl<'a, A, B, Theme, Renderer> Map<'a, A, B, Theme, Renderer> {
248 pub fn new<F>(
249 widget: Box<dyn Widget<A, Theme, Renderer> + 'a>,
250 mapper: F,
251 ) -> Map<'a, A, B, Theme, Renderer>
252 where
253 F: 'a + Fn(A) -> B,
254 {
255 Map {
256 widget,
257 mapper: Box::new(mapper),
258 }
259 }
260}
261
262impl<'a, A, B, Theme, Renderer> Widget<B, Theme, Renderer>
263 for Map<'a, A, B, Theme, Renderer>
264where
265 Renderer: crate::Renderer + 'a,
266 A: 'a,
267 B: 'a,
268{
269 fn tag(&self) -> tree::Tag {
270 self.widget.tag()
271 }
272
273 fn state(&self) -> tree::State {
274 self.widget.state()
275 }
276
277 fn children(&self) -> Vec<Tree> {
278 self.widget.children()
279 }
280
281 fn diff(&self, tree: &mut Tree) {
282 self.widget.diff(tree);
283 }
284
285 fn size(&self) -> Size<Length> {
286 self.widget.size()
287 }
288
289 fn size_hint(&self) -> Size<Length> {
290 self.widget.size_hint()
291 }
292
293 fn layout(
294 &self,
295 tree: &mut Tree,
296 renderer: &Renderer,
297 limits: &layout::Limits,
298 ) -> layout::Node {
299 self.widget.layout(tree, renderer, limits)
300 }
301
302 fn operate(
303 &self,
304 tree: &mut Tree,
305 layout: Layout<'_>,
306 renderer: &Renderer,
307 operation: &mut dyn widget::Operation,
308 ) {
309 self.widget.operate(tree, layout, renderer, operation);
310 }
311
312 fn update(
313 &mut self,
314 tree: &mut Tree,
315 event: &Event,
316 layout: Layout<'_>,
317 cursor: mouse::Cursor,
318 renderer: &Renderer,
319 clipboard: &mut dyn Clipboard,
320 shell: &mut Shell<'_, B>,
321 viewport: &Rectangle,
322 ) {
323 let mut local_messages = Vec::new();
324 let mut local_shell = Shell::new(&mut local_messages);
325
326 self.widget.update(
327 tree,
328 event,
329 layout,
330 cursor,
331 renderer,
332 clipboard,
333 &mut local_shell,
334 viewport,
335 );
336
337 shell.merge(local_shell, &self.mapper);
338 }
339
340 fn draw(
341 &self,
342 tree: &Tree,
343 renderer: &mut Renderer,
344 theme: &Theme,
345 style: &renderer::Style,
346 layout: Layout<'_>,
347 cursor: mouse::Cursor,
348 viewport: &Rectangle,
349 ) {
350 self.widget
351 .draw(tree, renderer, theme, style, layout, cursor, viewport);
352 }
353
354 fn mouse_interaction(
355 &self,
356 tree: &Tree,
357 layout: Layout<'_>,
358 cursor: mouse::Cursor,
359 viewport: &Rectangle,
360 renderer: &Renderer,
361 ) -> mouse::Interaction {
362 self.widget
363 .mouse_interaction(tree, layout, cursor, viewport, renderer)
364 }
365
366 fn overlay<'b>(
367 &'b mut self,
368 tree: &'b mut Tree,
369 layout: Layout<'_>,
370 renderer: &Renderer,
371 translation: Vector,
372 ) -> Option<overlay::Element<'b, B, Theme, Renderer>> {
373 let mapper = &self.mapper;
374
375 self.widget
376 .overlay(tree, layout, renderer, translation)
377 .map(move |overlay| overlay.map(mapper))
378 }
379}
380
381struct Explain<'a, Message, Theme, Renderer: crate::Renderer> {
382 element: Element<'a, Message, Theme, Renderer>,
383 color: Color,
384}
385
386impl<'a, Message, Theme, Renderer> Explain<'a, Message, Theme, Renderer>
387where
388 Renderer: crate::Renderer,
389{
390 fn new(
391 element: Element<'a, Message, Theme, Renderer>,
392 color: Color,
393 ) -> Self {
394 Explain { element, color }
395 }
396}
397
398impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer>
399 for Explain<'_, Message, Theme, Renderer>
400where
401 Renderer: crate::Renderer,
402{
403 fn size(&self) -> Size<Length> {
404 self.element.widget.size()
405 }
406
407 fn size_hint(&self) -> Size<Length> {
408 self.element.widget.size_hint()
409 }
410
411 fn tag(&self) -> tree::Tag {
412 self.element.widget.tag()
413 }
414
415 fn state(&self) -> tree::State {
416 self.element.widget.state()
417 }
418
419 fn children(&self) -> Vec<Tree> {
420 self.element.widget.children()
421 }
422
423 fn diff(&self, tree: &mut Tree) {
424 self.element.widget.diff(tree);
425 }
426
427 fn layout(
428 &self,
429 tree: &mut Tree,
430 renderer: &Renderer,
431 limits: &layout::Limits,
432 ) -> layout::Node {
433 self.element.widget.layout(tree, renderer, limits)
434 }
435
436 fn operate(
437 &self,
438 state: &mut Tree,
439 layout: Layout<'_>,
440 renderer: &Renderer,
441 operation: &mut dyn widget::Operation,
442 ) {
443 self.element
444 .widget
445 .operate(state, layout, renderer, operation);
446 }
447
448 fn update(
449 &mut self,
450 state: &mut Tree,
451 event: &Event,
452 layout: Layout<'_>,
453 cursor: mouse::Cursor,
454 renderer: &Renderer,
455 clipboard: &mut dyn Clipboard,
456 shell: &mut Shell<'_, Message>,
457 viewport: &Rectangle,
458 ) {
459 self.element.widget.update(
460 state, event, layout, cursor, renderer, clipboard, shell, viewport,
461 );
462 }
463
464 fn draw(
465 &self,
466 state: &Tree,
467 renderer: &mut Renderer,
468 theme: &Theme,
469 style: &renderer::Style,
470 layout: Layout<'_>,
471 cursor: mouse::Cursor,
472 viewport: &Rectangle,
473 ) {
474 fn explain_layout<Renderer: crate::Renderer>(
475 renderer: &mut Renderer,
476 color: Color,
477 layout: Layout<'_>,
478 ) {
479 renderer.fill_quad(
480 renderer::Quad {
481 bounds: layout.bounds(),
482 border: Border {
483 color,
484 width: 1.0,
485 ..Border::default()
486 },
487 ..renderer::Quad::default()
488 },
489 Color::TRANSPARENT,
490 );
491
492 for child in layout.children() {
493 explain_layout(renderer, color, child);
494 }
495 }
496
497 self.element
498 .widget
499 .draw(state, renderer, theme, style, layout, cursor, viewport);
500
501 explain_layout(renderer, self.color, layout);
502 }
503
504 fn mouse_interaction(
505 &self,
506 state: &Tree,
507 layout: Layout<'_>,
508 cursor: mouse::Cursor,
509 viewport: &Rectangle,
510 renderer: &Renderer,
511 ) -> mouse::Interaction {
512 self.element
513 .widget
514 .mouse_interaction(state, layout, cursor, viewport, renderer)
515 }
516
517 fn overlay<'b>(
518 &'b mut self,
519 state: &'b mut Tree,
520 layout: Layout<'_>,
521 renderer: &Renderer,
522 translation: Vector,
523 ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
524 self.element
525 .widget
526 .overlay(state, layout, renderer, translation)
527 }
528}