project_panel: Only show sticky item shadow when list is scrolled (#34050)

Follow up: https://github.com/zed-industries/zed/pull/34042

- Removes `top_slot_items` from `uniform_list` in favor of using
existing `decorations`
- Add condition to only show shadow for sticky item when list is
scrolled and scrollable

Release Notes:

- N/A
This commit is contained in:
Smit Barmase 2025-07-08 14:22:24 +05:30 committed by GitHub
parent f1db3b4e1d
commit 1f3575ad6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 180 additions and 178 deletions

View file

@ -42,7 +42,6 @@ where
item_count,
item_to_measure_index: 0,
render_items: Box::new(render_range),
top_slot: None,
decorations: Vec::new(),
interactivity: Interactivity {
element_id: Some(id),
@ -62,7 +61,6 @@ pub struct UniformList {
render_items: Box<
dyn for<'a> Fn(Range<usize>, &'a mut Window, &'a mut App) -> SmallVec<[AnyElement; 64]>,
>,
top_slot: Option<Box<dyn UniformListTopSlot>>,
decorations: Vec<Box<dyn UniformListDecoration>>,
interactivity: Interactivity,
scroll_handle: Option<UniformListScrollHandle>,
@ -73,7 +71,6 @@ pub struct UniformList {
/// Frame state used by the [UniformList].
pub struct UniformListFrameState {
items: SmallVec<[AnyElement; 32]>,
top_slot_items: SmallVec<[AnyElement; 8]>,
decorations: SmallVec<[AnyElement; 1]>,
}
@ -145,6 +142,15 @@ impl UniformListScrollHandle {
.map(|(ix, _)| ix)
.unwrap_or_else(|| this.base_handle.logical_scroll_top().0)
}
/// Checks if the list can be scrolled vertically.
pub fn is_scrollable(&self) -> bool {
if let Some(size) = self.0.borrow().last_item_size {
size.contents.height > size.item.height
} else {
false
}
}
}
impl Styled for UniformList {
@ -217,7 +223,6 @@ impl Element for UniformList {
UniformListFrameState {
items: SmallVec::new(),
decorations: SmallVec::new(),
top_slot_items: SmallVec::new(),
},
)
}
@ -369,17 +374,8 @@ impl Element for UniformList {
let last_visible_element_ix = ((-scroll_offset.y + padded_bounds.size.height)
/ item_height)
.ceil() as usize;
let initial_range = first_visible_element_ix
..cmp::min(last_visible_element_ix, self.item_count);
let mut top_slot_elements = if let Some(ref mut top_slot) = self.top_slot {
top_slot.compute(initial_range, window, cx)
} else {
SmallVec::new()
};
let top_slot_offset = top_slot_elements.len();
let visible_range = (top_slot_offset + first_visible_element_ix)
let visible_range = first_visible_element_ix
..cmp::min(last_visible_element_ix, self.item_count);
let items = if y_flipped {
@ -418,20 +414,6 @@ impl Element for UniformList {
frame_state.items.push(item);
}
if let Some(ref top_slot) = self.top_slot {
top_slot.prepaint(
&mut top_slot_elements,
padded_bounds,
item_height,
scroll_offset,
padding,
can_scroll_horizontally,
window,
cx,
);
}
frame_state.top_slot_items = top_slot_elements;
let bounds = Bounds::new(
padded_bounds.origin
+ point(
@ -448,6 +430,7 @@ impl Element for UniformList {
let mut decoration = decoration.as_ref().compute(
visible_range.clone(),
bounds,
scroll_offset,
item_height,
self.item_count,
window,
@ -493,9 +476,6 @@ impl Element for UniformList {
for decoration in &mut request_layout.decorations {
decoration.paint(window, cx);
}
if let Some(ref top_slot) = self.top_slot {
top_slot.paint(&mut request_layout.top_slot_items, window, cx);
}
},
)
}
@ -518,6 +498,7 @@ pub trait UniformListDecoration {
&self,
visible_range: Range<usize>,
bounds: Bounds<Pixels>,
scroll_offset: Point<Pixels>,
item_height: Pixels,
item_count: usize,
window: &mut Window,
@ -592,12 +573,6 @@ impl UniformList {
self
}
/// Sets a top slot for the list.
pub fn with_top_slot(mut self, top_slot: impl UniformListTopSlot + 'static) -> Self {
self.top_slot = Some(Box::new(top_slot));
self
}
fn measure_item(
&self,
list_width: Option<Pixels>,