makepad_widgets/
multi_image.rs1use crate::{
2 makepad_derive_widget::*,
3 image_cache::*,
4 makepad_draw::*,
5 widget::*
6};
7
8live_design!{
9 MultiImageBase = {{MultiImage}} {}
10}
11
12#[derive(Live, Widget)]
13pub struct MultiImage {
14 #[walk] walk: Walk,
15 #[redraw] #[live] draw_bg: DrawQuad,
16 #[live] min_width: i64,
17 #[live] min_height: i64,
18 #[live(1.0)] width_scale: f64,
19 #[live] fit: ImageFit,
20 #[live] source1: LiveDependency,
21 #[live] source2: LiveDependency,
22 #[live] source3: LiveDependency,
23 #[live] source4: LiveDependency,
24 #[rust] textures: [Option<Texture>;4],
25}
26
27impl ImageCacheImpl for MultiImage {
28 fn get_texture(&self, id:usize) -> &Option<Texture> {
29 &self.textures[id]
30 }
31
32 fn set_texture(&mut self, texture: Option<Texture>, id:usize) {
33 self.textures[id] = texture;
34 }
35}
36
37impl LiveHook for MultiImage{
38 fn after_apply(&mut self, cx: &mut Cx, _applyl: &mut Apply, _index: usize, _nodes: &[LiveNode]) {
39 self.lazy_create_image_cache(cx);
40 for (i,source) in [self.source1.clone(), self.source2.clone(), self.source2.clone(), self.source3.clone()].iter().enumerate(){
41 if source.as_str().len()>0 {
42 let _ = self.load_image_dep_by_path(cx, source.as_str(), i);
43 }
44 }
45 }
46}
47
48impl Widget for MultiImage {
49 fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep {
50 self.draw_walk(cx, walk)
51 }
52}
53
54impl MultiImage {
55 pub fn size_in_pixels(&self, cx: &mut Cx) -> Option<(usize, usize)> {
59 self.textures[0].as_ref()
60 .and_then(|t| t.get_format(cx).vec_width_height())
61 }
62
63 pub fn draw_walk(&mut self, cx: &mut Cx2d, mut walk: Walk) -> DrawStep {
64 let rect = cx.peek_walk_turtle(walk);
67 let dpi = cx.current_dpi_factor();
68 for i in 0..self.textures.len(){
69 if let Some(image_texture) = &self.textures[i]{
70 self.draw_bg.draw_vars.set_texture(i, image_texture);
71 }
72 }
73
74 let (width, height) = if let Some(image_texture) = &self.textures[0]{
75 let (width,height) = image_texture.get_format(cx).vec_width_height().unwrap_or((self.min_width as usize, self.min_height as usize));
76 (width as f64 * self.width_scale, height as f64)
77 }
78 else {
79 self.draw_bg.draw_vars.empty_texture(0);
80 (self.min_width as f64 / dpi, self.min_height as f64 / dpi)
81 };
82
83 let aspect = width / height;
84 match self.fit {
85 ImageFit::Size => {
86 walk.width = Size::Fixed(width);
87 walk.height = Size::Fixed(height);
88 }
89 ImageFit::Stretch => {
90 }
91 ImageFit::Horizontal => {
92 walk.height = Size::Fixed(rect.size.x / aspect);
93 }
94 ImageFit::Vertical => {
95 walk.width = Size::Fixed(rect.size.y * aspect);
96 }
97 ImageFit::Smallest => {
98 let walk_height = rect.size.x / aspect;
99 if walk_height > rect.size.y {
100 walk.width = Size::Fixed(rect.size.y * aspect);
101 }
102 else {
103 walk.height = Size::Fixed(walk_height);
104 }
105 }
106 ImageFit::Biggest => {
107 let walk_height = rect.size.x / aspect;
108 if walk_height < rect.size.y {
109 walk.width = Size::Fixed(rect.size.y * aspect);
110 }
111 else {
112 walk.height = Size::Fixed(walk_height);
113 }
114 }
115 }
116
117 self.draw_bg.draw_walk(cx, walk);
118
119 DrawStep::done()
120 }
121}