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>
74 lines
2.1 KiB
Rust
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
|
|
}
|
|
}
|