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)]
50pub struct WebView {
51 webview_id: WebViewId,
52 url: String,
53 close_on_drop: bool,
54 on_created: Option<WebViewCallback>,
55 layout: LayoutData,
56}
57
58impl PartialEq for WebView {
59 fn eq(&self, other: &Self) -> bool {
60 self.webview_id == other.webview_id
61 && self.url == other.url
62 && self.close_on_drop == other.close_on_drop
63 && match (&self.on_created, &other.on_created) {
64 (None, None) => true,
65 (Some(a), Some(b)) => std::sync::Arc::ptr_eq(a, b),
66 _ => false,
67 }
68 && self.layout == other.layout
69 }
70}
71
72impl WebView {
73 pub fn new(url: impl Into<String>) -> Self {
74 Self {
75 webview_id: WebViewId::new(),
76 url: url.into(),
77 close_on_drop: true,
78 on_created: None,
79 layout: LayoutData::default(),
80 }
81 }
82
83 pub fn url(mut self, url: impl Into<String>) -> Self {
85 self.url = url.into();
86 self
87 }
88
89 pub fn id(mut self, id: WebViewId) -> Self {
92 self.webview_id = id;
93 self
94 }
95
96 pub fn close_on_drop(mut self, close: bool) -> Self {
98 self.close_on_drop = close;
99 self
100 }
101
102 pub fn on_created(
105 mut self,
106 on_created: impl Fn(wry::WebViewBuilder) -> wry::WebViewBuilder + Send + 'static,
107 ) -> Self {
108 self.on_created = Some(WebViewCallback::new(Box::new(on_created)));
109 self
110 }
111}
112
113impl LayoutExt for WebView {
114 fn get_layout(&mut self) -> &mut LayoutData {
115 &mut self.layout
116 }
117}
118impl ContainerExt for WebView {}
119
120const WEBVIEW_CONTEXT_ERROR: &str = "
121Error: Make sure to register the WebViewPlugin in your LaunchConfig:
122
123LaunchConfig::new()
124 .with_plugin(WebViewPlugin::new())
125";
126
127impl Component for WebView {
128 fn render(&self) -> impl IntoElement {
129 let events = try_consume_root_context::<crate::lifecycle::WebViewEvents>()
130 .expect(WEBVIEW_CONTEXT_ERROR);
131
132 let webview_id = self.webview_id;
133 let url = self.url.clone();
134 let close_on_drop = self.close_on_drop;
135 let on_created = self.on_created.clone();
136
137 let config = WebViewConfig {
138 url: url.clone(),
139 transparent: false,
140 user_agent: None,
141 on_created,
142 };
143
144 use_drop({
145 let events = events.clone();
146 move || {
147 events.lock().unwrap().push(if close_on_drop {
148 WebViewLifecycleEvent::Close { id: webview_id }
149 } else {
150 WebViewLifecycleEvent::Hide { id: webview_id }
151 });
152 }
153 });
154
155 webview(&url)
156 .layout(self.layout.clone())
157 .on_sized(move |event: Event<SizedEventData>| {
158 events.lock().unwrap().push(WebViewLifecycleEvent::Resized {
159 id: webview_id,
160 area: event.area,
161 config: config.clone(),
162 });
163 Platform::get().send(UserEvent::RequestRedraw);
164 })
165 }
166
167 fn render_key(&self) -> DiffKey {
168 DiffKey::from(&self.webview_id)
169 }
170}