winio_handle/
container.rs1cfg_if::cfg_if! {
2 if #[cfg(windows)] {
3 use std::marker::PhantomData;
4
5 #[derive(Clone, Copy)]
6 enum BorrowedContainerInner<'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::Controls::Canvas),
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 BorrowedContainerInner<'a> = &'a Retained<objc2_app_kit::NSView>;
18 } else {
19 use std::marker::PhantomData;
20
21 #[derive(Clone, Copy)]
22 enum BorrowedContainerInner<'a> {
23 #[cfg(feature = "qt")]
24 Qt(*mut core::ffi::c_void, PhantomData<&'a ()>),
25 #[cfg(feature = "gtk")]
26 Gtk(&'a gtk4::Fixed),
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 BorrowedContainer<'a>(BorrowedContainerInner<'a>);
36
37#[allow(unreachable_patterns)]
38#[cfg(windows)]
39impl<'a> BorrowedContainer<'a> {
40 #[cfg(feature = "win32")]
48 pub unsafe fn win32(hwnd: windows_sys::Win32::Foundation::HWND) -> Self {
49 Self(BorrowedContainerInner::Win32(hwnd, PhantomData))
50 }
51
52 #[cfg(feature = "winui")]
54 pub fn winui(container: &'a winui3::Microsoft::UI::Xaml::Controls::Canvas) -> Self {
55 Self(BorrowedContainerInner::WinUI(container))
56 }
57
58 #[cfg(feature = "win32")]
60 pub fn as_win32(&self) -> windows_sys::Win32::Foundation::HWND {
61 match &self.0 {
62 BorrowedContainerInner::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::Controls::Canvas {
70 match &self.0 {
71 BorrowedContainerInner::WinUI(container) => container,
72 _ => panic!("unsupported handle type"),
73 }
74 }
75}
76
77#[cfg(target_os = "macos")]
78impl<'a> BorrowedContainer<'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> BorrowedContainer<'a> {
93 #[cfg(feature = "qt")]
99 pub unsafe fn qt<T>(widget: *mut T) -> Self {
100 Self(BorrowedContainerInner::Qt(widget.cast(), PhantomData))
101 }
102
103 #[cfg(feature = "gtk")]
105 pub fn gtk(fixed: &'a gtk4::Fixed) -> Self {
106 Self(BorrowedContainerInner::Gtk(fixed))
107 }
108
109 #[cfg(feature = "qt")]
111 pub fn as_qt<T>(&self) -> *mut T {
112 match &self.0 {
113 BorrowedContainerInner::Qt(w, ..) => (*w).cast(),
114 _ => panic!("unsupported handle type"),
115 }
116 }
117
118 #[cfg(feature = "gtk")]
120 pub fn to_gtk(&self) -> &'a gtk4::Fixed {
121 match &self.0 {
122 BorrowedContainerInner::Gtk(w) => w,
123 _ => panic!("unsupported handle type"),
124 }
125 }
126}
127
128pub trait AsContainer {
130 fn as_container(&self) -> BorrowedContainer<'_>;
132}
133
134impl AsContainer for BorrowedContainer<'_> {
135 fn as_container(&self) -> BorrowedContainer<'_> {
136 *self
137 }
138}
139
140impl<T: AsContainer + ?Sized> AsContainer for &T {
141 #[inline]
142 fn as_container(&self) -> BorrowedContainer<'_> {
143 T::as_container(self)
144 }
145}
146
147impl<'a, T: AsContainer + ?Sized> From<&'a T> for BorrowedContainer<'a> {
148 fn from(value: &'a T) -> Self {
149 value.as_container()
150 }
151}
152
153#[doc(hidden)]
154pub struct MaybeBorrowedContainer<'a>(pub Option<BorrowedContainer<'a>>);
155
156impl<'a, T: Into<BorrowedContainer<'a>>> From<T> for MaybeBorrowedContainer<'a> {
157 fn from(value: T) -> Self {
158 Self(Some(value.into()))
159 }
160}
161
162impl<'a, T: Into<BorrowedContainer<'a>>> From<Option<T>> for MaybeBorrowedContainer<'a> {
163 fn from(value: Option<T>) -> Self {
164 Self(value.map(|v| v.into()))
165 }
166}
167
168impl From<()> for MaybeBorrowedContainer<'_> {
169 fn from(_: ()) -> Self {
170 Self(None)
171 }
172}
173
174#[doc(hidden)]
175#[macro_export]
176macro_rules! impl_as_container {
177 ($t:ty, $inner:ident) => {
178 impl $crate::AsContainer for $t {
179 fn as_container(&self) -> $crate::BorrowedContainer<'_> {
180 self.$inner.as_container()
181 }
182 }
183 };
184}