1use std::{ops::Deref, sync::Arc};
3
4use crate::{
5 bitmap::BitmapFormat,
6 error::CreationError,
7 event::{KeyEvent, MouseEvent, ScrollEvent},
8 javascript::JSContext,
9 rect::Rect,
10 renderer::Session,
11 string::UlString,
12 surface::Surface,
13 Library,
14};
15
16#[derive(Clone, Copy, Debug)]
18pub enum Cursor {
19 Alias = ul_sys::ULCursor_kCursor_Alias as isize,
20 Cell = ul_sys::ULCursor_kCursor_Cell as isize,
21 ColumnResize = ul_sys::ULCursor_kCursor_ColumnResize as isize,
22 ContextMenu = ul_sys::ULCursor_kCursor_ContextMenu as isize,
23 Copy = ul_sys::ULCursor_kCursor_Copy as isize,
24 Cross = ul_sys::ULCursor_kCursor_Cross as isize,
25 Custom = ul_sys::ULCursor_kCursor_Custom as isize,
26 EastPanning = ul_sys::ULCursor_kCursor_EastPanning as isize,
27 EastResize = ul_sys::ULCursor_kCursor_EastResize as isize,
28 EastWestResize = ul_sys::ULCursor_kCursor_EastWestResize as isize,
29 Grab = ul_sys::ULCursor_kCursor_Grab as isize,
30 Grabbing = ul_sys::ULCursor_kCursor_Grabbing as isize,
31 Hand = ul_sys::ULCursor_kCursor_Hand as isize,
32 Help = ul_sys::ULCursor_kCursor_Help as isize,
33 IBeam = ul_sys::ULCursor_kCursor_IBeam as isize,
34 MiddlePanning = ul_sys::ULCursor_kCursor_MiddlePanning as isize,
35 Move = ul_sys::ULCursor_kCursor_Move as isize,
36 NoDrop = ul_sys::ULCursor_kCursor_NoDrop as isize,
37 None = ul_sys::ULCursor_kCursor_None as isize,
38 NorthEastPanning = ul_sys::ULCursor_kCursor_NorthEastPanning as isize,
39 NorthEastResize = ul_sys::ULCursor_kCursor_NorthEastResize as isize,
40 NorthEastSouthWestResize = ul_sys::ULCursor_kCursor_NorthEastSouthWestResize as isize,
41 NorthPanning = ul_sys::ULCursor_kCursor_NorthPanning as isize,
42 NorthResize = ul_sys::ULCursor_kCursor_NorthResize as isize,
43 NorthSouthResize = ul_sys::ULCursor_kCursor_NorthSouthResize as isize,
44 NorthWestPanning = ul_sys::ULCursor_kCursor_NorthWestPanning as isize,
45 NorthWestResize = ul_sys::ULCursor_kCursor_NorthWestResize as isize,
46 NorthWestSouthEastResize = ul_sys::ULCursor_kCursor_NorthWestSouthEastResize as isize,
47 NotAllowed = ul_sys::ULCursor_kCursor_NotAllowed as isize,
48 Pointer = ul_sys::ULCursor_kCursor_Pointer as isize,
49 Progress = ul_sys::ULCursor_kCursor_Progress as isize,
50 RowResize = ul_sys::ULCursor_kCursor_RowResize as isize,
51 SouthEastPanning = ul_sys::ULCursor_kCursor_SouthEastPanning as isize,
52 SouthEastResize = ul_sys::ULCursor_kCursor_SouthEastResize as isize,
53 SouthPanning = ul_sys::ULCursor_kCursor_SouthPanning as isize,
54 SouthResize = ul_sys::ULCursor_kCursor_SouthResize as isize,
55 SouthWestPanning = ul_sys::ULCursor_kCursor_SouthWestPanning as isize,
56 SouthWestResize = ul_sys::ULCursor_kCursor_SouthWestResize as isize,
57 VerticalText = ul_sys::ULCursor_kCursor_VerticalText as isize,
58 Wait = ul_sys::ULCursor_kCursor_Wait as isize,
59 WestPanning = ul_sys::ULCursor_kCursor_WestPanning as isize,
60 WestResize = ul_sys::ULCursor_kCursor_WestResize as isize,
61 ZoomIn = ul_sys::ULCursor_kCursor_ZoomIn as isize,
62 ZoomOut = ul_sys::ULCursor_kCursor_ZoomOut as isize,
63}
64
65impl TryFrom<ul_sys::ULCursor> for Cursor {
66 type Error = ();
67
68 fn try_from(value: ul_sys::ULCursor) -> Result<Self, Self::Error> {
69 match value {
70 ul_sys::ULCursor_kCursor_Alias => Ok(Self::Alias),
71 ul_sys::ULCursor_kCursor_Cell => Ok(Self::Cell),
72 ul_sys::ULCursor_kCursor_ColumnResize => Ok(Self::ColumnResize),
73 ul_sys::ULCursor_kCursor_ContextMenu => Ok(Self::ContextMenu),
74 ul_sys::ULCursor_kCursor_Copy => Ok(Self::Copy),
75 ul_sys::ULCursor_kCursor_Cross => Ok(Self::Cross),
76 ul_sys::ULCursor_kCursor_Custom => Ok(Self::Custom),
77 ul_sys::ULCursor_kCursor_EastPanning => Ok(Self::EastPanning),
78 ul_sys::ULCursor_kCursor_EastResize => Ok(Self::EastResize),
79 ul_sys::ULCursor_kCursor_EastWestResize => Ok(Self::EastWestResize),
80 ul_sys::ULCursor_kCursor_Grab => Ok(Self::Grab),
81 ul_sys::ULCursor_kCursor_Grabbing => Ok(Self::Grabbing),
82 ul_sys::ULCursor_kCursor_Hand => Ok(Self::Hand),
83 ul_sys::ULCursor_kCursor_Help => Ok(Self::Help),
84 ul_sys::ULCursor_kCursor_IBeam => Ok(Self::IBeam),
85 ul_sys::ULCursor_kCursor_MiddlePanning => Ok(Self::MiddlePanning),
86 ul_sys::ULCursor_kCursor_Move => Ok(Self::Move),
87 ul_sys::ULCursor_kCursor_NoDrop => Ok(Self::NoDrop),
88 ul_sys::ULCursor_kCursor_None => Ok(Self::None),
89 ul_sys::ULCursor_kCursor_NorthEastPanning => Ok(Self::NorthEastPanning),
90 ul_sys::ULCursor_kCursor_NorthEastResize => Ok(Self::NorthEastResize),
91 ul_sys::ULCursor_kCursor_NorthEastSouthWestResize => Ok(Self::NorthEastSouthWestResize),
92 ul_sys::ULCursor_kCursor_NorthPanning => Ok(Self::NorthPanning),
93 ul_sys::ULCursor_kCursor_NorthResize => Ok(Self::NorthResize),
94 ul_sys::ULCursor_kCursor_NorthSouthResize => Ok(Self::NorthSouthResize),
95 ul_sys::ULCursor_kCursor_NorthWestPanning => Ok(Self::NorthWestPanning),
96 ul_sys::ULCursor_kCursor_NorthWestResize => Ok(Self::NorthWestResize),
97 ul_sys::ULCursor_kCursor_NorthWestSouthEastResize => Ok(Self::NorthWestSouthEastResize),
98 ul_sys::ULCursor_kCursor_NotAllowed => Ok(Self::NotAllowed),
99 ul_sys::ULCursor_kCursor_Pointer => Ok(Self::Pointer),
100 ul_sys::ULCursor_kCursor_Progress => Ok(Self::Progress),
101 ul_sys::ULCursor_kCursor_RowResize => Ok(Self::RowResize),
102 ul_sys::ULCursor_kCursor_SouthEastPanning => Ok(Self::SouthEastPanning),
103 ul_sys::ULCursor_kCursor_SouthEastResize => Ok(Self::SouthEastResize),
104 ul_sys::ULCursor_kCursor_SouthPanning => Ok(Self::SouthPanning),
105 ul_sys::ULCursor_kCursor_SouthResize => Ok(Self::SouthResize),
106 ul_sys::ULCursor_kCursor_SouthWestPanning => Ok(Self::SouthWestPanning),
107 ul_sys::ULCursor_kCursor_SouthWestResize => Ok(Self::SouthWestResize),
108 ul_sys::ULCursor_kCursor_VerticalText => Ok(Self::VerticalText),
109 ul_sys::ULCursor_kCursor_Wait => Ok(Self::Wait),
110 ul_sys::ULCursor_kCursor_WestPanning => Ok(Self::WestPanning),
111 ul_sys::ULCursor_kCursor_WestResize => Ok(Self::WestResize),
112 ul_sys::ULCursor_kCursor_ZoomIn => Ok(Self::ZoomIn),
113 ul_sys::ULCursor_kCursor_ZoomOut => Ok(Self::ZoomOut),
114 _ => Err(()),
115 }
116 }
117}
118
119#[derive(Clone, Copy, Debug)]
126pub struct RenderTarget {
127 pub is_empty: bool,
129 pub width: u32,
131 pub height: u32,
133 pub texture_id: u32,
136 pub texture_width: u32,
138 pub texture_height: u32,
140 pub texture_format: BitmapFormat,
142 pub uv_coords: Rect<f32>,
144 pub render_buffer_id: u32,
147}
148
149impl From<ul_sys::ULRenderTarget> for RenderTarget {
150 fn from(rt: ul_sys::ULRenderTarget) -> Self {
151 RenderTarget {
152 is_empty: rt.is_empty,
153 width: rt.width,
154 height: rt.height,
155 texture_id: rt.texture_id,
156 texture_width: rt.texture_width,
157 texture_height: rt.texture_height,
158 texture_format: BitmapFormat::try_from(rt.texture_format).unwrap(),
159 uv_coords: rt.uv_coords.into(),
160 render_buffer_id: rt.render_buffer_id,
161 }
162 }
163}
164
165#[derive(Clone, Copy, Debug)]
167#[non_exhaustive]
168pub enum ConsoleMessageSource {
169 XML = ul_sys::ULMessageSource_kMessageSource_XML as isize,
170 JS = ul_sys::ULMessageSource_kMessageSource_JS as isize,
171 Network = ul_sys::ULMessageSource_kMessageSource_Network as isize,
172 ConsoleAPI = ul_sys::ULMessageSource_kMessageSource_ConsoleAPI as isize,
173 Storage = ul_sys::ULMessageSource_kMessageSource_Storage as isize,
174 AppCache = ul_sys::ULMessageSource_kMessageSource_AppCache as isize,
175 Rendering = ul_sys::ULMessageSource_kMessageSource_Rendering as isize,
176 CSS = ul_sys::ULMessageSource_kMessageSource_CSS as isize,
177 Security = ul_sys::ULMessageSource_kMessageSource_Security as isize,
178 ContentBlocker = ul_sys::ULMessageSource_kMessageSource_ContentBlocker as isize,
179 Media = ul_sys::ULMessageSource_kMessageSource_Media as isize,
180 MediaSource = ul_sys::ULMessageSource_kMessageSource_MediaSource as isize,
181 WebRTC = ul_sys::ULMessageSource_kMessageSource_WebRTC as isize,
182 ITPDebug = ul_sys::ULMessageSource_kMessageSource_ITPDebug as isize,
183 PrivateClickMeasurement =
184 ul_sys::ULMessageSource_kMessageSource_PrivateClickMeasurement as isize,
185 PaymentRequest = ul_sys::ULMessageSource_kMessageSource_PaymentRequest as isize,
186 Other = ul_sys::ULMessageSource_kMessageSource_Other as isize,
187}
188
189impl TryFrom<ul_sys::ULMessageSource> for ConsoleMessageSource {
190 type Error = ();
191 fn try_from(value: ul_sys::ULMessageSource) -> Result<Self, Self::Error> {
192 match value {
193 ul_sys::ULMessageSource_kMessageSource_XML => Ok(ConsoleMessageSource::XML),
194 ul_sys::ULMessageSource_kMessageSource_JS => Ok(ConsoleMessageSource::JS),
195 ul_sys::ULMessageSource_kMessageSource_Network => Ok(ConsoleMessageSource::Network),
196 ul_sys::ULMessageSource_kMessageSource_ConsoleAPI => {
197 Ok(ConsoleMessageSource::ConsoleAPI)
198 }
199 ul_sys::ULMessageSource_kMessageSource_Storage => Ok(ConsoleMessageSource::Storage),
200 ul_sys::ULMessageSource_kMessageSource_AppCache => Ok(ConsoleMessageSource::AppCache),
201 ul_sys::ULMessageSource_kMessageSource_Rendering => Ok(ConsoleMessageSource::Rendering),
202 ul_sys::ULMessageSource_kMessageSource_CSS => Ok(ConsoleMessageSource::CSS),
203 ul_sys::ULMessageSource_kMessageSource_Security => Ok(ConsoleMessageSource::Security),
204 ul_sys::ULMessageSource_kMessageSource_ContentBlocker => {
205 Ok(ConsoleMessageSource::ContentBlocker)
206 }
207 ul_sys::ULMessageSource_kMessageSource_Other => Ok(ConsoleMessageSource::Other),
208 _ => Err(()),
209 }
210 }
211}
212
213#[derive(Clone, Copy, Debug)]
215pub enum ConsoleMessageLevel {
216 Log = ul_sys::ULMessageLevel_kMessageLevel_Log as isize,
217 Warning = ul_sys::ULMessageLevel_kMessageLevel_Warning as isize,
218 Error = ul_sys::ULMessageLevel_kMessageLevel_Error as isize,
219 Debug = ul_sys::ULMessageLevel_kMessageLevel_Debug as isize,
220 Info = ul_sys::ULMessageLevel_kMessageLevel_Info as isize,
221}
222
223impl TryFrom<ul_sys::ULMessageLevel> for ConsoleMessageLevel {
224 type Error = ();
225 fn try_from(value: ul_sys::ULMessageLevel) -> Result<Self, ()> {
226 match value {
227 ul_sys::ULMessageLevel_kMessageLevel_Log => Ok(ConsoleMessageLevel::Log),
228 ul_sys::ULMessageLevel_kMessageLevel_Warning => Ok(ConsoleMessageLevel::Warning),
229 ul_sys::ULMessageLevel_kMessageLevel_Error => Ok(ConsoleMessageLevel::Error),
230 ul_sys::ULMessageLevel_kMessageLevel_Debug => Ok(ConsoleMessageLevel::Debug),
231 ul_sys::ULMessageLevel_kMessageLevel_Info => Ok(ConsoleMessageLevel::Info),
232 _ => Err(()),
233 }
234 }
235}
236
237pub struct ViewConfig {
239 lib: Arc<Library>,
240 internal: ul_sys::ULViewConfig,
241}
242
243impl ViewConfig {
244 pub fn start() -> ViewConfigBuilder {
247 ViewConfigBuilder::default()
248 }
249
250 pub(crate) unsafe fn to_ul(&self) -> ul_sys::ULViewConfig {
253 self.internal
254 }
255}
256
257impl Drop for ViewConfig {
258 fn drop(&mut self) {
259 unsafe {
260 self.lib.ultralight().ulDestroyViewConfig(self.internal);
261 }
262 }
263}
264
265#[derive(Default)]
267pub struct ViewConfigBuilder {
268 is_accelerated: Option<bool>,
269 is_transparent: Option<bool>,
270 initial_device_scale: Option<f64>,
271 initial_focus: Option<bool>,
272 enable_images: Option<bool>,
273 enable_javascript: Option<bool>,
274 font_family_standard: Option<String>,
275 font_family_fixed: Option<String>,
276 font_family_serif: Option<String>,
277 font_family_sans_serif: Option<String>,
278 user_agent: Option<String>,
279 }
281
282impl ViewConfigBuilder {
283 pub fn is_accelerated(mut self, is_accelerated: bool) -> Self {
292 self.is_accelerated = Some(is_accelerated);
293 self
294 }
295
296 pub fn is_transparent(mut self, is_transparent: bool) -> Self {
305 self.is_transparent = Some(is_transparent);
306 self
307 }
308
309 pub fn initial_device_scale(mut self, initial_device_scale: f64) -> Self {
317 self.initial_device_scale = Some(initial_device_scale);
318 self
319 }
320
321 pub fn initial_focus(mut self, initial_focus: bool) -> Self {
325 self.initial_focus = Some(initial_focus);
326 self
327 }
328
329 pub fn enable_images(mut self, enable_images: bool) -> Self {
333 self.enable_images = Some(enable_images);
334 self
335 }
336
337 pub fn enable_javascript(mut self, enable_javascript: bool) -> Self {
341 self.enable_javascript = Some(enable_javascript);
342 self
343 }
344
345 pub fn font_family_standard(mut self, font_family_standard: &str) -> Self {
349 self.font_family_standard = Some(font_family_standard.to_string());
350 self
351 }
352
353 pub fn font_family_fixed(mut self, font_family_fixed: &str) -> Self {
357 self.font_family_fixed = Some(font_family_fixed.to_string());
358 self
359 }
360
361 pub fn font_family_serif(mut self, font_family_serif: &str) -> Self {
365 self.font_family_serif = Some(font_family_serif.to_string());
366 self
367 }
368
369 pub fn font_family_sans_serif(mut self, font_family_sans_serif: &str) -> Self {
373 self.font_family_sans_serif = Some(font_family_sans_serif.to_string());
374 self
375 }
376
377 pub fn user_agent(mut self, user_agent: &str) -> Self {
384 self.user_agent = Some(user_agent.to_string());
385 self
386 }
387
388 pub fn build(self, lib: Arc<Library>) -> Option<ViewConfig> {
407 let internal = unsafe { lib.ultralight().ulCreateViewConfig() };
408
409 if internal.is_null() {
410 return None;
411 }
412
413 set_config!(
414 internal,
415 self.is_accelerated,
416 lib.ultralight().ulViewConfigSetIsAccelerated
417 );
418 set_config!(
419 internal,
420 self.is_transparent,
421 lib.ultralight().ulViewConfigSetIsTransparent
422 );
423 set_config!(
424 internal,
425 self.initial_device_scale,
426 lib.ultralight().ulViewConfigSetInitialDeviceScale
427 );
428 set_config!(
429 internal,
430 self.initial_focus,
431 lib.ultralight().ulViewConfigSetInitialFocus
432 );
433 set_config!(
434 internal,
435 self.enable_images,
436 lib.ultralight().ulViewConfigSetEnableImages
437 );
438 set_config!(
439 internal,
440 self.enable_javascript,
441 lib.ultralight().ulViewConfigSetEnableJavaScript
442 );
443 set_config_str!(
444 internal,
445 self.font_family_standard,
446 lib.ultralight().ulViewConfigSetFontFamilyStandard
447 );
448 set_config_str!(
449 internal,
450 self.font_family_fixed,
451 lib.ultralight().ulViewConfigSetFontFamilyFixed
452 );
453 set_config_str!(
454 internal,
455 self.font_family_serif,
456 lib.ultralight().ulViewConfigSetFontFamilySerif
457 );
458 set_config_str!(
459 internal,
460 self.font_family_sans_serif,
461 lib.ultralight().ulViewConfigSetFontFamilySansSerif
462 );
463 set_config_str!(
464 internal,
465 self.user_agent,
466 lib.ultralight().ulViewConfigSetUserAgent
467 );
468 Some(ViewConfig { lib, internal })
471 }
472}
473
474pub struct ViewJSContextGuard<'a> {
482 view: &'a View,
483 js_ctx: JSContext,
484}
485
486impl Deref for ViewJSContextGuard<'_> {
487 type Target = JSContext;
488
489 fn deref(&self) -> &Self::Target {
490 &self.js_ctx
491 }
492}
493
494impl Drop for ViewJSContextGuard<'_> {
495 fn drop(&mut self) {
496 unsafe {
497 self.view
498 .lib
499 .ultralight()
500 .ulViewUnlockJSContext(self.view.internal);
501 }
502 }
503}
504
505pub struct View {
522 lib: Arc<Library>,
523 internal: ul_sys::ULView,
524 need_to_destroy: bool,
525}
526
527impl View {
528 pub(crate) unsafe fn from_raw(lib: Arc<Library>, raw: ul_sys::ULView) -> Option<Self> {
531 if raw.is_null() {
532 None
533 } else {
534 Some(Self {
535 lib,
536 internal: raw,
537 need_to_destroy: false,
538 })
539 }
540 }
541
542 pub(crate) unsafe fn create(
545 renderer: ul_sys::ULRenderer,
546 width: u32,
547 height: u32,
548 view_config: &ViewConfig,
549 session: Option<&Session>,
550 ) -> Option<Self> {
551 let lib = view_config.lib.clone();
552 let internal = lib.ultralight().ulCreateView(
553 renderer,
554 width,
555 height,
556 view_config.to_ul(),
557 session.map(|s| s.to_ul()).unwrap_or(std::ptr::null_mut()),
558 );
559
560 if internal.is_null() {
561 None
562 } else {
563 Some(Self {
564 lib,
565 internal,
566 need_to_destroy: true,
567 })
568 }
569 }
570
571 #[allow(dead_code)]
574 pub(crate) unsafe fn to_ul(&self) -> ul_sys::ULView {
575 self.internal
576 }
577}
578
579impl View {
580 pub fn url(&self) -> Result<String, CreationError> {
582 unsafe {
583 let url_string = self.lib.ultralight().ulViewGetURL(self.internal);
584 UlString::copy_raw_to_string(&self.lib, url_string)
585 }
586 }
587
588 pub fn title(&self) -> Result<String, CreationError> {
590 unsafe {
591 let title_string = self.lib.ultralight().ulViewGetTitle(self.internal);
592 UlString::copy_raw_to_string(&self.lib, title_string)
593 }
594 }
595
596 pub fn width(&self) -> u32 {
598 unsafe { self.lib.ultralight().ulViewGetWidth(self.internal) }
599 }
600
601 pub fn height(&self) -> u32 {
603 unsafe { self.lib.ultralight().ulViewGetHeight(self.internal) }
604 }
605
606 pub fn device_scale(&self) -> f64 {
610 unsafe { self.lib.ultralight().ulViewGetDeviceScale(self.internal) }
611 }
612
613 pub fn set_device_scale(&self, scale: f64) {
615 unsafe {
616 self.lib
617 .ultralight()
618 .ulViewSetDeviceScale(self.internal, scale)
619 }
620 }
621
622 pub fn is_accelerated(&self) -> bool {
625 unsafe { self.lib.ultralight().ulViewIsAccelerated(self.internal) }
626 }
627
628 pub fn is_transparent(&self) -> bool {
630 unsafe { self.lib.ultralight().ulViewIsTransparent(self.internal) }
631 }
632
633 pub fn is_loading(&self) -> bool {
635 unsafe { self.lib.ultralight().ulViewIsLoading(self.internal) }
636 }
637
638 pub fn render_target(&self) -> Option<RenderTarget> {
642 if self.is_accelerated() {
643 Some(unsafe {
644 RenderTarget::from(self.lib.ultralight().ulViewGetRenderTarget(self.internal))
645 })
646 } else {
647 None
648 }
649 }
650
651 pub fn surface(&self) -> Option<Surface> {
655 if !self.is_accelerated() {
656 unsafe {
657 let surface = self.lib.ultralight().ulViewGetSurface(self.internal);
658 if surface.is_null() {
659 None
660 } else {
661 Some(Surface::from_raw(self.lib.clone(), surface))
662 }
663 }
664 } else {
665 None
666 }
667 }
668
669 pub fn load_html(&self, html: &str) -> Result<(), CreationError> {
671 unsafe {
672 let ul_string = UlString::from_str(self.lib.clone(), html)?;
673 self.lib
674 .ultralight()
675 .ulViewLoadHTML(self.internal, ul_string.to_ul());
676 }
677 Ok(())
678 }
679
680 pub fn load_url(&self, url: &str) -> Result<(), CreationError> {
684 unsafe {
685 let ul_string = UlString::from_str(self.lib.clone(), url)?;
686 self.lib
687 .ultralight()
688 .ulViewLoadURL(self.internal, ul_string.to_ul());
689 }
690 Ok(())
691 }
692
693 pub fn resize(&self, width: u32, height: u32) {
699 unsafe {
700 self.lib
701 .ultralight()
702 .ulViewResize(self.internal, width, height);
703 }
704 }
705
706 pub fn lock_js_context(&self) -> ViewJSContextGuard {
715 let ctx = unsafe { self.lib.ultralight().ulViewLockJSContext(self.internal) };
716
717 let js_ctx = JSContext::copy_from_raw(self.lib.clone(), ctx);
718
719 ViewJSContextGuard { view: self, js_ctx }
720 }
721
722 pub fn evaluate_script(&self, script: &str) -> Result<Result<String, String>, CreationError> {
728 unsafe {
729 let ul_script_string = UlString::from_str(self.lib.clone(), script)?;
730 let mut exception_string = 1 as ul_sys::ULString;
732 let result_string = self.lib.ultralight().ulViewEvaluateScript(
733 self.internal,
734 ul_script_string.to_ul(),
735 &mut exception_string as _,
736 );
737
738 let has_exception = !self.lib.ultralight().ulStringIsEmpty(exception_string);
739 if has_exception {
740 let exception_string = UlString::copy_raw_to_string(&self.lib, exception_string)?;
741 Ok(Err(exception_string))
742 } else {
743 let result_string = UlString::copy_raw_to_string(&self.lib, result_string)?;
744 Ok(Ok(result_string))
745 }
746 }
747 }
748
749 pub fn can_go_back(&self) -> bool {
751 unsafe { self.lib.ultralight().ulViewCanGoBack(self.internal) }
752 }
753
754 pub fn can_go_forward(&self) -> bool {
756 unsafe { self.lib.ultralight().ulViewCanGoForward(self.internal) }
757 }
758
759 pub fn go_back(&self) {
761 unsafe { self.lib.ultralight().ulViewGoBack(self.internal) }
762 }
763
764 pub fn go_forward(&self) {
766 unsafe { self.lib.ultralight().ulViewGoForward(self.internal) }
767 }
768
769 pub fn go_to_history_offset(&self, offset: i32) {
771 unsafe {
772 self.lib
773 .ultralight()
774 .ulViewGoToHistoryOffset(self.internal, offset)
775 }
776 }
777
778 pub fn reload(&self) {
780 unsafe { self.lib.ultralight().ulViewReload(self.internal) }
781 }
782
783 pub fn stop(&self) {
785 unsafe { self.lib.ultralight().ulViewStop(self.internal) }
786 }
787
788 pub fn focus(&self) {
793 unsafe { self.lib.ultralight().ulViewFocus(self.internal) }
794 }
795
796 pub fn unfocus(&self) {
800 unsafe { self.lib.ultralight().ulViewUnfocus(self.internal) }
801 }
802
803 pub fn has_focus(&self) -> bool {
805 unsafe { self.lib.ultralight().ulViewHasFocus(self.internal) }
806 }
807
808 pub fn has_input_focus(&self) -> bool {
814 unsafe { self.lib.ultralight().ulViewHasInputFocus(self.internal) }
815 }
816
817 pub fn fire_key_event(&self, key_event: KeyEvent) {
822 unsafe {
823 self.lib
824 .ultralight()
825 .ulViewFireKeyEvent(self.internal, key_event.to_ul())
826 }
827 }
828
829 pub fn fire_mouse_event(&self, mouse_event: MouseEvent) {
831 unsafe {
832 self.lib
833 .ultralight()
834 .ulViewFireMouseEvent(self.internal, mouse_event.to_ul())
835 }
836 }
837
838 pub fn fire_scroll_event(&self, scroll_event: ScrollEvent) {
840 unsafe {
841 self.lib
842 .ultralight()
843 .ulViewFireScrollEvent(self.internal, scroll_event.to_ul())
844 }
845 }
846
847 pub fn get_display_id(&self) -> u32 {
849 unsafe { self.lib.ultralight().ulViewGetDisplayId(self.internal) }
850 }
851
852 pub fn set_display_id(&self, display_id: u32) {
856 unsafe {
857 self.lib
858 .ultralight()
859 .ulViewSetDisplayId(self.internal, display_id)
860 }
861 }
862
863 set_callback! {
868 pub fn set_change_title_callback(&self, callback: FnMut(view: &View, title: String)) :
874 [View::lib.ultralight()][s] ulViewSetChangeTitleCallback(ul_view: ul_sys::ULView, ul_title: ul_sys::ULString) {
875 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
876 let title = UlString::copy_raw_to_string(&s.lib,ul_title).unwrap();
877 }
878 }
879
880 set_callback! {
881 pub fn set_change_url_callback(&self, callback: FnMut(view: &View, url: String)) :
887 [View::lib.ultralight()][s] ulViewSetChangeURLCallback(ul_view: ul_sys::ULView, ul_url: ul_sys::ULString) {
888 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
889 let url = UlString::copy_raw_to_string(&s.lib,ul_url).unwrap();
890 }
891 }
892
893 set_callback! {
894 pub fn set_change_tooltip_callback(&self, callback: FnMut(view: &View, tooltip: String)) :
900 [View::lib.ultralight()][s] ulViewSetChangeTooltipCallback(ul_view: ul_sys::ULView, ul_tooltip: ul_sys::ULString) {
901 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
902 let tooltip = UlString::copy_raw_to_string(&s.lib,ul_tooltip).unwrap();
903 }
904 }
905
906 set_callback! {
907 pub fn set_change_cursor_callback(&self, callback: FnMut(view: &View, cursor: Cursor)) :
913 [View::lib.ultralight()][s] ulViewSetChangeCursorCallback(ul_view: ul_sys::ULView, ul_cursor: ul_sys::ULCursor) {
914 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
915 let cursor = Cursor::try_from(ul_cursor).unwrap();
916 }
917 }
918
919 set_callback! {
920 pub fn set_add_console_message_callback(&self, callback: FnMut(
931 view: &View,
932 message_source: ConsoleMessageSource,
933 message_level: ConsoleMessageLevel,
934 message: String,
935 line_number:u32,
936 column_number:u32,
937 source_id: String)) :
938 [View::lib.ultralight()][s] ulViewSetAddConsoleMessageCallback(
939 ul_view: ul_sys::ULView,
940 ul_message_source: ul_sys::ULMessageSource,
941 ul_message_level: ul_sys::ULMessageLevel,
942 ul_message: ul_sys::ULString,
943 line_number: u32,
944 column_number :u32,
945 ul_source_id: ul_sys::ULString
946 ) {
947 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
948 let message_source = ConsoleMessageSource::try_from(ul_message_source).unwrap();
949 let message_level = ConsoleMessageLevel::try_from(ul_message_level).unwrap();
950 let message = UlString::copy_raw_to_string(&s.lib,ul_message).unwrap();
951 let source_id = UlString::copy_raw_to_string(&s.lib,ul_source_id).unwrap();
952 }
953 }
954
955 set_callback! {
956 pub fn set_create_child_view_callback(&self, callback: FnMut(
984 view: &View,
985 opener_url: String,
986 target_url: String,
987 is_popup: bool,
988 popup_rect: Rect<i32>
989 ) -> ret_view: Option<View>) :
992 [View::lib.ultralight()][s] ulViewSetCreateChildViewCallback(
993 ul_view: ul_sys::ULView,
994 ul_opener_url: ul_sys::ULString,
995 ul_target_url: ul_sys::ULString,
996 is_popup: bool,
997 ul_popup_rect: ul_sys::ULIntRect
998 ) -> ul_sys::ULView {
999 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1000 let opener_url = UlString::copy_raw_to_string(&s.lib,ul_opener_url).unwrap();
1001 let target_url = UlString::copy_raw_to_string(&s.lib,ul_target_url).unwrap();
1002 let popup_rect = Rect::from(ul_popup_rect);
1003 } {
1004 if let Some(ret_view) = ret_view {
1005 ret_view.internal
1006 } else {
1007 std::ptr::null_mut()
1008 }
1009 }
1010 }
1011
1012 set_callback! {
1013 pub fn set_create_inspector_view_callback(&self, callback: FnMut(
1037 view: &View,
1038 is_local: bool,
1039 inspected_url: String
1040 ) -> ret_view: Option<View>) :
1043 [View::lib.ultralight()][s] ulViewSetCreateInspectorViewCallback(
1044 ul_view: ul_sys::ULView,
1045 is_local: bool,
1046 ul_inspected_url: ul_sys::ULString
1047 ) -> ul_sys::ULView {
1048 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1049 let inspected_url = UlString::copy_raw_to_string(&s.lib,ul_inspected_url).unwrap();
1050 } {
1051 if let Some(ret_view) = ret_view {
1052 ret_view.internal
1053 } else {
1054 std::ptr::null_mut()
1055 }
1056 }
1057 }
1058
1059 set_callback! {
1060 pub fn set_begin_loading_callback(&self, callback: FnMut(
1068 view: &View,
1069 frame_id: u64,
1070 is_main_frame: bool,
1071 url: String)) :
1072 [View::lib.ultralight()][s] ulViewSetBeginLoadingCallback(
1073 ul_view: ul_sys::ULView,
1074 frame_id: u64,
1075 is_main_frame: bool,
1076 ul_url: ul_sys::ULString
1077 ) {
1078 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1079 let url = UlString::copy_raw_to_string(&s.lib,ul_url).unwrap();
1080 }
1081 }
1082
1083 set_callback! {
1084 pub fn set_finish_loading_callback(&self, callback: FnMut(
1092 view: &View,
1093 frame_id: u64,
1094 is_main_frame: bool,
1095 url: String)) :
1096 [View::lib.ultralight()][s] ulViewSetFinishLoadingCallback(
1097 ul_view: ul_sys::ULView,
1098 frame_id: u64,
1099 is_main_frame: bool,
1100 ul_url: ul_sys::ULString
1101 ) {
1102 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1103 let url = UlString::copy_raw_to_string(&s.lib,ul_url).unwrap();
1104 }
1105 }
1106
1107 set_callback! {
1108 pub fn set_fail_loading_callback(&self, callback: FnMut(
1119 view: &View,
1120 frame_id: u64,
1121 is_main_frame: bool,
1122 url: String,
1123 description: String,
1124 error_domain: String,
1125 error_code: i32)) :
1126 [View::lib.ultralight()][s] ulViewSetFailLoadingCallback(
1127 ul_view: ul_sys::ULView,
1128 frame_id: u64,
1129 is_main_frame: bool,
1130 ul_url: ul_sys::ULString,
1131 ul_description: ul_sys::ULString,
1132 ul_error_domain: ul_sys::ULString,
1133 error_code: i32
1134 ) {
1135 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1136 let url = UlString::copy_raw_to_string(&s.lib,ul_url).unwrap();
1137 let description = UlString::copy_raw_to_string(&s.lib,ul_description).unwrap();
1138 let error_domain = UlString::copy_raw_to_string(&s.lib,ul_error_domain).unwrap();
1139 }
1140 }
1141
1142 set_callback! {
1143 pub fn set_window_object_ready_callback(&self, callback: FnMut(
1160 view: &View,
1161 frame_id: u64,
1162 is_main_frame: bool,
1163 url: String)) :
1164 [View::lib.ultralight()][s] ulViewSetWindowObjectReadyCallback(
1165 ul_view: ul_sys::ULView,
1166 frame_id: u64,
1167 is_main_frame: bool,
1168 ul_url: ul_sys::ULString
1169 ) {
1170 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1171 let url = UlString::copy_raw_to_string(&s.lib,ul_url).unwrap();
1172 }
1173 }
1174
1175 set_callback! {
1176 pub fn set_dom_ready_callback(&self, callback: FnMut(
1187 view: &View,
1188 frame_id: u64,
1189 is_main_frame: bool,
1190 url: String)) :
1191 [View::lib.ultralight()][s] ulViewSetDOMReadyCallback(
1192 ul_view: ul_sys::ULView,
1193 frame_id: u64,
1194 is_main_frame: bool,
1195 ul_url: ul_sys::ULString
1196 ) {
1197 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1198 let url = UlString::copy_raw_to_string(&s.lib, ul_url).unwrap();
1199 }
1200 }
1201
1202 set_callback! {
1203 pub fn set_update_history_callback(&self, callback: FnMut(view: &View)) :
1208 [View::lib.ultralight()][s] ulViewSetUpdateHistoryCallback(ul_view: ul_sys::ULView) {
1209 let view = &View::from_raw(s.lib.clone(), ul_view).unwrap();
1210 }
1211 }
1212
1213 pub fn set_needs_paint(&self, needs_paint: bool) {
1219 unsafe {
1220 self.lib
1221 .ultralight()
1222 .ulViewSetNeedsPaint(self.internal, needs_paint)
1223 }
1224 }
1225
1226 pub fn needs_paint(&self) -> bool {
1229 unsafe { self.lib.ultralight().ulViewGetNeedsPaint(self.internal) }
1230 }
1231
1232 pub fn create_local_inspector_view(&self) {
1242 unsafe {
1243 self.lib
1244 .ultralight()
1245 .ulViewCreateLocalInspectorView(self.internal);
1246 }
1247 }
1248}
1249
1250impl Drop for View {
1251 fn drop(&mut self) {
1252 if self.need_to_destroy {
1253 unsafe {
1254 self.lib.ultralight().ulDestroyView(self.internal);
1255 }
1256 }
1257 }
1258}