2021-04-27 17:58:59 +00:00
|
|
|
use std::borrow::Cow;
|
|
|
|
|
2021-04-07 05:50:13 +00:00
|
|
|
use serde_json::json;
|
|
|
|
|
2021-03-10 04:00:51 +00:00
|
|
|
use crate::{
|
2021-08-03 19:48:58 +00:00
|
|
|
color::Color,
|
2021-04-06 11:44:38 +00:00
|
|
|
geometry::{
|
|
|
|
rect::RectF,
|
|
|
|
vector::{vec2f, Vector2F},
|
|
|
|
},
|
2021-08-20 22:40:45 +00:00
|
|
|
scene, DebugContext, Element, Event, EventContext, LayoutContext, PaintContext, SizeConstraint,
|
2021-03-10 04:00:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
pub struct Svg {
|
2021-04-27 17:58:59 +00:00
|
|
|
path: Cow<'static, str>,
|
2021-08-03 19:48:58 +00:00
|
|
|
color: Color,
|
2021-03-10 04:00:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Svg {
|
2021-04-27 17:58:59 +00:00
|
|
|
pub fn new(path: impl Into<Cow<'static, str>>) -> Self {
|
2021-04-06 11:44:38 +00:00
|
|
|
Self {
|
2021-04-27 17:58:59 +00:00
|
|
|
path: path.into(),
|
2021-08-03 19:48:58 +00:00
|
|
|
color: Color::black(),
|
2021-04-06 11:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-03 19:48:58 +00:00
|
|
|
pub fn with_color(mut self, color: Color) -> Self {
|
2021-04-06 11:44:38 +00:00
|
|
|
self.color = color;
|
|
|
|
self
|
2021-03-10 04:00:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Element for Svg {
|
2021-04-06 11:44:38 +00:00
|
|
|
type LayoutState = Option<usvg::Tree>;
|
2021-03-22 02:54:23 +00:00
|
|
|
type PaintState = ();
|
|
|
|
|
2021-03-10 04:00:51 +00:00
|
|
|
fn layout(
|
|
|
|
&mut self,
|
2021-04-06 11:44:38 +00:00
|
|
|
constraint: SizeConstraint,
|
2021-05-28 22:25:15 +00:00
|
|
|
cx: &mut LayoutContext,
|
2021-03-22 02:54:23 +00:00
|
|
|
) -> (Vector2F, Self::LayoutState) {
|
2021-05-28 22:25:15 +00:00
|
|
|
match cx.asset_cache.svg(&self.path) {
|
2021-04-06 11:44:38 +00:00
|
|
|
Ok(tree) => {
|
2021-09-14 22:39:35 +00:00
|
|
|
let size = constrain_size_preserving_aspect_ratio(
|
|
|
|
constraint.max,
|
|
|
|
from_usvg_rect(tree.svg_node().view_box.rect).size(),
|
|
|
|
);
|
2021-04-06 11:44:38 +00:00
|
|
|
(size, Some(tree))
|
|
|
|
}
|
2021-09-20 00:34:04 +00:00
|
|
|
Err(_error) => {
|
|
|
|
#[cfg(not(any(test, feature = "test-support")))]
|
|
|
|
log::error!("{}", _error);
|
2021-04-06 11:44:38 +00:00
|
|
|
(constraint.min, None)
|
|
|
|
}
|
|
|
|
}
|
2021-03-10 04:00:51 +00:00
|
|
|
}
|
|
|
|
|
2021-09-02 09:42:23 +00:00
|
|
|
fn paint(
|
|
|
|
&mut self,
|
|
|
|
bounds: RectF,
|
|
|
|
_visible_bounds: RectF,
|
|
|
|
svg: &mut Self::LayoutState,
|
|
|
|
cx: &mut PaintContext,
|
|
|
|
) {
|
2021-04-06 11:44:38 +00:00
|
|
|
if let Some(svg) = svg.clone() {
|
2021-05-28 22:25:15 +00:00
|
|
|
cx.scene.push_icon(scene::Icon {
|
2021-04-06 11:44:38 +00:00
|
|
|
bounds,
|
|
|
|
svg,
|
|
|
|
path: self.path.clone(),
|
|
|
|
color: self.color,
|
|
|
|
});
|
|
|
|
}
|
2021-03-10 04:00:51 +00:00
|
|
|
}
|
|
|
|
|
2021-03-22 02:54:23 +00:00
|
|
|
fn dispatch_event(
|
|
|
|
&mut self,
|
|
|
|
_: &Event,
|
2021-04-06 11:44:38 +00:00
|
|
|
_: RectF,
|
2022-04-07 13:10:09 +00:00
|
|
|
_: RectF,
|
2021-03-22 02:54:23 +00:00
|
|
|
_: &mut Self::LayoutState,
|
|
|
|
_: &mut Self::PaintState,
|
|
|
|
_: &mut EventContext,
|
|
|
|
) -> bool {
|
2021-03-10 04:00:51 +00:00
|
|
|
false
|
|
|
|
}
|
2021-04-07 05:50:13 +00:00
|
|
|
|
|
|
|
fn debug(
|
|
|
|
&self,
|
|
|
|
bounds: RectF,
|
|
|
|
_: &Self::LayoutState,
|
|
|
|
_: &Self::PaintState,
|
|
|
|
_: &DebugContext,
|
|
|
|
) -> serde_json::Value {
|
|
|
|
json!({
|
|
|
|
"type": "Svg",
|
|
|
|
"bounds": bounds.to_json(),
|
|
|
|
"path": self.path,
|
|
|
|
"color": self.color.to_json(),
|
|
|
|
})
|
|
|
|
}
|
2021-03-10 04:00:51 +00:00
|
|
|
}
|
2021-04-06 11:44:38 +00:00
|
|
|
|
2021-04-07 05:50:13 +00:00
|
|
|
use crate::json::ToJson;
|
|
|
|
|
2021-09-14 22:39:35 +00:00
|
|
|
use super::constrain_size_preserving_aspect_ratio;
|
|
|
|
|
2021-04-06 11:44:38 +00:00
|
|
|
fn from_usvg_rect(rect: usvg::Rect) -> RectF {
|
|
|
|
RectF::new(
|
|
|
|
vec2f(rect.x() as f32, rect.y() as f32),
|
|
|
|
vec2f(rect.width() as f32, rect.height() as f32),
|
|
|
|
)
|
|
|
|
}
|