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 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!")
// let theme = theme::current(cx).clone();
// let theme = &theme.update_notification;

View file

@ -3295,9 +3295,9 @@ impl 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()
.key_context("CollabPanel")
.track_focus(&self.focus_handle)

View file

@ -82,9 +82,9 @@ pub struct 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()
.id("titlebar")
.justify_between()

View file

@ -77,9 +77,9 @@ impl FocusableView 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())
}
}

View file

@ -91,9 +91,9 @@ struct DiagnosticGroupState {
impl EventEmitter<ItemEvent> 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() {
div()
.bg(cx.theme().colors().editor_background)

View file

@ -22,9 +22,9 @@ pub struct 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) {
(0, 0) => h_stack().child(IconElement::new(Icon::Check).color(Color::Success)),
(0, warning_count) => h_stack()

View file

@ -8,9 +8,9 @@ pub struct 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
.editor
.as_ref()

View file

@ -9386,9 +9386,9 @@ impl FocusableView 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 text_style = match self.mode {
EditorMode::SingleLine => TextStyle {

View file

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

View file

@ -118,9 +118,9 @@ impl FocusableView 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())
}
}

View file

@ -145,9 +145,9 @@ impl 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()
.elevation_2(cx)
.key_context("GoToLine")

View file

@ -630,9 +630,9 @@ impl AnyWindowHandle {
pub struct 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()
}
}

View file

