maycoon_widgets/
image.rs

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
13/// Owned shareable image data.
14pub type ImageData = vello::peniko::Image;
15
16/// An image widget. Pretty self-explanatory.
17///
18/// See the [image](https://github.com/maycoon-ui/maycoon/blob/master/examples/image/src/main.rs) example for how to use it in practice.
19///
20/// ### Theming
21/// The widget itself only draws the underlying image, so theming is useless.
22pub struct Image {
23    image: MaybeSignal<ImageData>,
24    style: MaybeSignal<LayoutStyle>,
25}
26
27impl Image {
28    /// Create an image widget from the given [ImageData].
29    pub fn new(image: impl Into<MaybeSignal<ImageData>>) -> Self {
30        Self {
31            image: image.into(),
32            style: LayoutStyle::default().into(),
33        }
34    }
35
36    /// Set the image.
37    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}