1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
2 | // SPDX-License-Identifier: MIT |
3 | |
4 | #[allow (dead_code)] |
5 | // ANCHOR: tiles |
6 | fn main() { |
7 | use slint::Model; |
8 | |
9 | let main_window = MainWindow::new().unwrap(); |
10 | |
11 | // Fetch the tiles from the model |
12 | let mut tiles: Vec<TileData> = main_window.get_memory_tiles().iter().collect(); |
13 | // Duplicate them to ensure that we have pairs |
14 | tiles.extend(iter:tiles.clone()); |
15 | |
16 | // Randomly mix the tiles |
17 | use rand::seq::SliceRandom; |
18 | let mut rng: ThreadRng = rand::thread_rng(); |
19 | tiles.shuffle(&mut rng); |
20 | |
21 | // Assign the shuffled Vec to the model property |
22 | let tiles_model: Rc> = std::rc::Rc::new(slint::VecModel::from(tiles)); |
23 | main_window.set_memory_tiles(tiles_model.into()); |
24 | |
25 | main_window.run().unwrap(); |
26 | } |
27 | |
28 | // ANCHOR_END: tiles |
29 | slint::slint! { |
30 | struct TileData { |
31 | image: image, |
32 | image_visible: bool, |
33 | solved: bool, |
34 | } |
35 | |
36 | component MemoryTile inherits Rectangle { |
37 | callback clicked; |
38 | in property <bool> open_curtain; |
39 | in property <bool> solved; |
40 | in property <image> icon; |
41 | |
42 | height: 64px; |
43 | width: 64px; |
44 | background: solved ? #34CE57 : #3960D5; |
45 | animate background { duration: 800ms; } |
46 | |
47 | Image { |
48 | source: icon; |
49 | width: parent.width; |
50 | height: parent.height; |
51 | } |
52 | |
53 | // Left curtain |
54 | Rectangle { |
55 | background: #193076; |
56 | width: open_curtain ? 0px : (parent.width / 2); |
57 | height: parent.height; |
58 | animate width { duration: 250ms; easing: ease-in; } |
59 | } |
60 | |
61 | // Right curtain |
62 | Rectangle { |
63 | background: #193076; |
64 | x: open_curtain ? parent.width : (parent.width / 2); |
65 | width: open_curtain ? 0px : (parent.width / 2); |
66 | height: parent.height; |
67 | animate width { duration: 250ms; easing: ease-in; } |
68 | animate x { duration: 250ms; easing: ease-in; } |
69 | } |
70 | |
71 | TouchArea { |
72 | clicked => { |
73 | // Delegate to the user of this element |
74 | root.clicked(); |
75 | } |
76 | } |
77 | } |
78 | |
79 | export component MainWindow inherits Window { |
80 | width: 326px; |
81 | height: 326px; |
82 | |
83 | in-out property <[TileData]> memory_tiles: [ |
84 | { image: @image-url("icons/at.png" ) }, |
85 | { image: @image-url("icons/balance-scale.png" ) }, |
86 | { image: @image-url("icons/bicycle.png" ) }, |
87 | { image: @image-url("icons/bus.png" ) }, |
88 | { image: @image-url("icons/cloud.png" ) }, |
89 | { image: @image-url("icons/cogs.png" ) }, |
90 | { image: @image-url("icons/motorcycle.png" ) }, |
91 | { image: @image-url("icons/video.png" ) }, |
92 | ]; |
93 | for tile[i] in memory_tiles : MemoryTile { |
94 | x: mod(i, 4) * 74px; |
95 | y: floor(i / 4) * 74px; |
96 | width: 64px; |
97 | height: 64px; |
98 | icon: tile.image; |
99 | open_curtain: tile.image_visible || tile.solved; |
100 | // propagate the solved status from the model to the tile |
101 | solved: tile.solved; |
102 | clicked => { |
103 | tile.image_visible = !tile.image_visible; |
104 | } |
105 | } |
106 | } |
107 | } |
108 | |