image.rs

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