We're planning to associate "selection sources" with global element ids to allow arbitrary UI text to be selected in GPUI. Previously, global ids were not exposed outside the framework and we entangled management of the element id stack with element state access. This was more acceptable when element state was the only place we used global element ids, but now that we're planning to use them more places, it makes sense to deal with element identity as a first-class part of the element system. We now ensure that the stack of element ids which forms the current global element id is correctly managed in every phase of element layout and paint and make the global id available to each element method. In a subsequent PR, we'll use the global element id as part of implementing arbitrary selection for UI text. Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com>
86 lines
2.3 KiB
Rust
86 lines
2.3 KiB
Rust
use crate::{
|
|
AnyElement, Bounds, Element, GlobalElementId, IntoElement, LayoutId, Pixels, WindowContext,
|
|
};
|
|
|
|
/// 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 id(&self) -> Option<crate::ElementId> {
|
|
None
|
|
}
|
|
|
|
fn request_layout(
|
|
&mut self,
|
|
_id: Option<&GlobalElementId>,
|
|
cx: &mut WindowContext,
|
|
) -> (LayoutId, ()) {
|
|
let layout_id = self.child.as_mut().unwrap().request_layout(cx);
|
|
(layout_id, ())
|
|
}
|
|
|
|
fn prepaint(
|
|
&mut self,
|
|
_id: Option<&GlobalElementId>,
|
|
_bounds: Bounds<Pixels>,
|
|
_request_layout: &mut Self::RequestLayoutState,
|
|
cx: &mut WindowContext,
|
|
) {
|
|
let child = self.child.take().unwrap();
|
|
let element_offset = cx.element_offset();
|
|
cx.defer_draw(child, element_offset, self.priority)
|
|
}
|
|
|
|
fn paint(
|
|
&mut self,
|
|
_id: Option<&GlobalElementId>,
|
|
_bounds: Bounds<Pixels>,
|
|
_request_layout: &mut Self::RequestLayoutState,
|
|
_prepaint: &mut Self::PrepaintState,
|
|
_cx: &mut WindowContext,
|
|
) {
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|