counter_button.rs 3.2 KB

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