gpui: Simplify uniform list API by removing entity param (#32480)

This PR also introduces `Context::processor`, a sibling of
`Context::listener` that takes a strong pointer to entity and allows for
a return result.

Release Notes:

- N/A

Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
Ben Kunkle 2025-06-10 13:50:57 -05:00 committed by GitHub
parent c55630889a
commit f567bb52ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 80 additions and 77 deletions

View file

@ -378,8 +378,6 @@ impl DataTable {
impl Render for DataTable {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let entity = cx.entity();
div()
.font_family(".SystemUIFont")
.bg(gpui::white())
@ -431,8 +429,10 @@ impl Render for DataTable {
.relative()
.size_full()
.child(
uniform_list(entity, "items", self.quotes.len(), {
move |this, range, _, _| {
uniform_list(
"items",
self.quotes.len(),
cx.processor(move |this, range: Range<usize>, _, _| {
this.visible_range = range.clone();
let mut items = Vec::with_capacity(range.end - range.start);
for i in range {
@ -441,8 +441,8 @@ impl Render for DataTable {
}
}
items
}
})
}),
)
.size_full()
.track_scroll(self.scroll_handle.clone()),
)

View file

@ -9,10 +9,9 @@ impl Render for UniformListExample {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
div().size_full().bg(rgb(0xffffff)).child(
uniform_list(
cx.entity().clone(),
"entries",
50,
|_this, range, _window, _cx| {
cx.processor(|_this, range, _window, _cx| {
let mut items = Vec::new();
for ix in range {
let item = ix + 1;
@ -29,7 +28,7 @@ impl Render for UniformListExample {
);
}
items
},
}),
)
.h_full(),
)

View file

@ -225,6 +225,18 @@ impl<'a, T: 'static> Context<'a, T> {
}
}
/// Convenience method for producing view state in a closure.
/// See `listener` for more details.
pub fn processor<E, R>(
&self,
f: impl Fn(&mut T, E, &mut Window, &mut Context<T>) -> R + 'static,
) -> impl Fn(E, &mut Window, &mut App) -> R + 'static {
let view = self.entity();
move |e: E, window: &mut Window, cx: &mut App| {
view.update(cx, |view, cx| f(view, e, window, cx))
}
}
/// Run something using this entity and cx, when the returned struct is dropped
pub fn on_drop(
&self,

View file

@ -5,10 +5,10 @@
//! elements with uniform height.
use crate::{
AnyElement, App, AvailableSpace, Bounds, ContentMask, Context, Element, ElementId, Entity,
GlobalElementId, Hitbox, InspectorElementId, InteractiveElement, Interactivity, IntoElement,
IsZero, LayoutId, ListSizingBehavior, Overflow, Pixels, Render, ScrollHandle, Size,
StyleRefinement, Styled, Window, point, size,
AnyElement, App, AvailableSpace, Bounds, ContentMask, Element, ElementId, GlobalElementId,
Hitbox, InspectorElementId, InteractiveElement, Interactivity, IntoElement, IsZero, LayoutId,
ListSizingBehavior, Overflow, Pixels, ScrollHandle, Size, StyleRefinement, Styled, Window,
point, size,
};
use smallvec::SmallVec;
use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@ -19,28 +19,23 @@ use super::ListHorizontalSizingBehavior;
/// When rendered into a container with overflow-y: hidden and a fixed (or max) height,
/// uniform_list will only render the visible subset of items.
#[track_caller]
pub fn uniform_list<I, R, V>(
view: Entity<V>,
id: I,
pub fn uniform_list<R>(
id: impl Into<ElementId>,
item_count: usize,
f: impl 'static + Fn(&mut V, Range<usize>, &mut Window, &mut Context<V>) -> Vec<R>,
f: impl 'static + Fn(Range<usize>, &mut Window, &mut App) -> Vec<R>,
) -> UniformList
where
I: Into<ElementId>,
R: IntoElement,
V: Render,
{
let id = id.into();
let mut base_style = StyleRefinement::default();
base_style.overflow.y = Some(Overflow::Scroll);
let render_range = move |range, window: &mut Window, cx: &mut App| {
view.update(cx, |this, cx| {
f(this, range, window, cx)
.into_iter()
.map(|component| component.into_any_element())
.collect()
})
let render_range = move |range: Range<usize>, window: &mut Window, cx: &mut App| {
f(range, window, cx)
.into_iter()
.map(|component| component.into_any_element())
.collect()
};
UniformList {