Files
oak-gpui/crates/gpui/src/elements/deferred.rs
T
Antonio ScandurraandNathan bcbf2f2fd3 Introduce autoscroll support for elements (#10889)
This pull request introduces the new
`ElementContext::request_autoscroll(bounds)` and
`ElementContext::take_autoscroll()` methods in GPUI. These new APIs
enable container elements such as `List` to change their scroll position
if one of their children requested an autoscroll. We plan to use this in
the revamped assistant.

As a drive-by, we also:

- Renamed `Element::before_layout` to `Element::request_layout`
- Renamed `Element::after_layout` to `Element::prepaint`
- Introduced a new `List::splice_focusable` method to splice focusable
elements into the list, which enables rendering offscreen elements that
are focused.

Release Notes:

- N/A

---------

Co-authored-by: Nathan <nathan@zed.dev>
2024-04-23 15:14:22 +02:00

74 lines
2.1 KiB
Rust

use crate::{AnyElement, Bounds, Element, ElementContext, IntoElement, LayoutId, Pixels};
/// Builds a `Deferred` element, which delays the layout and paint of its child.
pub fn deferred(child: impl IntoElement) -> Deferred {
Deferred {
child: Some(child.into_any_element()),
priority: 0,
}
}
/// An element which delays the painting of its child until after all of
/// its ancestors, while keeping its layout as part of the current element tree.
pub struct Deferred {
child: Option<AnyElement>,
priority: usize,
}
impl Deferred {
/// Sets the `priority` value of the `deferred` element, which
/// determines the drawing order relative to other deferred elements,
/// with higher values being drawn on top.
pub fn with_priority(mut self, priority: usize) -> Self {
self.priority = priority;
self
}
}
impl Element for Deferred {
type RequestLayoutState = ();
type PrepaintState = ();
fn request_layout(&mut self, cx: &mut ElementContext) -> (LayoutId, ()) {
let layout_id = self.child.as_mut().unwrap().request_layout(cx);
(layout_id, ())
}
fn prepaint(
&mut self,
_bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState,
cx: &mut ElementContext,
) {
let child = self.child.take().unwrap();
let element_offset = cx.element_offset();
cx.defer_draw(child, element_offset, self.priority)
}
fn paint(
&mut self,
_bounds: Bounds<Pixels>,
_request_layout: &mut Self::RequestLayoutState,
_prepaint: &mut Self::PrepaintState,
_cx: &mut ElementContext,
) {
}
}
impl IntoElement for Deferred {
type Element = Self;
fn into_element(self) -> Self::Element {
self
}
}
impl Deferred {
/// Sets a priority for the element. A higher priority conceptually means painting the element
/// on top of deferred draws with a lower priority (i.e. closer to the viewer).
pub fn priority(mut self, priority: usize) -> Self {
self.priority = priority;
self
}
}