makepad_widgets/
image_blend.rs1use crate::{
2 makepad_derive_widget::*,
3 image_cache::*,
4 makepad_draw::*,
5 widget::*,
6 image::Image,
7};
8use std::path::Path;
9
10live_design!{
11 link widgets;
12 use link::widgets::*;
13 use link::shaders::*;
14
15 pub ImageBlendBase = {{ImageBlend}} {}
16
17 pub ImageBlend = <ImageBlendBase> {
18 image_a: <Image>{
19 fit: Smallest
20 width: Fill,
21 height: Fill
22 },
23 image_b: <Image>{
24 fit: Smallest
25 width: Fill,
26 height: Fill
27 },
28 width: Fill,
29 height: Fill,
30 flow: Overlay
31 align: {x: 0.5, y: 0.5}
32 animator: {
33 blend = {
34 default: zero,
35 zero = {
36 from: {all: Forward {duration: 0.525}}
37 apply: {
38 image_b:{draw_bg:{opacity: 0.0}}
39 }
40 }
41 one = {
42 from: {
43 all: Forward {duration: 0.525}
44 }
45 apply: {
46 image_b:{draw_bg:{opacity: 1.0}}
47 }
48 }
49 }
50 }
51 }
52
53}
54
55#[derive(Live, Widget, LiveHook)]
56pub struct ImageBlend {
57 #[animator] animator:Animator,
58 #[walk] walk: Walk,
59 #[layout] layout: Layout,
60 #[redraw] #[live] image_a: Image,
61 #[redraw] #[live] image_b: Image,
62}
63
64impl ImageCacheImpl for ImageBlend {
65 fn get_texture(&self, id:usize) -> &Option<Texture> {
66 if id == 0 {
67 self.image_a.get_texture(0)
68 }
69 else{
70 self.image_b.get_texture(0)
71 }
72 }
73
74 fn set_texture(&mut self, texture: Option<Texture>, id:usize) {
75 if id == 0{
76 self.image_a.set_texture(texture, 0)
77 }
78 else{
79 self.image_b.set_texture(texture, 0)
80 }
81 }
82}
83
84impl Widget for ImageBlend {
85 fn draw_walk(&mut self, cx: &mut Cx2d, _scope: &mut Scope, walk: Walk) -> DrawStep {
86 self.draw_walk(cx, walk)
87 }
88
89 fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
90 if self.animator_handle_event(cx, event).must_redraw() {
91 self.image_a.redraw(cx);
92 self.image_b.redraw(cx);
93 }
94 self.image_a.handle_event(cx, event, scope);
95 self.image_b.handle_event(cx, event, scope);
96 }
97}
98
99impl ImageBlend {
100
101 pub fn draw_walk(&mut self, cx: &mut Cx2d, walk: Walk) -> DrawStep {
102 cx.begin_turtle(walk, self.layout);
103 self.image_a.draw_all_unscoped(cx);
104 self.image_b.draw_all_unscoped(cx);
105 cx.end_turtle();
106 DrawStep::done()
107 }
108
109 fn flip_animate(&mut self, cx: &mut Cx)->usize{
110 if self.animator_in_state(cx, id!(blend.one)) {
111 self.animator_play(cx, id!(blend.zero));
112 0
113 }
114 else{
115 self.animator_play(cx, id!(blend.one));
116 1
117 }
118 }
119}
120
121impl ImageBlendRef {
122 pub fn switch_image(&self, cx:&mut Cx) {
123 if let Some(mut inner) = self.borrow_mut() {
124 inner.flip_animate(cx);
125 }
126 }
127 pub fn set_texture(&self, cx:&mut Cx, texture: Option<Texture>) {
128 if let Some(mut inner) = self.borrow_mut() {
129
130 let slot = inner.flip_animate(cx);
131 inner.set_texture(texture, slot);
132 }
133 }
134 pub fn load_image_dep_by_path(&self, cx: &mut Cx, image_path: &str) -> Result<(), ImageError> {
136 if let Some(mut inner) = self.borrow_mut() {
137 inner.load_image_dep_by_path(cx, image_path, 0)
138 } else {
139 Ok(()) }
141 }
142
143 pub fn load_image_file_by_path(&self, cx: &mut Cx, image_path: &Path) -> Result<(), ImageError> {
145 if let Some(mut inner) = self.borrow_mut() {
146 inner.load_image_file_by_path(cx, image_path, 0)
147 } else {
148 Ok(()) }
150 }
151
152 pub fn load_jpg_from_data(&self, cx: &mut Cx, data: &[u8]) -> Result<(), ImageError> {
154 if let Some(mut inner) = self.borrow_mut() {
155 inner.load_jpg_from_data(cx, data, 0)
156 } else {
157 Ok(()) }
159 }
160
161 pub fn load_png_from_data(&self, cx: &mut Cx, data: &[u8]) -> Result<(), ImageError> {
163 if let Some(mut inner) = self.borrow_mut() {
164 inner.load_png_from_data(cx, data, 0)
165 } else {
166 Ok(()) }
168 }
169
170}
171