1use maycoon_core::app::context::AppContext;
2use maycoon_core::app::info::AppInfo;
3use maycoon_core::app::update::Update;
4use maycoon_core::layout::{LayoutNode, LayoutStyle, StyleNode};
5use maycoon_core::signal::MaybeSignal;
6use maycoon_core::vg::kurbo::{Affine, Vec2};
7use maycoon_core::vg::Scene;
8use maycoon_core::widget::{Widget, WidgetLayoutExt};
9use maycoon_theme::id::WidgetId;
10use maycoon_theme::theme::Theme;
11use vello_svg::vello;
12
13pub type ImageData = vello::peniko::Image;
15
16pub struct Image {
23 image: MaybeSignal<ImageData>,
24 style: MaybeSignal<LayoutStyle>,
25}
26
27impl Image {
28 pub fn new(image: impl Into<MaybeSignal<ImageData>>) -> Self {
30 Self {
31 image: image.into(),
32 style: LayoutStyle::default().into(),
33 }
34 }
35
36 pub fn with_image(mut self, image: impl Into<MaybeSignal<ImageData>>) -> Self {
38 self.image = image.into();
39 self
40 }
41}
42
43impl WidgetLayoutExt for Image {
44 fn set_layout_style(&mut self, layout_style: impl Into<MaybeSignal<LayoutStyle>>) {
45 self.style = layout_style.into();
46 }
47}
48
49impl Widget for Image {
50 fn render(
51 &mut self,
52 scene: &mut Scene,
53 _: &mut dyn Theme,
54 layout_node: &LayoutNode,
55 _: &AppInfo,
56 _: AppContext,
57 ) {
58 let image = self.image.get();
59
60 scene.draw_image(
61 &image,
62 Affine::translate(Vec2::new(
63 layout_node.layout.location.x as f64,
64 layout_node.layout.location.y as f64,
65 )),
66 );
67 }
68
69 fn layout_style(&self) -> StyleNode {
70 StyleNode {
71 style: self.style.get().clone(),
72 children: Vec::new(),
73 }
74 }
75
76 fn update(&mut self, _: &LayoutNode, _: AppContext, _: &AppInfo) -> Update {
77 Update::empty()
78 }
79
80 fn widget_id(&self) -> WidgetId {
81 WidgetId::new("maycoon-widgets", "Image")
82 }
83}