1use std::{
2 any::{Any, TypeId},
3 borrow::{Borrow, BorrowMut, Cow},
4 mem,
5 rc::Rc,
6 sync::Arc,
7};
8
9use anyhow::Result;
10use derive_more::{Deref, DerefMut};
11use media::core_video::CVImageBuffer;
12use util::post_inc;
13
14use crate::{
15 prelude::*, size, AppContext, AvailableSpace, Bounds, BoxShadow, ContentMask, Corners,
16 DevicePixels, DispatchPhase, ElementId, ElementStateBox, EntityId, FocusHandle, FontId,
17 GlyphId, Hsla, ImageData, InputHandler, IsZero, KeyContext, KeyEvent, LayoutId,
18 MonochromeSprite, MouseEvent, PaintQuad, Path, Pixels, PlatformInputHandler, Point,
19 PolychromeSprite, Quad, RenderGlyphParams, RenderImageParams, RenderSvgParams, Shadow,
20 SharedString, Size, Style, Surface, Underline, UnderlineStyle, Window, WindowContext,
21 SUBPIXEL_VARIANTS,
22};
23
24use super::RequestedInputHandler;
25
26/// This context is used for assisting in the implementation of the element trait
27#[derive(Deref, DerefMut)]
28pub struct ElementContext<'a> {
29 pub(crate) cx: WindowContext<'a>,
30}
31
32impl<'a> WindowContext<'a> {
33 pub fn with_element_context<R>(&mut self, f: impl FnOnce(&mut ElementContext) -> R) -> R {
34 f(&mut ElementContext {
35 cx: WindowContext::new(self.app, self.window),
36 })
37 }
38}
39
40impl<'a> Borrow<AppContext> for ElementContext<'a> {
41 fn borrow(&self) -> &AppContext {
42 self.cx.app
43 }
44}
45
46impl<'a> BorrowMut<AppContext> for ElementContext<'a> {
47 fn borrow_mut(&mut self) -> &mut AppContext {
48 self.cx.borrow_mut()
49 }
50}
51
52impl<'a> Borrow<WindowContext<'a>> for ElementContext<'a> {
53 fn borrow(&self) -> &WindowContext<'a> {
54 &self.cx
55 }
56}
57
58impl<'a> BorrowMut<WindowContext<'a>> for ElementContext<'a> {
59 fn borrow_mut(&mut self) -> &mut WindowContext<'a> {
60 &mut self.cx
61 }
62}
63
64impl<'a> Borrow<Window> for ElementContext<'a> {
65 fn borrow(&self) -> &Window {
66 self.cx.window
67 }
68}
69
70impl<'a> BorrowMut<Window> for ElementContext<'a> {
71 fn borrow_mut(&mut self) -> &mut Window {
72 self.cx.borrow_mut()
73 }
74}
75
76impl<'a> Context for ElementContext<'a> {
77 type Result<T> = <WindowContext<'a> as Context>::Result<T>;
78
79 fn new_model<T: 'static>(
80 &mut self,
81 build_model: impl FnOnce(&mut crate::ModelContext<'_, T>) -> T,
82 ) -> Self::Result<crate::Model<T>> {
83 self.cx.new_model(build_model)
84 }
85
86 fn update_model<T, R>(
87 &mut self,
88 handle: &crate::Model<T>,
89 update: impl FnOnce(&mut T, &mut crate::ModelContext<'_, T>) -> R,
90 ) -> Self::Result<R>
91 where
92 T: 'static,
93 {
94 self.cx.update_model(handle, update)
95 }
96
97 fn read_model<T, R>(
98 &self,
99 handle: &crate::Model<T>,
100 read: impl FnOnce(&T, &AppContext) -> R,
101 ) -> Self::Result<R>
102 where
103 T: 'static,
104 {
105 self.cx.read_model(handle, read)
106 }
107
108 fn update_window<T, F>(&mut self, window: crate::AnyWindowHandle, f: F) -> Result<T>
109 where
110 F: FnOnce(crate::AnyView, &mut WindowContext<'_>) -> T,
111 {
112 self.cx.update_window(window, f)
113 }
114
115 fn read_window<T, R>(
116 &self,
117 window: &crate::WindowHandle<T>,
118 read: impl FnOnce(crate::View<T>, &AppContext) -> R,
119 ) -> Result<R>
120 where
121 T: 'static,
122 {
123 self.cx.read_window(window, read)
124 }
125}
126
127impl<'a> VisualContext for ElementContext<'a> {
128 fn new_view<V>(
129 &mut self,
130 build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
131 ) -> Self::Result<crate::View<V>>
132 where
133 V: 'static + Render,
134 {
135 self.cx.new_view(build_view)
136 }
137
138 fn update_view<V: 'static, R>(
139 &mut self,
140 view: &crate::View<V>,
141 update: impl FnOnce(&mut V, &mut crate::ViewContext<'_, V>) -> R,
142 ) -> Self::Result<R> {
143 self.cx.update_view(view, update)
144 }
145
146 fn replace_root_view<V>(
147 &mut self,
148 build_view: impl FnOnce(&mut crate::ViewContext<'_, V>) -> V,
149 ) -> Self::Result<crate::View<V>>
150 where
151 V: 'static + Render,
152 {
153 self.cx.replace_root_view(build_view)
154 }
155
156 fn focus_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
157 where
158 V: crate::FocusableView,
159 {
160 self.cx.focus_view(view)
161 }
162
163 fn dismiss_view<V>(&mut self, view: &crate::View<V>) -> Self::Result<()>
164 where
165 V: crate::ManagedView,
166 {
167 self.cx.dismiss_view(view)
168 }
169}
170
171impl<'a> ElementContext<'a> {
172 /// Pushes the given element id onto the global stack and invokes the given closure
173 /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor
174 /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is
175 /// used to associate state with identified elements across separate frames.
176 pub fn with_element_id<R>(
177 &mut self,
178 id: Option<impl Into<ElementId>>,
179 f: impl FnOnce(&mut Self) -> R,
180 ) -> R {
181 if let Some(id) = id.map(Into::into) {
182 let window = self.window_mut();
183 window.element_id_stack.push(id);
184 let result = f(self);
185 let window: &mut Window = self.borrow_mut();
186 window.element_id_stack.pop();
187 result
188 } else {
189 f(self)
190 }
191 }
192
193 /// Invoke the given function with the given content mask after intersecting it
194 /// with the current mask.
195 pub fn with_content_mask<R>(
196 &mut self,
197 mask: Option<ContentMask<Pixels>>,
198 f: impl FnOnce(&mut Self) -> R,
199 ) -> R {
200 if let Some(mask) = mask {
201 let mask = mask.intersect(&self.content_mask());
202 self.window_mut().next_frame.content_mask_stack.push(mask);
203 let result = f(self);
204 self.window_mut().next_frame.content_mask_stack.pop();
205 result
206 } else {
207 f(self)
208 }
209 }
210
211 /// Invoke the given function with the content mask reset to that
212 /// of the window.
213 pub fn break_content_mask<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
214 let mask = ContentMask {
215 bounds: Bounds {
216 origin: Point::default(),
217 size: self.window().viewport_size,
218 },
219 };
220 let new_stacking_order_id =
221 post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
222 let new_root_z_index = post_inc(&mut self.window_mut().next_frame.next_root_z_index);
223 let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
224 self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
225 self.window_mut()
226 .next_frame
227 .z_index_stack
228 .push(new_root_z_index);
229 self.window_mut().next_frame.content_mask_stack.push(mask);
230 let result = f(self);
231 self.window_mut().next_frame.content_mask_stack.pop();
232 self.window_mut().next_frame.z_index_stack = old_stacking_order;
233 result
234 }
235
236 /// Called during painting to invoke the given closure in a new stacking context. The given
237 /// z-index is interpreted relative to the previous call to `stack`.
238 pub fn with_z_index<R>(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R {
239 let new_stacking_order_id =
240 post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
241 let old_stacking_order_id = mem::replace(
242 &mut self.window_mut().next_frame.z_index_stack.id,
243 new_stacking_order_id,
244 );
245 self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
246 self.window_mut().next_frame.z_index_stack.push(z_index);
247 let result = f(self);
248 self.window_mut().next_frame.z_index_stack.id = old_stacking_order_id;
249 self.window_mut().next_frame.z_index_stack.pop();
250 result
251 }
252
253 /// Updates the global element offset relative to the current offset. This is used to implement
254 /// scrolling.
255 pub fn with_element_offset<R>(
256 &mut self,
257 offset: Point<Pixels>,
258 f: impl FnOnce(&mut Self) -> R,
259 ) -> R {
260 if offset.is_zero() {
261 return f(self);
262 };
263
264 let abs_offset = self.element_offset() + offset;
265 self.with_absolute_element_offset(abs_offset, f)
266 }
267
268 /// Updates the global element offset based on the given offset. This is used to implement
269 /// drag handles and other manual painting of elements.
270 pub fn with_absolute_element_offset<R>(
271 &mut self,
272 offset: Point<Pixels>,
273 f: impl FnOnce(&mut Self) -> R,
274 ) -> R {
275 self.window_mut()
276 .next_frame
277 .element_offset_stack
278 .push(offset);
279 let result = f(self);
280 self.window_mut().next_frame.element_offset_stack.pop();
281 result
282 }
283
284 /// Obtain the current element offset.
285 pub fn element_offset(&self) -> Point<Pixels> {
286 self.window()
287 .next_frame
288 .element_offset_stack
289 .last()
290 .copied()
291 .unwrap_or_default()
292 }
293
294 /// Obtain the current content mask.
295 pub fn content_mask(&self) -> ContentMask<Pixels> {
296 self.window()
297 .next_frame
298 .content_mask_stack
299 .last()
300 .cloned()
301 .unwrap_or_else(|| ContentMask {
302 bounds: Bounds {
303 origin: Point::default(),
304 size: self.window().viewport_size,
305 },
306 })
307 }
308
309 /// The size of an em for the base font of the application. Adjusting this value allows the
310 /// UI to scale, just like zooming a web page.
311 pub fn rem_size(&self) -> Pixels {
312 self.window().rem_size
313 }
314
315 /// Updates or initializes state for an element with the given id that lives across multiple
316 /// frames. If an element with this ID existed in the rendered frame, its state will be passed
317 /// to the given closure. The state returned by the closure will be stored so it can be referenced
318 /// when drawing the next frame.
319 pub fn with_element_state<S, R>(
320 &mut self,
321 id: ElementId,
322 f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
323 ) -> R
324 where
325 S: 'static,
326 {
327 self.with_element_id(Some(id), |cx| {
328 let global_id = cx.window().element_id_stack.clone();
329
330 if let Some(any) = cx
331 .window_mut()
332 .next_frame
333 .element_states
334 .remove(&global_id)
335 .or_else(|| {
336 cx.window_mut()
337 .rendered_frame
338 .element_states
339 .remove(&global_id)
340 })
341 {
342 let ElementStateBox {
343 inner,
344 parent_view_id,
345 #[cfg(debug_assertions)]
346 type_name
347 } = any;
348 // Using the extra inner option to avoid needing to reallocate a new box.
349 let mut state_box = inner
350 .downcast::<Option<S>>()
351 .map_err(|_| {
352 #[cfg(debug_assertions)]
353 {
354 anyhow::anyhow!(
355 "invalid element state type for id, requested_type {:?}, actual type: {:?}",
356 std::any::type_name::<S>(),
357 type_name
358 )
359 }
360
361 #[cfg(not(debug_assertions))]
362 {
363 anyhow::anyhow!(
364 "invalid element state type for id, requested_type {:?}",
365 std::any::type_name::<S>(),
366 )
367 }
368 })
369 .unwrap();
370
371 // Actual: Option<AnyElement> <- View
372 // Requested: () <- AnyElement
373 let state = state_box
374 .take()
375 .expect("element state is already on the stack");
376 let (result, state) = f(Some(state), cx);
377 state_box.replace(state);
378 cx.window_mut()
379 .next_frame
380 .element_states
381 .insert(global_id, ElementStateBox {
382 inner: state_box,
383 parent_view_id,
384 #[cfg(debug_assertions)]
385 type_name
386 });
387 result
388 } else {
389 let (result, state) = f(None, cx);
390 let parent_view_id = cx.parent_view_id();
391 cx.window_mut()
392 .next_frame
393 .element_states
394 .insert(global_id,
395 ElementStateBox {
396 inner: Box::new(Some(state)),
397 parent_view_id,
398 #[cfg(debug_assertions)]
399 type_name: std::any::type_name::<S>()
400 }
401
402 );
403 result
404 }
405 })
406 }
407 /// Paint one or more drop shadows into the scene for the next frame at the current z-index.
408 pub fn paint_shadows(
409 &mut self,
410 bounds: Bounds<Pixels>,
411 corner_radii: Corners<Pixels>,
412 shadows: &[BoxShadow],
413 ) {
414 let scale_factor = self.scale_factor();
415 let content_mask = self.content_mask();
416 let view_id = self.parent_view_id();
417 let window = &mut *self.window;
418 for shadow in shadows {
419 let mut shadow_bounds = bounds;
420 shadow_bounds.origin += shadow.offset;
421 shadow_bounds.dilate(shadow.spread_radius);
422 window.next_frame.scene.insert(
423 &window.next_frame.z_index_stack,
424 Shadow {
425 view_id: view_id.into(),
426 layer_id: 0,
427 order: 0,
428 bounds: shadow_bounds.scale(scale_factor),
429 content_mask: content_mask.scale(scale_factor),
430 corner_radii: corner_radii.scale(scale_factor),
431 color: shadow.color,
432 blur_radius: shadow.blur_radius.scale(scale_factor),
433 },
434 );
435 }
436 }
437
438 /// Paint one or more quads into the scene for the next frame at the current stacking context.
439 /// Quads are colored rectangular regions with an optional background, border, and corner radius.
440 /// see [`fill`], [`outline`], and [`quad`] to construct this type.
441 pub fn paint_quad(&mut self, quad: PaintQuad) {
442 let scale_factor = self.scale_factor();
443 let content_mask = self.content_mask();
444 let view_id = self.parent_view_id();
445
446 let window = &mut *self.window;
447 window.next_frame.scene.insert(
448 &window.next_frame.z_index_stack,
449 Quad {
450 view_id: view_id.into(),
451 layer_id: 0,
452 order: 0,
453 bounds: quad.bounds.scale(scale_factor),
454 content_mask: content_mask.scale(scale_factor),
455 background: quad.background,
456 border_color: quad.border_color,
457 corner_radii: quad.corner_radii.scale(scale_factor),
458 border_widths: quad.border_widths.scale(scale_factor),
459 },
460 );
461 }
462
463 /// Paint the given `Path` into the scene for the next frame at the current z-index.
464 pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
465 let scale_factor = self.scale_factor();
466 let content_mask = self.content_mask();
467 let view_id = self.parent_view_id();
468
469 path.content_mask = content_mask;
470 path.color = color.into();
471 path.view_id = view_id.into();
472 let window = &mut *self.window;
473 window
474 .next_frame
475 .scene
476 .insert(&window.next_frame.z_index_stack, path.scale(scale_factor));
477 }
478
479 /// Paint an underline into the scene for the next frame at the current z-index.
480 pub fn paint_underline(
481 &mut self,
482 origin: Point<Pixels>,
483 width: Pixels,
484 style: &UnderlineStyle,
485 ) {
486 let scale_factor = self.scale_factor();
487 let height = if style.wavy {
488 style.thickness * 3.
489 } else {
490 style.thickness
491 };
492 let bounds = Bounds {
493 origin,
494 size: size(width, height),
495 };
496 let content_mask = self.content_mask();
497 let view_id = self.parent_view_id();
498
499 let window = &mut *self.window;
500 window.next_frame.scene.insert(
501 &window.next_frame.z_index_stack,
502 Underline {
503 view_id: view_id.into(),
504 layer_id: 0,
505 order: 0,
506 bounds: bounds.scale(scale_factor),
507 content_mask: content_mask.scale(scale_factor),
508 thickness: style.thickness.scale(scale_factor),
509 color: style.color.unwrap_or_default(),
510 wavy: style.wavy,
511 },
512 );
513 }
514
515 /// Paint a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
516 /// The y component of the origin is the baseline of the glyph.
517 pub fn paint_glyph(
518 &mut self,
519 origin: Point<Pixels>,
520 font_id: FontId,
521 glyph_id: GlyphId,
522 font_size: Pixels,
523 color: Hsla,
524 ) -> Result<()> {
525 let scale_factor = self.scale_factor();
526 let glyph_origin = origin.scale(scale_factor);
527 let subpixel_variant = Point {
528 x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
529 y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
530 };
531 let params = RenderGlyphParams {
532 font_id,
533 glyph_id,
534 font_size,
535 subpixel_variant,
536 scale_factor,
537 is_emoji: false,
538 };
539
540 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
541 if !raster_bounds.is_zero() {
542 let tile =
543 self.window
544 .sprite_atlas
545 .get_or_insert_with(¶ms.clone().into(), &mut || {
546 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
547 Ok((size, Cow::Owned(bytes)))
548 })?;
549 let bounds = Bounds {
550 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
551 size: tile.bounds.size.map(Into::into),
552 };
553 let content_mask = self.content_mask().scale(scale_factor);
554 let view_id = self.parent_view_id();
555 let window = &mut *self.window;
556 window.next_frame.scene.insert(
557 &window.next_frame.z_index_stack,
558 MonochromeSprite {
559 view_id: view_id.into(),
560 layer_id: 0,
561 order: 0,
562 bounds,
563 content_mask,
564 color,
565 tile,
566 },
567 );
568 }
569 Ok(())
570 }
571
572 /// Paint an emoji glyph into the scene for the next frame at the current z-index.
573 /// The y component of the origin is the baseline of the glyph.
574 pub fn paint_emoji(
575 &mut self,
576 origin: Point<Pixels>,
577 font_id: FontId,
578 glyph_id: GlyphId,
579 font_size: Pixels,
580 ) -> Result<()> {
581 let scale_factor = self.scale_factor();
582 let glyph_origin = origin.scale(scale_factor);
583 let params = RenderGlyphParams {
584 font_id,
585 glyph_id,
586 font_size,
587 // We don't render emojis with subpixel variants.
588 subpixel_variant: Default::default(),
589 scale_factor,
590 is_emoji: true,
591 };
592
593 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
594 if !raster_bounds.is_zero() {
595 let tile =
596 self.window
597 .sprite_atlas
598 .get_or_insert_with(¶ms.clone().into(), &mut || {
599 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
600 Ok((size, Cow::Owned(bytes)))
601 })?;
602 let bounds = Bounds {
603 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
604 size: tile.bounds.size.map(Into::into),
605 };
606 let content_mask = self.content_mask().scale(scale_factor);
607 let view_id = self.parent_view_id();
608 let window = &mut *self.window;
609
610 window.next_frame.scene.insert(
611 &window.next_frame.z_index_stack,
612 PolychromeSprite {
613 view_id: view_id.into(),
614 layer_id: 0,
615 order: 0,
616 bounds,
617 corner_radii: Default::default(),
618 content_mask,
619 tile,
620 grayscale: false,
621 },
622 );
623 }
624 Ok(())
625 }
626
627 /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
628 pub fn paint_svg(
629 &mut self,
630 bounds: Bounds<Pixels>,
631 path: SharedString,
632 color: Hsla,
633 ) -> Result<()> {
634 let scale_factor = self.scale_factor();
635 let bounds = bounds.scale(scale_factor);
636 // Render the SVG at twice the size to get a higher quality result.
637 let params = RenderSvgParams {
638 path,
639 size: bounds
640 .size
641 .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
642 };
643
644 let tile =
645 self.window
646 .sprite_atlas
647 .get_or_insert_with(¶ms.clone().into(), &mut || {
648 let bytes = self.svg_renderer.render(¶ms)?;
649 Ok((params.size, Cow::Owned(bytes)))
650 })?;
651 let content_mask = self.content_mask().scale(scale_factor);
652 let view_id = self.parent_view_id();
653
654 let window = &mut *self.window;
655 window.next_frame.scene.insert(
656 &window.next_frame.z_index_stack,
657 MonochromeSprite {
658 view_id: view_id.into(),
659 layer_id: 0,
660 order: 0,
661 bounds,
662 content_mask,
663 color,
664 tile,
665 },
666 );
667
668 Ok(())
669 }
670
671 /// Paint an image into the scene for the next frame at the current z-index.
672 pub fn paint_image(
673 &mut self,
674 bounds: Bounds<Pixels>,
675 corner_radii: Corners<Pixels>,
676 data: Arc<ImageData>,
677 grayscale: bool,
678 ) -> Result<()> {
679 let scale_factor = self.scale_factor();
680 let bounds = bounds.scale(scale_factor);
681 let params = RenderImageParams { image_id: data.id };
682
683 let tile = self
684 .window
685 .sprite_atlas
686 .get_or_insert_with(¶ms.clone().into(), &mut || {
687 Ok((data.size(), Cow::Borrowed(data.as_bytes())))
688 })?;
689 let content_mask = self.content_mask().scale(scale_factor);
690 let corner_radii = corner_radii.scale(scale_factor);
691 let view_id = self.parent_view_id();
692
693 let window = &mut *self.window;
694 window.next_frame.scene.insert(
695 &window.next_frame.z_index_stack,
696 PolychromeSprite {
697 view_id: view_id.into(),
698 layer_id: 0,
699 order: 0,
700 bounds,
701 content_mask,
702 corner_radii,
703 tile,
704 grayscale,
705 },
706 );
707 Ok(())
708 }
709
710 /// Paint a surface into the scene for the next frame at the current z-index.
711 pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVImageBuffer) {
712 let scale_factor = self.scale_factor();
713 let bounds = bounds.scale(scale_factor);
714 let content_mask = self.content_mask().scale(scale_factor);
715 let view_id = self.parent_view_id();
716 let window = &mut *self.window;
717 window.next_frame.scene.insert(
718 &window.next_frame.z_index_stack,
719 Surface {
720 view_id: view_id.into(),
721 layer_id: 0,
722 order: 0,
723 bounds,
724 content_mask,
725 image_buffer,
726 },
727 );
728 }
729
730 #[must_use]
731 /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
732 /// layout is being requested, along with the layout ids of any children. This method is called during
733 /// calls to the `Element::layout` trait method and enables any element to participate in layout.
734 pub fn request_layout(
735 &mut self,
736 style: &Style,
737 children: impl IntoIterator<Item = LayoutId>,
738 ) -> LayoutId {
739 self.app.layout_id_buffer.clear();
740 self.app.layout_id_buffer.extend(children);
741 let rem_size = self.rem_size();
742
743 self.cx
744 .window
745 .layout_engine
746 .as_mut()
747 .unwrap()
748 .request_layout(style, rem_size, &self.cx.app.layout_id_buffer)
749 }
750
751 /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
752 /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
753 /// determine the element's size. One place this is used internally is when measuring text.
754 ///
755 /// The given closure is invoked at layout time with the known dimensions and available space and
756 /// returns a `Size`.
757 pub fn request_measured_layout<
758 F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut WindowContext) -> Size<Pixels>
759 + 'static,
760 >(
761 &mut self,
762 style: Style,
763 measure: F,
764 ) -> LayoutId {
765 let rem_size = self.rem_size();
766 self.window
767 .layout_engine
768 .as_mut()
769 .unwrap()
770 .request_measured_layout(style, rem_size, measure)
771 }
772
773 /// Compute the layout for the given id within the given available space.
774 /// This method is called for its side effect, typically by the framework prior to painting.
775 /// After calling it, you can request the bounds of the given layout node id or any descendant.
776 pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
777 let mut layout_engine = self.window.layout_engine.take().unwrap();
778 layout_engine.compute_layout(layout_id, available_space, self);
779 self.window.layout_engine = Some(layout_engine);
780 }
781
782 /// Obtain the bounds computed for the given LayoutId relative to the window. This method should not
783 /// be invoked until the paint phase begins, and will usually be invoked by GPUI itself automatically
784 /// in order to pass your element its `Bounds` automatically.
785 pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
786 let mut bounds = self
787 .window
788 .layout_engine
789 .as_mut()
790 .unwrap()
791 .layout_bounds(layout_id)
792 .map(Into::into);
793 bounds.origin += self.element_offset();
794 bounds
795 }
796
797 pub(crate) fn layout_style(&self, layout_id: LayoutId) -> Option<&Style> {
798 self.window
799 .layout_engine
800 .as_ref()
801 .unwrap()
802 .requested_style(layout_id)
803 }
804
805 /// Called during painting to track which z-index is on top at each pixel position
806 pub fn add_opaque_layer(&mut self, bounds: Bounds<Pixels>) {
807 let stacking_order = self.window.next_frame.z_index_stack.clone();
808 let view_id = self.parent_view_id();
809 let depth_map = &mut self.window.next_frame.depth_map;
810 match depth_map.binary_search_by(|(level, _, _)| stacking_order.cmp(level)) {
811 Ok(i) | Err(i) => depth_map.insert(i, (stacking_order, view_id, bounds)),
812 }
813 }
814
815 /// Invoke the given function with the given focus handle present on the key dispatch stack.
816 /// If you want an element to participate in key dispatch, use this method to push its key context and focus handle into the stack during paint.
817 pub fn with_key_dispatch<R>(
818 &mut self,
819 context: Option<KeyContext>,
820 focus_handle: Option<FocusHandle>,
821 f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
822 ) -> R {
823 let window = &mut self.window;
824 let focus_id = focus_handle.as_ref().map(|handle| handle.id);
825 window
826 .next_frame
827 .dispatch_tree
828 .push_node(context.clone(), focus_id, None);
829
830 let result = f(focus_handle, self);
831
832 self.window.next_frame.dispatch_tree.pop_node();
833
834 result
835 }
836
837 /// Invoke the given function with the given view id present on the view stack.
838 /// This is a fairly low-level method used to layout views.
839 pub fn with_view_id<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
840 let text_system = self.text_system().clone();
841 text_system.with_view(view_id, || {
842 if self.window.next_frame.view_stack.last() == Some(&view_id) {
843 return f(self);
844 } else {
845 self.window.next_frame.view_stack.push(view_id);
846 let result = f(self);
847 self.window.next_frame.view_stack.pop();
848 result
849 }
850 })
851 }
852
853 /// Invoke the given function with the given view id present on the view stack.
854 /// This is a fairly low-level method used to paint views.
855 pub fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
856 let text_system = self.text_system().clone();
857 text_system.with_view(view_id, || {
858 if self.window.next_frame.view_stack.last() == Some(&view_id) {
859 return f(self);
860 } else {
861 self.window.next_frame.view_stack.push(view_id);
862 self.window
863 .next_frame
864 .dispatch_tree
865 .push_node(None, None, Some(view_id));
866 let result = f(self);
867 self.window.next_frame.dispatch_tree.pop_node();
868 self.window.next_frame.view_stack.pop();
869 result
870 }
871 })
872 }
873
874 /// Sets an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
875 /// platform to receive textual input with proper integration with concerns such
876 /// as IME interactions. This handler will be active for the upcoming frame until the following frame is
877 /// rendered.
878 ///
879 /// [element_input_handler]: crate::ElementInputHandler
880 pub fn handle_input(&mut self, focus_handle: &FocusHandle, input_handler: impl InputHandler) {
881 if focus_handle.is_focused(self) {
882 let view_id = self.parent_view_id();
883 self.window.next_frame.requested_input_handler = Some(RequestedInputHandler {
884 view_id,
885 handler: Some(PlatformInputHandler::new(
886 self.to_async(),
887 Box::new(input_handler),
888 )),
889 })
890 }
891 }
892
893 /// Register a mouse event listener on the window for the next frame. The type of event
894 /// is determined by the first parameter of the given listener. When the next frame is rendered
895 /// the listener will be cleared.
896 pub fn on_mouse_event<Event: MouseEvent>(
897 &mut self,
898 mut handler: impl FnMut(&Event, DispatchPhase, &mut ElementContext) + 'static,
899 ) {
900 let view_id = self.parent_view_id();
901 let order = self.window.next_frame.z_index_stack.clone();
902 self.window
903 .next_frame
904 .mouse_listeners
905 .entry(TypeId::of::<Event>())
906 .or_default()
907 .push((
908 order,
909 view_id,
910 Box::new(
911 move |event: &dyn Any, phase: DispatchPhase, cx: &mut ElementContext<'_>| {
912 handler(event.downcast_ref().unwrap(), phase, cx)
913 },
914 ),
915 ))
916 }
917
918 /// Register a key event listener on the window for the next frame. The type of event
919 /// is determined by the first parameter of the given listener. When the next frame is rendered
920 /// the listener will be cleared.
921 ///
922 /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
923 /// a specific need to register a global listener.
924 pub fn on_key_event<Event: KeyEvent>(
925 &mut self,
926 listener: impl Fn(&Event, DispatchPhase, &mut ElementContext) + 'static,
927 ) {
928 self.window.next_frame.dispatch_tree.on_key_event(Rc::new(
929 move |event: &dyn Any, phase, cx: &mut ElementContext<'_>| {
930 if let Some(event) = event.downcast_ref::<Event>() {
931 listener(event, phase, cx)
932 }
933 },
934 ));
935 }
936}