mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-09 21:26:14 +03:00
Merge branch 'gpui2' of github.com:zed-industries/zed into gpui2
This commit is contained in:
commit
b0b7f27f3a
@ -1,4 +1,4 @@
|
||||
use crate::{BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, ViewContext};
|
||||
use crate::{BorrowWindow, Bounds, ElementId, LayoutId, Pixels, ViewContext};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
pub(crate) use smallvec::SmallVec;
|
||||
use std::mem;
|
||||
@ -62,7 +62,7 @@ pub trait ParentElement: Element {
|
||||
trait ElementObject<V>: 'static + Send + Sync {
|
||||
fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
|
||||
fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId;
|
||||
fn paint(&mut self, view_state: &mut V, offset: Option<Point<Pixels>>, cx: &mut ViewContext<V>);
|
||||
fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
|
||||
}
|
||||
|
||||
struct RenderedElement<E: Element> {
|
||||
@ -145,19 +145,13 @@ where
|
||||
layout_id
|
||||
}
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
view_state: &mut E::ViewState,
|
||||
offset: Option<Point<Pixels>>,
|
||||
cx: &mut ViewContext<E::ViewState>,
|
||||
) {
|
||||
fn paint(&mut self, view_state: &mut E::ViewState, cx: &mut ViewContext<E::ViewState>) {
|
||||
self.phase = match mem::take(&mut self.phase) {
|
||||
ElementRenderPhase::LayoutRequested {
|
||||
layout_id,
|
||||
mut frame_state,
|
||||
} => {
|
||||
let mut bounds = cx.layout_bounds(layout_id);
|
||||
offset.map(|offset| bounds.origin += offset);
|
||||
let bounds = cx.layout_bounds(layout_id);
|
||||
if let Some(id) = self.element.id() {
|
||||
cx.with_element_state(id, |element_state, cx| {
|
||||
let mut element_state = element_state.unwrap();
|
||||
@ -192,13 +186,8 @@ impl<V: 'static + Send + Sync> AnyElement<V> {
|
||||
self.0.layout(view_state, cx)
|
||||
}
|
||||
|
||||
pub fn paint(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
offset: Option<Point<Pixels>>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
self.0.paint(view_state, offset, cx)
|
||||
pub fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) {
|
||||
self.0.paint(view_state, cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ where
|
||||
for child_layout_id in &element_state.child_layout_ids {
|
||||
let child_bounds = cx.layout_bounds(*child_layout_id);
|
||||
child_min = child_min.min(&child_bounds.origin);
|
||||
child_max = child_min.max(&child_bounds.lower_right());
|
||||
child_max = child_max.max(&child_bounds.lower_right());
|
||||
}
|
||||
(child_max - child_min).into()
|
||||
};
|
||||
@ -298,9 +298,11 @@ where
|
||||
style.apply_text_style(cx, |cx| {
|
||||
style.apply_overflow(bounds, cx, |cx| {
|
||||
let scroll_offset = element_state.interactive.scroll_offset();
|
||||
for child in &mut this.children {
|
||||
child.paint(view_state, scroll_offset, cx);
|
||||
}
|
||||
cx.with_scroll_offset(scroll_offset, |cx| {
|
||||
for child in &mut this.children {
|
||||
child.paint(view_state, cx);
|
||||
}
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
||||
|
@ -97,9 +97,13 @@ impl<V: 'static + Send + Sync> Element for Text<V> {
|
||||
return Size::default();
|
||||
};
|
||||
|
||||
let line_count = lines
|
||||
.iter()
|
||||
.map(|line| line.wrap_count() + 1)
|
||||
.sum::<usize>();
|
||||
let size = Size {
|
||||
width: lines.iter().map(|line| line.layout.width).max().unwrap(),
|
||||
height: line_height * lines.len(),
|
||||
height: line_height * line_count,
|
||||
};
|
||||
|
||||
element_state
|
||||
|
@ -4,7 +4,7 @@ use refineable::Refineable;
|
||||
use std::{
|
||||
cmp::{self, PartialOrd},
|
||||
fmt,
|
||||
ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign},
|
||||
ops::{Add, Div, Mul, MulAssign, Sub},
|
||||
};
|
||||
|
||||
#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
@ -67,26 +67,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SubAssign<Size<T>> for Point<T>
|
||||
where
|
||||
T: Sub<Output = T> + Clone + Debug + Default,
|
||||
{
|
||||
fn sub_assign(&mut self, rhs: Size<T>) {
|
||||
self.x = self.x.clone() - rhs.width;
|
||||
self.y = self.y.clone() - rhs.height;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AddAssign<T> for Point<T>
|
||||
where
|
||||
T: Add<Output = T> + Clone + Default + Debug,
|
||||
{
|
||||
fn add_assign(&mut self, rhs: T) {
|
||||
self.x = self.x.clone() + rhs.clone();
|
||||
self.y = self.y.clone() + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, S> Div<S> for Point<T>
|
||||
where
|
||||
T: Div<S, Output = T> + Clone + Default + Debug,
|
||||
@ -187,7 +167,7 @@ impl Size<Pixels> {
|
||||
|
||||
impl<T> Size<T>
|
||||
where
|
||||
T: Ord + Clone + Default + Debug,
|
||||
T: PartialOrd + Clone + Default + Debug,
|
||||
{
|
||||
pub fn max(&self, other: &Self) -> Self {
|
||||
Size {
|
||||
|
@ -477,7 +477,7 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
|
||||
.get_or_insert_with(Arc::default)
|
||||
.clone();
|
||||
let line_height = cx.line_height();
|
||||
let scroll_max = content_size - bounds.size;
|
||||
let scroll_max = (content_size - bounds.size).max(&Size::default());
|
||||
|
||||
cx.on_mouse_event(move |_, event: &ScrollWheelEvent, _, cx| {
|
||||
if bounds.contains_point(&event.position) {
|
||||
|
@ -26,6 +26,10 @@ impl Line {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn wrap_count(&self) -> usize {
|
||||
self.layout.wrap_boundaries.len()
|
||||
}
|
||||
|
||||
pub fn paint(
|
||||
&self,
|
||||
origin: Point<Pixels>,
|
||||
|
@ -90,8 +90,7 @@ impl<V: 'static + Send + Sync> Element for View<V> {
|
||||
element: &mut Self::ElementState,
|
||||
cx: &mut ViewContext<()>,
|
||||
) {
|
||||
self.state
|
||||
.update(cx, |state, cx| element.paint(state, None, cx))
|
||||
self.state.update(cx, |state, cx| element.paint(state, cx))
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,7 +185,7 @@ impl<V: Send + Sync + 'static> ViewObject for View<V> {
|
||||
cx.with_element_id(self.entity_id(), |_global_id, cx| {
|
||||
self.state.update(cx, |state, cx| {
|
||||
let element = element.downcast_mut::<AnyElement<V>>().unwrap();
|
||||
element.paint(state, None, cx);
|
||||
element.paint(state, cx);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -159,6 +159,7 @@ pub struct Window {
|
||||
key_matchers: HashMap<GlobalElementId, KeyMatcher>,
|
||||
z_index_stack: StackingOrder,
|
||||
content_mask_stack: Vec<ContentMask<Pixels>>,
|
||||
scroll_offset_stack: Vec<Point<Pixels>>,
|
||||
mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyListener)>>,
|
||||
key_dispatch_stack: Vec<KeyDispatchStackFrame>,
|
||||
freeze_key_dispatch_stack: bool,
|
||||
@ -234,6 +235,7 @@ impl Window {
|
||||
key_matchers: HashMap::default(),
|
||||
z_index_stack: StackingOrder(SmallVec::new()),
|
||||
content_mask_stack: Vec::new(),
|
||||
scroll_offset_stack: Vec::new(),
|
||||
mouse_listeners: HashMap::default(),
|
||||
key_dispatch_stack: Vec::new(),
|
||||
freeze_key_dispatch_stack: false,
|
||||
@ -443,10 +445,13 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||
}
|
||||
|
||||
pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
|
||||
self.window
|
||||
let mut bounds = self
|
||||
.window
|
||||
.layout_engine
|
||||
.layout_bounds(layout_id)
|
||||
.map(Into::into)
|
||||
.map(Into::into);
|
||||
bounds.origin -= self.scroll_offset();
|
||||
bounds
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f32 {
|
||||
@ -1136,6 +1141,30 @@ pub trait BorrowWindow: BorrowAppContext {
|
||||
result
|
||||
}
|
||||
|
||||
fn with_scroll_offset<R>(
|
||||
&mut self,
|
||||
offset: Option<Point<Pixels>>,
|
||||
f: impl FnOnce(&mut Self) -> R,
|
||||
) -> R {
|
||||
let Some(offset) = offset else {
|
||||
return f(self);
|
||||
};
|
||||
|
||||
let offset = self.scroll_offset() + offset;
|
||||
self.window_mut().scroll_offset_stack.push(offset);
|
||||
let result = f(self);
|
||||
self.window_mut().scroll_offset_stack.pop();
|
||||
result
|
||||
}
|
||||
|
||||
fn scroll_offset(&self) -> Point<Pixels> {
|
||||
self.window()
|
||||
.scroll_offset_stack
|
||||
.last()
|
||||
.copied()
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn with_element_state<S: 'static + Send + Sync, R>(
|
||||
&mut self,
|
||||
id: ElementId,
|
||||
|
@ -86,7 +86,7 @@ pub fn derive_element(input: TokenStream) -> TokenStream {
|
||||
rendered_element: &mut Self::ElementState,
|
||||
cx: &mut gpui3::ViewContext<Self::ViewState>,
|
||||
) {
|
||||
rendered_element.paint(view_state, None, cx)
|
||||
rendered_element.paint(view_state, cx)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,9 +1,11 @@
|
||||
mod focus;
|
||||
mod kitchen_sink;
|
||||
mod scroll;
|
||||
mod text;
|
||||
mod z_index;
|
||||
|
||||
pub use focus::*;
|
||||
pub use kitchen_sink::*;
|
||||
pub use scroll::*;
|
||||
pub use text::*;
|
||||
pub use z_index::*;
|
||||
|
28
crates/storybook2/src/stories/scroll.rs
Normal file
28
crates/storybook2/src/stories/scroll.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use crate::themes::rose_pine;
|
||||
use gpui3::{div, view, Context, ParentElement, Styled, View, WindowContext};
|
||||
|
||||
pub struct ScrollStory {
|
||||
text: View<()>,
|
||||
}
|
||||
|
||||
impl ScrollStory {
|
||||
pub fn view(cx: &mut WindowContext) -> View<()> {
|
||||
let theme = rose_pine();
|
||||
|
||||
view(cx.entity(|cx| ()), move |_, cx| {
|
||||
div()
|
||||
.id("parent")
|
||||
.bg(theme.lowest.base.default.background)
|
||||
.size_full()
|
||||
.overflow_x_scroll()
|
||||
.child(div().w_96().flex().flex_row().children((0..3).map(|ix| {
|
||||
let bg = if ix % 2 == 0 {
|
||||
theme.middle.positive.default.background
|
||||
} else {
|
||||
theme.middle.warning.default.background
|
||||
};
|
||||
div().bg(bg).flex_1().h_20()
|
||||
})))
|
||||
})
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ pub enum ElementStory {
|
||||
Icon,
|
||||
Input,
|
||||
Label,
|
||||
Scroll,
|
||||
Text,
|
||||
ZIndex,
|
||||
}
|
||||
@ -46,6 +47,7 @@ impl ElementStory {
|
||||
Self::Label => {
|
||||
view(cx.entity(|cx| ()), |_, _| ui::LabelStory::new().into_any()).into_any()
|
||||
}
|
||||
Self::Scroll => ScrollStory::view(cx).into_any(),
|
||||
Self::Text => TextStory::view(cx).into_any(),
|
||||
Self::ZIndex => {
|
||||
view(cx.entity(|cx| ()), |_, _| ZIndexStory::new().into_any()).into_any()
|
||||
|
Loading…
Reference in New Issue
Block a user