1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#![allow(unused_imports)]
use crate::*;
use pax_engine::api::{Click, EasingCurve, Event};
use pax_engine::*;
use pax_runtime::api::NodeContext;

#[pax]
#[engine_import_path("pax_engine")]
#[file("layout/carousel.pax")]
pub struct Carousel {
    pub ticks: Property<usize>,
    pub cell_specs: Property<Vec<CarouselCell>>,
    pub current_cell: Property<usize>,
    pub current_cell_on_change: Property<bool>,
    pub transition: Property<f64>,
}

#[pax]
#[engine_import_path("pax_engine")]
pub struct CarouselCell {
    pub is_active: bool,
    pub x_percent: f64,
}

impl Carousel {
    pub fn on_mount(&mut self, ctx: &NodeContext) {
        let slot_children_count = ctx.slot_children_count.clone();
        let current_cell = self.current_cell.clone();
        let transition = self.transition.clone();

        let deps = [
            slot_children_count.untyped(),
            current_cell.untyped(),
            transition.untyped(),
        ];

        self.cell_specs.replace_with(Property::computed(
            move || {
                let slot_children_count = slot_children_count.get();
                let current_cell = current_cell.get();
                let transition = transition.get();

                let mut cell_specs = vec![];
                for i in 0..slot_children_count {
                    //let is_active = (i as isize) >= (current_cell as isize) - 1 && (i as isize) <= (current_cell as isize) + 1;
                    let is_active = true;

                    let x_percent = 50.0 + ((i as f64 * 100.0) - transition);

                    cell_specs.push(CarouselCell {
                        is_active,
                        x_percent,
                    });
                }

                cell_specs
            },
            &deps,
        ));

        let current_cell = self.current_cell.clone();
        let transition = self.transition.clone();
        let deps = [current_cell.untyped()];

        self.current_cell_on_change.replace_with(Property::computed(
            move || {
                let current_cell = current_cell.get();
                transition.ease_to(current_cell as f64 * 100.0, 60, EasingCurve::OutQuad);
                false
            },
            &deps,
        ));
    }

    pub fn update(&mut self, _ctx: &NodeContext) {
        self.current_cell_on_change.get();
    }

    pub fn increment(&mut self, ctx: &NodeContext, _args: Event<Click>) {
        let current_cell = self.current_cell.get();
        let children_count = ctx.slot_children_count.get();
        self.current_cell.set((current_cell + 1) % children_count);
    }

    pub fn decrement(&mut self, ctx: &NodeContext, _args: Event<Click>) {
        let current_cell = self.current_cell.get();
        let children_count = ctx.slot_children_count.get();
        if current_cell != 0 {
            self.current_cell.set((current_cell - 1) % children_count);
        } else {
            self.current_cell.set(children_count - 1);
        }
    }
}