Return impl IntoElement from RenderOnce::render

This makes it a bit more approachable to implement.

This required converting the state of Component to AnyElement, which
costs an allocation. I'm hoping this will be ok performance-wise now
that AnyElements use bump allocation, but I need to benchmark still.
This commit is contained in:
Nathan Sobo 2024-01-02 10:27:09 -07:00
parent 1b5c8b2b4a
commit 68e7d99219
35 changed files with 74 additions and 183 deletions

View File

@ -1,5 +1,5 @@
use gpui::{ use gpui::{
div, AnyElement, Div, ElementId, IntoElement, ParentElement, RenderOnce, Styled, WindowContext, div, AnyElement, ElementId, IntoElement, ParentElement, RenderOnce, Styled, WindowContext,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
@ -9,9 +9,7 @@ pub struct FacePile {
} }
impl RenderOnce for FacePile { impl RenderOnce for FacePile {
type Output = Div; fn render(self, _: &mut WindowContext) -> impl IntoElement {
fn render(self, _: &mut WindowContext) -> Self::Output {
let player_count = self.faces.len(); let player_count = self.faces.len();
let player_list = self.faces.into_iter().enumerate().map(|(ix, player)| { let player_list = self.faces.into_iter().enumerate().map(|(ix, player)| {
let isnt_last = ix < player_count - 1; let isnt_last = ix < player_count - 1;

View File

@ -113,9 +113,7 @@ pub trait Render: 'static + Sized {
/// You can derive [IntoElement] on any type that implements this trait. /// You can derive [IntoElement] on any type that implements this trait.
/// It is used to allow views to be expressed in terms of abstract data. /// It is used to allow views to be expressed in terms of abstract data.
pub trait RenderOnce: 'static { pub trait RenderOnce: 'static {
type Output: IntoElement; fn render(self, cx: &mut WindowContext) -> impl IntoElement;
fn render(self, cx: &mut WindowContext) -> Self::Output;
} }
pub trait ParentElement { pub trait ParentElement {
@ -139,66 +137,29 @@ pub trait ParentElement {
} }
} }
pub struct Component<C> { pub struct Component<C: RenderOnce>(Option<C>);
component: Option<C>,
}
pub struct ComponentState<C: RenderOnce> { impl<C: RenderOnce> Component<C> {
rendered_element: Option<<C::Output as IntoElement>::Element>,
rendered_element_state: Option<<<C::Output as IntoElement>::Element as Element>::State>,
}
impl<C> Component<C> {
pub fn new(component: C) -> Self { pub fn new(component: C) -> Self {
Component { Component(Some(component))
component: Some(component),
}
} }
} }
impl<C: RenderOnce> Element for Component<C> { impl<C: RenderOnce> Element for Component<C> {
type State = ComponentState<C>; type State = AnyElement;
fn request_layout( fn request_layout(
&mut self, &mut self,
state: Option<Self::State>, _: Option<Self::State>,
cx: &mut WindowContext, cx: &mut WindowContext,
) -> (LayoutId, Self::State) { ) -> (LayoutId, Self::State) {
let mut element = self.component.take().unwrap().render(cx).into_element(); let mut element = self.0.take().unwrap().render(cx).into_any_element();
if let Some(element_id) = element.element_id() { let layout_id = element.request_layout(cx);
let layout_id = (layout_id, element)
cx.with_element_state(element_id, |state, cx| element.request_layout(state, cx));
let state = ComponentState {
rendered_element: Some(element),
rendered_element_state: None,
};
(layout_id, state)
} else {
let (layout_id, state) =
element.request_layout(state.and_then(|s| s.rendered_element_state), cx);
let state = ComponentState {
rendered_element: Some(element),
rendered_element_state: Some(state),
};
(layout_id, state)
}
} }
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext) { fn paint(&mut self, _: Bounds<Pixels>, element: &mut Self::State, cx: &mut WindowContext) {
let mut element = state.rendered_element.take().unwrap(); element.paint(cx)
if let Some(element_id) = element.element_id() {
cx.with_element_state(element_id, |element_state, cx| {
let mut element_state = element_state.unwrap();
element.paint(bounds, &mut element_state, cx);
((), element_state)
});
} else {
element.paint(
bounds,
&mut state.rendered_element_state.as_mut().unwrap(),
cx,
);
}
} }
} }
@ -220,7 +181,7 @@ pub struct GlobalElementId(SmallVec<[ElementId; 32]>);
trait ElementObject { trait ElementObject {
fn element_id(&self) -> Option<ElementId>; fn element_id(&self) -> Option<ElementId>;
fn layout(&mut self, cx: &mut WindowContext) -> LayoutId; fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId;
fn paint(&mut self, cx: &mut WindowContext); fn paint(&mut self, cx: &mut WindowContext);
@ -395,7 +356,7 @@ where
self.as_ref().unwrap().element_id() self.as_ref().unwrap().element_id()
} }
fn layout(&mut self, cx: &mut WindowContext) -> LayoutId { fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId {
DrawableElement::request_layout(self.as_mut().unwrap(), cx) DrawableElement::request_layout(self.as_mut().unwrap(), cx)
} }
@ -435,8 +396,8 @@ impl AnyElement {
AnyElement(element) AnyElement(element)
} }
pub fn layout(&mut self, cx: &mut WindowContext) -> LayoutId { pub fn request_layout(&mut self, cx: &mut WindowContext) -> LayoutId {
self.0.layout(cx) self.0.request_layout(cx)
} }
pub fn paint(&mut self, cx: &mut WindowContext) { pub fn paint(&mut self, cx: &mut WindowContext) {
@ -475,7 +436,7 @@ impl Element for AnyElement {
_: Option<Self::State>, _: Option<Self::State>,
cx: &mut WindowContext, cx: &mut WindowContext,
) -> (LayoutId, Self::State) { ) -> (LayoutId, Self::State) {
let layout_id = self.layout(cx); let layout_id = self.request_layout(cx);
(layout_id, ()) (layout_id, ())
} }

View File

@ -782,7 +782,7 @@ impl Element for Div {
child_layout_ids = self child_layout_ids = self
.children .children
.iter_mut() .iter_mut()
.map(|child| child.layout(cx)) .map(|child| child.request_layout(cx))
.collect::<SmallVec<_>>(); .collect::<SmallVec<_>>();
cx.request_layout(&style, child_layout_ids.iter().copied()) cx.request_layout(&style, child_layout_ids.iter().copied())
}) })

View File

@ -68,7 +68,7 @@ impl Element for Overlay {
let child_layout_ids = self let child_layout_ids = self
.children .children
.iter_mut() .iter_mut()
.map(|child| child.layout(cx)) .map(|child| child.request_layout(cx))
.collect::<SmallVec<_>>(); .collect::<SmallVec<_>>();
let mut overlay_style = Style::default(); let mut overlay_style = Style::default();

View File

@ -87,7 +87,7 @@ impl<V: Render> Element for View<V> {
cx: &mut WindowContext, cx: &mut WindowContext,
) -> (LayoutId, Self::State) { ) -> (LayoutId, Self::State) {
let mut element = self.update(cx, |view, cx| view.render(cx).into_any_element()); let mut element = self.update(cx, |view, cx| view.render(cx).into_any_element());
let layout_id = element.layout(cx); let layout_id = element.request_layout(cx);
(layout_id, Some(element)) (layout_id, Some(element))
} }
@ -321,7 +321,7 @@ mod any_view {
) -> (LayoutId, AnyElement) { ) -> (LayoutId, AnyElement) {
let view = view.clone().downcast::<V>().unwrap(); let view = view.clone().downcast::<V>().unwrap();
let mut element = view.update(cx, |view, cx| view.render(cx).into_any_element()); let mut element = view.update(cx, |view, cx| view.render(cx).into_any_element());
let layout_id = element.layout(cx); let layout_id = element.request_layout(cx);
(layout_id, element) (layout_id, element)
} }

View File

@ -136,9 +136,7 @@ impl QuickActionBarButton {
} }
impl RenderOnce for QuickActionBarButton { impl RenderOnce for QuickActionBarButton {
type Output = IconButton; fn render(self, _: &mut WindowContext) -> impl IntoElement {
fn render(self, _: &mut WindowContext) -> Self::Output {
let tooltip = self.tooltip.clone(); let tooltip = self.tooltip.clone();
let action = self.action.boxed_clone(); let action = self.action.boxed_clone();

View File

@ -43,9 +43,7 @@ impl HighlightedText {
} }
impl RenderOnce for HighlightedText { impl RenderOnce for HighlightedText {
type Output = HighlightedLabel; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
HighlightedLabel::new(self.text, self.highlight_positions) HighlightedLabel::new(self.text, self.highlight_positions)
} }
} }

View File

@ -1,6 +1,5 @@
use gpui::{ use gpui::{
div, hsla, prelude::*, px, rems, AnyElement, Div, ElementId, Hsla, SharedString, Stateful, div, hsla, prelude::*, px, rems, AnyElement, Div, ElementId, Hsla, SharedString, WindowContext,
WindowContext,
}; };
use itertools::Itertools; use itertools::Itertools;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -74,9 +73,7 @@ impl ParentElement for StoryContainer {
} }
impl RenderOnce for StoryContainer { impl RenderOnce for StoryContainer {
type Output = Stateful<Div>; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
div() div()
.size_full() .size_full()
.flex() .flex()
@ -294,9 +291,7 @@ impl StoryItem {
} }
impl RenderOnce for StoryItem { impl RenderOnce for StoryItem {
type Output = Div; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
div() div()
.my_2() .my_2()
.flex() .flex()
@ -358,9 +353,7 @@ impl StorySection {
} }
impl RenderOnce for StorySection { impl RenderOnce for StorySection {
type Output = Div; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
let children: SmallVec<[AnyElement; 2]> = SmallVec::from_iter(Itertools::intersperse_with( let children: SmallVec<[AnyElement; 2]> = SmallVec::from_iter(Itertools::intersperse_with(
self.children.into_iter(), self.children.into_iter(),
|| Story::divider().into_any_element(), || Story::divider().into_any_element(),

View File

@ -80,9 +80,7 @@ struct ZIndexExample {
} }
impl RenderOnce for ZIndexExample { impl RenderOnce for ZIndexExample {
type Output = Div; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
div() div()
.relative() .relative()
.size_full() .size_full()

View File

@ -1,5 +1,5 @@
use crate::prelude::*; use crate::prelude::*;
use gpui::{img, Div, Hsla, ImageSource, Img, IntoElement, Styled}; use gpui::{img, Hsla, ImageSource, Img, IntoElement, Styled};
#[derive(Debug, Default, PartialEq, Clone)] #[derive(Debug, Default, PartialEq, Clone)]
pub enum Shape { pub enum Shape {
@ -16,9 +16,7 @@ pub struct Avatar {
} }
impl RenderOnce for Avatar { impl RenderOnce for Avatar {
type Output = Div; fn render(mut self, cx: &mut WindowContext) -> impl IntoElement {
fn render(mut self, cx: &mut WindowContext) -> Self::Output {
if self.image.style().corner_radii.top_left.is_none() { if self.image.style().corner_radii.top_left.is_none() {
self = self.shape(Shape::Circle); self = self.shape(Shape::Circle);
} }

View File

@ -136,9 +136,8 @@ impl ButtonCommon for Button {
} }
impl RenderOnce for Button { impl RenderOnce for Button {
type Output = ButtonLike; #[allow(refining_impl_trait)]
fn render(self, _cx: &mut WindowContext) -> ButtonLike {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
let is_disabled = self.base.disabled; let is_disabled = self.base.disabled;
let is_selected = self.base.selected; let is_selected = self.base.selected;

View File

@ -63,9 +63,7 @@ impl Selectable for ButtonIcon {
} }
impl RenderOnce for ButtonIcon { impl RenderOnce for ButtonIcon {
type Output = IconElement; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
let icon = self let icon = self
.selected_icon .selected_icon
.filter(|_| self.selected) .filter(|_| self.selected)

View File

@ -1,5 +1,5 @@
use gpui::{relative, DefiniteLength, MouseButton}; use gpui::{relative, DefiniteLength, MouseButton};
use gpui::{rems, transparent_black, AnyElement, AnyView, ClickEvent, Div, Hsla, Rems, Stateful}; use gpui::{rems, transparent_black, AnyElement, AnyView, ClickEvent, Hsla, Rems};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::prelude::*; use crate::prelude::*;
@ -363,9 +363,7 @@ impl ParentElement for ButtonLike {
} }
impl RenderOnce for ButtonLike { impl RenderOnce for ButtonLike {
type Output = Stateful<Div>; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
self.base self.base
.h_flex() .h_flex()
.id(self.id.clone()) .id(self.id.clone())

View File

@ -106,9 +106,7 @@ impl VisibleOnHover for IconButton {
} }
impl RenderOnce for IconButton { impl RenderOnce for IconButton {
type Output = ButtonLike; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
let is_disabled = self.base.disabled; let is_disabled = self.base.disabled;
let is_selected = self.base.selected; let is_selected = self.base.selected;

View File

@ -99,9 +99,7 @@ impl ButtonCommon for ToggleButton {
} }
impl RenderOnce for ToggleButton { impl RenderOnce for ToggleButton {
type Output = ButtonLike; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
let is_disabled = self.base.disabled; let is_disabled = self.base.disabled;
let is_selected = self.base.selected; let is_selected = self.base.selected;

View File

@ -1,4 +1,4 @@
use gpui::{div, prelude::*, Div, Element, ElementId, IntoElement, Styled, WindowContext}; use gpui::{div, prelude::*, Element, ElementId, IntoElement, Styled, WindowContext};
use crate::prelude::*; use crate::prelude::*;
use crate::{Color, Icon, IconElement, Selection}; use crate::{Color, Icon, IconElement, Selection};
@ -19,9 +19,7 @@ pub struct Checkbox {
} }
impl RenderOnce for Checkbox { impl RenderOnce for Checkbox {
type Output = gpui::Stateful<Div>; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
let group_id = format!("checkbox_group_{:?}", self.id); let group_id = format!("checkbox_group_{:?}", self.id);
let icon = match self.checked { let icon = match self.checked {

View File

@ -28,9 +28,7 @@ impl Disclosure {
} }
impl RenderOnce for Disclosure { impl RenderOnce for Disclosure {
type Output = IconButton; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
IconButton::new( IconButton::new(
self.id, self.id,
match self.is_open { match self.is_open {

View File

@ -1,4 +1,4 @@
use gpui::{Div, Hsla, IntoElement}; use gpui::{Hsla, IntoElement};
use crate::prelude::*; use crate::prelude::*;
@ -31,9 +31,7 @@ pub struct Divider {
} }
impl RenderOnce for Divider { impl RenderOnce for Divider {
type Output = Div; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.map(|this| match self.direction { .map(|this| match self.direction {
DividerDirection::Horizontal => { DividerDirection::Horizontal => {

View File

@ -1,4 +1,4 @@
use gpui::{rems, svg, IntoElement, Rems, Svg}; use gpui::{rems, svg, IntoElement, Rems};
use strum::EnumIter; use strum::EnumIter;
use crate::prelude::*; use crate::prelude::*;
@ -200,9 +200,7 @@ pub struct IconElement {
} }
impl RenderOnce for IconElement { impl RenderOnce for IconElement {
type Output = Svg; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
svg() svg()
.size(self.size.rems()) .size(self.size.rems())
.flex_none() .flex_none()

View File

@ -1,4 +1,4 @@
use gpui::{Div, Position}; use gpui::Position;
use crate::prelude::*; use crate::prelude::*;
@ -45,9 +45,7 @@ impl Indicator {
} }
impl RenderOnce for Indicator { impl RenderOnce for Indicator {
type Output = Div; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.flex_none() .flex_none()
.map(|this| match self.style { .map(|this| match self.style {

View File

@ -1,5 +1,5 @@
use crate::{h_stack, prelude::*, Icon, IconElement, IconSize}; use crate::{h_stack, prelude::*, Icon, IconElement, IconSize};
use gpui::{relative, rems, Action, Div, FocusHandle, IntoElement, Keystroke}; use gpui::{relative, rems, Action, FocusHandle, IntoElement, Keystroke};
#[derive(IntoElement, Clone)] #[derive(IntoElement, Clone)]
pub struct KeyBinding { pub struct KeyBinding {
@ -11,9 +11,7 @@ pub struct KeyBinding {
} }
impl RenderOnce for KeyBinding { impl RenderOnce for KeyBinding {
type Output = Div; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
h_stack() h_stack()
.flex_none() .flex_none()
.gap_2() .gap_2()
@ -87,9 +85,7 @@ pub struct Key {
} }
impl RenderOnce for Key { impl RenderOnce for Key {
type Output = Div; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
let single_char = self.key.len() == 1; let single_char = self.key.len() == 1;
div() div()
@ -121,9 +117,7 @@ pub struct KeyIcon {
} }
impl RenderOnce for KeyIcon { impl RenderOnce for KeyIcon {
type Output = Div; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
div() div()
.w(rems(14. / 16.)) .w(rems(14. / 16.))
.child(IconElement::new(self.icon).size(IconSize::Small)) .child(IconElement::new(self.icon).size(IconSize::Small))

View File

@ -46,9 +46,7 @@ impl LabelCommon for HighlightedLabel {
} }
impl RenderOnce for HighlightedLabel { impl RenderOnce for HighlightedLabel {
type Output = LabelLike; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
let highlight_color = cx.theme().colors().text_accent; let highlight_color = cx.theme().colors().text_accent;
let mut highlight_indices = self.highlight_indices.iter().copied().peekable(); let mut highlight_indices = self.highlight_indices.iter().copied().peekable();

View File

@ -40,9 +40,7 @@ impl LabelCommon for Label {
} }
impl RenderOnce for Label { impl RenderOnce for Label {
type Output = LabelLike; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
self.base.child(self.label) self.base.child(self.label)
} }
} }

View File

@ -1,4 +1,4 @@
use gpui::{relative, AnyElement, Div, Styled}; use gpui::{relative, AnyElement, Styled};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::prelude::*; use crate::prelude::*;
@ -76,9 +76,7 @@ impl ParentElement for LabelLike {
} }
impl RenderOnce for LabelLike { impl RenderOnce for LabelLike {
type Output = Div; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.when(self.strikethrough, |this| { .when(self.strikethrough, |this| {
this.relative().child( this.relative().child(

View File

@ -1,4 +1,4 @@
use gpui::{AnyElement, Div}; use gpui::AnyElement;
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::{prelude::*, v_stack, Label, ListHeader}; use crate::{prelude::*, v_stack, Label, ListHeader};
@ -46,9 +46,7 @@ impl ParentElement for List {
} }
impl RenderOnce for List { impl RenderOnce for List {
type Output = Div; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
v_stack().w_full().py_1().children(self.header).map(|this| { v_stack().w_full().py_1().children(self.header).map(|this| {
match (self.children.is_empty(), self.toggle) { match (self.children.is_empty(), self.toggle) {
(false, _) => this.children(self.children), (false, _) => this.children(self.children),

View File

@ -1,6 +1,5 @@
use gpui::{AnyElement, ClickEvent, Div, Stateful};
use crate::{h_stack, prelude::*, Disclosure, Label}; use crate::{h_stack, prelude::*, Disclosure, Label};
use gpui::{AnyElement, ClickEvent};
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct ListHeader { pub struct ListHeader {
@ -76,9 +75,7 @@ impl Selectable for ListHeader {
} }
impl RenderOnce for ListHeader { impl RenderOnce for ListHeader {
type Output = Stateful<Div>; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
h_stack() h_stack()
.id(self.label.clone()) .id(self.label.clone())
.w_full() .w_full()

View File

@ -1,6 +1,4 @@
use gpui::{ use gpui::{px, AnyElement, AnyView, ClickEvent, MouseButton, MouseDownEvent, Pixels};
px, AnyElement, AnyView, ClickEvent, Div, MouseButton, MouseDownEvent, Pixels, Stateful,
};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::{prelude::*, Disclosure}; use crate::{prelude::*, Disclosure};
@ -147,9 +145,7 @@ impl ParentElement for ListItem {
} }
impl RenderOnce for ListItem { impl RenderOnce for ListItem {
type Output = Stateful<Div>; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
h_stack() h_stack()
.id(self.id) .id(self.id)
.w_full() .w_full()

View File

@ -1,14 +1,10 @@
use gpui::Div;
use crate::prelude::*; use crate::prelude::*;
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct ListSeparator; pub struct ListSeparator;
impl RenderOnce for ListSeparator { impl RenderOnce for ListSeparator {
type Output = Div; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.h_px() .h_px()
.w_full() .w_full()

View File

@ -1,5 +1,3 @@
use gpui::Div;
use crate::prelude::*; use crate::prelude::*;
use crate::{h_stack, Icon, IconElement, IconSize, Label}; use crate::{h_stack, Icon, IconElement, IconSize, Label};
@ -26,9 +24,7 @@ impl ListSubHeader {
} }
impl RenderOnce for ListSubHeader { impl RenderOnce for ListSubHeader {
type Output = Div; fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
fn render(self, _cx: &mut WindowContext) -> Self::Output {
h_stack().flex_1().w_full().relative().py_1().child( h_stack().flex_1().w_full().relative().py_1().child(
div() div()
.h_6() .h_6()

View File

@ -1,5 +1,5 @@
use gpui::{ use gpui::{
div, AnyElement, Div, Element, ElementId, IntoElement, ParentElement, RenderOnce, Styled, div, AnyElement, Element, ElementId, IntoElement, ParentElement, RenderOnce, Styled,
WindowContext, WindowContext,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
@ -41,9 +41,7 @@ pub struct Popover {
} }
impl RenderOnce for Popover { impl RenderOnce for Popover {
type Output = Div; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.flex() .flex()
.gap_1() .gap_1()

View File

@ -153,7 +153,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
} }
let mut element = overlay.child(menu.clone()).into_any(); let mut element = overlay.child(menu.clone()).into_any();
menu_layout_id = Some(element.layout(cx)); menu_layout_id = Some(element.request_layout(cx));
element element
}); });
@ -164,7 +164,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
let child_layout_id = child_element let child_layout_id = child_element
.as_mut() .as_mut()
.map(|child_element| child_element.layout(cx)); .map(|child_element| child_element.request_layout(cx));
let layout_id = cx.request_layout( let layout_id = cx.request_layout(
&gpui::Style::default(), &gpui::Style::default(),

View File

@ -81,7 +81,7 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
overlay = overlay.position(*position.borrow()); overlay = overlay.position(*position.borrow());
let mut element = overlay.child(menu.clone()).into_any(); let mut element = overlay.child(menu.clone()).into_any();
menu_layout_id = Some(element.layout(cx)); menu_layout_id = Some(element.request_layout(cx));
element element
}); });
@ -92,7 +92,7 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
let child_layout_id = child_element let child_layout_id = child_element
.as_mut() .as_mut()
.map(|child_element| child_element.layout(cx)); .map(|child_element| child_element.request_layout(cx));
let layout_id = cx.request_layout( let layout_id = cx.request_layout(
&gpui::Style::default(), &gpui::Style::default(),

View File

@ -93,9 +93,8 @@ impl ParentElement for Tab {
} }
impl RenderOnce for Tab { impl RenderOnce for Tab {
type Output = Stateful<Div>; #[allow(refining_impl_trait)]
fn render(self, cx: &mut WindowContext) -> Stateful<Div> {
fn render(self, cx: &mut WindowContext) -> Self::Output {
let (text_color, tab_bg, _tab_hover_bg, _tab_active_bg) = match self.selected { let (text_color, tab_bg, _tab_hover_bg, _tab_active_bg) = match self.selected {
false => ( false => (
cx.theme().colors().text_muted, cx.theme().colors().text_muted,

View File

@ -1,4 +1,4 @@
use gpui::{AnyElement, ScrollHandle, Stateful}; use gpui::{AnyElement, ScrollHandle};
use smallvec::SmallVec; use smallvec::SmallVec;
use crate::prelude::*; use crate::prelude::*;
@ -89,9 +89,7 @@ impl ParentElement for TabBar {
} }
impl RenderOnce for TabBar { impl RenderOnce for TabBar {
type Output = Stateful<Div>; fn render(self, cx: &mut WindowContext) -> impl IntoElement {
fn render(self, cx: &mut WindowContext) -> Self::Output {
const HEIGHT_IN_REMS: f32 = 30. / 16.; const HEIGHT_IN_REMS: f32 = 30. / 16.;
div() div()

View File

@ -4305,7 +4305,7 @@ impl Element for DisconnectedOverlay {
"Your connection to the remote project has been lost.", "Your connection to the remote project has been lost.",
)) ))
.into_any(); .into_any();
(overlay.layout(cx), overlay) (overlay.request_layout(cx), overlay)
} }
fn paint(&mut self, bounds: Bounds<Pixels>, overlay: &mut Self::State, cx: &mut WindowContext) { fn paint(&mut self, bounds: Bounds<Pixels>, overlay: &mut Self::State, cx: &mut WindowContext) {