Detailed changes
@@ -2640,15 +2640,6 @@ impl Element<Editor> for EditorElement {
cx.request_layout(&style, None)
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut Editor,
- element_state: &mut Self::ElementState,
- cx: &mut ViewContext<Editor>,
- ) {
- }
-
fn paint(
&mut self,
bounds: Bounds<gpui::Pixels>,
@@ -26,14 +26,6 @@ pub trait Element<V: 'static> {
cx: &mut ViewContext<V>,
) -> LayoutId;
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut V,
- element_state: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- );
-
fn paint(
&mut self,
bounds: Bounds<Pixels>,
@@ -70,7 +62,6 @@ pub trait ParentElement<V: 'static> {
trait ElementObject<V> {
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 prepaint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
fn measure(
&mut self,
@@ -208,36 +199,6 @@ where
};
}
- fn prepaint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) {
- self.phase = match mem::take(&mut self.phase) {
- ElementRenderPhase::LayoutRequested {
- layout_id,
- mut frame_state,
- }
- | ElementRenderPhase::LayoutComputed {
- layout_id,
- mut frame_state,
- ..
- } => {
- 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();
- self.element
- .prepaint(bounds, view_state, &mut element_state, cx);
- ((), element_state)
- });
- } else {
- self.element
- .prepaint(bounds, view_state, frame_state.as_mut().unwrap(), cx);
- }
- ElementRenderPhase::Painted
- }
-
- _ => panic!("must call layout before paint"),
- };
- }
-
fn measure(
&mut self,
available_space: Size<AvailableSpace>,
@@ -322,10 +283,6 @@ impl<V> AnyElement<V> {
self.0.paint(view_state, cx)
}
- pub fn prepaint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) {
- self.0.prepaint(view_state, cx)
- }
-
/// Initializes this element and performs layout within the given available space to determine its size.
pub fn measure(
&mut self,
@@ -419,16 +376,6 @@ where
rendered_element.layout(view_state, cx)
}
- fn prepaint(
- &mut self,
- _bounds: Bounds<Pixels>,
- view_state: &mut V,
- rendered_element: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- ) {
- rendered_element.prepaint(view_state, cx)
- }
-
fn paint(
&mut self,
_bounds: Bounds<Pixels>,
@@ -265,16 +265,6 @@ where
})
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut V,
- element_state: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- ) {
- todo!()
- }
-
fn paint(
&mut self,
bounds: Bounds<Pixels>,
@@ -94,15 +94,6 @@ where
self.base.layout(view_state, element_state, cx)
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut V,
- element_state: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- ) {
- }
-
fn paint(
&mut self,
bounds: Bounds<Pixels>,
@@ -274,9 +274,7 @@ pub trait InteractiveComponent<V: 'static> {
}
}
-pub trait StatefulInteractiveComponent<V: 'static> {
- fn interactivity(&mut self) -> &mut StatefulInteractivity<V>;
-
+pub trait StatefulInteractiveComponent<V: 'static>: InteractiveComponent<V> {
fn active(mut self, f: impl FnOnce(StyleRefinement) -> StyleRefinement) -> Self
where
Self: Sized,
@@ -525,23 +523,14 @@ pub struct FocusEvent {
}
pub struct Node<V> {
- style: StyleRefinement,
key_context: KeyContext,
interactivity: Interactivity<V>,
children: Vec<AnyElement<V>>,
}
-impl<V> Node<V> {
- fn compute_style(&self) -> Style {
- let mut style = Style::default();
- style.refine(&self.style);
- style
- }
-}
-
impl<V> Styled for Node<V> {
fn style(&mut self) -> &mut StyleRefinement {
- &mut self.style
+ &mut self.interactivity.base_style
}
}
@@ -582,7 +571,7 @@ impl<V: 'static> Element<V> for Node<V> {
element_state: &mut Self::ElementState,
cx: &mut ViewContext<V>,
) -> crate::LayoutId {
- let style = self.compute_style();
+ let style = self.interactivity().compute_style(None, cx);
style.with_text_style(cx, |cx| {
element_state.child_layout_ids = self
.children
@@ -593,20 +582,6 @@ impl<V: 'static> Element<V> for Node<V> {
})
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut V,
- _: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- ) {
- for child in &mut self.children {
- child.prepaint(view_state, cx);
- }
- self.interactivity
- .refine_style(&mut self.style, bounds, view_state, cx);
- }
-
fn paint(
&mut self,
bounds: Bounds<Pixels>,
@@ -614,7 +589,7 @@ impl<V: 'static> Element<V> for Node<V> {
element_state: &mut Self::ElementState,
cx: &mut ViewContext<V>,
) {
- let style = self.compute_style();
+ let style = self.interactivity.compute_style(Some(bounds), cx);
if style.visibility == Visibility::Hidden {
return;
}
@@ -671,12 +646,37 @@ impl<V: 'static> Element<V> for Node<V> {
}
}
+pub struct ComputedStyle {
+ base: StyleRefinement,
+ focus: StyleRefinement,
+ hover: StyleRefinement,
+ active: StyleRefinement,
+}
+
+pub struct StyleCascade {
+ pub base: StyleRefinement,
+ pub focus: StyleRefinement,
+ pub hover: StyleRefinement,
+ pub dragged_over: StyleRefinement,
+ pub active: StyleRefinement,
+}
+
pub struct Interactivity<V> {
+ pub active: bool,
+ pub group_active: bool,
+ pub hovered: bool,
+ pub group_hovered: bool,
+ pub focused: bool,
+ pub scroll_offset: Point<Pixels>,
+ pub base_style: StyleRefinement,
+ pub focus_style: StyleRefinement,
pub hover_style: StyleRefinement,
pub group_hover_style: Option<GroupStyle>,
+ pub active_style: StyleRefinement,
+ pub group_active_style: Option<GroupStyle>,
pub drag_over_styles: SmallVec<[(TypeId, StyleRefinement); 2]>,
pub group_drag_over_styles: SmallVec<[(TypeId, GroupStyle); 2]>,
- group: Option<SharedString>,
+ pub group: Option<SharedString>,
pub dispatch_context: KeyContext,
pub mouse_down_listeners: SmallVec<[MouseDownListener<V>; 2]>,
pub mouse_up_listeners: SmallVec<[MouseUpListener<V>; 2]>,
@@ -685,49 +685,68 @@ pub struct Interactivity<V> {
pub key_down_listeners: SmallVec<[KeyDownListener<V>; 2]>,
pub key_up_listeners: SmallVec<[KeyUpListener<V>; 2]>,
pub action_listeners: SmallVec<[(TypeId, ActionListener<V>); 8]>,
- drop_listeners: SmallVec<[(TypeId, Box<DropListener<V>>); 2]>,
- scroll_offset: Point<Pixels>,
+ pub drop_listeners: SmallVec<[(TypeId, Box<DropListener<V>>); 2]>,
+ pub click_listeners: SmallVec<[ClickListener<V>; 2]>,
+ pub drag_listener: Option<DragListener<V>>,
+ pub hover_listener: Option<HoverListener<V>>,
+ pub tooltip_builder: Option<TooltipBuilder<V>>,
}
impl<V: 'static> Interactivity<V> {
- fn refine_style(
- &self,
- style: &mut StyleRefinement,
- bounds: Bounds<Pixels>,
- cx: &mut ViewContext<V>,
- ) {
- let mouse_position = cx.mouse_position();
- if let Some(group_hover) = self.group_hover_style.as_ref() {
- if let Some(group_bounds) = GroupBounds::get(&group_hover.group, cx) {
- if group_bounds.contains_point(&mouse_position) {
- style.refine(&group_hover.style);
+ fn compute_style(&self, bounds: Option<Bounds<Pixels>>, cx: &mut ViewContext<V>) -> Style {
+ let mut style = Style::default();
+ style.refine(&self.base_style);
+ if self.focused {
+ style.refine(&self.focus_style);
+ }
+
+ if let Some(bounds) = bounds {
+ let mouse_position = cx.mouse_position();
+ if let Some(group_hover) = self.group_hover_style.as_ref() {
+ if let Some(group_bounds) = GroupBounds::get(&group_hover.group, cx) {
+ if group_bounds.contains_point(&mouse_position) {
+ style.refine(&group_hover.style);
+ }
}
}
- }
- if bounds.contains_point(&mouse_position) {
- style.refine(&self.hover_style);
- }
+ if bounds.contains_point(&mouse_position) {
+ style.refine(&self.hover_style);
+ }
+
+ if let Some(drag) = cx.active_drag.take() {
+ for (state_type, group_drag_style) in &self.group_drag_over_styles {
+ if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) {
+ if *state_type == drag.view.entity_type()
+ && group_bounds.contains_point(&mouse_position)
+ {
+ style.refine(&group_drag_style.style);
+ }
+ }
+ }
- if let Some(drag) = cx.active_drag.take() {
- for (state_type, group_drag_style) in &self.group_drag_over_styles {
- if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) {
+ for (state_type, drag_over_style) in &self.drag_over_styles {
if *state_type == drag.view.entity_type()
- && group_bounds.contains_point(&mouse_position)
+ && bounds.contains_point(&mouse_position)
{
- style.refine(&group_drag_style.style);
+ style.refine(drag_over_style);
}
}
+
+ cx.active_drag = Some(drag);
}
+ }
- for (state_type, drag_over_style) in &self.drag_over_styles {
- if *state_type == drag.view.entity_type() && bounds.contains_point(&mouse_position)
- {
- style.refine(drag_over_style);
- }
+ if self.group_active {
+ if let Some(group) = self.group_active_style.as_ref() {
+ style.refine(&group.style)
}
+ }
- cx.active_drag = Some(drag);
+ if self.active {
+ style.refine(&self.active_style)
}
+
+ style
}
fn paint(&mut self, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
@@ -863,32 +882,15 @@ impl<V: 'static, E: InteractiveComponent<V>> InteractiveComponent<V> for Focusab
impl<V: 'static, E: StatefulInteractiveComponent<V>> StatefulInteractiveComponent<V>
for Focusable<V, E>
{
- fn interactivity(&mut self) -> &mut StatefulInteractivity<V> {
- self.element.interactivity()
- }
}
pub struct Stateful<V, E> {
id: SharedString,
- interactivity: StatefulInteractivity<V>,
view_type: PhantomData<V>,
element: E,
}
-pub struct StatefulInteractivity<V> {
- click_listeners: SmallVec<[ClickListener<V>; 2]>,
- active_style: StyleRefinement,
- group_active_style: Option<GroupStyle>,
- drag_listener: Option<DragListener<V>>,
- hover_listener: Option<HoverListener<V>>,
- tooltip_builder: Option<TooltipBuilder<V>>,
-}
-
-impl<V: 'static, E> StatefulInteractiveComponent<V> for Stateful<V, E> {
- fn interactivity(&mut self) -> &mut StatefulInteractivity<V> {
- &mut self.interactivity
- }
-}
+impl<V: 'static, E: InteractiveComponent<V>> StatefulInteractiveComponent<V> for Stateful<V, E> {}
impl<V: 'static, E: InteractiveComponent<V>> InteractiveComponent<V> for Stateful<V, E> {
fn interactivity(&mut self) -> &mut Interactivity<V> {
@@ -84,15 +84,6 @@ where
self.base.layout(view_state, element_state, cx)
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut V,
- element_state: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- ) {
- }
-
fn paint(
&mut self,
bounds: Bounds<Pixels>,
@@ -121,15 +121,6 @@ impl<V: 'static> Element<V> for Text<V> {
layout_id
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut V,
- element_state: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- ) {
- }
-
fn paint(
&mut self,
bounds: Bounds<Pixels>,
@@ -152,16 +152,6 @@ impl<V: 'static> Element<V> for UniformList<V> {
)
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut V,
- element_state: &mut Self::ElementState,
- cx: &mut ViewContext<V>,
- ) {
- todo!()
- }
-
fn paint(
&mut self,
bounds: crate::Bounds<crate::Pixels>,
@@ -147,7 +147,6 @@ pub struct AnyView {
model: AnyModel,
initialize: fn(&AnyView, &mut WindowContext) -> AnyBox,
layout: fn(&AnyView, &mut AnyBox, &mut WindowContext) -> LayoutId,
- prepaint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
paint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
}
@@ -157,7 +156,6 @@ impl AnyView {
model: self.model.downgrade(),
initialize: self.initialize,
layout: self.layout,
- prepaint: self.prepaint,
paint: self.paint,
}
}
@@ -169,7 +167,6 @@ impl AnyView {
model,
initialize: self.initialize,
layout: self.layout,
- prepaint: self.prepaint,
paint: self.paint,
}),
}
@@ -201,7 +198,6 @@ impl<V: Render> From<View<V>> for AnyView {
model: value.model.into_any(),
initialize: any_view::initialize::<V>,
layout: any_view::layout::<V>,
- prepaint: any_view::prepaint::<V>,
paint: any_view::paint::<V>,
}
}
@@ -232,16 +228,6 @@ impl<ParentViewState: 'static> Element<ParentViewState> for AnyView {
(self.layout)(self, rendered_element, cx)
}
- fn prepaint(
- &mut self,
- bounds: Bounds<Pixels>,
- view_state: &mut ParentViewState,
- rendered_element: &mut Self::ElementState,
- cx: &mut ViewContext<ParentViewState>,
- ) {
- (self.prepaint)(self, rendered_element, cx)
- }
-
fn paint(
&mut self,
_bounds: Bounds<Pixels>,
@@ -257,7 +243,6 @@ pub struct AnyWeakView {
model: AnyWeakModel,
initialize: fn(&AnyView, &mut WindowContext) -> AnyBox,
layout: fn(&AnyView, &mut AnyBox, &mut WindowContext) -> LayoutId,
- prepaint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
paint: fn(&AnyView, &mut AnyBox, &mut WindowContext),
}
@@ -268,7 +253,6 @@ impl AnyWeakView {
model,
initialize: self.initialize,
layout: self.layout,
- prepaint: self.prepaint,
paint: self.paint,
})
}
@@ -280,7 +264,6 @@ impl<V: Render> From<WeakView<V>> for AnyWeakView {
model: view.model.into(),
initialize: any_view::initialize::<V>,
layout: any_view::layout::<V>,
- prepaint: any_view::prepaint::<V>,
paint: any_view::paint::<V>,
}
}
@@ -326,18 +309,6 @@ mod any_view {
})
}
- pub(crate) fn prepaint<V: Render>(
- view: &AnyView,
- element: &mut Box<dyn Any>,
- cx: &mut WindowContext,
- ) {
- cx.with_element_id(view.model.entity_id, |_, cx| {
- let view = view.clone().downcast::<V>().unwrap();
- let element = element.downcast_mut::<AnyElement<V>>().unwrap();
- view.update(cx, |view, cx| element.prepaint(view, cx))
- })
- }
-
pub(crate) fn paint<V: Render>(
view: &AnyView,
element: &mut Box<dyn Any>,