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::vgi::{ImageBrush, ImageData, Scene};
7use maycoon_core::widget::{Widget, WidgetLayoutExt};
8use maycoon_theme::id::WidgetId;
9use maycoon_theme::theme::Theme;
10use nalgebra::Vector2;
11
12/// An image widget. Pretty self-explanatory.
13///
14/// See the [image](https://github.com/maycoon-ui/maycoon/blob/master/examples/image/src/main.rs) example for how to use it in practice.
15///
16/// ### Theming
17/// The widget itself only draws the underlying image, so theming is useless.
18///
19/// The [WidgetId] is equal to `maycoon-widgets:Image`.
20pub struct Image {
21    image: MaybeSignal<ImageData>,
22    style: MaybeSignal<LayoutStyle>,
23}
24
25impl Image {
26    /// Create an image widget from the given [ImageData].
27    #[inline(always)]
28    pub fn new(image: impl Into<MaybeSignal<ImageData>>) -> Self {
29        Self {
30            image: image.into(),
31            style: LayoutStyle::default().into(),
32        }
33    }
34
35    /// Set the image.
36    #[inline(always)]
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    #[inline(always)]
45    fn set_layout_style(&mut self, layout_style: impl Into<MaybeSignal<LayoutStyle>>) {
46        self.style = layout_style.into();
47    }
48}
49
50impl Widget for Image {
51    #[inline(always)]
52    fn render(
53        &mut self,
54        scene: &mut dyn Scene,
55        _: &mut dyn Theme,
56        layout_node: &LayoutNode,
57        _: &AppInfo,
58        _: AppContext,
59    ) {
60        let image = self.image.get();
61        let brush = ImageBrush::new(image.clone());
62
63        scene.draw_image(
64            &brush,
65            None,
66            Vector2::new(layout_node.layout.location.x, layout_node.layout.location.y),
67        );
68    }
69
70    #[inline(always)]
71    fn layout_style(&self) -> StyleNode {
72        StyleNode {
73            style: self.style.get().clone(),
74            children: Vec::new(),
75        }
76    }
77
78    #[inline(always)]
79    fn update(&mut self, _: &LayoutNode, _: AppContext, _: &AppInfo) -> Update {
80        Update::empty()
81    }
82
83    #[inline(always)]
84    fn widget_id(&self) -> WidgetId {
85        WidgetId::new("maycoon-widgets", "Image")
86    }
87}