1use super::constrain_size_preserving_aspect_ratio;
2use crate::{
3 geometry::{rect::RectF, vector::Vector2F},
4 json::{json, ToJson},
5 scene, Border, DebugContext, Element, Event, EventContext, ImageData, LayoutContext,
6 PaintContext, SizeConstraint,
7};
8use serde::Deserialize;
9use std::sync::Arc;
10
11pub struct Image {
12 data: Arc<ImageData>,
13 style: ImageStyle,
14}
15
16#[derive(Copy, Clone, Default, Deserialize)]
17pub struct ImageStyle {
18 #[serde(default)]
19 border: Border,
20 #[serde(default)]
21 corner_radius: f32,
22}
23
24impl Image {
25 pub fn new(data: Arc<ImageData>) -> Self {
26 Self {
27 data,
28 style: Default::default(),
29 }
30 }
31
32 pub fn with_style(mut self, style: ImageStyle) -> Self {
33 self.style = style;
34 self
35 }
36}
37
38impl Element for Image {
39 type LayoutState = ();
40 type PaintState = ();
41
42 fn layout(
43 &mut self,
44 constraint: SizeConstraint,
45 _: &mut LayoutContext,
46 ) -> (Vector2F, Self::LayoutState) {
47 let size =
48 constrain_size_preserving_aspect_ratio(constraint.max, self.data.size().to_f32());
49 (size, ())
50 }
51
52 fn paint(
53 &mut self,
54 bounds: RectF,
55 _: RectF,
56 _: &mut Self::LayoutState,
57 cx: &mut PaintContext,
58 ) -> Self::PaintState {
59 cx.scene.push_image(scene::Image {
60 bounds,
61 border: self.style.border,
62 corner_radius: self.style.corner_radius,
63 data: self.data.clone(),
64 });
65 }
66
67 fn dispatch_event(
68 &mut self,
69 _: &Event,
70 _: RectF,
71 _: &mut Self::LayoutState,
72 _: &mut Self::PaintState,
73 _: &mut EventContext,
74 ) -> bool {
75 false
76 }
77
78 fn debug(
79 &self,
80 bounds: RectF,
81 _: &Self::LayoutState,
82 _: &Self::PaintState,
83 _: &DebugContext,
84 ) -> serde_json::Value {
85 json!({
86 "type": "Image",
87 "bounds": bounds.to_json(),
88 })
89 }
90}