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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::any::Any;
use dioxus::prelude::*;
use rpgx::{engine::Engine, library::Library, prelude::RPGXError};
#[derive(PartialEq, Props, Clone)]
pub struct GridProps {
pub engine: Signal<Engine>,
pub library: Signal<Library<Box<dyn Any>>>,
pub square_size: u32,
pub onclick: EventHandler<Result<rpgx::prelude::Rect, RPGXError>>,
}
#[allow(non_snake_case)]
pub fn Grid(props: GridProps) -> Element {
let engine = props.engine.read();
let get_background = |texture_id: u32| {
if let Some(asset) = props
.library
.read()
.get_by_id(texture_id)
.and_then(|boxed| boxed.downcast_ref::<String>())
{
format!("background-image: url({}); background-size: cover;", asset)
} else {
"background-size: cover;".to_string()
}
};
if let Some(scene) = engine.get_active_scene() {
rsx! {
{
scene
.map
.layers
.iter()
.flat_map(|layer| {
layer
.masks
.iter()
.flat_map(move |mask| {
let mask_texture = mask.get_texture();
let background = if let Some(texture_id) = mask_texture {
get_background(texture_id)
} else {
"background-size: cover;".to_string()
};
mask.tiles
.iter()
.flat_map(move |tile| {
let x = tile.origin.x;
let y = tile.origin.y;
let base_style = format!(
"{background} \
position: absolute; \
left: {}px; \
top: {}px; \
width: {}px; \
height: {}px; \
border: solid 1px rgba(255,255,255,0.1); \
z-index: {}; \
pointer-events: {}; \
cursor: pointer;",
x * props.square_size,
y * props.square_size,
tile.shape.width * props.square_size,
tile.shape.height * props.square_size,
layer.z,
"auto"
);
let onclick_tile = {
let tile = tile.clone();
move |_| {
println!("onclick_tile");
let _ = props.onclick.call(Ok(tile.clone()));
}
};
let library = props.library.read();
rsx! {
div {
class: "layer-tile",
style: "{base_style}",
onclick: onclick_tile,
{
mask
.get_render()
.and_then(|id| {
println!(
"Rendering custom VNode from library {:?}",
library.get_by_id(id),
);
let f = library.get_by_id(id)?.downcast_ref::<Box<dyn Fn() -> VNode>>()?;
Some(f())
})
.unwrap_or(rsx! {}.unwrap())
}
}
}
})
})
.collect::<Vec<_>>()
})
}
}
} else {
rsx! {
div {}
}
}
}