grid.rs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. use dioxus_html::EventData;
  2. use dioxus_native_core::{
  3. node::TextNode,
  4. prelude::*,
  5. real_dom::{NodeImmutable, NodeTypeMut},
  6. NodeId,
  7. };
  8. use rink::{render, Config, Driver};
  9. use rustc_hash::FxHashSet;
  10. use std::rc::Rc;
  11. use std::sync::{Arc, RwLock};
  12. const SIZE: usize = 20;
  13. #[derive(Default, Clone, Copy)]
  14. struct Node {
  15. container_id: Option<NodeId>,
  16. text_id: Option<NodeId>,
  17. count: usize,
  18. }
  19. struct Test {
  20. node_states: [[Node; SIZE]; SIZE],
  21. dirty: FxHashSet<(usize, usize)>,
  22. }
  23. impl Default for Test {
  24. fn default() -> Self {
  25. Self {
  26. node_states: [[Node {
  27. container_id: None,
  28. text_id: None,
  29. count: 0,
  30. }; SIZE]; SIZE],
  31. dirty: FxHashSet::default(),
  32. }
  33. }
  34. }
  35. impl Test {
  36. fn create(mut root: NodeMut) -> Self {
  37. let mut myself = Self::default();
  38. // Set the root node to be a flexbox with a column direction.
  39. if let NodeTypeMut::Element(mut el) = root.node_type_mut() {
  40. el.set_attribute("display".to_string(), "flex".to_string());
  41. el.set_attribute(("flex-direction", "style"), "column".to_string());
  42. el.set_attribute(("width", "style"), "100%".to_string());
  43. el.set_attribute(("height", "style"), "100%".to_string());
  44. }
  45. let root_id = root.id();
  46. let rdom = root.real_dom_mut();
  47. // create the grid
  48. for (x, row) in myself.node_states.iter_mut().enumerate() {
  49. let row_node = rdom
  50. .create_node(NodeType::Element(ElementNode {
  51. tag: "div".to_string(),
  52. attributes: [
  53. ("display".to_string().into(), "flex".to_string().into()),
  54. (("flex-direction", "style").into(), "row".to_string().into()),
  55. (("width", "style").into(), "100%".to_string().into()),
  56. (("height", "style").into(), "100%".to_string().into()),
  57. ]
  58. .into_iter()
  59. .collect(),
  60. ..Default::default()
  61. }))
  62. .id();
  63. for (y, node) in row.iter_mut().enumerate() {
  64. let count = node.count;
  65. let id = rdom
  66. .create_node(NodeType::Text(TextNode::new(count.to_string())))
  67. .id();
  68. let mut button = rdom.create_node(NodeType::Element(ElementNode {
  69. tag: "div".to_string(),
  70. attributes: [
  71. ("display".to_string().into(), "flex".to_string().into()),
  72. (
  73. ("background-color", "style").into(),
  74. format!("rgb({}, {}, {})", count * 10, 0, (x + y),).into(),
  75. ),
  76. (("width", "style").into(), "100%".to_string().into()),
  77. (("height", "style").into(), "100%".to_string().into()),
  78. (("flex-direction", "style").into(), "row".to_string().into()),
  79. (
  80. ("justify-content", "style").into(),
  81. "center".to_string().into(),
  82. ),
  83. (("align-items", "style").into(), "center".to_string().into()),
  84. ]
  85. .into_iter()
  86. .collect(),
  87. ..Default::default()
  88. }));
  89. button.add_event_listener("click");
  90. button.add_event_listener("wheel");
  91. button.add_child(id);
  92. let button_id = button.id();
  93. rdom.get_mut(row_node).unwrap().add_child(button_id);
  94. node.container_id = Some(button_id);
  95. node.text_id = Some(id);
  96. }
  97. rdom.get_mut(root_id).unwrap().add_child(row_node);
  98. }
  99. myself
  100. }
  101. }
  102. impl Driver for Test {
  103. fn update(&mut self, rdom: &Arc<RwLock<RealDom>>) {
  104. let mut rdom = rdom.write().unwrap();
  105. for (x, y) in self.dirty.drain() {
  106. let node = self.node_states[x][y];
  107. let node_id = node.container_id.unwrap();
  108. let mut container = rdom.get_mut(node_id).unwrap();
  109. if let NodeTypeMut::Element(mut el) = container.node_type_mut() {
  110. el.set_attribute(
  111. ("background-color", "style"),
  112. format!("rgb({}, {}, {})", node.count * 10, 0, (x + y),),
  113. );
  114. }
  115. let text_id = node.text_id.unwrap();
  116. let mut text = rdom.get_mut(text_id).unwrap();
  117. let type_mut = text.node_type_mut();
  118. if let NodeTypeMut::Text(mut text) = type_mut {
  119. *text = node.count.to_string();
  120. }
  121. }
  122. }
  123. fn handle_event(
  124. &mut self,
  125. rdom: &Arc<RwLock<RealDom>>,
  126. id: NodeId,
  127. _: &str,
  128. _: Rc<EventData>,
  129. _: bool,
  130. ) {
  131. let rdom = rdom.read().unwrap();
  132. let node = rdom.get(id).unwrap();
  133. if let Some(parent) = node.parent() {
  134. let child_number = parent
  135. .child_ids()
  136. .iter()
  137. .position(|id| *id == node.id())
  138. .unwrap();
  139. if let Some(parents_parent) = parent.parent() {
  140. let parents_child_number = parents_parent
  141. .child_ids()
  142. .iter()
  143. .position(|id| *id == parent.id())
  144. .unwrap();
  145. self.node_states[parents_child_number][child_number].count += 1;
  146. self.dirty.insert((parents_child_number, child_number));
  147. }
  148. }
  149. }
  150. fn poll_async(&mut self) -> std::pin::Pin<Box<dyn futures::Future<Output = ()> + '_>> {
  151. Box::pin(async move { tokio::time::sleep(std::time::Duration::from_millis(1000)).await })
  152. }
  153. }
  154. fn main() {
  155. render(Config::new(), |rdom, _, _| {
  156. let mut rdom = rdom.write().unwrap();
  157. let root = rdom.root_id();
  158. Test::create(rdom.get_mut(root).unwrap())
  159. })
  160. .unwrap();
  161. }