Rename List -> UniformList

Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
Max Brunsfeld 2023-11-07 11:00:53 -08:00
parent 2412873719
commit 6928ad1335
3 changed files with 27 additions and 40 deletions

View file

@ -1,11 +1,11 @@
mod div; mod div;
mod img; mod img;
mod list;
mod svg; mod svg;
mod text; mod text;
mod uniform_list;
pub use div::*; pub use div::*;
pub use img::*; pub use img::*;
pub use list::*;
pub use svg::*; pub use svg::*;
pub use text::*; pub use text::*;
pub use uniform_list::*;

View file

@ -9,18 +9,18 @@ use smallvec::SmallVec;
use std::{cmp, ops::Range, sync::Arc}; use std::{cmp, ops::Range, sync::Arc};
use taffy::style::Overflow; use taffy::style::Overflow;
pub fn list<Id, V, C>( pub fn uniform_list<Id, V, C>(
id: Id, id: Id,
item_count: usize, item_count: usize,
f: impl 'static + Fn(&mut V, Range<usize>, &mut ViewContext<V>) -> SmallVec<[C; 64]>, f: impl 'static + Fn(&mut V, Range<usize>, &mut ViewContext<V>) -> SmallVec<[C; 64]>,
) -> List<V> ) -> UniformList<V>
where where
Id: Into<ElementId>, Id: Into<ElementId>,
V: 'static, V: 'static,
C: Component<V>, C: Component<V>,
{ {
let id = id.into(); let id = id.into();
List { UniformList {
id: id.clone(), id: id.clone(),
style: Default::default(), style: Default::default(),
item_count, item_count,
@ -35,7 +35,7 @@ where
} }
} }
pub struct List<V: 'static> { pub struct UniformList<V: 'static> {
id: ElementId, id: ElementId,
style: StyleRefinement, style: StyleRefinement,
item_count: usize, item_count: usize,
@ -47,20 +47,20 @@ pub struct List<V: 'static> {
) -> SmallVec<[AnyElement<V>; 64]>, ) -> SmallVec<[AnyElement<V>; 64]>,
>, >,
interactivity: StatefulInteractivity<V>, interactivity: StatefulInteractivity<V>,
scroll_handle: Option<ListScrollHandle>, scroll_handle: Option<UniformListScrollHandle>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct ListScrollHandle(Arc<Mutex<Option<ListScrollHandleState>>>); pub struct UniformListScrollHandle(Arc<Mutex<Option<ScrollHandleState>>>);
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct ListScrollHandleState { struct ScrollHandleState {
item_height: Pixels, item_height: Pixels,
list_height: Pixels, list_height: Pixels,
scroll_offset: Arc<Mutex<Point<Pixels>>>, scroll_offset: Arc<Mutex<Point<Pixels>>>,
} }
impl ListScrollHandle { impl UniformListScrollHandle {
pub fn new() -> Self { pub fn new() -> Self {
Self(Arc::new(Mutex::new(None))) Self(Arc::new(Mutex::new(None)))
} }
@ -80,19 +80,14 @@ impl ListScrollHandle {
} }
} }
#[derive(Default)] impl<V: 'static> Styled for UniformList<V> {
pub struct ListState {
interactive: InteractiveElementState,
}
impl<V: 'static> Styled for List<V> {
fn style(&mut self) -> &mut StyleRefinement { fn style(&mut self) -> &mut StyleRefinement {
&mut self.style &mut self.style
} }
} }
impl<V: 'static> Element<V> for List<V> { impl<V: 'static> Element<V> for UniformList<V> {
type ElementState = ListState; type ElementState = InteractiveElementState;
fn id(&self) -> Option<crate::ElementId> { fn id(&self) -> Option<crate::ElementId> {
Some(self.id.clone()) Some(self.id.clone())
@ -104,8 +99,7 @@ impl<V: 'static> Element<V> for List<V> {
element_state: Option<Self::ElementState>, element_state: Option<Self::ElementState>,
_: &mut ViewContext<V>, _: &mut ViewContext<V>,
) -> Self::ElementState { ) -> Self::ElementState {
let element_state = element_state.unwrap_or_default(); element_state.unwrap_or_default()
element_state
} }
fn layout( fn layout(
@ -141,16 +135,15 @@ impl<V: 'static> Element<V> for List<V> {
if self.item_count > 0 { if self.item_count > 0 {
let item_height = self.measure_item_height(view_state, padded_bounds, cx); let item_height = self.measure_item_height(view_state, padded_bounds, cx);
if let Some(scroll_handle) = self.scroll_handle.clone() { if let Some(scroll_handle) = self.scroll_handle.clone() {
scroll_handle.0.lock().replace(ListScrollHandleState { scroll_handle.0.lock().replace(ScrollHandleState {
item_height, item_height,
list_height: padded_bounds.size.height, list_height: padded_bounds.size.height,
scroll_offset: element_state.interactive.track_scroll_offset(), scroll_offset: element_state.track_scroll_offset(),
}); });
} }
let visible_item_count = let visible_item_count =
(padded_bounds.size.height / item_height).ceil() as usize + 1; (padded_bounds.size.height / item_height).ceil() as usize + 1;
let scroll_offset = element_state let scroll_offset = element_state
.interactive
.scroll_offset() .scroll_offset()
.map_or((0.0).into(), |offset| offset.y); .map_or((0.0).into(), |offset| offset.y);
let first_visible_element_ix = (-scroll_offset / item_height).floor() as usize; let first_visible_element_ix = (-scroll_offset / item_height).floor() as usize;
@ -194,19 +187,14 @@ impl<V: 'static> Element<V> for List<V> {
let overflow = point(style.overflow.x, Overflow::Scroll); let overflow = point(style.overflow.x, Overflow::Scroll);
cx.with_z_index(0, |cx| { cx.with_z_index(0, |cx| {
self.interactivity.paint( self.interactivity
bounds, .paint(bounds, content_size, overflow, element_state, cx);
content_size,
overflow,
&mut element_state.interactive,
cx,
);
}); });
}) })
} }
} }
impl<V> List<V> { impl<V> UniformList<V> {
fn measure_item_height( fn measure_item_height(
&self, &self,
view_state: &mut V, view_state: &mut V,
@ -228,25 +216,25 @@ impl<V> List<V> {
cx.layout_bounds(layout_id).size.height cx.layout_bounds(layout_id).size.height
} }
pub fn track_scroll(mut self, handle: ListScrollHandle) -> Self { pub fn track_scroll(mut self, handle: UniformListScrollHandle) -> Self {
self.scroll_handle = Some(handle); self.scroll_handle = Some(handle);
self self
} }
} }
impl<V: 'static> StatelessInteractive<V> for List<V> { impl<V: 'static> StatelessInteractive<V> for UniformList<V> {
fn stateless_interactivity(&mut self) -> &mut StatelessInteractivity<V> { fn stateless_interactivity(&mut self) -> &mut StatelessInteractivity<V> {
self.interactivity.as_stateless_mut() self.interactivity.as_stateless_mut()
} }
} }
impl<V: 'static> StatefulInteractive<V> for List<V> { impl<V: 'static> StatefulInteractive<V> for UniformList<V> {
fn stateful_interactivity(&mut self) -> &mut StatefulInteractivity<V> { fn stateful_interactivity(&mut self) -> &mut StatefulInteractivity<V> {
&mut self.interactivity &mut self.interactivity
} }
} }
impl<V: 'static> Component<V> for List<V> { impl<V: 'static> Component<V> for UniformList<V> {
fn render(self) -> AnyElement<V> { fn render(self) -> AnyElement<V> {
AnyElement::new(self) AnyElement::new(self)
} }

View file

@ -1,6 +1,6 @@
use gpui::{ use gpui::{
div, list, Component, ElementId, FocusHandle, ListScrollHandle, ParentElement, div, uniform_list, Component, ElementId, FocusHandle, ParentElement, StatelessInteractive,
StatelessInteractive, Styled, ViewContext, Styled, UniformListScrollHandle, ViewContext,
}; };
use std::cmp; use std::cmp;
@ -24,7 +24,6 @@ pub trait PickerDelegate: Sized + 'static {
fn confirm(&mut self, secondary: bool, picker_id: ElementId, cx: &mut ViewContext<Self>); fn confirm(&mut self, secondary: bool, picker_id: ElementId, cx: &mut ViewContext<Self>);
fn dismissed(&mut self, picker_id: ElementId, cx: &mut ViewContext<Self>); fn dismissed(&mut self, picker_id: ElementId, cx: &mut ViewContext<Self>);
// todo!("rename to render_candidate?")
fn render_match( fn render_match(
&self, &self,
ix: usize, ix: usize,
@ -47,7 +46,7 @@ impl<V: PickerDelegate> Picker<V> {
impl<V: 'static + PickerDelegate> Picker<V> { impl<V: 'static + PickerDelegate> Picker<V> {
pub fn render(self, view: &mut V, _cx: &mut ViewContext<V>) -> impl Component<V> { pub fn render(self, view: &mut V, _cx: &mut ViewContext<V>) -> impl Component<V> {
let id = self.id.clone(); let id = self.id.clone();
let scroll_handle = ListScrollHandle::new(); let scroll_handle = UniformListScrollHandle::new();
div() div()
.size_full() .size_full()
.id(self.id.clone()) .id(self.id.clone())
@ -120,7 +119,7 @@ impl<V: 'static + PickerDelegate> Picker<V> {
} }
}) })
.child( .child(
list( uniform_list(
"candidates", "candidates",
view.match_count(self.id.clone()), view.match_count(self.id.clone()),
move |view: &mut V, visible_range, cx| { move |view: &mut V, visible_range, cx| {