freya_webview/
component.rs1use freya_core::{
2 events::data::{
3 Event,
4 SizedEventData,
5 },
6 prelude::*,
7};
8
9use crate::{
10 element::webview,
11 lifecycle::WebViewLifecycleEvent,
12 prelude::{
13 WebViewConfig,
14 WebViewId,
15 },
16 registry::WebViewCallback,
17};
18
19#[derive(Clone)]
20pub struct WebView {
21 webview_id: WebViewId,
22 url: String,
23 close_on_drop: bool,
24 on_created: Option<WebViewCallback>,
25 layout: LayoutData,
26}
27
28impl PartialEq for WebView {
29 fn eq(&self, other: &Self) -> bool {
30 self.webview_id == other.webview_id
31 && self.url == other.url
32 && self.close_on_drop == other.close_on_drop
33 && match (&self.on_created, &other.on_created) {
34 (None, None) => true,
35 (Some(a), Some(b)) => std::sync::Arc::ptr_eq(a, b),
36 _ => false,
37 }
38 && self.layout == other.layout
39 }
40}
41
42impl WebView {
43 pub fn new(url: impl Into<String>) -> Self {
44 Self {
45 webview_id: WebViewId::new(),
46 url: url.into(),
47 close_on_drop: true,
48 on_created: None,
49 layout: LayoutData::default(),
50 }
51 }
52
53 pub fn url(mut self, url: impl Into<String>) -> Self {
54 self.url = url.into();
55 self
56 }
57
58 pub fn id(mut self, id: WebViewId) -> Self {
59 self.webview_id = id;
60 self
61 }
62
63 pub fn close_on_drop(mut self, close: bool) -> Self {
65 self.close_on_drop = close;
66 self
67 }
68
69 pub fn on_created(
70 mut self,
71 on_created: impl Fn(wry::WebViewBuilder) -> wry::WebViewBuilder + Send + 'static,
72 ) -> Self {
73 self.on_created = Some(WebViewCallback::new(Box::new(on_created)));
74 self
75 }
76}
77
78impl LayoutExt for WebView {
79 fn get_layout(&mut self) -> &mut LayoutData {
80 &mut self.layout
81 }
82}
83impl ContainerExt for WebView {}
84
85const WEBVIEW_CONTEXT_ERROR: &str = "
86Error: Make sure to register the WebViewPlugin in your LaunchConfig:
87
88LaunchConfig::new()
89 .with_plugin(WebViewPlugin::new())
90";
91
92impl Component for WebView {
93 fn render(&self) -> impl IntoElement {
94 let events = try_consume_root_context::<crate::lifecycle::WebViewEvents>()
95 .expect(WEBVIEW_CONTEXT_ERROR);
96
97 let webview_id = self.webview_id;
98 let url = self.url.clone();
99 let close_on_drop = self.close_on_drop;
100 let on_created = self.on_created.clone();
101
102 let config = WebViewConfig {
103 url: url.clone(),
104 transparent: false,
105 user_agent: None,
106 on_created,
107 };
108
109 use_drop({
110 let events = events.clone();
111 move || {
112 events.lock().unwrap().push(if close_on_drop {
113 WebViewLifecycleEvent::Close { id: webview_id }
114 } else {
115 WebViewLifecycleEvent::Hide { id: webview_id }
116 });
117 }
118 });
119
120 webview(&url)
121 .layout(self.layout.clone())
122 .on_sized(move |event: Event<SizedEventData>| {
123 events.lock().unwrap().push(WebViewLifecycleEvent::Resized {
124 id: webview_id,
125 area: event.area,
126 config: config.clone(),
127 });
128 Platform::get().send(UserEvent::RequestRedraw);
129 })
130 }
131
132 fn render_key(&self) -> DiffKey {
133 DiffKey::from(&self.webview_id)
134 }
135}