1use crate::core::layout;
22use crate::core::mouse;
23use crate::core::overlay;
24use crate::core::renderer;
25use crate::core::widget;
26use crate::core::{Event, Layout, Length, Pixels, Point, Rectangle, Shell, Size, Vector, Widget};
27
28pub struct Pin<W> {
51 content: W,
52 width: Length,
53 height: Length,
54 position: Point,
55}
56
57impl<W> Pin<W> {
58 pub fn new(content: W) -> Self {
60 Self {
61 content,
62 width: Length::Fill,
63 height: Length::Fill,
64 position: Point::ORIGIN,
65 }
66 }
67
68 pub fn width(mut self, width: impl Into<Length>) -> Self {
70 self.width = width.into();
71 self
72 }
73
74 pub fn height(mut self, height: impl Into<Length>) -> Self {
76 self.height = height.into();
77 self
78 }
79
80 pub fn position(mut self, position: impl Into<Point>) -> Self {
82 self.position = position.into();
83 self
84 }
85
86 pub fn x(mut self, x: impl Into<Pixels>) -> Self {
88 self.position.x = x.into().0;
89 self
90 }
91
92 pub fn y(mut self, y: impl Into<Pixels>) -> Self {
94 self.position.y = y.into().0;
95 self
96 }
97}
98
99impl<W> widget::Meta for Pin<W> {}
100
101impl<W, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Pin<W>
102where
103 W: Widget<Message, Theme, Renderer>,
104{
105 fn tag(&self) -> widget::tree::Tag {
106 self.content.tag()
107 }
108
109 fn state(&self) -> widget::tree::State {
110 self.content.state()
111 }
112
113 fn diff(&mut self, tree: &mut widget::Tree) {
114 tree.diff_children(std::slice::from_mut(&mut self.content));
115 }
116
117 fn size(&self) -> Size<Length> {
118 Size {
119 width: self.width,
120 height: self.height,
121 }
122 }
123
124 fn layout(&mut self, tree: &mut widget::Tree, renderer: &Renderer, limits: &layout::Limits) {
125 let limits = limits.width(self.width).height(self.height);
126
127 let available = limits.bounds() - Size::new(self.position.x, self.position.y);
128
129 self.content.layout(
130 &mut tree.children[0],
131 renderer,
132 &layout::Limits::new(Size::ZERO, available),
133 );
134
135 tree.children[0].translation = Vector::new(self.position.x, self.position.y);
136 tree.size = limits.resolve(self.width, self.height, tree.children[0].size);
137 }
138
139 fn operate(
140 &mut self,
141 tree: &mut widget::Tree,
142 layout: Layout,
143 viewport: &Rectangle,
144 renderer: &Renderer,
145 operation: &mut dyn widget::Operation,
146 ) {
147 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
148
149 self.content
150 .operate(tree, layout, viewport, renderer, operation);
151 }
152
153 fn update(
154 &mut self,
155 tree: &mut widget::Tree,
156 event: &Event,
157 layout: Layout,
158 cursor: mouse::Cursor,
159 renderer: &Renderer,
160 shell: &mut Shell<'_, Message>,
161 viewport: &Rectangle,
162 ) {
163 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
164
165 self.content
166 .update(tree, event, layout, cursor, renderer, shell, viewport);
167 }
168
169 fn mouse_interaction(
170 &self,
171 tree: &widget::Tree,
172 layout: Layout,
173 cursor: mouse::Cursor,
174 viewport: &Rectangle,
175 renderer: &Renderer,
176 ) -> mouse::Interaction {
177 let (layout, tree) = layout.iter(&tree.children).next().unwrap();
178
179 self.content
180 .mouse_interaction(tree, layout, cursor, viewport, renderer)
181 }
182
183 fn draw(
184 &self,
185 tree: &widget::Tree,
186 renderer: &mut Renderer,
187 theme: &Theme,
188 style: &renderer::Style,
189 layout: Layout,
190 cursor: mouse::Cursor,
191 viewport: &Rectangle,
192 ) {
193 let bounds = layout.bounds();
194
195 if let Some(clipped_viewport) = bounds.intersection(viewport) {
196 let (layout, tree) = layout.iter(&tree.children).next().unwrap();
197
198 self.content.draw(
199 tree,
200 renderer,
201 theme,
202 style,
203 layout,
204 cursor,
205 &clipped_viewport,
206 );
207 }
208 }
209
210 fn overlay<'b>(
211 &'b mut self,
212 tree: &'b mut widget::Tree,
213 layout: Layout,
214 renderer: &Renderer,
215 viewport: &Rectangle,
216 translation: Vector,
217 window: Size,
218 ) -> Vec<overlay::Element<'b, Message, Theme, Renderer>> {
219 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
220
221 self.content
222 .overlay(tree, layout, renderer, viewport, translation, window)
223 }
224}