Merge branch 'main' into zed2-project-test
Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
commit
291d35f337
607 changed files with 52667 additions and 14124 deletions
|
@ -2,7 +2,8 @@ use std::{any::Any, cell::Cell, f32::INFINITY, ops::Range, rc::Rc};
|
|||
|
||||
use crate::{
|
||||
json::{self, ToJson, Value},
|
||||
AnyElement, Axis, Element, ElementStateHandle, SizeConstraint, Vector2FExt, ViewContext,
|
||||
AnyElement, Axis, Element, ElementStateHandle, SizeConstraint, TypeTag, Vector2FExt,
|
||||
ViewContext,
|
||||
};
|
||||
use pathfinder_geometry::{
|
||||
rect::RectF,
|
||||
|
@ -10,10 +11,10 @@ use pathfinder_geometry::{
|
|||
};
|
||||
use serde_json::json;
|
||||
|
||||
#[derive(Default)]
|
||||
struct ScrollState {
|
||||
scroll_to: Cell<Option<usize>>,
|
||||
scroll_position: Cell<f32>,
|
||||
type_tag: TypeTag,
|
||||
}
|
||||
|
||||
pub struct Flex<V> {
|
||||
|
@ -66,8 +67,14 @@ impl<V: 'static> Flex<V> {
|
|||
where
|
||||
Tag: 'static,
|
||||
{
|
||||
let scroll_state = cx.default_element_state::<Tag, Rc<ScrollState>>(element_id);
|
||||
scroll_state.read(cx).scroll_to.set(scroll_to);
|
||||
let scroll_state = cx.element_state::<Tag, Rc<ScrollState>>(
|
||||
element_id,
|
||||
Rc::new(ScrollState {
|
||||
scroll_to: Cell::new(scroll_to),
|
||||
scroll_position: Default::default(),
|
||||
type_tag: TypeTag::new::<Tag>(),
|
||||
}),
|
||||
);
|
||||
self.scroll_state = Some((scroll_state, cx.handle().id()));
|
||||
self
|
||||
}
|
||||
|
@ -276,38 +283,44 @@ impl<V: 'static> Element<V> for Flex<V> {
|
|||
if let Some((scroll_state, id)) = &self.scroll_state {
|
||||
let scroll_state = scroll_state.read(cx).clone();
|
||||
cx.scene().push_mouse_region(
|
||||
crate::MouseRegion::new::<Self>(*id, 0, bounds)
|
||||
.on_scroll({
|
||||
let axis = self.axis;
|
||||
move |e, _: &mut V, cx| {
|
||||
if remaining_space < 0. {
|
||||
let scroll_delta = e.delta.raw();
|
||||
crate::MouseRegion::from_handlers(
|
||||
scroll_state.type_tag,
|
||||
*id,
|
||||
0,
|
||||
bounds,
|
||||
Default::default(),
|
||||
)
|
||||
.on_scroll({
|
||||
let axis = self.axis;
|
||||
move |e, _: &mut V, cx| {
|
||||
if remaining_space < 0. {
|
||||
let scroll_delta = e.delta.raw();
|
||||
|
||||
let mut delta = match axis {
|
||||
Axis::Horizontal => {
|
||||
if scroll_delta.x().abs() >= scroll_delta.y().abs() {
|
||||
scroll_delta.x()
|
||||
} else {
|
||||
scroll_delta.y()
|
||||
}
|
||||
let mut delta = match axis {
|
||||
Axis::Horizontal => {
|
||||
if scroll_delta.x().abs() >= scroll_delta.y().abs() {
|
||||
scroll_delta.x()
|
||||
} else {
|
||||
scroll_delta.y()
|
||||
}
|
||||
Axis::Vertical => scroll_delta.y(),
|
||||
};
|
||||
if !e.delta.precise() {
|
||||
delta *= 20.;
|
||||
}
|
||||
|
||||
scroll_state
|
||||
.scroll_position
|
||||
.set(scroll_state.scroll_position.get() - delta);
|
||||
|
||||
cx.notify();
|
||||
} else {
|
||||
cx.propagate_event();
|
||||
Axis::Vertical => scroll_delta.y(),
|
||||
};
|
||||
if !e.delta.precise() {
|
||||
delta *= 20.;
|
||||
}
|
||||
|
||||
scroll_state
|
||||
.scroll_position
|
||||
.set(scroll_state.scroll_position.get() - delta);
|
||||
|
||||
cx.notify();
|
||||
} else {
|
||||
cx.propagate_event();
|
||||
}
|
||||
})
|
||||
.on_move(|_, _: &mut V, _| { /* Capture move events */ }),
|
||||
}
|
||||
})
|
||||
.on_move(|_, _: &mut V, _| { /* Capture move events */ }),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ struct StateInner<V> {
|
|||
orientation: Orientation,
|
||||
overdraw: f32,
|
||||
#[allow(clippy::type_complexity)]
|
||||
scroll_handler: Option<Box<dyn FnMut(Range<usize>, &mut V, &mut ViewContext<V>)>>,
|
||||
scroll_handler: Option<Box<dyn FnMut(Range<usize>, usize, &mut V, &mut ViewContext<V>)>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
|
@ -378,6 +378,10 @@ impl<V: 'static> ListState<V> {
|
|||
.extend((0..element_count).map(|_| ListItem::Unrendered), &());
|
||||
}
|
||||
|
||||
pub fn item_count(&self) -> usize {
|
||||
self.0.borrow().items.summary().count
|
||||
}
|
||||
|
||||
pub fn splice(&self, old_range: Range<usize>, count: usize) {
|
||||
let state = &mut *self.0.borrow_mut();
|
||||
|
||||
|
@ -416,7 +420,7 @@ impl<V: 'static> ListState<V> {
|
|||
|
||||
pub fn set_scroll_handler(
|
||||
&mut self,
|
||||
handler: impl FnMut(Range<usize>, &mut V, &mut ViewContext<V>) + 'static,
|
||||
handler: impl FnMut(Range<usize>, usize, &mut V, &mut ViewContext<V>) + 'static,
|
||||
) {
|
||||
self.0.borrow_mut().scroll_handler = Some(Box::new(handler))
|
||||
}
|
||||
|
@ -529,7 +533,12 @@ impl<V: 'static> StateInner<V> {
|
|||
|
||||
if self.scroll_handler.is_some() {
|
||||
let visible_range = self.visible_range(height, scroll_top);
|
||||
self.scroll_handler.as_mut().unwrap()(visible_range, view, cx);
|
||||
self.scroll_handler.as_mut().unwrap()(
|
||||
visible_range,
|
||||
self.items.summary().count,
|
||||
view,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
|
|
|
@ -266,6 +266,8 @@ impl Line {
|
|||
self.layout.len == 0
|
||||
}
|
||||
|
||||
/// index_for_x returns the character containing the given x coordinate.
|
||||
/// (e.g. to handle a mouse-click)
|
||||
pub fn index_for_x(&self, x: f32) -> Option<usize> {
|
||||
if x >= self.layout.width {
|
||||
None
|
||||
|
@ -281,6 +283,28 @@ impl Line {
|
|||
}
|
||||
}
|
||||
|
||||
/// closest_index_for_x returns the character boundary closest to the given x coordinate
|
||||
/// (e.g. to handle aligning up/down arrow keys)
|
||||
pub fn closest_index_for_x(&self, x: f32) -> usize {
|
||||
let mut prev_index = 0;
|
||||
let mut prev_x = 0.0;
|
||||
|
||||
for run in self.layout.runs.iter() {
|
||||
for glyph in run.glyphs.iter() {
|
||||
if glyph.position.x() >= x {
|
||||
if glyph.position.x() - x < x - prev_x {
|
||||
return glyph.index;
|
||||
} else {
|
||||
return prev_index;
|
||||
}
|
||||
}
|
||||
prev_index = glyph.index;
|
||||
prev_x = glyph.position.x();
|
||||
}
|
||||
}
|
||||
prev_index
|
||||
}
|
||||
|
||||
pub fn paint(
|
||||
&self,
|
||||
origin: Vector2F,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue