Rename List -> UniformList
Co-authored-by: Mikayla <mikayla@zed.dev>
This commit is contained in:
parent
2412873719
commit
6928ad1335
3 changed files with 27 additions and 40 deletions
|
@ -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::*;
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue