use crate::assets::AssetManager;
use crate::impl_style;
use crate::style::BoxStyle;
use crate::widgets::{Svg, Widget};
use agape_core::{Color, GlobalId};
use agape_layout::{BlockLayout, EmptyLayout, Layout};
use agape_renderer::Renderer;
use agape_renderer::rect::Rect;
use std::io::Read;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone)]
pub struct Icon {
id: GlobalId,
path: PathBuf,
data: Option<Svg>,
style: BoxStyle,
}
impl Icon {
pub fn asset(path: impl AsRef<Path>) -> Self {
Self {
id: GlobalId::new(),
path: path.as_ref().to_path_buf(),
data: None,
style: Default::default(),
}
}
impl_style! {}
}
impl Widget for Icon {
fn id(&self) -> GlobalId {
self.id
}
fn get_assets(&mut self, assets: &AssetManager) {
if self.data.is_some() {
return;
}
let mut file = assets.get(&self.path).unwrap().unwrap();
let mut bytes = vec![];
file.read_to_end(&mut bytes).unwrap();
let mut svg = Svg::bytes(&bytes).unwrap();
svg.style = self.style.clone();
self.data = Some(svg);
}
fn children(&self) -> Vec<&dyn Widget> {
match &self.data {
Some(data) => vec![data],
None => vec![],
}
}
fn traverse(&mut self, f: &mut dyn FnMut(&mut dyn Widget)) {
if let Some(child) = &mut self.data {
f(child);
child.traverse(f);
}
}
fn layout(&self, renderer: &mut Renderer) -> Box<dyn Layout> {
if let Some(child) = &self.data {
let child_layout = child.layout(renderer);
let mut layout = BlockLayout::new(child_layout);
layout.id = self.id;
layout.intrinsic_size = self.style.intrinsic_size;
return Box::new(layout);
}
let layout = EmptyLayout {
id: self.id,
intrinsic_size: self.style.intrinsic_size,
..Default::default()
};
Box::new(layout)
}
fn render(&self, renderer: &mut Renderer, layout_tree: &dyn Layout) {
let layout = layout_tree.get(self.id).unwrap();
let size = layout.size();
let position = layout.position();
if let Some(child) = &self.data {
child.render(renderer, layout_tree);
} else {
let rect = Rect::new()
.color(Color::BLACK)
.size(size.width, size.height)
.position(position.x, position.y);
renderer.draw_rect(rect);
}
}
}