1cfg_if::cfg_if! {
2 if #[cfg(windows)] {
3 use std::marker::PhantomData;
4
5 #[derive(Clone, Copy)]
6 enum BorrowedWidgetInner<'a> {
7 #[cfg(feature = "win32")]
8 Win32(windows_sys::Win32::Foundation::HWND, PhantomData<&'a ()>),
9 #[cfg(feature = "winui")]
10 WinUI(&'a winui3::Microsoft::UI::Xaml::FrameworkElement),
11 #[cfg(not(any(feature = "win32", feature = "winui")))]
12 Dummy(std::convert::Infallible, PhantomData<&'a ()>),
13 }
14 } else if #[cfg(target_os = "macos")] {
15 use objc2::rc::Retained;
16
17 type BorrowedWidgetInner<'a> = &'a Retained<objc2_app_kit::NSView>;
18 } else {
19 use std::marker::PhantomData;
20
21 #[derive(Clone, Copy)]
22 enum BorrowedWidgetInner<'a> {
23 #[cfg(feature = "qt")]
24 Qt(*mut core::ffi::c_void, PhantomData<&'a ()>),
25 #[cfg(feature = "gtk")]
26 Gtk(&'a gtk4::Widget),
27 #[cfg(not(any(feature = "qt", feature = "gtk")))]
28 Dummy(std::convert::Infallible, PhantomData<&'a ()>),
29 }
30 }
31}
32
33#[derive(Clone, Copy)]
35pub struct BorrowedWidget<'a>(BorrowedWidgetInner<'a>);
36
37#[allow(unreachable_patterns)]
38#[cfg(windows)]
39impl<'a> BorrowedWidget<'a> {
40 #[cfg(feature = "win32")]
48 pub unsafe fn win32(hwnd: windows_sys::Win32::Foundation::HWND) -> Self {
49 Self(BorrowedWidgetInner::Win32(hwnd, PhantomData))
50 }
51
52 #[cfg(feature = "winui")]
54 pub fn winui(element: &'a winui3::Microsoft::UI::Xaml::FrameworkElement) -> Self {
55 Self(BorrowedWidgetInner::WinUI(element))
56 }
57
58 #[cfg(feature = "win32")]
60 pub fn as_win32(&self) -> windows_sys::Win32::Foundation::HWND {
61 match &self.0 {
62 BorrowedWidgetInner::Win32(hwnd, ..) => *hwnd,
63 _ => panic!("unsupported handle type"),
64 }
65 }
66
67 #[cfg(feature = "winui")]
69 pub fn as_winui(&self) -> &winui3::Microsoft::UI::Xaml::FrameworkElement {
70 match &self.0 {
71 BorrowedWidgetInner::WinUI(e) => e,
72 _ => panic!("unsupported handle type"),
73 }
74 }
75}
76
77#[cfg(target_os = "macos")]
78impl<'a> BorrowedWidget<'a> {
79 pub fn app_kit(view: &'a Retained<objc2_app_kit::NSView>) -> Self {
81 Self(view)
82 }
83
84 pub fn as_app_kit(&self) -> &'a Retained<objc2_app_kit::NSView> {
86 self.0
87 }
88}
89
90#[allow(unreachable_patterns)]
91#[cfg(not(any(windows, target_os = "macos")))]
92impl<'a> BorrowedWidget<'a> {
93 #[cfg(feature = "qt")]
99 pub unsafe fn qt<T>(widget: *mut T) -> Self {
100 Self(BorrowedWidgetInner::Qt(widget.cast(), PhantomData))
101 }
102
103 #[cfg(feature = "gtk")]
105 pub fn gtk(widget: &'a gtk4::Widget) -> Self {
106 Self(BorrowedWidgetInner::Gtk(widget))
107 }
108
109 #[cfg(feature = "qt")]
111 pub fn as_qt<T>(&self) -> *mut T {
112 match &self.0 {
113 BorrowedWidgetInner::Qt(w, ..) => (*w).cast(),
114 _ => panic!("unsupported handle type"),
115 }
116 }
117
118 #[cfg(feature = "gtk")]
120 pub fn to_gtk(&self) -> &'a gtk4::Widget {
121 match &self.0 {
122 BorrowedWidgetInner::Gtk(w) => w,
123 _ => panic!("unsupported handle type"),
124 }
125 }
126}
127
128pub trait AsWidget {
130 fn as_widget(&self) -> BorrowedWidget<'_>;
132}
133
134impl AsWidget for BorrowedWidget<'_> {
135 fn as_widget(&self) -> BorrowedWidget<'_> {
136 *self
137 }
138}
139
140impl<T: AsWidget + ?Sized> AsWidget for &T {
141 #[inline]
142 fn as_widget(&self) -> BorrowedWidget<'_> {
143 T::as_widget(self)
144 }
145}
146
147impl<'a, T: AsWidget + ?Sized> From<&'a T> for BorrowedWidget<'a> {
148 fn from(value: &'a T) -> Self {
149 value.as_widget()
150 }
151}
152
153#[doc(hidden)]
154#[macro_export]
155macro_rules! impl_as_widget {
156 ($t:ty, $inner:ident) => {
157 impl $crate::AsWidget for $t {
158 fn as_widget(&self) -> $crate::BorrowedWidget<'_> {
159 self.$inner.as_widget()
160 }
161 }
162 };
163}