Skip to main content

vizia_core/views/
image.rs

1use vizia_style::Url;
2
3use crate::prelude::*;
4
5/// A view which presents an image.
6///
7/// The image URL can be static or reactive (via a Signal). Loading and error
8/// UI can be composed externally with `Binding` and `LoadingStatus`.
9pub struct Image {}
10
11impl Image {
12    /// Creates a new [Image] view.
13    ///
14    /// The `img` parameter can be a static string or a reactive signal of image paths/URLs.
15    pub fn new<T>(cx: &mut Context, img: impl Res<T> + 'static) -> Handle<'_, Self>
16    where
17        T: ToString + Clone + 'static,
18    {
19        let img = img.to_signal(cx).map(|img| {
20            let path = img.to_string();
21            BackgroundImage::Url(Url { url: path.into() })
22        });
23
24        let handle = Self {}.build(cx, |_| {});
25
26        handle.background_image(img)
27    }
28}
29
30impl View for Image {
31    fn element(&self) -> Option<&'static str> {
32        Some("image")
33    }
34}
35
36/// A view which presents an SVG image.
37pub struct Svg {}
38
39impl Svg {
40    /// Creates a new [Svg] view.
41    pub fn new<T>(cx: &mut Context, data: impl Res<T>) -> Handle<Self>
42    where
43        T: AsRef<[u8]> + 'static,
44    {
45        let mut handle = Self {}.build(cx, |_| {});
46        let entity = handle.entity();
47
48        data.set_or_bind(handle.context(), move |cx, data| {
49            let svg_data = data.get_value(cx);
50            let hash = format!("{:x}", fxhash::hash64(svg_data.as_ref()));
51
52            cx.load_svg(&hash, svg_data.as_ref(), ImageRetentionPolicy::DropWhenNoObservers);
53            cx.style.background_image.insert(entity, vec![ImageOrGradient::Image(hash)]);
54            cx.needs_redraw(entity);
55        });
56
57        handle.hoverable(false)
58    }
59}
60
61impl View for Svg {
62    fn element(&self) -> Option<&'static str> {
63        Some("svg")
64    }
65}