mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-29 05:33:49 +00:00
Checkpoint
This commit is contained in:
parent
006f840570
commit
e2da2b232e
7 changed files with 68 additions and 131 deletions
|
@ -1,4 +1,4 @@
|
||||||
use crate::{BorrowWindow, Bounds, ElementId, Identified, LayoutId, Pixels, Point, ViewContext};
|
use crate::{BorrowWindow, Bounds, ElementId, LayoutId, Pixels, Point, ViewContext};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
pub(crate) use smallvec::SmallVec;
|
pub(crate) use smallvec::SmallVec;
|
||||||
|
|
||||||
|
@ -6,9 +6,7 @@ pub trait Element: 'static + Send + Sync {
|
||||||
type ViewState: 'static + Send + Sync;
|
type ViewState: 'static + Send + Sync;
|
||||||
type ElementState: 'static + Send + Sync;
|
type ElementState: 'static + Send + Sync;
|
||||||
|
|
||||||
fn element_id(&self) -> Option<ElementId> {
|
fn element_id(&self) -> Option<ElementId>;
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -24,16 +22,6 @@ pub trait Element: 'static + Send + Sync {
|
||||||
element_state: &mut Self::ElementState,
|
element_state: &mut Self::ElementState,
|
||||||
cx: &mut ViewContext<Self::ViewState>,
|
cx: &mut ViewContext<Self::ViewState>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn id(self, id: impl Into<ElementId>) -> Identified<Self>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
Identified {
|
|
||||||
element: self,
|
|
||||||
id: id.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait StatefulElement: Element {
|
pub trait StatefulElement: Element {
|
||||||
|
|
|
@ -1,30 +1,41 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyElement, Bounds, Element, Interactive, LayoutId, MouseEventListeners, Overflow,
|
AnyElement, Bounds, Element, ElementId, Interactive, LayoutId, MouseEventListeners, Overflow,
|
||||||
ParentElement, Pixels, Point, Refineable, RefinementCascade, Style, Styled, ViewContext,
|
ParentElement, Pixels, Point, Refineable, RefinementCascade, StatefulElement, Style, Styled,
|
||||||
|
ViewContext,
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::sync::Arc;
|
use std::{marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
pub struct Div<S: 'static> {
|
pub enum HasId {}
|
||||||
|
|
||||||
|
pub struct Div<S: 'static, I = ()> {
|
||||||
styles: RefinementCascade<Style>,
|
styles: RefinementCascade<Style>,
|
||||||
|
id: Option<ElementId>,
|
||||||
listeners: MouseEventListeners<S>,
|
listeners: MouseEventListeners<S>,
|
||||||
children: SmallVec<[AnyElement<S>; 2]>,
|
children: SmallVec<[AnyElement<S>; 2]>,
|
||||||
scroll_state: Option<ScrollState>,
|
scroll_state: Option<ScrollState>,
|
||||||
|
identified: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn div<S>() -> Div<S> {
|
pub fn div<S>() -> Div<S> {
|
||||||
Div {
|
Div {
|
||||||
styles: Default::default(),
|
styles: Default::default(),
|
||||||
|
id: None,
|
||||||
listeners: Default::default(),
|
listeners: Default::default(),
|
||||||
children: Default::default(),
|
children: Default::default(),
|
||||||
scroll_state: None,
|
scroll_state: None,
|
||||||
|
identified: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> Element for Div<S> {
|
impl<S: 'static + Send + Sync, Marker: 'static + Send + Sync> Element for Div<S, Marker> {
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = Vec<LayoutId>;
|
type ElementState = ();
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<ElementId> {
|
||||||
|
self.id.clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -35,14 +46,14 @@ impl<S: 'static + Send + Sync> Element for Div<S> {
|
||||||
let style = self.computed_style();
|
let style = self.computed_style();
|
||||||
let child_layout_ids = style.apply_text_style(cx, |cx| self.layout_children(view, cx));
|
let child_layout_ids = style.apply_text_style(cx, |cx| self.layout_children(view, cx));
|
||||||
let layout_id = cx.request_layout(style.into(), child_layout_ids.clone());
|
let layout_id = cx.request_layout(style.into(), child_layout_ids.clone());
|
||||||
(layout_id, child_layout_ids)
|
(layout_id, ())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(
|
fn paint(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Bounds<Pixels>,
|
bounds: Bounds<Pixels>,
|
||||||
state: &mut S,
|
state: &mut S,
|
||||||
child_layout_ids: &mut Self::ElementState,
|
_: &mut (),
|
||||||
cx: &mut ViewContext<S>,
|
cx: &mut ViewContext<S>,
|
||||||
) {
|
) {
|
||||||
let style = self.computed_style();
|
let style = self.computed_style();
|
||||||
|
@ -57,17 +68,30 @@ impl<S: 'static + Send + Sync> Element for Div<S> {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
self.handle_scroll(bounds, style.overflow.clone(), child_layout_ids, cx);
|
|
||||||
|
|
||||||
// todo!("enable inspector")
|
|
||||||
// if cx.is_inspector_enabled() {
|
|
||||||
// self.paint_inspector(parent_origin, layout, cx);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static + Send + Sync> Div<S> {
|
impl<S> Div<S, ()>
|
||||||
|
where
|
||||||
|
S: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
pub fn id(self, id: impl Into<ElementId>) -> Div<S, HasId> {
|
||||||
|
Div {
|
||||||
|
styles: self.styles,
|
||||||
|
id: Some(id.into()),
|
||||||
|
listeners: self.listeners,
|
||||||
|
children: self.children,
|
||||||
|
scroll_state: self.scroll_state,
|
||||||
|
identified: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, Marker> Div<S, Marker>
|
||||||
|
where
|
||||||
|
S: 'static + Send + Sync,
|
||||||
|
Marker: 'static + Send + Sync,
|
||||||
|
{
|
||||||
pub fn overflow_hidden(mut self) -> Self {
|
pub fn overflow_hidden(mut self) -> Self {
|
||||||
self.declared_style().overflow.x = Some(Overflow::Hidden);
|
self.declared_style().overflow.x = Some(Overflow::Hidden);
|
||||||
self.declared_style().overflow.y = Some(Overflow::Hidden);
|
self.declared_style().overflow.y = Some(Overflow::Hidden);
|
||||||
|
@ -133,106 +157,9 @@ impl<S: 'static + Send + Sync> Div<S> {
|
||||||
child.paint(state, Some(scroll_offset), cx);
|
child.paint(state, Some(scroll_offset), cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_scroll(
|
|
||||||
&mut self,
|
|
||||||
bounds: Bounds<Pixels>,
|
|
||||||
overflow: Point<Overflow>,
|
|
||||||
child_layout_ids: &[LayoutId],
|
|
||||||
cx: &mut ViewContext<S>,
|
|
||||||
) {
|
|
||||||
if overflow.y == Overflow::Scroll || overflow.x == Overflow::Scroll {
|
|
||||||
let mut scroll_max = Point::default();
|
|
||||||
for child_layout_id in child_layout_ids {
|
|
||||||
let child_bounds = cx.layout_bounds(*child_layout_id);
|
|
||||||
scroll_max = scroll_max.max(&child_bounds.lower_right());
|
|
||||||
}
|
|
||||||
scroll_max -= bounds.size;
|
|
||||||
|
|
||||||
// todo!("handle scroll")
|
|
||||||
// let scroll_state = self.scroll_state.as_ref().unwrap().clone();
|
|
||||||
// cx.on_event(order, move |_, event: &ScrollWheelEvent, cx| {
|
|
||||||
// if bounds.contains_point(event.position) {
|
|
||||||
// let scroll_delta = match event.delta {
|
|
||||||
// ScrollDelta::Pixels(delta) => delta,
|
|
||||||
// ScrollDelta::Lines(delta) => cx.text_style().font_size * delta,
|
|
||||||
// };
|
|
||||||
// if overflow.x == Overflow::Scroll {
|
|
||||||
// scroll_state.set_x(
|
|
||||||
// (scroll_state.x() - scroll_delta.x())
|
|
||||||
// .max(px(0.))
|
|
||||||
// .min(scroll_max.x),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// if overflow.y == Overflow::Scroll {
|
|
||||||
// scroll_state.set_y(
|
|
||||||
// (scroll_state.y() - scroll_delta.y())
|
|
||||||
// .max(px(0.))
|
|
||||||
// .min(scroll_max.y),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// cx.repaint();
|
|
||||||
// } else {
|
|
||||||
// cx.bubble_event();
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn paint_inspector(
|
|
||||||
// &self,
|
|
||||||
// parent_origin: Point<Pixels>,
|
|
||||||
// layout: &Layout,
|
|
||||||
// cx: &mut ViewContext<V>,
|
|
||||||
// ) {
|
|
||||||
// let style = self.styles.merged();
|
|
||||||
// let bounds = layout.bounds;
|
|
||||||
|
|
||||||
// let hovered = bounds.contains_point(cx.mouse_position());
|
|
||||||
// if hovered {
|
|
||||||
// let rem_size = cx.rem_size();
|
|
||||||
// // cx.scene().push_quad(scene::Quad {
|
|
||||||
// // bounds,
|
|
||||||
// // background: Some(hsla(0., 0., 1., 0.05).into()),
|
|
||||||
// // border: gpui::Border {
|
|
||||||
// // color: hsla(0., 0., 1., 0.2).into(),
|
|
||||||
// // top: 1.,
|
|
||||||
// // right: 1.,
|
|
||||||
// // bottom: 1.,
|
|
||||||
// // left: 1.,
|
|
||||||
// // },
|
|
||||||
// // corner_radii: CornerRadii::default()
|
|
||||||
// // .refined(&style.corner_radii)
|
|
||||||
// // .to_gpui(bounds.size(), rem_size),
|
|
||||||
// // })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // let pressed = Cell::new(hovered && cx.is_mouse_down(MouseButton::Left));
|
|
||||||
// // cx.on_event(layout.order, move |_, event: &MouseButtonEvent, _| {
|
|
||||||
// // if bounds.contains_point(event.position) {
|
|
||||||
// // if event.is_down {
|
|
||||||
// // pressed.set(true);
|
|
||||||
// // } else if pressed.get() {
|
|
||||||
// // pressed.set(false);
|
|
||||||
// // eprintln!("clicked div {:?} {:#?}", bounds, style);
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // });
|
|
||||||
|
|
||||||
// // let hovered = Cell::new(hovered);
|
|
||||||
// // cx.on_event(layout.order, move |_, event: &MouseMovedEvent, cx| {
|
|
||||||
// // cx.bubble_event();
|
|
||||||
// // let hovered_now = bounds.contains_point(event.position);
|
|
||||||
// // if hovered.get() != hovered_now {
|
|
||||||
// // hovered.set(hovered_now);
|
|
||||||
// // cx.repaint();
|
|
||||||
// // }
|
|
||||||
// // });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static + Send + Sync> Styled for Div<V> {
|
impl<V: 'static + Send + Sync, Marker: 'static + Send + Sync> Styled for Div<V, Marker> {
|
||||||
type Style = Style;
|
type Style = Style;
|
||||||
|
|
||||||
fn style_cascade(&mut self) -> &mut RefinementCascade<Self::Style> {
|
fn style_cascade(&mut self) -> &mut RefinementCascade<Self::Style> {
|
||||||
|
@ -244,7 +171,9 @@ impl<V: 'static + Send + Sync> Styled for Div<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Send + Sync + 'static> Interactive<V> for Div<V> {
|
impl<V: Send + Sync + 'static> StatefulElement for Div<V, HasId> {}
|
||||||
|
|
||||||
|
impl<V: Send + Sync + 'static> Interactive<V> for Div<V, HasId> {
|
||||||
fn listeners(&mut self) -> &mut MouseEventListeners<V> {
|
fn listeners(&mut self) -> &mut MouseEventListeners<V> {
|
||||||
&mut self.listeners
|
&mut self.listeners
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,10 @@ impl<S: Send + Sync + 'static> Element for Img<S> {
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = ();
|
type ElementState = ();
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut Self::ViewState,
|
_: &mut Self::ViewState,
|
||||||
|
|
|
@ -28,6 +28,10 @@ impl<S: 'static + Send + Sync> Element for Svg<S> {
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = ();
|
type ElementState = ();
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut S,
|
_: &mut S,
|
||||||
|
|
|
@ -34,6 +34,10 @@ impl<S: 'static + Send + Sync> Element for Text<S> {
|
||||||
type ViewState = S;
|
type ViewState = S;
|
||||||
type ElementState = Arc<Mutex<Option<TextElementState>>>;
|
type ElementState = Arc<Mutex<Option<TextElementState>>>;
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_view: &mut S,
|
_view: &mut S,
|
||||||
|
|
|
@ -53,6 +53,10 @@ impl<S: 'static + Send + Sync, P: 'static + Send + Sync> Element for View<S, P>
|
||||||
type ViewState = P;
|
type ViewState = P;
|
||||||
type ElementState = AnyElement<S>;
|
type ElementState = AnyElement<S>;
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut Self::ViewState,
|
_: &mut Self::ViewState,
|
||||||
|
@ -110,6 +114,10 @@ impl<S: 'static + Send + Sync> Element for AnyView<S> {
|
||||||
type ViewState = ();
|
type ViewState = ();
|
||||||
type ElementState = AnyBox;
|
type ElementState = AnyBox;
|
||||||
|
|
||||||
|
fn element_id(&self) -> Option<crate::ElementId> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: &mut Self::ViewState,
|
_: &mut Self::ViewState,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::theme::{theme, Theme};
|
use crate::theme::{theme, Theme};
|
||||||
use gpui3::{
|
use gpui3::{
|
||||||
div, img, svg, view, AppContext, Context, Element, ElementId, Interactive, IntoAnyElement,
|
div, img, svg, view, AppContext, Context, Element, ElementId, IntoAnyElement, MouseButton,
|
||||||
MouseButton, ParentElement, ScrollState, SharedString, StyleHelpers, Styled, View, ViewContext,
|
ParentElement, ScrollState, SharedString, StyleHelpers, Styled, View, ViewContext,
|
||||||
WindowContext,
|
WindowContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue