element.rs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. use dioxus_core::ElementId;
  2. use dioxus_html::{geometry::euclid::Rect, MountedResult, RenderedElementBacking};
  3. use crate::{desktop_context::DesktopContext, query::QueryEngine};
  4. #[derive(Clone)]
  5. /// A mounted element passed to onmounted events
  6. pub struct DesktopElement {
  7. id: ElementId,
  8. webview: DesktopContext,
  9. query: QueryEngine,
  10. }
  11. impl DesktopElement {
  12. pub(crate) fn new(id: ElementId, webview: DesktopContext, query: QueryEngine) -> Self {
  13. Self { id, webview, query }
  14. }
  15. }
  16. impl RenderedElementBacking for DesktopElement {
  17. fn as_any(&self) -> &dyn std::any::Any {
  18. self
  19. }
  20. fn get_client_rect(
  21. &self,
  22. ) -> std::pin::Pin<
  23. Box<
  24. dyn futures_util::Future<
  25. Output = dioxus_html::MountedResult<dioxus_html::geometry::euclid::Rect<f64, f64>>,
  26. >,
  27. >,
  28. > {
  29. let script = format!("return window.interpreter.getClientRect({});", self.id.0);
  30. let fut = self
  31. .query
  32. .new_query::<Option<Rect<f64, f64>>>(&script, self.webview.clone())
  33. .resolve();
  34. Box::pin(async move {
  35. match fut.await {
  36. Ok(Some(rect)) => Ok(rect),
  37. Ok(None) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
  38. Box::new(DesktopQueryError::FailedToQuery),
  39. )),
  40. Err(err) => {
  41. MountedResult::Err(dioxus_html::MountedError::OperationFailed(Box::new(err)))
  42. }
  43. }
  44. })
  45. }
  46. fn scroll_to(
  47. &self,
  48. behavior: dioxus_html::ScrollBehavior,
  49. ) -> std::pin::Pin<Box<dyn futures_util::Future<Output = dioxus_html::MountedResult<()>>>> {
  50. let script = format!(
  51. "return window.interpreter.scrollTo({}, {});",
  52. self.id.0,
  53. serde_json::to_string(&behavior).expect("Failed to serialize ScrollBehavior")
  54. );
  55. let fut = self
  56. .query
  57. .new_query::<bool>(&script, self.webview.clone())
  58. .resolve();
  59. Box::pin(async move {
  60. match fut.await {
  61. Ok(true) => Ok(()),
  62. Ok(false) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
  63. Box::new(DesktopQueryError::FailedToQuery),
  64. )),
  65. Err(err) => {
  66. MountedResult::Err(dioxus_html::MountedError::OperationFailed(Box::new(err)))
  67. }
  68. }
  69. })
  70. }
  71. fn set_focus(
  72. &self,
  73. focus: bool,
  74. ) -> std::pin::Pin<Box<dyn futures_util::Future<Output = dioxus_html::MountedResult<()>>>> {
  75. let script = format!(
  76. "return window.interpreter.setFocus({}, {});",
  77. self.id.0, focus
  78. );
  79. let fut = self
  80. .query
  81. .new_query::<bool>(&script, self.webview.clone())
  82. .resolve();
  83. Box::pin(async move {
  84. match fut.await {
  85. Ok(true) => Ok(()),
  86. Ok(false) => MountedResult::Err(dioxus_html::MountedError::OperationFailed(
  87. Box::new(DesktopQueryError::FailedToQuery),
  88. )),
  89. Err(err) => {
  90. MountedResult::Err(dioxus_html::MountedError::OperationFailed(Box::new(err)))
  91. }
  92. }
  93. })
  94. }
  95. }
  96. #[derive(Debug)]
  97. enum DesktopQueryError {
  98. FailedToQuery,
  99. }
  100. impl std::fmt::Display for DesktopQueryError {
  101. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  102. match self {
  103. DesktopQueryError::FailedToQuery => write!(f, "Failed to query the element"),
  104. }
  105. }
  106. }
  107. impl std::error::Error for DesktopQueryError {}