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
85impl Component for WebView {
86 fn render(&self) -> impl IntoElement {
87 let events = consume_root_context::<crate::lifecycle::WebViewEvents>();
88
89 let webview_id = self.webview_id;
90 let url = self.url.clone();
91 let close_on_drop = self.close_on_drop;
92 let on_created = self.on_created.clone();
93
94 let config = WebViewConfig {
95 url: url.clone(),
96 transparent: false,
97 user_agent: None,
98 on_created,
99 };
100
101 use_drop({
102 let events = events.clone();
103 move || {
104 events.lock().unwrap().push(if close_on_drop {
105 WebViewLifecycleEvent::Close { id: webview_id }
106 } else {
107 WebViewLifecycleEvent::Hide { id: webview_id }
108 });
109 }
110 });
111
112 webview(&url)
113 .layout(self.layout.clone())
114 .on_sized(move |event: Event<SizedEventData>| {
115 events.lock().unwrap().push(WebViewLifecycleEvent::Resized {
116 id: webview_id,
117 area: event.area,
118 config: config.clone(),
119 });
120 })
121 }
122
123 fn render_key(&self) -> DiffKey {
124 DiffKey::from(&self.webview_id)
125 }
126}