1extern crate gl;
6extern crate image;
7extern crate keyframe;
8
9use self::gl::types::*;
10use cgmath::{Deg, Matrix, Matrix4, SquareMatrix, Vector3};
11use image::DynamicImage;
12use std::ffi::CStr;
13use std::mem;
14use std::os::raw::c_void;
15use std::path::Path;
16use std::ptr;
17
18use stretch::{
19 node::{Node, Stretch},
20 style::*,
21};
22
23use crate::animation::Animation;
24use crate::font::FontRenderer;
25
26#[repr(i32)]
27#[derive(Copy, Clone, Debug, PartialEq)]
28pub enum Key {
29 Space = 32,
30 Enter = 36,
31 Tab = 48,
32 Backspace = 51,
33 Escape = 53,
34 Right = 262,
35 Left = 263,
36 Down = 264,
37 Up = 265,
38}
39
40#[derive(Copy, Clone, Debug)]
41pub enum LayoutMode {
42 UserDefine,
43 Flex,
44}
45
46macro_rules! c_str {
47 ($literal:expr) => {
48 CStr::from_bytes_with_nul_unchecked(concat!($literal, "\0").as_bytes())
49 };
50}
51
52pub struct RALayer {
53 pub name: String,
54 pub x: i32,
55 pub y: i32,
56 pub z: f32,
57 pub width: u32,
58 pub height: u32,
59 pub anchor_x: f32,
60 pub anchor_y: f32,
61 pub scale_x: f32,
62 pub scale_y: f32,
63 pub rotation: i32,
64 pub visible: bool,
65 color: [f32; 3],
66 pub opacity: f32, pub image_path: String,
68 pub sub_layer_list: Vec<RALayer>,
69 vertex_array_obj: gl::types::GLuint,
70 texture: gl::types::GLuint,
71 pub animated: bool,
72 pub animation: Option<Animation>,
73 animations: std::collections::HashMap<String, Animation>, event_handler: Option<Box<dyn EventHandler>>,
75 layout: Option<Box<dyn Layout>>,
76 focused_sub_layer: usize,
77 focused: bool,
78 pub needs_update: bool,
79 pub node: Option<Node>, pub style: Option<Style>, }
82
83pub trait EventHandler {
84 fn key_focus_in(&mut self, layer: &mut RALayer);
85 fn key_focus_out(&mut self, layer: &mut RALayer);
86 fn key_down(&mut self, key: Key, layer: &mut RALayer);
87}
88
89pub trait Layout {
90 fn layout_sub_layers(
91 &mut self,
92 layer: &mut RALayer,
93 parent_layer: Option<&RALayer>,
94 stretch: &mut Option<Stretch>,
95 );
96 fn update_layout(&mut self, layer: &mut RALayer, stretch: &mut Option<Stretch>);
97 fn finalize(&mut self);
98}
99
100impl RALayer {
101 pub fn new(name: String, w: u32, h: u32, event_handler: Option<Box<dyn EventHandler>>) -> Self {
102 let mut layer = RALayer {
103 name: name,
104 x: 0,
105 y: 0,
106 z: 0.0,
107 width: w,
108 height: h,
109 anchor_x: 0.5,
110 anchor_y: 0.5,
111 scale_x: 1.0,
112 scale_y: 1.0,
113 rotation: 0,
114 visible: true,
115 color: [1.0, 1.0, 1.0],
116 opacity: 1.0,
117 image_path: "".to_string(),
118 sub_layer_list: Vec::new(),
119 vertex_array_obj: gl::types::GLuint::default(),
120 texture: gl::types::GLuint::default(),
121 animated: false,
122 animation: None,
123 animations: std::collections::HashMap::new(),
124 event_handler: event_handler,
125 layout: None,
126 focused_sub_layer: 0,
127 focused: false,
128 needs_update: true,
129 node: None,
130 style: None,
131 };
132 layer.init_gl();
133
134 layer
135 }
136
137 pub fn init_gl(&mut self) {
138 #[cfg(test)]
140 {
141 return;
142 }
143
144 #[cfg(not(test))]
145 unsafe {
146 let (mut vertex_array_buffer, mut elem_array_buffer) = (0, 0);
147 let vertices: [f32; 20] = [
148 self.width as f32,
150 self.height as f32,
151 0.0,
152 1.0,
153 1.0, self.width as f32,
155 0.0,
156 0.0,
157 1.0,
158 0.0, 0.0,
160 0.0,
161 0.0,
162 0.0,
163 0.0, 0.0,
165 self.height as f32,
166 0.0,
167 0.0,
168 1.0, ];
170 let indices = [
171 0, 1, 3, 1, 2, 3, ];
174
175 gl::GenVertexArrays(1, &mut self.vertex_array_obj);
176 gl::BindVertexArray(self.vertex_array_obj);
177
178 gl::GenBuffers(1, &mut vertex_array_buffer);
180 gl::BindBuffer(gl::ARRAY_BUFFER, vertex_array_buffer);
181 gl::BufferData(
182 gl::ARRAY_BUFFER,
183 (vertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
184 &vertices[0] as *const f32 as *const c_void,
185 gl::STATIC_DRAW,
186 );
187 gl::GenBuffers(1, &mut elem_array_buffer);
189 gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, elem_array_buffer);
190 gl::BufferData(
191 gl::ELEMENT_ARRAY_BUFFER,
192 (indices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
193 &indices[0] as *const i32 as *const c_void,
194 gl::STATIC_DRAW,
195 );
196
197 let stride = 5 * mem::size_of::<GLfloat>() as GLsizei;
198 gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());
200 gl::EnableVertexAttribArray(0);
201 }
202 }
203
204 pub fn set_color(&mut self, r: f32, g: f32, b: f32) {
205 self.color[0] = r;
206 self.color[1] = g;
207 self.color[2] = b;
208 }
209
210 pub fn set_text(&mut self, text: &str) {
211 let mut font_renderer: FontRenderer = FontRenderer::new("fonts/DejaVuSans.ttf".to_string());
212 let image = font_renderer.render(text);
213 let dynamic_image = DynamicImage::ImageRgba8(image);
214
215 dynamic_image.save("temp.png").unwrap();
216
217 self.image_path = "temp".to_string();
218 let stride = 5 * mem::size_of::<GLfloat>() as GLsizei;
219
220 unsafe {
221 gl::VertexAttribPointer(
223 1,
224 2,
225 gl::FLOAT,
226 gl::FALSE,
227 stride,
228 (3 * mem::size_of::<GLfloat>()) as *const c_void,
229 );
230 gl::EnableVertexAttribArray(1);
231
232 gl::GenTextures(1, &mut self.texture);
234 gl::BindTexture(gl::TEXTURE_2D, self.texture);
235 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32);
237 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as i32);
238 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
240 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
241
242 self.width = dynamic_image.width();
243 self.height = dynamic_image.height();
244
245 println!("width: {}, height: {}", self.width, self.height);
246
247 let to_rgba = dynamic_image.to_rgba8();
250 let data = to_rgba.into_raw();
251 gl::TexImage2D(
252 gl::TEXTURE_2D,
253 0,
254 gl::RGBA as i32,
255 self.width as i32,
256 self.height as i32,
257 0,
258 gl::RGBA,
259 gl::UNSIGNED_BYTE,
260 data.as_ptr() as *const c_void,
261 );
262 gl::GenerateMipmap(gl::TEXTURE_2D);
263 gl::BindTexture(gl::TEXTURE_2D, 0);
265 }
266 }
267
268 pub fn set_image(&mut self, path: String) {
269 self.image_path = path;
270
271 if !self.image_path.is_empty() {
272 let stride = 5 * mem::size_of::<GLfloat>() as GLsizei;
273 unsafe {
274 gl::VertexAttribPointer(
276 1,
277 2,
278 gl::FLOAT,
279 gl::FALSE,
280 stride,
281 (3 * mem::size_of::<GLfloat>()) as *const c_void,
282 );
283 gl::EnableVertexAttribArray(1);
284
285 gl::GenTextures(1, &mut self.texture);
287 gl::BindTexture(gl::TEXTURE_2D, self.texture);
288 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32);
290 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as i32);
291 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32);
293 gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32);
294
295 match image::open(&Path::new(&self.image_path)) {
296 Ok(img) => {
297 let to_rgba = img.to_rgba8();
298 let data = to_rgba.into_vec();
299 gl::TexImage2D(
300 gl::TEXTURE_2D,
301 0,
302 gl::RGB as i32,
303 img.width() as i32,
304 img.height() as i32,
305 0,
306 gl::RGBA,
307 gl::UNSIGNED_BYTE,
308 &data[0] as *const u8 as *const c_void,
309 );
310 gl::GenerateMipmap(gl::TEXTURE_2D);
311 }
312 Err(err) => println!("Fail to load a image {:?}", err),
313 }
314 }
315 }
316 }
317
318 pub fn set_layout(&mut self, layout: Option<Box<dyn Layout>>) {
319 self.layout = layout;
320 }
321
322 pub fn set_animation(&mut self, animation: Option<Animation>) {
323 self.animation = animation;
324 }
325
326 pub fn set_style(&mut self, style: Style) {
327 self.style = Some(style);
328 }
329
330 pub fn set_visible(&mut self, visible: bool) {
331 self.visible = visible;
332 }
333
334 pub fn animate(&mut self) {
340 if let Some(mut animation) = self.animation.take() {
342 animation.run(self);
343 self.animation = Some(animation);
344 }
345
346 let mut animations = std::mem::take(&mut self.animations);
349 for (_key, animation) in animations.iter_mut() {
350 animation.run(self);
351 }
352 self.animations = animations;
354
355 for sub_layer in self.sub_layer_list.iter_mut() {
356 sub_layer.animate();
357 }
358 }
359
360 pub fn select_next_sub_layer(&mut self) {
361 if self.sub_layer_list.is_empty() {
362 return;
363 }
364 if self.focused_sub_layer < self.sub_layer_list.len() - 1 {
366 let prev_focused_sub_layer = self.focused_sub_layer;
367 self.focused_sub_layer += 1;
368 self.sub_layer_list[self.focused_sub_layer].set_focus(true);
369 self.sub_layer_list[prev_focused_sub_layer].set_focus(false);
370 }
371 }
372
373 pub fn select_prev_sub_layer(&mut self) {
374 if self.sub_layer_list.is_empty() {
375 return;
376 }
377 if self.focused_sub_layer == 0 {
379 return;
380 }
381 let prev_focused_sub_layer = self.focused_sub_layer;
382 self.focused_sub_layer -= 1;
383 self.sub_layer_list[self.focused_sub_layer].set_focus(true);
384 self.sub_layer_list[prev_focused_sub_layer].set_focus(false);
385 }
386
387 pub fn set_focus(&mut self, focused: bool) {
388 self.focused = focused;
389 if let Some(mut event_handler) = self.event_handler.take() {
390 if self.focused {
393 event_handler.key_focus_in(self);
394 } else {
395 event_handler.key_focus_out(self);
396 }
397 self.event_handler = Some(event_handler);
398 }
399 }
400
401 pub fn handle_input(&mut self, key: Key) {
402 for sub_layer in self.sub_layer_list.iter_mut() {
403 if sub_layer.focused {
404 sub_layer.handle_input(key);
405 }
406 }
407 if let Some(mut event_handler) = self.event_handler.take() {
408 event_handler.key_down(key, self);
409 self.event_handler = Some(event_handler);
410 }
411 }
412
413 pub fn layout_sub_layers(&mut self, parent_layer: Option<&RALayer>, stretch: &mut Option<Stretch>) {
414 if let Some(mut layout) = self.layout.take() {
415 layout.layout_sub_layers(self, parent_layer, stretch);
416 self.layout = Some(layout); }
418
419 let mut sub_layer_list = std::mem::replace(&mut self.sub_layer_list, Vec::new());
421
422 for sub_layer in &mut sub_layer_list {
424 sub_layer.layout_sub_layers(Some(self), stretch);
426 }
427
428 self.sub_layer_list = sub_layer_list;
430 }
431
432 pub fn update_layout(&mut self, stretch: &mut Option<Stretch>) {
433 if let Some(mut layout) = self.layout.take() {
434 layout.update_layout(self, stretch);
435 self.layout = Some(layout); }
437
438 for sub_layer in self.sub_layer_list.iter_mut() {
439 sub_layer.update_layout(stretch);
440 }
441 }
442
443 pub fn finalize_layout(&mut self) {
444 if let Some(ref mut layout) = self.layout {
445 layout.finalize();
446 }
447 }
448
449 pub fn model_matrix(&self) -> Matrix4<f32> {
450 let mut transform: Matrix4<f32> = Matrix4::identity();
451 transform = transform
452 * Matrix4::<f32>::from_translation(Vector3::new(self.x as f32, self.y as f32, self.z as f32));
453
454 transform = transform
457 * Matrix4::<f32>::from_translation(Vector3::new(
458 self.width as f32 * self.anchor_x,
459 self.height as f32 * self.anchor_y,
460 0.0,
461 ));
462
463 if self.rotation != 0 {
464 transform = transform * Matrix4::<f32>::from_angle_z(Deg(self.rotation as f32));
465 }
466
467 transform = transform * Matrix4::from_nonuniform_scale(self.scale_x, self.scale_y, 0.0);
468
469 transform = transform
471 * Matrix4::<f32>::from_translation(Vector3::new(
472 -(self.width as f32 * self.anchor_x),
473 -(self.height as f32 * self.anchor_y),
474 0.0,
475 ));
476
477 transform
478 }
479
480 pub fn render(
481 &mut self,
482 shader_program: GLuint,
483 parent_model_matrix: Option<&Matrix4<f32>>,
484 projection: &Matrix4<f32>,
485 ) {
486 if !self.visible {
487 return;
488 }
489
490 let mut transform: Matrix4<f32> = self.model_matrix();
491 if let Some(parent_model_matrix) = parent_model_matrix {
492 transform = transform * parent_model_matrix;
493 }
494
495 unsafe {
496 gl::UseProgram(shader_program);
497 let loc_color = gl::GetUniformLocation(shader_program, c_str!("color").as_ptr());
498 let loc_transform = gl::GetUniformLocation(shader_program, c_str!("transform").as_ptr());
499 let loc_projection = gl::GetUniformLocation(shader_program, c_str!("projection").as_ptr());
500 let loc_use_texture = gl::GetUniformLocation(shader_program, c_str!("useTexture").as_ptr());
501
502 gl::Uniform4f(loc_color, self.color[0], self.color[1], self.color[2], self.opacity);
503 gl::UniformMatrix4fv(loc_transform, 1, gl::FALSE, transform.as_ptr());
504 gl::UniformMatrix4fv(loc_projection, 1, gl::FALSE, projection.as_ptr());
505
506 if !self.image_path.is_empty() {
507 gl::BindTexture(gl::TEXTURE_2D, self.texture);
508 gl::Uniform1i(loc_use_texture, 1);
509 } else {
510 gl::Uniform1i(loc_use_texture, 0);
511 }
512
513 gl::BindVertexArray(self.vertex_array_obj);
514 gl::DrawElements(gl::TRIANGLES, 6, gl::UNSIGNED_INT, ptr::null());
515 }
516
517 for sub_layer in self.sub_layer_list.iter_mut() {
518 if sub_layer.focused == false {
519 sub_layer.render(shader_program, Some(&transform), projection);
520 }
521 }
522
523 if !self.sub_layer_list.is_empty() {
525 self.sub_layer_list[self.focused_sub_layer].render(
526 shader_program,
527 Some(&transform),
528 projection,
529 );
530 }
531 }
532
533 pub fn add_sub_layer(&mut self, layer: RALayer) {
534 self.sub_layer_list.push(layer);
535 }
536
537 pub fn set_position(&mut self, x: i32, y: i32) {
541 self.x = x;
542 self.y = y;
543 }
544
545 pub fn position(&self) -> (i32, i32) {
547 (self.x, self.y)
548 }
549
550 pub fn set_bounds(&mut self, width: u32, height: u32) {
552 self.width = width;
553 self.height = height;
554 }
555
556 pub fn bounds(&self) -> (u32, u32) {
558 (self.width, self.height)
559 }
560
561 pub fn set_opacity(&mut self, opacity: f32) {
563 self.opacity = opacity.max(0.0).min(1.0);
564 }
565
566 pub fn set_background_color(&mut self, r: f32, g: f32, b: f32) {
568 self.set_color(r, g, b);
569 }
570
571 pub fn background_color(&self) -> (f32, f32, f32) {
573 (self.color[0], self.color[1], self.color[2])
574 }
575
576 pub fn add_animation(&mut self, animation: Animation, key: Option<&str>) {
578 if let Some(key_str) = key {
579 self.animations.insert(key_str.to_string(), animation);
580 } else {
581 self.animation = Some(animation);
583 }
584 }
585
586 pub fn remove_all_animations(&mut self) {
588 self.animations.clear();
589 self.animation = None;
590 }
591
592 pub fn remove_animation(&mut self, key: &str) {
594 self.animations.remove(key);
595 }
596
597 pub fn add_sublayer(&mut self, layer: RALayer) {
599 self.add_sub_layer(layer);
600 }
601
602 pub fn sublayers(&self) -> &Vec<RALayer> {
604 &self.sub_layer_list
605 }
606
607 pub fn sublayers_mut(&mut self) -> &mut Vec<RALayer> {
609 &mut self.sub_layer_list
610 }
611}
612
613#[cfg(test)]
614mod tests {
615 use super::*;
616 use crate::animation::{Animation, EasingFunction};
617
618 #[test]
619 fn test_position_api() {
620 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
621 layer.set_position(50, 75);
622 let (x, y) = layer.position();
623 assert_eq!(x, 50);
624 assert_eq!(y, 75);
625 }
626
627 #[test]
628 fn test_bounds_api() {
629 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
630 layer.set_bounds(200, 150);
631 let (w, h) = layer.bounds();
632 assert_eq!(w, 200);
633 assert_eq!(h, 150);
634 }
635
636 #[test]
637 fn test_opacity_api() {
638 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
639 assert_eq!(layer.opacity, 1.0);
640
641 layer.set_opacity(0.5);
642 assert_eq!(layer.opacity, 0.5);
643
644 layer.set_opacity(1.5);
646 assert_eq!(layer.opacity, 1.0);
647
648 layer.set_opacity(-0.5);
649 assert_eq!(layer.opacity, 0.0);
650 }
651
652 #[test]
653 fn test_background_color_api() {
654 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
655 layer.set_background_color(0.5, 0.6, 0.7);
656 let (r, g, b) = layer.background_color();
657 assert_eq!(r, 0.5);
658 assert_eq!(g, 0.6);
659 assert_eq!(b, 0.7);
660 }
661
662 #[test]
663 fn test_add_animation_with_key() {
664 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
665 let mut animation = Animation::with_key_path("position.x");
666 animation.duration = 2.0;
667 animation.timing_function = Some(EasingFunction::Linear);
668
669 layer.add_animation(animation, Some("moveX"));
670 assert_eq!(layer.animations.len(), 1);
671 assert!(layer.animations.contains_key("moveX"));
672 }
673
674 #[test]
675 fn test_remove_animation() {
676 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
677 let animation1 = Animation::with_key_path("position.x");
678 let animation2 = Animation::with_key_path("opacity");
679
680 layer.add_animation(animation1, Some("anim1"));
681 layer.add_animation(animation2, Some("anim2"));
682 assert_eq!(layer.animations.len(), 2);
683
684 layer.remove_animation("anim1");
685 assert_eq!(layer.animations.len(), 1);
686 assert!(!layer.animations.contains_key("anim1"));
687 assert!(layer.animations.contains_key("anim2"));
688 }
689
690 #[test]
691 fn test_remove_all_animations() {
692 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
693 let animation1 = Animation::with_key_path("position.x");
694 let animation2 = Animation::with_key_path("opacity");
695 let animation3 = Animation::new();
696
697 layer.add_animation(animation1, Some("anim1"));
698 layer.add_animation(animation2, Some("anim2"));
699 layer.set_animation(Some(animation3));
700
701 assert_eq!(layer.animations.len(), 2);
702 assert!(layer.animation.is_some());
703
704 layer.remove_all_animations();
705 assert_eq!(layer.animations.len(), 0);
706 assert!(layer.animation.is_none());
707 }
708
709 #[test]
710 fn test_sublayers_api() {
711 let mut parent = RALayer::new("parent".to_string(), 200, 200, None);
712 let child1 = RALayer::new("child1".to_string(), 50, 50, None);
713 let child2 = RALayer::new("child2".to_string(), 50, 50, None);
714
715 parent.add_sublayer(child1);
716 parent.add_sublayer(child2);
717
718 let sublayers = parent.sublayers();
719 assert_eq!(sublayers.len(), 2);
720 assert_eq!(sublayers[0].name, "child1");
721 assert_eq!(sublayers[1].name, "child2");
722 }
723
724 #[test]
725 fn test_backward_compatibility() {
726 let mut layer = RALayer::new("test".to_string(), 100, 100, None);
727
728 layer.x = 50;
730 layer.y = 75;
731 assert_eq!(layer.x, 50);
732 assert_eq!(layer.y, 75);
733
734 let mut animation = Animation::new();
736 animation.apply_translation_x(0, 100, 1.0, EasingFunction::Linear);
737 layer.set_animation(Some(animation));
738
739 assert!(layer.animation.is_some());
740 }
741}