counter_button.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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 std::rc::Rc;
  10. use std::sync::{Arc, RwLock};
  11. #[derive(Default)]
  12. struct Counter {
  13. count: usize,
  14. counter_id: NodeId,
  15. button_id: NodeId,
  16. }
  17. impl Counter {
  18. fn create(mut root: NodeMut) -> Self {
  19. let mut myself = Self::default();
  20. let root_id = root.id();
  21. let rdom = root.real_dom_mut();
  22. // create the counter
  23. let count = myself.count;
  24. myself.counter_id = rdom
  25. .create_node(NodeType::Text(TextNode::new(count.to_string())))
  26. .id();
  27. let mut button = rdom.create_node(NodeType::Element(ElementNode {
  28. tag: "div".to_string(),
  29. attributes: [
  30. ("display".to_string().into(), "flex".to_string().into()),
  31. (
  32. ("background-color", "style").into(),
  33. format!("rgb({}, {}, {})", count * 10, 0, 0,).into(),
  34. ),
  35. (("width", "style").into(), "100%".to_string().into()),
  36. (("height", "style").into(), "100%".to_string().into()),
  37. (("flex-direction", "style").into(), "row".to_string().into()),
  38. (
  39. ("justify-content", "style").into(),
  40. "center".to_string().into(),
  41. ),
  42. (("align-items", "style").into(), "center".to_string().into()),
  43. ]
  44. .into_iter()
  45. .collect(),
  46. ..Default::default()
  47. }));
  48. button.add_event_listener("click");
  49. button.add_event_listener("wheel");
  50. button.add_child(myself.counter_id);
  51. myself.button_id = button.id();
  52. rdom.get_mut(root_id).unwrap().add_child(myself.button_id);
  53. myself
  54. }
  55. }
  56. impl Driver for Counter {
  57. fn update(&mut self, rdom: &Arc<RwLock<RealDom>>) {
  58. // update the counter
  59. let mut rdom = rdom.write().unwrap();
  60. let mut node = rdom.get_mut(self.button_id).unwrap();
  61. if let NodeTypeMut::Element(mut el) = node.node_type_mut() {
  62. el.set_attribute(
  63. ("background-color", "style"),
  64. format!("rgb({}, {}, {})", self.count * 10, 0, 0,),
  65. );
  66. }
  67. let mut text = rdom.get_mut(self.counter_id).unwrap();
  68. let type_mut = text.node_type_mut();
  69. if let NodeTypeMut::Text(mut text) = type_mut {
  70. *text = self.count.to_string();
  71. }
  72. }
  73. fn handle_event(
  74. &mut self,
  75. _: &Arc<RwLock<RealDom>>,
  76. _: NodeId,
  77. _: &str,
  78. _: Rc<EventData>,
  79. _: bool,
  80. ) {
  81. // when a click or wheel event is fired, increment the counter
  82. self.count += 1;
  83. }
  84. fn poll_async(&mut self) -> std::pin::Pin<Box<dyn futures::Future<Output = ()> + '_>> {
  85. Box::pin(async move { tokio::time::sleep(std::time::Duration::from_millis(1000)).await })
  86. }
  87. }
  88. fn main() {
  89. render(Config::new(), |rdom, _, _| {
  90. let mut rdom = rdom.write().unwrap();
  91. let root = rdom.root_id();
  92. Counter::create(rdom.get_mut(root).unwrap())
  93. })
  94. .unwrap();
  95. }