rpgx_dioxus/components/grid.rs
1use std::any::Any;
2
3use dioxus::prelude::*;
4use rpgx::{engine::Engine, library::Library, prelude::RPGXError};
5
6#[derive(PartialEq, Props, Clone)]
7pub struct GridProps {
8 pub engine: Signal<Engine>,
9 pub library: Signal<Library<Box<dyn Any>>>,
10 pub square_size: u32,
11 pub onclick: EventHandler<Result<rpgx::prelude::Rect, RPGXError>>,
12}
13
14#[allow(non_snake_case)]
15pub fn Grid(props: GridProps) -> Element {
16 let engine = props.engine.read();
17 let get_background = |texture_id: u32| {
18 if let Some(asset) = props
19 .library
20 .read()
21 .get_by_id(texture_id)
22 .and_then(|boxed| boxed.downcast_ref::<String>())
23 {
24 format!("background-image: url({}); background-size: cover;", asset)
25 } else {
26 "background-size: cover;".to_string()
27 }
28 };
29 if let Some(scene) = engine.get_active_scene() {
30 rsx! {
31 {
32 scene
33 .map
34 .layers
35 .iter()
36 .flat_map(|layer| {
37 layer
38 .masks
39 .iter()
40 .flat_map(move |mask| {
41 let mask_texture = mask.get_texture();
42 let background = if let Some(texture_id) = mask_texture {
43 get_background(texture_id)
44 } else {
45 "background-size: cover;".to_string()
46 };
47 mask.tiles
48 .iter()
49 .flat_map(move |tile| {
50 let x = tile.origin.x;
51 let y = tile.origin.y;
52
53 let base_style = format!(
54 "{background} \
55 position: absolute; \
56 left: {}px; \
57 top: {}px; \
58 width: {}px; \
59 height: {}px; \
60 border: solid 1px rgba(255,255,255,0.1); \
61 z-index: {}; \
62 pointer-events: {}; \
63 cursor: pointer;",
64 x * props.square_size,
65 y * props.square_size,
66 tile.shape.width * props.square_size,
67 tile.shape.height * props.square_size,
68 layer.z,
69 "auto"
70 );
71
72 let onclick_tile = {
73 let tile = tile.clone();
74 move |_| {
75 println!("onclick_tile");
76 let _ = props.onclick.call(Ok(tile.clone()));
77 }
78 };
79
80 let library = props.library.read();
81 rsx! {
82 div {
83 class: "layer-tile",
84 style: "{base_style}",
85 onclick: onclick_tile,
86 {
87 mask
88 .get_render()
89 .and_then(|id| {
90 println!(
91 "Rendering custom VNode from library {:?}",
92 library.get_by_id(id),
93 );
94 let f = library.get_by_id(id)?.downcast_ref::<Box<dyn Fn() -> VNode>>()?;
95 Some(f())
96 })
97 .unwrap_or(rsx! {}.unwrap())
98 }
99 }
100 }
101 })
102 })
103 .collect::<Vec<_>>()
104 })
105 }
106 }
107 } else {
108 rsx! {
109 div {}
110 }
111 }
112}