use crate::{
makepad_derive_widget::*,
image_cache::*,
makepad_draw::*,
widget::*
};
live_design!{
MultiImageBase = {{MultiImage}} {}
}
#[derive(Live, Widget)]
pub struct MultiImage {
#[walk] walk: Walk,
#[redraw] #[live] draw_bg: DrawQuad,
#[live] min_width: i64,
#[live] min_height: i64,
#[live(1.0)] width_scale: f64,
#[live] fit: ImageFit,
#[live] source1: LiveDependency,
#[live] source2: LiveDependency,
#[live] source3: LiveDependency,
#[live] source4: LiveDependency,
#[rust] textures: [Option<Texture>;4],
}
impl ImageCacheImpl for MultiImage {
fn get_texture(&self, id:usize) -> &Option<Texture> {
&self.textures[id]
}
fn set_texture(&mut self, texture: Option<Texture>, id:usize) {
self.textures[id] = texture;
}
}
impl LiveHook for MultiImage{
fn after_apply(&mut self, cx: &mut Cx, _applyl: &mut Apply, _index: usize, _nodes: &[LiveNode]) {
self.lazy_create_image_cache(cx);
for (i,source) in [self.source1.clone(), self.source2.clone(), self.source2.clone(), self.source3.clone()].iter().enumerate(){
if source.as_str().len()>0 {
let _ = self.load_image_dep_by_path(cx, source.as_str(), i);
}
}
}
}
impl Widget for MultiImage {
fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep {
self.draw_walk(cx, walk)
}
}
impl MultiImage {
pub fn size_in_pixels(&self, cx: &mut Cx) -> Option<(usize, usize)> {
self.textures[0].as_ref()
.and_then(|t| t.get_format(cx).vec_width_height())
}
pub fn draw_walk(&mut self, cx: &mut Cx2d, mut walk: Walk) -> DrawStep {
let rect = cx.peek_walk_turtle(walk);
let dpi = cx.current_dpi_factor();
for i in 0..self.textures.len(){
if let Some(image_texture) = &self.textures[i]{
self.draw_bg.draw_vars.set_texture(i, image_texture);
}
}
let (width, height) = if let Some(image_texture) = &self.textures[0]{
let (width,height) = image_texture.get_format(cx).vec_width_height().unwrap_or((self.min_width as usize, self.min_height as usize));
(width as f64 * self.width_scale, height as f64)
}
else {
self.draw_bg.draw_vars.empty_texture(0);
(self.min_width as f64 / dpi, self.min_height as f64 / dpi)
};
let aspect = width / height;
match self.fit {
ImageFit::Size => {
walk.width = Size::Fixed(width);
walk.height = Size::Fixed(height);
}
ImageFit::Stretch => {
}
ImageFit::Horizontal => {
walk.height = Size::Fixed(rect.size.x / aspect);
}
ImageFit::Vertical => {
walk.width = Size::Fixed(rect.size.y * aspect);
}
ImageFit::Smallest => {
let walk_height = rect.size.x / aspect;
if walk_height > rect.size.y {
walk.width = Size::Fixed(rect.size.y * aspect);
}
else {
walk.height = Size::Fixed(walk_height);
}
}
ImageFit::Biggest => {
let walk_height = rect.size.x / aspect;
if walk_height < rect.size.y {
walk.width = Size::Fixed(rect.size.y * aspect);
}
else {
walk.height = Size::Fixed(walk_height);
}
}
}
self.draw_bg.draw_walk(cx, walk);
DrawStep::done()
}
}