@ -6,29 +6,82 @@ use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec;
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 {
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 {
type Element: Element + 'static;
type Output: Element + 'static;
fn element_id(&self) -> Option<ElementId>;
fn into_element(self) -> Self::Element;
fn into_element(self) -> Self::Output;
fn into_any_element(self) -> AnyElement {
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>(
self,
origin: Point<Pixels>,
available_space: Size<T>,
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
where
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
where
Self: Sized,
@ -99,40 +153,30 @@ pub trait Element: 'static + IntoElement {
}
}
pub trait RenderOnce: 'static {
type Rendered: IntoElement;
pub struct Component<R>(Option<R>);
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> {
component: Option<C>,
}
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<R> Component<R> {
pub fn new(renderable: R) -> Self {
Component(Some(renderable))
}
}
impl<C: RenderOnce> Element for Component<C> {
type State = CompositeElementState<C>;
impl<R: RenderOnce> Element for Component<R> {
type State = ComponentState<R>;
fn layout(
&mut self,
state: Option<Self::State>,
cx: &mut WindowContext,
) -> (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 state = CompositeElementState {
let state = ComponentState {
rendered_element: Some(element),
rendered_element_state: state,
};
@ -149,13 +193,90 @@ impl<C: RenderOnce> Element for Component<C> {
}
impl<C: RenderOnce> IntoElement for Component<C> {
type Element = Self;
type Output = Self;
fn element_id(&self) -> Option<ElementId> {
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
}
}
@ -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>>
where
E: Element,
@ -484,59 +572,13 @@ impl Element for AnyElement {
}
impl IntoElement for AnyElement {
type Element = Self;
type Output = Self;
fn element_id(&self) -> Option<ElementId> {
AnyElement::element_id(self)
}
fn into_element(self) -> Self::Element {
fn into_element(self) -> Self::Output {
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 {
type Element = Self;
type Output = Self;
fn element_id(&self) -> Option<ElementId> {
self.interactivity.element_id.clone()
}
fn into_element(self) -> Self::Element {
fn into_element(self) -> Self::Output {
self
}
}
@ -1282,13 +1282,13 @@ impl<E> IntoElement for Focusable<E>
where
E: Element,
{
type Element = E;
type Output = E;
fn element_id(&self) -> Option<ElementId> {
self.element.element_id()
}
fn into_element(self) -> Self::Element {
fn into_element(self) -> Self::Output {
self.element
}
}
@ -1317,7 +1317,7 @@ where
impl<E> StatefulInteractiveElement for Stateful<E>
where
E: Element,
E: IntoElement,
Self: InteractiveElement,
{
}
@ -1356,13 +1356,13 @@ impl<E> IntoElement for Stateful<E>
where
E: Element,
{
type Element = Self;
type Output = Self;
fn element_id(&self) -> Option<ElementId> {
self.element.element_id()
}
fn into_element(self) -> Self::Element {
fn into_element(self) -> Self::Output {
self
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
use crate::{
div, point, Div, Element, FocusHandle, IntoElement, Keystroke, Modifiers, Pixels, Point,
Render, ViewContext,
div, point, Div, FocusHandle, IntoElement, Keystroke, Modifiers, Pixels, Point, Render,
ViewContext,
};
use smallvec::SmallVec;
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
R: Fn(&mut V, &mut ViewContext<V>) -> E,
V: 'static,
E: Element,
E: IntoElement,
{
pub fn new(state: S, render_drag_handle: R) -> Self {
Drag {
@ -194,9 +194,9 @@ impl Deref for MouseExitEvent {
pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
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
}
}
@ -299,9 +299,9 @@ mod test {
actions!(TestAction);
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()
.key_context("parent")

View file

@ -85,7 +85,7 @@ impl<V: Render> Element for View<V> {
_state: Option<Self::State>,
cx: &mut WindowContext,
) -> (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);
(layout_id, Some(element))
}
@ -245,25 +245,25 @@ impl Element for AnyView {
}
impl<V: 'static + Render> IntoElement for View<V> {
type Element = View<V>;
type Output = View<V>;
fn element_id(&self) -> Option<ElementId> {
Some(self.model.entity_id.into())
}
fn into_element(self) -> Self::Element {
fn into_element(self) -> Self::Output {
self
}
}
impl IntoElement for AnyView {
type Element = Self;
type Output = Self;
fn element_id(&self) -> Option<ElementId> {
Some(self.model.entity_id.into())
}
fn into_element(self) -> Self::Element {
fn into_element(self) -> Self::Output {
self
}
}
@ -298,17 +298,17 @@ impl<V: 'static + Render> From<WeakView<V>> for AnyWeakView {
impl<T, E> Render for T
where
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)
}
}
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>(
view: &AnyView,
@ -316,7 +316,7 @@ mod any_view {
) -> (LayoutId, AnyElement) {
cx.with_element_id(Some(view.model.entity_id), |cx| {
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);
(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
#where_clause
{
type Element = gpui::Component<Self>;
type Output = gpui::Component<Self>;
fn element_id(&self) -> Option<ElementId> {
None
}
fn into_element(self) -> Self::Element {
fn into_element(self) -> Self::Output {
gpui::Component::new(self)
}
}

View file

@ -181,9 +181,9 @@ impl<D: PickerDelegate> 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()
.key_context("picker")
.size_full()

View file

@ -1427,9 +1427,9 @@ impl 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;
if has_worktree {

View file

@ -64,8 +64,8 @@ pub struct BufferSearchBar {
impl EventEmitter<Event> for BufferSearchBar {}
impl EventEmitter<workspace::ToolbarItemEvent> for BufferSearchBar {}
impl Render for BufferSearchBar {
type Element = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
type Output = Div;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Output {
// let query_container_style = if self.query_contains_error {
// theme.search.invalid_editor
// } 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()
.text_xl()
.text_color(hsla(0. / 360., 0. / 100., 0. / 100., 1.))
.child(title.into())
}
pub fn title_for<T>() -> impl Element {
pub fn title_for<T>() -> impl IntoElement {
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()
.mt_4()
.mb_2()

View file

@ -27,9 +27,9 @@ impl 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 color_1 = theme.status().created;
let color_2 = theme.status().modified;

View file

@ -14,9 +14,9 @@ impl 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()
.map(|selector| selector.story(cx))
.collect::<Vec<_>>();

View file

@ -206,9 +206,9 @@ impl 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()
.bg(cx.theme().styles.colors.background)
.size_full()

View file

@ -11,9 +11,9 @@ impl 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 color_1 = theme.status().created;
let color_2 = theme.status().modified;

View file

@ -12,9 +12,9 @@ impl 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()
.bg(blue())
.child(

View file

@ -7,9 +7,9 @@ use ui::prelude::*;
pub struct 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(
div()
.flex()
@ -82,9 +82,9 @@ struct 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()
.relative()
.size_full()

View file

@ -102,9 +102,9 @@ impl 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()
.flex()
.flex_col()

View file

@ -336,9 +336,9 @@ impl TerminalPanel {
impl EventEmitter<PanelEvent> 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())
}
}

View file

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

View file

@ -15,9 +15,9 @@ pub struct 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();
if self.shape == Shape::Circle {

View file

@ -77,9 +77,9 @@ pub struct 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) {
(true, _) => (Color::Disabled, Color::Disabled),
(_, None) => (Color::Default, Color::Default),
@ -213,13 +213,13 @@ pub struct 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();
for button in self.buttons.into_iter() {
group = group.child(button.render(cx));
group = group.child(button.render_once(cx));
}
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;
@ -20,9 +20,9 @@ pub struct 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 icon = match self.checked {
@ -164,7 +164,7 @@ impl Checkbox {
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 icon = match self.checked {

View file

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

View file

@ -1,8 +1,8 @@
use gpui::{div, Element, ParentElement};
use gpui::{div, IntoElement, ParentElement};
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()) {
(false, _) => div(),
(_, true) => div().child(

View file

@ -14,9 +14,9 @@ pub struct 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()
.map(|this| match self.direction {
DividerDirection::Horizontal => {
@ -50,7 +50,7 @@ impl Divider {
self
}
fn render(self, cx: &mut WindowContext) -> impl Element {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
div()
.map(|this| match self.direction {
DividerDirection::Horizontal => {

View file

@ -141,9 +141,9 @@ pub struct 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 {
IconSize::Small => rems(0.75),
IconSize::Medium => rems(0.9375),
@ -184,7 +184,7 @@ impl IconElement {
self
}
fn render(self, cx: &mut WindowContext) -> impl Element {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
let svg_size = match self.size {
IconSize::Small => rems(0.75),
IconSize::Medium => rems(0.9375),

View file

@ -14,9 +14,9 @@ pub struct 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) {
(InteractionState::Disabled, _) => Color::Disabled,
(InteractionState::Active, _) => Color::Selected,

View file

@ -19,9 +19,9 @@ pub struct 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 {
InputVariant::Ghost => (
cx.theme().colors().ghost_element_background,

View file

@ -11,9 +11,9 @@ pub struct 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()
.flex()
.gap_2()
@ -50,9 +50,9 @@ pub struct 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()
.px_2()
.py_0()

View file

@ -27,9 +27,9 @@ pub struct 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()
.when(self.strikethrough, |this| {
this.relative().child(
@ -95,9 +95,9 @@ pub struct 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 mut text_style = cx.text_style().clone();

View file

@ -35,9 +35,9 @@ pub struct 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 meta = match self.meta {
@ -202,9 +202,9 @@ impl 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(
div()
.h_6()
@ -329,9 +329,9 @@ impl 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() {
Some(GraphicSlot::Icon(i)) => Some(
h_stack().child(
@ -409,9 +409,9 @@ impl 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)
}
}
@ -427,9 +427,9 @@ pub struct 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) {
(false, _) => div().children(self.children),
(true, Toggle::Toggled(false)) => div(),

View file

@ -40,9 +40,9 @@ pub struct 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()
.relative()
.elevation_2(cx)

View file

@ -7,9 +7,9 @@ use crate::Avatar;
pub struct 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()
.child(Story::title_for::<Avatar>())
.child(Story::label("Default"))

View file

@ -8,9 +8,9 @@ use crate::{h_stack, v_stack, Button, Icon, IconPosition, Label};
pub struct 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();
Story::container()

View file

@ -7,9 +7,9 @@ use crate::{h_stack, Checkbox};
pub struct 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()
.child(Story::title_for::<Checkbox>())
.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;
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()
.on_action(|_: &PrintCurrentDate, _| {
println!("printing unix time!");

View file

@ -8,9 +8,9 @@ use crate::{Icon, IconElement};
pub struct 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();
Story::container()

View file

@ -7,9 +7,9 @@ use crate::Input;
pub struct 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()
.child(Story::title_for::<Input>())
.child(Story::label("Default"))

View file

@ -14,9 +14,9 @@ pub fn binding(key: &str) -> gpui::KeyBinding {
}
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);
Story::container()

View file

@ -7,9 +7,9 @@ use crate::{HighlightedLabel, Label};
pub struct 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()
.child(Story::title_for::<Label>())
.child(Story::label("Default"))

View file

@ -68,9 +68,9 @@ impl 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();
overlay().child(
// padding to avoid mouse cursor

View file

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

View file

@ -477,9 +477,9 @@ impl 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() {
let size = entry.panel.size(cx);
@ -663,9 +663,9 @@ impl PanelButtons {
// here be kittens
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!()
let dock = self.dock.read(cx);
let active_index = dock.active_panel_index;
@ -782,9 +782,9 @@ pub mod test {
}
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()
}
}

View file

@ -72,9 +72,9 @@ impl 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 {
return div();
};

View file

@ -254,9 +254,9 @@ pub mod simple_message_notification {
}
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!()
}
}

View file

@ -1894,9 +1894,9 @@ impl FocusableView 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()
.key_context("Pane")
.track_focus(&self.focus_handle)
@ -2958,9 +2958,9 @@ struct 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())
}
}

View file

@ -35,9 +35,9 @@ pub struct 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()
.py_0p5()
.px_1()

View file

@ -77,9 +77,9 @@ impl 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());
v_stack()
.border_b()

View file

@ -3607,9 +3607,9 @@ impl FocusableView 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();
context.add("Workspace");