Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
Nathan Sobo
4013cf9229 One more doc 2023-11-22 13:32:08 -07:00
Nathan Sobo
ed92f7a037 More docs 2023-11-22 13:03:31 -07:00
Nathan Sobo
d3576ddd0e Write some docs 2023-11-22 12:57:47 -07:00
Nathan Sobo
6dcbb9a05d Further refine element traits 2023-11-22 12:39:55 -07:00
Nathan Sobo
5158508d0a Add RenderOnceStateful 2023-11-22 12:16:27 -07:00
65 changed files with 339 additions and 297 deletions

View file

@ -9,9 +9,9 @@ pub struct UpdateNotification {
impl EventEmitter<NotificationEvent> for UpdateNotification {} impl EventEmitter<NotificationEvent> for UpdateNotification {}
impl Render for UpdateNotification { impl Render for UpdateNotification {
type Element = Div; type Output = Div;
fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> Self::Output {
div().child("Updated zed!") div().child("Updated zed!")
// let theme = theme::current(cx).clone(); // let theme = theme::current(cx).clone();
// let theme = &theme.update_notification; // let theme = &theme.update_notification;

View file

@ -3295,9 +3295,9 @@ impl CollabPanel {
// } // }
impl Render for CollabPanel { impl Render for CollabPanel {
type Element = Focusable<Div>; type Output = Focusable<Div>;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Output {
div() div()
.key_context("CollabPanel") .key_context("CollabPanel")
.track_focus(&self.focus_handle) .track_focus(&self.focus_handle)

View file

@ -82,9 +82,9 @@ pub struct CollabTitlebarItem {
} }
impl Render for CollabTitlebarItem { impl Render for CollabTitlebarItem {
type Element = Stateful<Div>; type Output = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
h_stack() h_stack()
.id("titlebar") .id("titlebar")
.justify_between() .justify_between()

View file

@ -77,9 +77,9 @@ impl FocusableView for CommandPalette {
} }
impl Render for CommandPalette { impl Render for CommandPalette {
type Element = Div; type Output = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Output {
v_stack().w_96().child(self.picker.clone()) v_stack().w_96().child(self.picker.clone())
} }
} }

View file

@ -91,9 +91,9 @@ struct DiagnosticGroupState {
impl EventEmitter<ItemEvent> for ProjectDiagnosticsEditor {} impl EventEmitter<ItemEvent> for ProjectDiagnosticsEditor {}
impl Render for ProjectDiagnosticsEditor { impl Render for ProjectDiagnosticsEditor {
type Element = Focusable<Div>; type Output = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let child = if self.path_states.is_empty() { let child = if self.path_states.is_empty() {
div() div()
.bg(cx.theme().colors().editor_background) .bg(cx.theme().colors().editor_background)

View file

@ -22,9 +22,9 @@ pub struct DiagnosticIndicator {
} }
impl Render for DiagnosticIndicator { impl Render for DiagnosticIndicator {
type Element = Stateful<Div>; type Output = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) { let diagnostic_indicator = match (self.summary.error_count, self.summary.warning_count) {
(0, 0) => h_stack().child(IconElement::new(Icon::Check).color(Color::Success)), (0, 0) => h_stack().child(IconElement::new(Icon::Check).color(Color::Success)),
(0, warning_count) => h_stack() (0, warning_count) => h_stack()

View file

@ -8,9 +8,9 @@ pub struct ToolbarControls {
} }
impl Render for ToolbarControls { impl Render for ToolbarControls {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let include_warnings = self let include_warnings = self
.editor .editor
.as_ref() .as_ref()

View file

@ -9386,9 +9386,9 @@ impl FocusableView for Editor {
} }
impl Render for Editor { impl Render for Editor {
type Element = EditorElement; type Output = EditorElement;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let settings = ThemeSettings::get_global(cx); let settings = ThemeSettings::get_global(cx);
let text_style = match self.mode { let text_style = match self.mode {
EditorMode::SingleLine => TextStyle { EditorMode::SingleLine => TextStyle {

View file

@ -2654,13 +2654,13 @@ impl Element for EditorElement {
} }
impl IntoElement for EditorElement { impl IntoElement for EditorElement {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<gpui::ElementId> { fn element_id(&self) -> Option<gpui::ElementId> {
self.editor.element_id() self.editor.element_id()
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -118,9 +118,9 @@ impl FocusableView for FileFinder {
} }
} }
impl Render for FileFinder { impl Render for FileFinder {
type Element = Div; type Output = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Output {
v_stack().w_96().child(self.picker.clone()) v_stack().w_96().child(self.picker.clone())
} }
} }

View file

@ -145,9 +145,9 @@ impl GoToLine {
} }
impl Render for GoToLine { impl Render for GoToLine {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
div() div()
.elevation_2(cx) .elevation_2(cx)
.key_context("GoToLine") .key_context("GoToLine")

View file

@ -630,9 +630,9 @@ impl AnyWindowHandle {
pub struct EmptyView {} pub struct EmptyView {}
impl Render for EmptyView { impl Render for EmptyView {
type Element = Div; type Output = Div;
fn render(&mut self, _cx: &mut crate::ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut crate::ViewContext<Self>) -> Self::Output {
div() div()
} }
} }

View file

@ -6,29 +6,82 @@ use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec; pub(crate) use smallvec::SmallVec;
use std::{any::Any, fmt::Debug}; use std::{any::Any, fmt::Debug};
/// To create a window, you'll need to pass a `View<V>`, requires type `V` to
/// implement this trait to GPUI knows how to present it on screen. Since `View`s
/// are themselves elements, they can be used to embed a stateful subset within
/// a larger element tree.
///
/// In Zed, major parts of the UI such as editors and panels are implemented as
/// views. If you only require state that lives as long as an identified element
/// is present in the element tree, consider implementing `RenderOnceStateful` instead,
/// which moves self and fully constructed on each render.
pub trait Render: 'static + Sized { pub trait Render: 'static + Sized {
type Element: Element + 'static; /// The type of the element returned
type Output: IntoElement + 'static;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element; fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output;
} }
/// Use this trait to implement components that don't maintain state across frames.
/// If you implement this trait, your type can be annotated #[derive(IntoElement)], which
/// enables it to be passed as a child of other elements.
///
/// If none of your types fields are optional, you should consider using a simple function
/// instead, but this trait can be useful for building a builder-style API for your component
/// that allow users to opt into functionality with chained method calls.
pub trait RenderOnce: 'static {
type Output: IntoElement;
fn render_once(self, cx: &mut WindowContext) -> Self::Output;
}
/// This trait is similar to [RenderOnce], but allows state to maintained across frames and requires
/// your type to be associated with an id to support this. If a type implements this trait, you can
/// derive IntoElement by adding the stateful attribute:
///
/// #[derive(IntoElement)]
/// #[stateful]
/// struct MyComponent {
/// id: usize,
/// // ...
/// }
///
/// impl RenderOnceStateful { /* ... */ }
pub trait RenderOnceStateful: 'static {
type Output: IntoElement;
type State: 'static;
/// An identifier that's unique in the containing namespace, which is introduced by the nearest
/// containing element with an id.
fn element_id(&self) -> ElementId;
/// The first time your element appears, `state` will be `None`, and you can reassign it.
/// If your element disappears for one frame and then reappears, the state will be discarded.
fn render_once(self, state: &mut Option<Self::State>, cx: &mut WindowContext) -> Self::Output;
}
/// Anything that can be turned into an element. You can derive this trait on your type by implementing
/// [RenderOnce] or [RenderOnceStateful].
pub trait IntoElement: Sized { pub trait IntoElement: Sized {
type Element: Element + 'static; type Output: Element + 'static;
fn element_id(&self) -> Option<ElementId>; fn element_id(&self) -> Option<ElementId>;
fn into_element(self) -> Self::Element; fn into_element(self) -> Self::Output;
fn into_any_element(self) -> AnyElement { fn into_any_element(self) -> AnyElement {
self.into_element().into_any() self.into_element().into_any()
} }
/// Convert into an element and draw at the specified origin, laying out the element at the root
/// of its own layout tree in the given available space. The given function is passed the
/// element's frame state after paint if the element does not have an id.
fn draw<T, R>( fn draw<T, R>(
self, self,
origin: Point<Pixels>, origin: Point<Pixels>,
available_space: Size<T>, available_space: Size<T>,
cx: &mut WindowContext, cx: &mut WindowContext,
f: impl FnOnce(&mut <Self::Element as Element>::State, &mut WindowContext) -> R, f: impl FnOnce(&mut <Self::Output as Element>::State, &mut WindowContext) -> R,
) -> R ) -> R
where where
T: Clone + Default + Debug + Into<AvailableSpace>, T: Clone + Default + Debug + Into<AvailableSpace>,
@ -54,6 +107,7 @@ pub trait IntoElement: Sized {
} }
} }
/// Map this type to a different type with the given function. Useful when method chaining.
fn map<U>(self, f: impl FnOnce(Self) -> U) -> U fn map<U>(self, f: impl FnOnce(Self) -> U) -> U
where where
Self: Sized, Self: Sized,
@ -99,40 +153,30 @@ pub trait Element: 'static + IntoElement {
} }
} }
pub trait RenderOnce: 'static { pub struct Component<R>(Option<R>);
type Rendered: IntoElement;
fn render(self, cx: &mut WindowContext) -> Self::Rendered; pub struct ComponentState<C: RenderOnce> {
rendered_element: Option<<C::Output as IntoElement>::Output>,
rendered_element_state: <<C::Output as IntoElement>::Output as Element>::State,
} }
pub struct Component<C> { impl<R> Component<R> {
component: Option<C>, pub fn new(renderable: R) -> Self {
} Component(Some(renderable))
pub struct CompositeElementState<C: RenderOnce> {
rendered_element: Option<<C::Rendered as IntoElement>::Element>,
rendered_element_state: <<C::Rendered as IntoElement>::Element as Element>::State,
}
impl<C> Component<C> {
pub fn new(component: C) -> Self {
Component {
component: Some(component),
}
} }
} }
impl<C: RenderOnce> Element for Component<C> { impl<R: RenderOnce> Element for Component<R> {
type State = CompositeElementState<C>; type State = ComponentState<R>;
fn layout( fn layout(
&mut self, &mut self,
state: Option<Self::State>, 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_once(cx).into_element();
let (layout_id, state) = element.layout(state.map(|s| s.rendered_element_state), cx); let (layout_id, state) = element.layout(state.map(|s| s.rendered_element_state), cx);
let state = CompositeElementState { let state = ComponentState {
rendered_element: Some(element), rendered_element: Some(element),
rendered_element_state: state, rendered_element_state: state,
}; };
@ -149,13 +193,90 @@ impl<C: RenderOnce> Element for Component<C> {
} }
impl<C: RenderOnce> IntoElement for Component<C> { impl<C: RenderOnce> IntoElement for Component<C> {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
None None
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self
}
}
pub struct StatefulComponent<R>(Option<R>);
pub struct StatefulComponentState<R: RenderOnceStateful> {
rendered_element: Option<<R::Output as IntoElement>::Output>,
rendered_element_state: <<R::Output as IntoElement>::Output as Element>::State,
component_state: Option<R::State>,
}
impl<R: RenderOnceStateful> Element for StatefulComponent<R> {
type State = StatefulComponentState<R>;
fn layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
) -> (LayoutId, Self::State) {
if let Some(StatefulComponentState {
rendered_element_state,
mut component_state,
..
}) = state
{
let mut rendered_element = self
.0
.take()
.unwrap()
.render_once(&mut component_state, cx)
.into_element();
let (layout_id, rendered_element_state) =
rendered_element.layout(Some(rendered_element_state), cx);
let state = StatefulComponentState {
rendered_element: Some(rendered_element),
rendered_element_state,
component_state,
};
(layout_id, state)
} else {
let mut component_state = None;
let mut rendered_element = self
.0
.take()
.unwrap()
.render_once(&mut component_state, cx)
.into_element();
let (layout_id, rendered_element_state) = rendered_element.layout(None, cx);
let state = StatefulComponentState {
rendered_element: Some(rendered_element),
rendered_element_state,
component_state,
};
(layout_id, state)
}
}
fn paint(self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext) {
state
.rendered_element
.take()
.unwrap()
.paint(bounds, &mut state.rendered_element_state, cx)
}
}
impl<R: RenderOnceStateful> IntoElement for StatefulComponent<R> {
type Output = Self;
fn element_id(&self) -> Option<ElementId> {
Some(self.0.as_ref().unwrap().element_id())
}
fn into_element(self) -> Self::Output {
self self
} }
} }
@ -350,39 +471,6 @@ impl<E: Element> DrawableElement<E> {
} }
} }
// impl<V: 'static, E: Element> Element for DrawableElement<V, E> {
// type State = <E::Element as Element>::State;
// fn layout(
// &mut self,
// element_state: Option<Self::State>,
// cx: &mut WindowContext,
// ) -> (LayoutId, Self::State) {
// }
// fn paint(
// self,
// bounds: Bounds<Pixels>,
// element_state: &mut Self::State,
// cx: &mut WindowContext,
// ) {
// todo!()
// }
// }
// impl<V: 'static, E: 'static + Element> RenderOnce for DrawableElement<V, E> {
// type Element = Self;
// fn element_id(&self) -> Option<ElementId> {
// self.element.as_ref()?.element_id()
// }
// fn render_once(self) -> Self::Element {
// self
// }
// }
impl<E> ElementObject for Option<DrawableElement<E>> impl<E> ElementObject for Option<DrawableElement<E>>
where where
E: Element, E: Element,
@ -484,59 +572,13 @@ impl Element for AnyElement {
} }
impl IntoElement for AnyElement { impl IntoElement for AnyElement {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
AnyElement::element_id(self) AnyElement::element_id(self)
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }
// impl<V, E, F> Element for Option<F>
// where
// V: 'static,
// E: Element,
// F: FnOnce(&mut V, &mut WindowContext<'_, V>) -> E + 'static,
// {
// type State = Option<AnyElement>;
// fn element_id(&self) -> Option<ElementId> {
// None
// }
// fn layout(
// &mut self,
// _: Option<Self::State>,
// cx: &mut WindowContext,
// ) -> (LayoutId, Self::State) {
// let render = self.take().unwrap();
// let mut element = (render)(view_state, cx).into_any();
// let layout_id = element.layout(view_state, cx);
// (layout_id, Some(element))
// }
// fn paint(
// self,
// _bounds: Bounds<Pixels>,
// rendered_element: &mut Self::State,
// cx: &mut WindowContext,
// ) {
// rendered_element.take().unwrap().paint(view_state, cx);
// }
// }
// impl<V, E, F> RenderOnce for Option<F>
// where
// V: 'static,
// E: Element,
// F: FnOnce(&mut V, &mut WindowContext) -> E + 'static,
// {
// type Element = Self;
// fn render(self) -> Self::Element {
// self
// }
// }

View file

@ -667,13 +667,13 @@ impl Element for Div {
} }
impl IntoElement for Div { impl IntoElement for Div {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
self.interactivity.element_id.clone() self.interactivity.element_id.clone()
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }
@ -1282,13 +1282,13 @@ impl<E> IntoElement for Focusable<E>
where where
E: Element, E: Element,
{ {
type Element = E; type Output = E;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
self.element.element_id() self.element.element_id()
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self.element self.element
} }
} }
@ -1317,7 +1317,7 @@ where
impl<E> StatefulInteractiveElement for Stateful<E> impl<E> StatefulInteractiveElement for Stateful<E>
where where
E: Element, E: IntoElement,
Self: InteractiveElement, Self: InteractiveElement,
{ {
} }
@ -1356,13 +1356,13 @@ impl<E> IntoElement for Stateful<E>
where where
E: Element, E: Element,
{ {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
self.element.element_id() self.element.element_id()
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -87,13 +87,13 @@ impl Element for Img {
} }
impl IntoElement for Img { impl IntoElement for Img {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<crate::ElementId> { fn element_id(&self) -> Option<crate::ElementId> {
self.interactivity.element_id.clone() self.interactivity.element_id.clone()
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -152,13 +152,13 @@ impl Element for Overlay {
} }
impl IntoElement for Overlay { impl IntoElement for Overlay {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<crate::ElementId> { fn element_id(&self) -> Option<crate::ElementId> {
None None
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -1,5 +1,5 @@
use crate::{ use crate::{
Bounds, Element, ElementId, InteractiveElement, InteractiveElementState, Interactivity, Bounds, ElementId, InteractiveElement, InteractiveElementState, Interactivity, Element,
IntoElement, LayoutId, Pixels, SharedString, StyleRefinement, Styled, WindowContext, IntoElement, LayoutId, Pixels, SharedString, StyleRefinement, Styled, WindowContext,
}; };
use util::ResultExt; use util::ResultExt;
@ -50,13 +50,13 @@ impl Element for Svg {
} }
impl IntoElement for Svg { impl IntoElement for Svg {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
self.interactivity.element_id.clone() self.interactivity.element_id.clone()
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -27,13 +27,13 @@ impl Element for &'static str {
} }
impl IntoElement for &'static str { impl IntoElement for &'static str {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
None None
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }
@ -58,13 +58,13 @@ impl Element for SharedString {
} }
impl IntoElement for SharedString { impl IntoElement for SharedString {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
None None
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }
@ -107,13 +107,13 @@ impl Element for StyledText {
} }
impl IntoElement for StyledText { impl IntoElement for StyledText {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<crate::ElementId> { fn element_id(&self) -> Option<crate::ElementId> {
None None
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }
@ -273,13 +273,13 @@ impl Element for InteractiveText {
} }
impl IntoElement for InteractiveText { impl IntoElement for InteractiveText {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
Some(self.element_id.clone()) Some(self.element_id.clone())
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -244,13 +244,13 @@ impl Element for UniformList {
} }
impl IntoElement for UniformList { impl IntoElement for UniformList {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<crate::ElementId> { fn element_id(&self) -> Option<crate::ElementId> {
Some(self.id.clone()) Some(self.id.clone())
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
div, point, Div, Element, FocusHandle, IntoElement, Keystroke, Modifiers, Pixels, Point, div, point, Div, FocusHandle, IntoElement, Keystroke, Modifiers, Pixels, Point, Render,
Render, ViewContext, ViewContext,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{any::Any, fmt::Debug, marker::PhantomData, ops::Deref, path::PathBuf}; use std::{any::Any, fmt::Debug, marker::PhantomData, ops::Deref, path::PathBuf};
@ -75,7 +75,7 @@ impl<S, R, V, E> Drag<S, R, V, E>
where where
R: Fn(&mut V, &mut ViewContext<V>) -> E, R: Fn(&mut V, &mut ViewContext<V>) -> E,
V: 'static, V: 'static,
E: Element, E: IntoElement,
{ {
pub fn new(state: S, render_drag_handle: R) -> Self { pub fn new(state: S, render_drag_handle: R) -> Self {
Drag { Drag {
@ -194,9 +194,9 @@ impl Deref for MouseExitEvent {
pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>); pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
impl Render for ExternalPaths { impl Render for ExternalPaths {
type Element = Div; type Output = Div;
fn render(&mut self, _: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, _: &mut ViewContext<Self>) -> Self::Output {
div() // Intentionally left empty because the platform will render icons for the dragged files div() // Intentionally left empty because the platform will render icons for the dragged files
} }
} }
@ -299,9 +299,9 @@ mod test {
actions!(TestAction); actions!(TestAction);
impl Render for TestView { impl Render for TestView {
type Element = Stateful<Div>; type Output = Stateful<Div>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Output {
div().id("testview").child( div().id("testview").child(
div() div()
.key_context("parent") .key_context("parent")

View file

@ -85,7 +85,7 @@ impl<V: Render> Element for View<V> {
_state: Option<Self::State>, _state: Option<Self::State>,
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()); let mut element = self.update(cx, |view, cx| view.render(cx).into_any_element());
let layout_id = element.layout(cx); let layout_id = element.layout(cx);
(layout_id, Some(element)) (layout_id, Some(element))
} }
@ -245,25 +245,25 @@ impl Element for AnyView {
} }
impl<V: 'static + Render> IntoElement for View<V> { impl<V: 'static + Render> IntoElement for View<V> {
type Element = View<V>; type Output = View<V>;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
Some(self.model.entity_id.into()) Some(self.model.entity_id.into())
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }
impl IntoElement for AnyView { impl IntoElement for AnyView {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
Some(self.model.entity_id.into()) Some(self.model.entity_id.into())
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }
@ -298,17 +298,17 @@ impl<V: 'static + Render> From<WeakView<V>> for AnyWeakView {
impl<T, E> Render for T impl<T, E> Render for T
where where
T: 'static + FnMut(&mut WindowContext) -> E, T: 'static + FnMut(&mut WindowContext) -> E,
E: 'static + Send + Element, E: 'static + Send + IntoElement,
{ {
type Element = E; type Output = E;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
(self)(cx) (self)(cx)
} }
} }
mod any_view { mod any_view {
use crate::{AnyElement, AnyView, BorrowWindow, Element, LayoutId, Render, WindowContext}; use crate::{AnyElement, AnyView, BorrowWindow, IntoElement, LayoutId, Render, WindowContext};
pub(crate) fn layout<V: 'static + Render>( pub(crate) fn layout<V: 'static + Render>(
view: &AnyView, view: &AnyView,
@ -316,7 +316,7 @@ mod any_view {
) -> (LayoutId, AnyElement) { ) -> (LayoutId, AnyElement) {
cx.with_element_id(Some(view.model.entity_id), |cx| { cx.with_element_id(Some(view.model.entity_id), |cx| {
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()); let mut element = view.update(cx, |view, cx| view.render(cx).into_any_element());
let layout_id = element.layout(cx); let layout_id = element.layout(cx);
(layout_id, element) (layout_id, element)
}) })

View file

@ -11,13 +11,13 @@ pub fn derive_into_element(input: TokenStream) -> TokenStream {
impl #impl_generics gpui::IntoElement for #type_name #type_generics impl #impl_generics gpui::IntoElement for #type_name #type_generics
#where_clause #where_clause
{ {
type Element = gpui::Component<Self>; type Output = gpui::Component<Self>;
fn element_id(&self) -> Option<ElementId> { fn element_id(&self) -> Option<ElementId> {
None None
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
gpui::Component::new(self) gpui::Component::new(self)
} }
} }

View file

@ -181,9 +181,9 @@ impl<D: PickerDelegate> Picker<D> {
} }
impl<D: PickerDelegate> Render for Picker<D> { impl<D: PickerDelegate> Render for Picker<D> {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
div() div()
.key_context("picker") .key_context("picker")
.size_full() .size_full()

View file

@ -1427,9 +1427,9 @@ impl ProjectPanel {
} }
impl Render for ProjectPanel { impl Render for ProjectPanel {
type Element = Focusable<Stateful<Div>>; type Output = Focusable<Stateful<Div>>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Output {
let has_worktree = self.visible_entries.len() != 0; let has_worktree = self.visible_entries.len() != 0;
if has_worktree { if has_worktree {

View file

@ -64,8 +64,8 @@ pub struct BufferSearchBar {
impl EventEmitter<Event> for BufferSearchBar {} impl EventEmitter<Event> for BufferSearchBar {}
impl EventEmitter<workspace::ToolbarItemEvent> for BufferSearchBar {} impl EventEmitter<workspace::ToolbarItemEvent> for BufferSearchBar {}
impl Render for BufferSearchBar { impl Render for BufferSearchBar {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
// let query_container_style = if self.query_contains_error { // let query_container_style = if self.query_contains_error {
// theme.search.invalid_editor // theme.search.invalid_editor
// } else { // } else {

View file

@ -13,18 +13,18 @@ impl Story {
)) ))
} }
pub fn title(title: impl Into<SharedString>) -> impl Element { pub fn title(title: impl Into<SharedString>) -> impl IntoElement {
div() div()
.text_xl() .text_xl()
.text_color(hsla(0. / 360., 0. / 100., 0. / 100., 1.)) .text_color(hsla(0. / 360., 0. / 100., 0. / 100., 1.))
.child(title.into()) .child(title.into())
} }
pub fn title_for<T>() -> impl Element { pub fn title_for<T>() -> impl IntoElement {
Self::title(std::any::type_name::<T>()) Self::title(std::any::type_name::<T>())
} }
pub fn label(label: impl Into<SharedString>) -> impl Element { pub fn label(label: impl Into<SharedString>) -> impl IntoElement {
div() div()
.mt_4() .mt_4()
.mb_2() .mb_2()

View file

@ -27,9 +27,9 @@ impl FocusStory {
} }
impl Render for FocusStory { impl Render for FocusStory {
type Element = Focusable<Stateful<Div>>; type Output = Focusable<Stateful<Div>>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Output {
let theme = cx.theme(); let theme = cx.theme();
let color_1 = theme.status().created; let color_1 = theme.status().created;
let color_2 = theme.status().modified; let color_2 = theme.status().modified;

View file

@ -14,9 +14,9 @@ impl KitchenSinkStory {
} }
impl Render for KitchenSinkStory { impl Render for KitchenSinkStory {
type Element = Stateful<Div>; type Output = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let component_stories = ComponentStory::iter() let component_stories = ComponentStory::iter()
.map(|selector| selector.story(cx)) .map(|selector| selector.story(cx))
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -206,9 +206,9 @@ impl PickerStory {
} }
impl Render for PickerStory { impl Render for PickerStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Output {
div() div()
.bg(cx.theme().styles.colors.background) .bg(cx.theme().styles.colors.background)
.size_full() .size_full()

View file

@ -11,9 +11,9 @@ impl ScrollStory {
} }
impl Render for ScrollStory { impl Render for ScrollStory {
type Element = Stateful<Div>; type Output = Stateful<Div>;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Output {
let theme = cx.theme(); let theme = cx.theme();
let color_1 = theme.status().created; let color_1 = theme.status().created;
let color_2 = theme.status().modified; let color_2 = theme.status().modified;

View file

@ -12,9 +12,9 @@ impl TextStory {
} }
impl Render for TextStory { impl Render for TextStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> Self::Output {
v_stack() v_stack()
.bg(blue()) .bg(blue())
.child( .child(

View file

@ -7,9 +7,9 @@ use ui::prelude::*;
pub struct ZIndexStory; pub struct ZIndexStory;
impl Render for ZIndexStory { impl Render for ZIndexStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
Story::container().child(Story::title("z-index")).child( Story::container().child(Story::title("z-index")).child(
div() div()
.flex() .flex()
@ -82,9 +82,9 @@ struct ZIndexExample {
} }
impl RenderOnce for ZIndexExample { impl RenderOnce for ZIndexExample {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.relative() .relative()
.size_full() .size_full()

View file

@ -102,9 +102,9 @@ impl StoryWrapper {
} }
impl Render for StoryWrapper { impl Render for StoryWrapper {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
div() div()
.flex() .flex()
.flex_col() .flex_col()

View file

@ -336,9 +336,9 @@ impl TerminalPanel {
impl EventEmitter<PanelEvent> for TerminalPanel {} impl EventEmitter<PanelEvent> for TerminalPanel {}
impl Render for TerminalPanel { impl Render for TerminalPanel {
type Element = Div; type Output = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Output {
div().child(self.pane.clone()) div().child(self.pane.clone())
} }
} }

View file

@ -9,8 +9,8 @@ pub mod terminal_panel;
// use crate::terminal_element::TerminalElement; // use crate::terminal_element::TerminalElement;
use editor::{scroll::autoscroll::Autoscroll, Editor}; use editor::{scroll::autoscroll::Autoscroll, Editor};
use gpui::{ use gpui::{
actions, div, Action, AnyElement, AppContext, Div, Element, EventEmitter, FocusEvent, actions, div, Action, AnyElement, AppContext, Div, EventEmitter, FocusEvent, FocusHandle,
FocusHandle, Focusable, FocusableElement, FocusableView, InputHandler, InteractiveElement, Focusable, FocusableElement, FocusableView, InputHandler, InteractiveElement, IntoElement,
KeyDownEvent, Keystroke, Model, MouseButton, MouseDownEvent, ParentElement, Pixels, Render, KeyDownEvent, Keystroke, Model, MouseButton, MouseDownEvent, ParentElement, Pixels, Render,
SharedString, Styled, Task, View, ViewContext, VisualContext, WeakView, WindowContext, SharedString, Styled, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
}; };
@ -532,9 +532,9 @@ impl TerminalView {
} }
impl Render for TerminalView { impl Render for TerminalView {
type Element = Focusable<Div>; type Output = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let terminal_handle = self.terminal.clone().downgrade(); let terminal_handle = self.terminal.clone().downgrade();
let self_id = cx.entity_id(); let self_id = cx.entity_id();
@ -749,7 +749,7 @@ impl Item for TerminalView {
div() div()
.child(IconElement::new(Icon::Terminal)) .child(IconElement::new(Icon::Terminal))
.child(Label::new(title)) .child(Label::new(title))
.into_any() .into_any_element()
} }
fn clone_on_split( fn clone_on_split(

View file

@ -15,9 +15,9 @@ pub struct Avatar {
} }
impl RenderOnce for Avatar { impl RenderOnce for Avatar {
type Rendered = Img; type Output = Img;
fn render(self, _: &mut WindowContext) -> Self::Rendered { fn render_once(self, _: &mut WindowContext) -> Self::Output {
let mut img = img(); let mut img = img();
if self.shape == Shape::Circle { if self.shape == Shape::Circle {

View file

@ -77,9 +77,9 @@ pub struct Button {
} }
impl RenderOnce for Button { impl RenderOnce for Button {
type Rendered = gpui::Stateful<Div>; type Output = gpui::Stateful<Div>;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let (icon_color, label_color) = match (self.disabled, self.color) { let (icon_color, label_color) = match (self.disabled, self.color) {
(true, _) => (Color::Disabled, Color::Disabled), (true, _) => (Color::Disabled, Color::Disabled),
(_, None) => (Color::Default, Color::Default), (_, None) => (Color::Default, Color::Default),
@ -213,13 +213,13 @@ pub struct ButtonGroup {
} }
impl RenderOnce for ButtonGroup { impl RenderOnce for ButtonGroup {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let mut group = h_stack(); let mut group = h_stack();
for button in self.buttons.into_iter() { for button in self.buttons.into_iter() {
group = group.child(button.render(cx)); group = group.child(button.render_once(cx));
} }
group group

View file

@ -1,4 +1,4 @@
use gpui::{div, prelude::*, Div, Element, ElementId, IntoElement, Styled, WindowContext}; use gpui::{div, prelude::*, Div, ElementId, IntoElement, Styled, WindowContext};
use theme2::ActiveTheme; use theme2::ActiveTheme;
@ -20,9 +20,9 @@ pub struct Checkbox {
} }
impl RenderOnce for Checkbox { impl RenderOnce for Checkbox {
type Rendered = gpui::Stateful<Div>; type Output = gpui::Stateful<Div>;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(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 {
@ -164,7 +164,7 @@ impl Checkbox {
self self
} }
pub fn render(self, cx: &mut WindowContext) -> impl Element { pub fn render(self, cx: &mut WindowContext) -> impl IntoElement {
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

@ -5,8 +5,8 @@ use crate::{prelude::*, v_stack, List};
use crate::{ListItem, ListSeparator, ListSubHeader}; use crate::{ListItem, ListSeparator, ListSubHeader};
use gpui::{ use gpui::{
overlay, px, Action, AnchorCorner, AnyElement, AppContext, Bounds, ClickEvent, DispatchPhase, overlay, px, Action, AnchorCorner, AnyElement, AppContext, Bounds, ClickEvent, DispatchPhase,
Div, EventEmitter, FocusHandle, FocusableView, IntoElement, LayoutId, ManagedView, Manager, Div, Element, EventEmitter, FocusHandle, FocusableView, IntoElement, LayoutId, ManagedView,
MouseButton, MouseDownEvent, Pixels, Point, Render, View, VisualContext, Manager, MouseButton, MouseDownEvent, Pixels, Point, Render, View, VisualContext,
}; };
pub enum ContextMenuItem { pub enum ContextMenuItem {
@ -82,9 +82,9 @@ impl ContextMenu {
} }
impl Render for ContextMenu { impl Render for ContextMenu {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
div().elevation_2(cx).flex().flex_row().child( div().elevation_2(cx).flex().flex_row().child(
v_stack() v_stack()
.min_w(px(200.)) .min_w(px(200.))
@ -287,13 +287,13 @@ impl<M: ManagedView> Element for MenuHandle<M> {
} }
impl<M: ManagedView> IntoElement for MenuHandle<M> { impl<M: ManagedView> IntoElement for MenuHandle<M> {
type Element = Self; type Output = Self;
fn element_id(&self) -> Option<gpui::ElementId> { fn element_id(&self) -> Option<gpui::ElementId> {
Some(self.id.clone()) Some(self.id.clone())
} }
fn into_element(self) -> Self::Element { fn into_element(self) -> Self::Output {
self self
} }
} }

View file

@ -1,8 +1,8 @@
use gpui::{div, Element, ParentElement}; use gpui::{div, IntoElement, ParentElement};
use crate::{Color, Icon, IconElement, IconSize, Toggle}; use crate::{Color, Icon, IconElement, IconSize, Toggle};
pub fn disclosure_control(toggle: Toggle) -> impl Element { pub fn disclosure_control(toggle: Toggle) -> impl IntoElement {
match (toggle.is_toggleable(), toggle.is_toggled()) { match (toggle.is_toggleable(), toggle.is_toggled()) {
(false, _) => div(), (false, _) => div(),
(_, true) => div().child( (_, true) => div().child(

View file

@ -14,9 +14,9 @@ pub struct Divider {
} }
impl RenderOnce for Divider { impl RenderOnce for Divider {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.map(|this| match self.direction { .map(|this| match self.direction {
DividerDirection::Horizontal => { DividerDirection::Horizontal => {
@ -50,7 +50,7 @@ impl Divider {
self self
} }
fn render(self, cx: &mut WindowContext) -> impl Element { fn render(self, cx: &mut WindowContext) -> impl IntoElement {
div() div()
.map(|this| match self.direction { .map(|this| match self.direction {
DividerDirection::Horizontal => { DividerDirection::Horizontal => {

View file

@ -141,9 +141,9 @@ pub struct IconElement {
} }
impl RenderOnce for IconElement { impl RenderOnce for IconElement {
type Rendered = Svg; type Output = Svg;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let svg_size = match self.size { let svg_size = match self.size {
IconSize::Small => rems(0.75), IconSize::Small => rems(0.75),
IconSize::Medium => rems(0.9375), IconSize::Medium => rems(0.9375),
@ -184,7 +184,7 @@ impl IconElement {
self self
} }
fn render(self, cx: &mut WindowContext) -> impl Element { fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let svg_size = match self.size { let svg_size = match self.size {
IconSize::Small => rems(0.75), IconSize::Small => rems(0.75),
IconSize::Medium => rems(0.9375), IconSize::Medium => rems(0.9375),

View file

@ -14,9 +14,9 @@ pub struct IconButton {
} }
impl RenderOnce for IconButton { impl RenderOnce for IconButton {
type Rendered = Stateful<Div>; type Output = Stateful<Div>;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let icon_color = match (self.state, self.color) { let icon_color = match (self.state, self.color) {
(InteractionState::Disabled, _) => Color::Disabled, (InteractionState::Disabled, _) => Color::Disabled,
(InteractionState::Active, _) => Color::Selected, (InteractionState::Active, _) => Color::Selected,

View file

@ -19,9 +19,9 @@ pub struct Input {
} }
impl RenderOnce for Input { impl RenderOnce for Input {
type Rendered = Stateful<Div>; type Output = Stateful<Div>;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let (input_bg, input_hover_bg, input_active_bg) = match self.variant { let (input_bg, input_hover_bg, input_active_bg) = match self.variant {
InputVariant::Ghost => ( InputVariant::Ghost => (
cx.theme().colors().ghost_element_background, cx.theme().colors().ghost_element_background,

View file

@ -11,9 +11,9 @@ pub struct KeyBinding {
} }
impl RenderOnce for KeyBinding { impl RenderOnce for KeyBinding {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.flex() .flex()
.gap_2() .gap_2()
@ -50,9 +50,9 @@ pub struct Key {
} }
impl RenderOnce for Key { impl RenderOnce for Key {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.px_2() .px_2()
.py_0() .py_0()

View file

@ -27,9 +27,9 @@ pub struct Label {
} }
impl RenderOnce for Label { impl RenderOnce for Label {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
div() div()
.when(self.strikethrough, |this| { .when(self.strikethrough, |this| {
this.relative().child( this.relative().child(
@ -95,9 +95,9 @@ pub struct HighlightedLabel {
} }
impl RenderOnce for HighlightedLabel { impl RenderOnce for HighlightedLabel {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let highlight_color = cx.theme().colors().text_accent; let highlight_color = cx.theme().colors().text_accent;
let mut text_style = cx.text_style().clone(); let mut text_style = cx.text_style().clone();

View file

@ -35,9 +35,9 @@ pub struct ListHeader {
} }
impl RenderOnce for ListHeader { impl RenderOnce for ListHeader {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let disclosure_control = disclosure_control(self.toggle); let disclosure_control = disclosure_control(self.toggle);
let meta = match self.meta { let meta = match self.meta {
@ -202,9 +202,9 @@ impl ListSubHeader {
} }
impl RenderOnce for ListSubHeader { impl RenderOnce for ListSubHeader {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(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()
@ -329,9 +329,9 @@ impl ListItem {
} }
impl RenderOnce for ListItem { impl RenderOnce for ListItem {
type Rendered = Stateful<Div>; type Output = Stateful<Div>;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let left_content = match self.left_slot.clone() { let left_content = match self.left_slot.clone() {
Some(GraphicSlot::Icon(i)) => Some( Some(GraphicSlot::Icon(i)) => Some(
h_stack().child( h_stack().child(
@ -409,9 +409,9 @@ impl ListSeparator {
} }
impl RenderOnce for ListSeparator { impl RenderOnce for ListSeparator {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
div().h_px().w_full().bg(cx.theme().colors().border_variant) div().h_px().w_full().bg(cx.theme().colors().border_variant)
} }
} }
@ -427,9 +427,9 @@ pub struct List {
} }
impl RenderOnce for List { impl RenderOnce for List {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
let list_content = match (self.children.is_empty(), self.toggle) { let list_content = match (self.children.is_empty(), self.toggle) {
(false, _) => div().children(self.children), (false, _) => div().children(self.children),
(true, Toggle::Toggled(false)) => div(), (true, Toggle::Toggled(false)) => div(),

View file

@ -40,9 +40,9 @@ pub struct Popover {
} }
impl RenderOnce for Popover { impl RenderOnce for Popover {
type Rendered = Div; type Output = Div;
fn render(self, cx: &mut WindowContext) -> Self::Rendered { fn render_once(self, cx: &mut WindowContext) -> Self::Output {
v_stack() v_stack()
.relative() .relative()
.elevation_2(cx) .elevation_2(cx)

View file

@ -7,9 +7,9 @@ use crate::Avatar;
pub struct AvatarStory; pub struct AvatarStory;
impl Render for AvatarStory { impl Render for AvatarStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
Story::container() Story::container()
.child(Story::title_for::<Avatar>()) .child(Story::title_for::<Avatar>())
.child(Story::label("Default")) .child(Story::label("Default"))

View file

@ -8,9 +8,9 @@ use crate::{h_stack, v_stack, Button, Icon, IconPosition, Label};
pub struct ButtonStory; pub struct ButtonStory;
impl Render for ButtonStory { impl Render for ButtonStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let states = InteractionState::iter(); let states = InteractionState::iter();
Story::container() Story::container()

View file

@ -7,9 +7,9 @@ use crate::{h_stack, Checkbox};
pub struct CheckboxStory; pub struct CheckboxStory;
impl Render for CheckboxStory { impl Render for CheckboxStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
Story::container() Story::container()
.child(Story::title_for::<Checkbox>()) .child(Story::title_for::<Checkbox>())
.child(Story::label("Default")) .child(Story::label("Default"))

View file

@ -27,9 +27,9 @@ fn build_menu(cx: &mut WindowContext, header: impl Into<SharedString>) -> View<C
pub struct ContextMenuStory; pub struct ContextMenuStory;
impl Render for ContextMenuStory { impl Render for ContextMenuStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
Story::container() Story::container()
.on_action(|_: &PrintCurrentDate, _| { .on_action(|_: &PrintCurrentDate, _| {
println!("printing unix time!"); println!("printing unix time!");

View file

@ -8,9 +8,9 @@ use crate::{Icon, IconElement};
pub struct IconStory; pub struct IconStory;
impl Render for IconStory { impl Render for IconStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let icons = Icon::iter(); let icons = Icon::iter();
Story::container() Story::container()

View file

@ -7,9 +7,9 @@ use crate::Input;
pub struct InputStory; pub struct InputStory;
impl Render for InputStory { impl Render for InputStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
Story::container() Story::container()
.child(Story::title_for::<Input>()) .child(Story::title_for::<Input>())
.child(Story::label("Default")) .child(Story::label("Default"))

View file

@ -14,9 +14,9 @@ pub fn binding(key: &str) -> gpui::KeyBinding {
} }
impl Render for KeybindingStory { impl Render for KeybindingStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let all_modifier_permutations = ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2); let all_modifier_permutations = ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
Story::container() Story::container()

View file

@ -7,9 +7,9 @@ use crate::{HighlightedLabel, Label};
pub struct LabelStory; pub struct LabelStory;
impl Render for LabelStory { impl Render for LabelStory {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
Story::container() Story::container()
.child(Story::title_for::<Label>()) .child(Story::title_for::<Label>())
.child(Story::label("Default")) .child(Story::label("Default"))

View file

@ -68,9 +68,9 @@ impl Tooltip {
} }
impl Render for Tooltip { impl Render for Tooltip {
type Element = Overlay; type Output = Overlay;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone(); let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
overlay().child( overlay().child(
// padding to avoid mouse cursor // padding to avoid mouse cursor

View file

@ -1,6 +1,6 @@
pub use gpui::{ pub use gpui::{
div, Element, ElementId, InteractiveElement, ParentElement, RenderOnce, SharedString, Styled, div, ElementId, InteractiveElement, IntoElement, ParentElement, RenderOnce, SharedString,
ViewContext, WindowContext, Styled, ViewContext, WindowContext,
}; };
pub use crate::StyledExt; pub use crate::StyledExt;

View file

@ -477,9 +477,9 @@ impl Dock {
} }
impl Render for Dock { impl Render for Dock {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
if let Some(entry) = self.visible_entry() { if let Some(entry) = self.visible_entry() {
let size = entry.panel.size(cx); let size = entry.panel.size(cx);
@ -663,9 +663,9 @@ impl PanelButtons {
// here be kittens // here be kittens
impl Render for PanelButtons { impl Render for PanelButtons {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
// todo!() // todo!()
let dock = self.dock.read(cx); let dock = self.dock.read(cx);
let active_index = dock.active_panel_index; let active_index = dock.active_panel_index;
@ -782,9 +782,9 @@ pub mod test {
} }
impl Render for TestPanel { impl Render for TestPanel {
type Element = Div; type Output = Div;
fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Output {
div() div()
} }
} }

View file

@ -72,9 +72,9 @@ impl ModalLayer {
} }
impl Render for ModalLayer { impl Render for ModalLayer {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let Some(active_modal) = &self.active_modal else { let Some(active_modal) = &self.active_modal else {
return div(); return div();
}; };

View file

@ -254,9 +254,9 @@ pub mod simple_message_notification {
} }
impl Render for MessageNotification { impl Render for MessageNotification {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
todo!() todo!()
} }
} }

View file

@ -1894,9 +1894,9 @@ impl FocusableView for Pane {
} }
impl Render for Pane { impl Render for Pane {
type Element = Focusable<Div>; type Output = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
v_stack() v_stack()
.key_context("Pane") .key_context("Pane")
.track_focus(&self.focus_handle) .track_focus(&self.focus_handle)
@ -2958,9 +2958,9 @@ struct DraggedTab {
} }
impl Render for DraggedTab { impl Render for DraggedTab {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
div().w_8().h_4().bg(gpui::red()) div().w_8().h_4().bg(gpui::red())
} }
} }

View file

@ -35,9 +35,9 @@ pub struct StatusBar {
} }
impl Render for StatusBar { impl Render for StatusBar {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
div() div()
.py_0p5() .py_0p5()
.px_1() .px_1()

View file

@ -77,9 +77,9 @@ impl Toolbar {
} }
impl Render for Toolbar { impl Render for Toolbar {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
//dbg!(&self.items.len()); //dbg!(&self.items.len());
v_stack() v_stack()
.border_b() .border_b()

View file

@ -3607,9 +3607,9 @@ impl FocusableView for Workspace {
} }
impl Render for Workspace { impl Render for Workspace {
type Element = Div; type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element { fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
let mut context = KeyContext::default(); let mut context = KeyContext::default();
context.add("Workspace"); context.add("Workspace");