Calin Martinconifix: Typos (#15313)3751f672 years agoHistory
190 lines · 5.4 KB · Rust
RawDownload
use crate::{    geometry::Negate as _, point, px, radians, size, Bounds, Element, GlobalElementId, Hitbox,    InteractiveElement, Interactivity, IntoElement, LayoutId, Pixels, Point, Radians, SharedString,    Size, StyleRefinement, Styled, TransformationMatrix, WindowContext,};use util::ResultExt; /// An SVG element.pub struct Svg {    interactivity: Interactivity,    transformation: Option<Transformation>,    path: Option<SharedString>,} /// Create a new SVG element.pub fn svg() -> Svg {    Svg {        interactivity: Interactivity::default(),        transformation: None,        path: None,    }} impl Svg {    /// Set the path to the SVG file for this element.    pub fn path(mut self, path: impl Into<SharedString>) -> Self {        self.path = Some(path.into());        self    }     /// Transform the SVG element with the given transformation.    /// Note that this won't effect the hitbox or layout of the element, only the rendering.    pub fn with_transformation(mut self, transformation: Transformation) -> Self {        self.transformation = Some(transformation);        self    }} impl Element for Svg {    type RequestLayoutState = ();    type PrepaintState = Option<Hitbox>;     fn id(&self) -> Option<crate::ElementId> {        self.interactivity.element_id.clone()    }     fn request_layout(        &mut self,        global_id: Option<&GlobalElementId>,        cx: &mut WindowContext,    ) -> (LayoutId, Self::RequestLayoutState) {        let layout_id = self            .interactivity            .request_layout(global_id, cx, |style, cx| cx.request_layout(style, None));        (layout_id, ())    }     fn prepaint(        &mut self,        global_id: Option<&GlobalElementId>,        bounds: Bounds<Pixels>,        _request_layout: &mut Self::RequestLayoutState,        cx: &mut WindowContext,    ) -> Option<Hitbox> {        self.interactivity            .prepaint(global_id, bounds, bounds.size, cx, |_, _, hitbox, _| hitbox)    }     fn paint(        &mut self,        global_id: Option<&GlobalElementId>,        bounds: Bounds<Pixels>,        _request_layout: &mut Self::RequestLayoutState,        hitbox: &mut Option<Hitbox>,        cx: &mut WindowContext,    ) where        Self: Sized,    {        self.interactivity            .paint(global_id, bounds, hitbox.as_ref(), cx, |style, cx| {                if let Some((path, color)) = self.path.as_ref().zip(style.text.color) {                    let transformation = self                        .transformation                        .as_ref()                        .map(|transformation| {                            transformation.into_matrix(bounds.center(), cx.scale_factor())                        })                        .unwrap_or_default();                     cx.paint_svg(bounds, path.clone(), transformation, color)                        .log_err();                }            })    }} impl IntoElement for Svg {    type Element = Self;     fn into_element(self) -> Self::Element {        self    }} impl Styled for Svg {    fn style(&mut self) -> &mut StyleRefinement {        &mut self.interactivity.base_style    }} impl InteractiveElement for Svg {    fn interactivity(&mut self) -> &mut Interactivity {        &mut self.interactivity    }} /// A transformation to apply to an SVG element.#[derive(Clone, Copy, Debug, PartialEq)]pub struct Transformation {    scale: Size<f32>,    translate: Point<Pixels>,    rotate: Radians,} impl Default for Transformation {    fn default() -> Self {        Self {            scale: size(1.0, 1.0),            translate: point(px(0.0), px(0.0)),            rotate: radians(0.0),        }    }} impl Transformation {    /// Create a new Transformation with the specified scale along each axis.    pub fn scale(scale: Size<f32>) -> Self {        Self {            scale,            translate: point(px(0.0), px(0.0)),            rotate: radians(0.0),        }    }     /// Create a new Transformation with the specified translation.    pub fn translate(translate: Point<Pixels>) -> Self {        Self {            scale: size(1.0, 1.0),            translate,            rotate: radians(0.0),        }    }     /// Create a new Transformation with the specified rotation in radians.    pub fn rotate(rotate: impl Into<Radians>) -> Self {        let rotate = rotate.into();        Self {            scale: size(1.0, 1.0),            translate: point(px(0.0), px(0.0)),            rotate,        }    }     /// Update the scaling factor of this transformation.    pub fn with_scaling(mut self, scale: Size<f32>) -> Self {        self.scale = scale;        self    }     /// Update the translation value of this transformation.    pub fn with_translation(mut self, translate: Point<Pixels>) -> Self {        self.translate = translate;        self    }     /// Update the rotation angle of this transformation.    pub fn with_rotation(mut self, rotate: impl Into<Radians>) -> Self {        self.rotate = rotate.into();        self    }     fn into_matrix(self, center: Point<Pixels>, scale_factor: f32) -> TransformationMatrix {        //Note: if you read this as a sequence of matrix multiplications, start from the bottom        TransformationMatrix::unit()            .translate(center.scale(scale_factor) + self.translate.scale(scale_factor))            .rotate(self.rotate)            .scale(self.scale)            .translate(center.scale(scale_factor).negate())    }}