1use std::{
2 borrow::Borrow,
3 cell::RefCell,
4 rc::Rc,
5 thread::{self, ThreadId},
6};
7
8use crate::Element;
9use iced::{Length, Rectangle, Size, event};
10use iced_core::{Widget, id::Id, widget, widget::tree};
11
12#[derive(Debug)]
13pub struct RcWrapper<T> {
14 pub(crate) data: Rc<RefCell<T>>,
15 pub(crate) thread_id: ThreadId,
16}
17
18impl<T: Default> Default for RcWrapper<T> {
19 fn default() -> Self {
20 Self::new(T::default())
21 }
22}
23
24impl<T> Clone for RcWrapper<T> {
25 fn clone(&self) -> Self {
26 Self {
27 data: self.data.clone(),
28 thread_id: self.thread_id,
29 }
30 }
31}
32
33unsafe impl<M: 'static> Send for RcWrapper<M> {}
34unsafe impl<M: 'static> Sync for RcWrapper<M> {}
35
36impl<T> RcWrapper<T> {
37 pub fn new(element: T) -> Self {
38 Self {
39 data: Rc::new(RefCell::new(element)),
40 thread_id: thread::current().id(),
41 }
42 }
43
44 pub fn with_data<O>(&self, f: impl FnOnce(&T) -> O) -> O {
48 assert_eq!(self.thread_id, thread::current().id());
49 let my_ref: &T = &RefCell::borrow(self.data.as_ref());
50 f(my_ref)
51 }
52
53 pub fn with_data_mut<O>(&self, f: impl FnOnce(&mut T) -> O) -> O {
57 assert_eq!(self.thread_id, thread::current().id());
58 let my_refmut: &mut T = &mut RefCell::borrow_mut(self.data.as_ref());
59 f(my_refmut)
60 }
61
62 pub(crate) unsafe fn as_ptr(&self) -> *mut T {
66 assert_eq!(self.thread_id, thread::current().id());
67 RefCell::as_ptr(self.data.as_ref())
68 }
69}
70
71#[derive(Clone)]
72pub struct RcElementWrapper<M> {
73 pub(crate) element: RcWrapper<Element<'static, M>>,
74}
75
76impl<M> RcElementWrapper<M> {
77 #[must_use]
78 pub fn new(element: Element<'static, M>) -> Self {
79 RcElementWrapper {
80 element: RcWrapper::new(element),
81 }
82 }
83}
84
85impl<M: 'static> Borrow<dyn Widget<M, crate::Theme, crate::Renderer>> for RcElementWrapper<M> {
86 fn borrow(&self) -> &(dyn Widget<M, crate::Theme, crate::Renderer> + 'static) {
87 self
88 }
89}
90
91impl<M> Widget<M, crate::Theme, crate::Renderer> for RcElementWrapper<M> {
92 fn size(&self) -> Size<Length> {
93 self.element.with_data(|e| e.as_widget().size())
94 }
95
96 fn size_hint(&self) -> Size<Length> {
97 self.element.with_data(move |e| e.as_widget().size_hint())
98 }
99
100 fn layout(
101 &self,
102 tree: &mut tree::Tree,
103 renderer: &crate::Renderer,
104 limits: &crate::iced_core::layout::Limits,
105 ) -> crate::iced_core::layout::Node {
106 self.element
107 .with_data_mut(|e| e.as_widget_mut().layout(tree, renderer, limits))
108 }
109
110 fn draw(
111 &self,
112 tree: &tree::Tree,
113 renderer: &mut crate::Renderer,
114 theme: &crate::Theme,
115 style: &crate::iced_core::renderer::Style,
116 layout: crate::iced_core::Layout<'_>,
117 cursor: crate::iced_core::mouse::Cursor,
118 viewport: &Rectangle,
119 ) {
120 self.element.with_data(move |e| {
121 e.as_widget()
122 .draw(tree, renderer, theme, style, layout, cursor, viewport);
123 });
124 }
125
126 fn tag(&self) -> tree::Tag {
127 self.element.with_data(|e| e.as_widget().tag())
128 }
129
130 fn state(&self) -> tree::State {
131 self.element.with_data(|e| e.as_widget().state())
132 }
133
134 fn children(&self) -> Vec<tree::Tree> {
135 self.element.with_data(|e| e.as_widget().children())
136 }
137
138 fn diff(&mut self, tree: &mut tree::Tree) {
139 self.element.with_data_mut(|e| e.as_widget_mut().diff(tree));
140 }
141
142 fn operate(
143 &self,
144 state: &mut tree::Tree,
145 layout: crate::iced_core::Layout<'_>,
146 renderer: &crate::Renderer,
147 operation: &mut dyn widget::Operation,
148 ) {
149 self.element.with_data(|e| {
150 e.as_widget().operate(state, layout, renderer, operation);
151 });
152 }
153
154 fn on_event(
155 &mut self,
156 state: &mut tree::Tree,
157 event: crate::iced::Event,
158 layout: crate::iced_core::Layout<'_>,
159 cursor: crate::iced_core::mouse::Cursor,
160 renderer: &crate::Renderer,
161 clipboard: &mut dyn crate::iced_core::Clipboard,
162 shell: &mut crate::iced_core::Shell<'_, M>,
163 viewport: &Rectangle,
164 ) -> event::Status {
165 self.element.with_data_mut(|e| {
166 e.as_widget_mut().on_event(
167 state, event, layout, cursor, renderer, clipboard, shell, viewport,
168 )
169 })
170 }
171
172 fn mouse_interaction(
173 &self,
174 state: &tree::Tree,
175 layout: crate::iced_core::Layout<'_>,
176 cursor: crate::iced_core::mouse::Cursor,
177 viewport: &Rectangle,
178 renderer: &crate::Renderer,
179 ) -> crate::iced_core::mouse::Interaction {
180 self.element.with_data(|e| {
181 e.as_widget()
182 .mouse_interaction(state, layout, cursor, viewport, renderer)
183 })
184 }
185
186 fn overlay<'a>(
187 &'a mut self,
188 state: &'a mut tree::Tree,
189 layout: crate::iced_core::Layout<'_>,
190 renderer: &crate::Renderer,
191 translation: crate::iced_core::Vector,
192 ) -> Option<crate::iced_core::overlay::Element<'a, M, crate::Theme, crate::Renderer>> {
193 assert_eq!(self.element.thread_id, thread::current().id());
194 Rc::get_mut(&mut self.element.data).and_then(|e| {
195 e.get_mut()
196 .as_widget_mut()
197 .overlay(state, layout, renderer, translation)
198 })
199 }
200
201 fn id(&self) -> Option<Id> {
202 self.element.with_data_mut(|e| e.as_widget_mut().id())
203 }
204
205 fn set_id(&mut self, id: Id) {
206 self.element.with_data_mut(|e| e.as_widget_mut().set_id(id));
207 }
208
209 fn drag_destinations(
210 &self,
211 state: &tree::Tree,
212 layout: crate::iced_core::Layout<'_>,
213 renderer: &crate::Renderer,
214 dnd_rectangles: &mut crate::iced_core::clipboard::DndDestinationRectangles,
215 ) {
216 self.element.with_data_mut(|e| {
217 e.as_widget_mut()
218 .drag_destinations(state, layout, renderer, dnd_rectangles);
219 });
220 }
221}
222
223impl<Message: 'static> From<RcElementWrapper<Message>> for Element<'static, Message> {
224 fn from(wrapper: RcElementWrapper<Message>) -> Self {
225 Element::new(wrapper)
226 }
227}
228
229impl<Message: 'static> From<Element<'static, Message>> for RcElementWrapper<Message> {
230 fn from(e: Element<'static, Message>) -> Self {
231 RcElementWrapper::new(e)
232 }
233}