WIP: Work toward eliminating Component trait
This refactor enhances the overall design by promoting reusable and composable UI component structures within the Zed project codebase.
This commit is contained in:
@@ -65,25 +65,26 @@ pub struct GlobalElementId(SmallVec<[ElementId; 32]>);
|
||||
pub trait ParentComponent<V: 'static> {
|
||||
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]>;
|
||||
|
||||
fn child(mut self, child: impl Component<V>) -> Self
|
||||
fn child(mut self, child: impl Element<V>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.children_mut().push(child.render());
|
||||
self.children_mut().push(child.into_any());
|
||||
self
|
||||
}
|
||||
|
||||
fn children(mut self, iter: impl IntoIterator<Item = impl Component<V>>) -> Self
|
||||
fn children(mut self, children: impl IntoIterator<Item = impl Element<V>>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.children_mut()
|
||||
.extend(iter.into_iter().map(|item| item.render()));
|
||||
.extend(children.into_iter().map(Element::into_any));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
trait ElementObject<V> {
|
||||
fn element_id(&self) -> Option<ElementId>;
|
||||
fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId;
|
||||
fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
|
||||
fn measure(
|
||||
@@ -132,6 +133,10 @@ impl<V, E: Element<V>> DrawableElement<V, E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.element.as_ref()?.element_id()
|
||||
}
|
||||
|
||||
fn layout(&mut self, state: &mut V, cx: &mut ViewContext<V>) -> LayoutId {
|
||||
let (layout_id, frame_state) = if let Some(id) = self.element.as_ref().unwrap().element_id()
|
||||
{
|
||||
@@ -256,6 +261,10 @@ where
|
||||
E: Element<V>,
|
||||
E::State: 'static,
|
||||
{
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
self.as_ref().unwrap().element_id()
|
||||
}
|
||||
|
||||
fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId {
|
||||
DrawableElement::layout(self.as_mut().unwrap(), view_state, cx)
|
||||
}
|
||||
@@ -302,6 +311,10 @@ impl<V> AnyElement<V> {
|
||||
AnyElement(Box::new(Some(DrawableElement::new(element))) as Box<dyn ElementObject<V>>)
|
||||
}
|
||||
|
||||
pub fn element_id(&self) -> Option<ElementId> {
|
||||
self.0.element_id()
|
||||
}
|
||||
|
||||
pub fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId {
|
||||
self.0.layout(view_state, cx)
|
||||
}
|
||||
@@ -332,6 +345,34 @@ impl<V> AnyElement<V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for AnyElement<V> {
|
||||
type State = ();
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
AnyElement::element_id(self)
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
_: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (LayoutId, Self::State) {
|
||||
let layout_id = self.layout(view_state, cx);
|
||||
(layout_id, ())
|
||||
}
|
||||
|
||||
fn paint(
|
||||
self,
|
||||
bounds: Bounds<Pixels>,
|
||||
view_state: &mut V,
|
||||
_: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
self.paint(view_state, cx);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Component<V> {
|
||||
fn render(self) -> AnyElement<V>;
|
||||
|
||||
@@ -426,3 +467,37 @@ where
|
||||
AnyElement::new(Some(self))
|
||||
}
|
||||
}
|
||||
|
||||
// impl<V, E, F> Element<V> for F
|
||||
// where
|
||||
// V: 'static,
|
||||
// E: 'static + Component<V>,
|
||||
// F: FnOnce(&mut V, &mut ViewContext<'_, V>) -> E + 'static,
|
||||
// {
|
||||
// type State = Option<AnyElement<V>>;
|
||||
|
||||
// fn element_id(&self) -> Option<ElementId> {
|
||||
// None
|
||||
// }
|
||||
|
||||
// fn layout(
|
||||
// &mut self,
|
||||
// view_state: &mut V,
|
||||
// element_state: Option<Self::State>,
|
||||
// cx: &mut ViewContext<V>,
|
||||
// ) -> (LayoutId, Self::State) {
|
||||
|
||||
// self(view_state)
|
||||
|
||||
// }
|
||||
|
||||
// fn paint(
|
||||
// self,
|
||||
// bounds: Bounds<Pixels>,
|
||||
// view_state: &mut V,
|
||||
// element_state: &mut Self::State,
|
||||
// cx: &mut ViewContext<V>,
|
||||
// ) {
|
||||
// todo!()
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -307,12 +307,7 @@ mod test {
|
||||
.key_context("parent")
|
||||
.on_key_down(|this: &mut TestView, _, _, _| this.saw_key_down = true)
|
||||
.on_action(|this: &mut TestView, _: &TestAction, _| this.saw_action = true)
|
||||
.child(|this: &mut Self, _cx: &mut ViewContext<Self>| {
|
||||
div()
|
||||
.key_context("nested")
|
||||
.track_focus(&this.focus_handle)
|
||||
.render()
|
||||
}),
|
||||
.child(div().key_context("nested").track_focus(&self.focus_handle)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ impl ZIndexExample {
|
||||
Self { z_index }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.relative()
|
||||
.size_full()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use gpui::{div, Component, Div, ParentComponent, Styled, ViewContext};
|
||||
use gpui::{div, Component, Div, Element, ParentComponent, SharedString, Styled, ViewContext};
|
||||
|
||||
use crate::ActiveTheme;
|
||||
|
||||
@@ -16,23 +16,26 @@ impl Story {
|
||||
.bg(cx.theme().colors().background)
|
||||
}
|
||||
|
||||
pub fn title<V: 'static>(cx: &mut ViewContext<V>, title: &str) -> impl Component<V> {
|
||||
pub fn title<V: 'static>(cx: &mut ViewContext<V>, title: SharedString) -> impl Element<V> {
|
||||
div()
|
||||
.text_xl()
|
||||
.text_color(cx.theme().colors().text)
|
||||
.child(title.to_owned())
|
||||
.child(title)
|
||||
}
|
||||
|
||||
pub fn title_for<V: 'static, T>(cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
Self::title(cx, std::any::type_name::<T>())
|
||||
pub fn title_for<V: 'static, T>(cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
Self::title(cx, std::any::type_name::<T>().into())
|
||||
}
|
||||
|
||||
pub fn label<V: 'static>(cx: &mut ViewContext<V>, label: &str) -> impl Component<V> {
|
||||
pub fn label<V: 'static>(
|
||||
cx: &mut ViewContext<V>,
|
||||
label: impl Into<SharedString>,
|
||||
) -> impl Element<V> {
|
||||
div()
|
||||
.mt_4()
|
||||
.mb_2()
|
||||
.text_xs()
|
||||
.text_color(cx.theme().colors().text)
|
||||
.child(label.to_owned())
|
||||
.child(label.into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,13 +49,13 @@ use gpui::hsla
|
||||
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().size_4().bg(hsla(50.0/360.0, 1.0, 0.5, 1.0))
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Every component needs a render method, and it should return `impl Component<V>`. This basic component will render a 16x16px yellow square on the screen.
|
||||
Every component needs a render method, and it should return `impl Element<V>`. This basic component will render a 16x16px yellow square on the screen.
|
||||
|
||||
A couple of questions might come to mind:
|
||||
|
||||
@@ -87,7 +87,7 @@ We can access the current theme's colors like this:
|
||||
~~~rust
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let color = cx.theme().colors()
|
||||
|
||||
div().size_4().hsla(50.0/360.0, 1.0, 0.5, 1.0)
|
||||
@@ -102,7 +102,7 @@ use gpui::hsla
|
||||
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let color = cx.theme().colors()
|
||||
|
||||
div().size_4().bg(color.surface)
|
||||
@@ -117,7 +117,7 @@ use gpui::hsla
|
||||
|
||||
impl<V: 'static> TodoList<V> {
|
||||
// ...
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let color = cx.theme().colors()
|
||||
|
||||
div()
|
||||
|
||||
@@ -21,7 +21,7 @@ impl Avatar {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let mut img = img();
|
||||
|
||||
if self.shape == Shape::Circle {
|
||||
|
||||
@@ -164,7 +164,7 @@ impl<V: 'static> Button<V> {
|
||||
self.icon.map(|i| IconElement::new(i).color(icon_color))
|
||||
}
|
||||
|
||||
pub fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
pub fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let (icon_color, label_color) = match (self.disabled, self.color) {
|
||||
(true, _) => (TextColor::Disabled, TextColor::Disabled),
|
||||
(_, None) => (TextColor::Default, TextColor::Default),
|
||||
@@ -222,7 +222,7 @@ impl<V: 'static> ButtonGroup<V> {
|
||||
Self { buttons }
|
||||
}
|
||||
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let mut el = h_stack().text_ui();
|
||||
|
||||
for button in self.buttons {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use gpui::{div, prelude::*, Component, ElementId, Styled, ViewContext};
|
||||
use gpui::{div, prelude::*, Component, Element, ElementId, Styled, ViewContext};
|
||||
use std::sync::Arc;
|
||||
use theme2::ActiveTheme;
|
||||
|
||||
@@ -42,7 +42,7 @@ impl<V: 'static> Checkbox<V> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
pub fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let group_id = format!("checkbox_group_{:?}", self.id);
|
||||
|
||||
let icon = match self.checked {
|
||||
|
||||
@@ -27,7 +27,7 @@ impl<V: 'static> Details<V> {
|
||||
self
|
||||
}
|
||||
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
v_stack()
|
||||
.p_1()
|
||||
.gap_0p5()
|
||||
|
||||
@@ -31,7 +31,7 @@ impl Divider {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.map(|this| match self.direction {
|
||||
DividerDirection::Horizontal => {
|
||||
|
||||
@@ -13,7 +13,7 @@ impl Facepile {
|
||||
}
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let player_count = self.players.len();
|
||||
let player_list = self.players.iter().enumerate().map(|(ix, player)| {
|
||||
let isnt_last = ix < player_count - 1;
|
||||
|
||||
@@ -163,7 +163,7 @@ impl IconElement {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let svg_size = match self.size {
|
||||
IconSize::Small => rems(0.75),
|
||||
IconSize::Medium => rems(0.9375),
|
||||
|
||||
@@ -80,7 +80,7 @@ impl<V: 'static> IconButton<V> {
|
||||
self.on_click(move |this, cx| cx.dispatch_action(action.boxed_clone()))
|
||||
}
|
||||
|
||||
fn render(mut self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(mut self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let icon_color = match (self.state, self.color) {
|
||||
(InteractionState::Disabled, _) => TextColor::Disabled,
|
||||
(InteractionState::Active, _) => TextColor::Selected,
|
||||
|
||||
@@ -10,7 +10,7 @@ impl UnreadIndicator {
|
||||
Self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.rounded_full()
|
||||
.border_2()
|
||||
|
||||
@@ -55,7 +55,7 @@ impl Input {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let (input_bg, input_hover_bg, input_active_bg) = match self.variant {
|
||||
InputVariant::Ghost => (
|
||||
cx.theme().colors().ghost_element_background,
|
||||
|
||||
@@ -24,7 +24,7 @@ impl KeyBinding {
|
||||
Self { key_binding }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.flex()
|
||||
.gap_2()
|
||||
@@ -52,7 +52,7 @@ impl Key {
|
||||
Self { key: key.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.px_2()
|
||||
.py_0()
|
||||
|
||||
@@ -100,7 +100,7 @@ impl Label {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.when(self.strikethrough, |this| {
|
||||
this.relative().child(
|
||||
@@ -161,7 +161,7 @@ impl HighlightedLabel {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let highlight_color = cx.theme().colors().text_accent;
|
||||
let mut text_style = cx.text_style().clone();
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ impl ListHeader {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let disclosure_control = disclosure_control(self.toggle);
|
||||
|
||||
let meta = match self.meta {
|
||||
@@ -138,7 +138,7 @@ impl ListSubHeader {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
h_stack().flex_1().w_full().relative().py_1().child(
|
||||
div()
|
||||
.h_6()
|
||||
@@ -198,7 +198,7 @@ impl From<ListSubHeader> for ListItem {
|
||||
}
|
||||
|
||||
impl ListItem {
|
||||
fn render<V: 'static>(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
match self {
|
||||
ListItem::Entry(entry) => div().child(entry.render(view, cx)),
|
||||
ListItem::Separator(separator) => div().child(separator.render(view, cx)),
|
||||
@@ -307,7 +307,7 @@ impl ListEntry {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let settings = user_settings(cx);
|
||||
|
||||
let left_content = match self.left_slot.clone() {
|
||||
@@ -385,7 +385,7 @@ impl ListSeparator {
|
||||
Self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().h_px().w_full().bg(cx.theme().colors().border_variant)
|
||||
}
|
||||
}
|
||||
@@ -425,7 +425,7 @@ impl List {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let list_content = match (self.items.is_empty(), self.toggle) {
|
||||
(false, _) => div().children(self.items),
|
||||
(true, Toggle::Toggled(false)) => div(),
|
||||
|
||||
@@ -38,7 +38,7 @@ impl<V: 'static> Modal<V> {
|
||||
self
|
||||
}
|
||||
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
v_stack()
|
||||
.id(self.id.clone())
|
||||
.w_96()
|
||||
|
||||
@@ -22,7 +22,7 @@ impl NotificationToast {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
h_stack()
|
||||
.z_index(5)
|
||||
.absolute()
|
||||
|
||||
@@ -42,7 +42,7 @@ impl Palette {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
v_stack()
|
||||
.id(self.id.clone())
|
||||
.w_96()
|
||||
@@ -135,7 +135,7 @@ impl PaletteItem {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.flex()
|
||||
.flex_row()
|
||||
|
||||
@@ -92,7 +92,7 @@ impl<V: 'static> Panel<V> {
|
||||
self
|
||||
}
|
||||
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let current_size = self.width.unwrap_or(self.initial_width);
|
||||
|
||||
v_stack()
|
||||
|
||||
@@ -13,7 +13,7 @@ impl PlayerStack {
|
||||
}
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let player = self.player_with_call_status.get_player();
|
||||
|
||||
let followers = self
|
||||
|
||||
@@ -86,7 +86,7 @@ impl Tab {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let has_fs_conflict = self.fs_status == FileSystemStatus::Conflict;
|
||||
let is_deleted = self.fs_status == FileSystemStatus::Deleted;
|
||||
|
||||
|
||||
@@ -21,12 +21,41 @@ pub enum ToastOrigin {
|
||||
/// they are actively showing the a process in progress.
|
||||
///
|
||||
/// Only one toast may be visible at a time.
|
||||
#[derive(Component)]
|
||||
pub struct Toast<V: 'static> {
|
||||
origin: ToastOrigin,
|
||||
children: SmallVec<[AnyElement<V>; 2]>,
|
||||
}
|
||||
|
||||
impl<V: 'static> Element<V> for Toast<V> {
|
||||
type State = Option<AnyElement<V>>;
|
||||
|
||||
fn element_id(&self) -> Option<ElementId> {
|
||||
None
|
||||
}
|
||||
|
||||
fn layout(
|
||||
&mut self,
|
||||
view_state: &mut V,
|
||||
_element_state: Option<Self::State>,
|
||||
cx: &mut ViewContext<V>,
|
||||
) -> (gpui::LayoutId, Self::State) {
|
||||
let mut element = self.render(view_state, cx).into_any();
|
||||
let layout_id = element.layout(view_state, cx);
|
||||
(layout_id, Some(element))
|
||||
}
|
||||
|
||||
fn paint(
|
||||
self,
|
||||
bounds: gpui::Bounds<gpui::Pixels>,
|
||||
view_state: &mut V,
|
||||
element: &mut Self::State,
|
||||
cx: &mut ViewContext<V>,
|
||||
) {
|
||||
let element = element.take().unwrap();
|
||||
element.paint(view_state, cx);
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: 'static> Toast<V> {
|
||||
pub fn new(origin: ToastOrigin) -> Self {
|
||||
Self {
|
||||
@@ -35,7 +64,7 @@ impl<V: 'static> Toast<V> {
|
||||
}
|
||||
}
|
||||
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let mut div = div();
|
||||
|
||||
if self.origin == ToastOrigin::Bottom {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use gpui::{div, Component, ParentComponent};
|
||||
use gpui::{div, Component, Element, ParentComponent};
|
||||
|
||||
use crate::{Icon, IconElement, IconSize, TextColor};
|
||||
|
||||
@@ -44,7 +44,7 @@ impl From<bool> for Toggle {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disclosure_control<V: 'static>(toggle: Toggle) -> impl Component<V> {
|
||||
pub fn disclosure_control<V: 'static>(toggle: Toggle) -> impl Element<V> {
|
||||
match (toggle.is_toggleable(), toggle.is_toggled()) {
|
||||
(false, _) => div(),
|
||||
(_, true) => div().child(
|
||||
|
||||
@@ -8,7 +8,7 @@ impl ToolDivider {
|
||||
Self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().w_px().h_3().bg(cx.theme().colors().border)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,18 +15,18 @@ impl Story {
|
||||
.bg(cx.theme().colors().background)
|
||||
}
|
||||
|
||||
pub fn title<V: 'static>(cx: &mut ViewContext<V>, title: &str) -> impl Component<V> {
|
||||
pub fn title<V: 'static>(cx: &mut ViewContext<V>, title: &str) -> impl Element<V> {
|
||||
div()
|
||||
.text_xl()
|
||||
.text_color(cx.theme().colors().text)
|
||||
.child(title.to_owned())
|
||||
}
|
||||
|
||||
pub fn title_for<V: 'static, T>(cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
pub fn title_for<V: 'static, T>(cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
Self::title(cx, std::any::type_name::<T>())
|
||||
}
|
||||
|
||||
pub fn label<V: 'static>(cx: &mut ViewContext<V>, label: &str) -> impl Component<V> {
|
||||
pub fn label<V: 'static>(cx: &mut ViewContext<V>, label: &str) -> impl Element<V> {
|
||||
div()
|
||||
.mt_4()
|
||||
.mb_2()
|
||||
|
||||
@@ -21,7 +21,7 @@ impl AssistantPanel {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
Panel::new(self.id.clone(), cx)
|
||||
.children(vec![div()
|
||||
.flex()
|
||||
|
||||
@@ -22,7 +22,7 @@ impl Breadcrumb {
|
||||
.text_color(cx.theme().colors().text_muted)
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, view_state: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, view_state: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let symbols_len = self.symbols.len();
|
||||
|
||||
h_stack()
|
||||
|
||||
@@ -154,7 +154,7 @@ impl Buffer {
|
||||
self
|
||||
}
|
||||
|
||||
fn render_row<V: 'static>(row: BufferRow, cx: &WindowContext) -> impl Component<V> {
|
||||
fn render_row<V: 'static>(row: BufferRow, cx: &WindowContext) -> impl Element<V> {
|
||||
let line_background = if row.current {
|
||||
cx.theme().colors().editor_active_line_background
|
||||
} else {
|
||||
@@ -202,7 +202,7 @@ impl Buffer {
|
||||
}))
|
||||
}
|
||||
|
||||
fn render_rows<V: 'static>(&self, cx: &WindowContext) -> Vec<impl Component<V>> {
|
||||
fn render_rows<V: 'static>(&self, cx: &WindowContext) -> Vec<impl Element<V>> {
|
||||
match &self.rows {
|
||||
Some(rows) => rows
|
||||
.rows
|
||||
@@ -213,7 +213,7 @@ impl Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let rows = self.render_rows(cx);
|
||||
|
||||
v_stack()
|
||||
|
||||
@@ -21,7 +21,7 @@ impl ChatPanel {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.id(self.element_id.clone())
|
||||
.flex()
|
||||
@@ -83,7 +83,7 @@ impl ChatMessage {
|
||||
}
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.flex()
|
||||
.flex_col()
|
||||
|
||||
@@ -14,7 +14,7 @@ impl CollabPanel {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
v_stack()
|
||||
.id(self.id.clone())
|
||||
.h_full()
|
||||
|
||||
@@ -11,7 +11,7 @@ impl CommandPalette {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().id(self.id.clone()).child(
|
||||
Palette::new("palette")
|
||||
.items(example_editor_actions())
|
||||
|
||||
@@ -10,7 +10,7 @@ impl CopilotModal {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().id(self.id.clone()).child(
|
||||
Modal::new("some-id")
|
||||
.title("Connect Copilot to Zed")
|
||||
|
||||
@@ -11,7 +11,7 @@ impl LanguageSelector {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().id(self.id.clone()).child(
|
||||
Palette::new("palette")
|
||||
.items(vec![
|
||||
|
||||
@@ -11,7 +11,7 @@ impl MultiBuffer {
|
||||
Self { buffers }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
v_stack()
|
||||
.w_full()
|
||||
.h_full()
|
||||
|
||||
@@ -15,7 +15,7 @@ impl NotificationsPanel {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.id(self.id.clone())
|
||||
.flex()
|
||||
@@ -241,7 +241,7 @@ impl<V> Notification<V> {
|
||||
self
|
||||
}
|
||||
|
||||
fn render_meta_items(&self, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render_meta_items(&self, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
if let Some(meta) = &self.meta {
|
||||
h_stack().children(
|
||||
meta.items
|
||||
@@ -260,14 +260,14 @@ impl<V> Notification<V> {
|
||||
}
|
||||
}
|
||||
|
||||
fn render_slot(&self, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render_slot(&self, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
match &self.slot {
|
||||
ActorOrIcon::Actor(actor) => Avatar::new(actor.avatar.clone()).render(),
|
||||
ActorOrIcon::Icon(icon) => IconElement::new(icon.clone()).render(),
|
||||
}
|
||||
}
|
||||
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.relative()
|
||||
.id(self.id.clone())
|
||||
|
||||
@@ -35,7 +35,7 @@ impl<V: 'static> Pane<V> {
|
||||
self
|
||||
}
|
||||
|
||||
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.id(self.id.clone())
|
||||
.flex()
|
||||
@@ -89,7 +89,7 @@ impl<V: 'static> PaneGroup<V> {
|
||||
}
|
||||
}
|
||||
|
||||
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
if !self.panes.is_empty() {
|
||||
let el = div()
|
||||
.flex()
|
||||
|
||||
@@ -14,7 +14,7 @@ impl ProjectPanel {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.id(self.id.clone())
|
||||
.flex()
|
||||
|
||||
@@ -11,7 +11,7 @@ impl RecentProjects {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().id(self.id.clone()).child(
|
||||
Palette::new("palette")
|
||||
.items(vec![
|
||||
|
||||
@@ -23,7 +23,7 @@ impl TabBar {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let (can_navigate_back, can_navigate_forward) = self.can_navigate;
|
||||
|
||||
div()
|
||||
|
||||
@@ -11,7 +11,7 @@ impl Terminal {
|
||||
Self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let can_navigate_back = true;
|
||||
let can_navigate_forward = false;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ impl ThemeSelector {
|
||||
Self { id: id.into() }
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div().child(
|
||||
Palette::new(self.id.clone())
|
||||
.items(vec![
|
||||
|
||||
@@ -20,7 +20,7 @@ impl<V: 'static> Toolbar<V> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn left_item(mut self, child: impl Component<V>) -> Self
|
||||
pub fn left_item(mut self, child: impl Element<V>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
@@ -28,7 +28,7 @@ impl<V: 'static> Toolbar<V> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn left_items(mut self, iter: impl IntoIterator<Item = impl Component<V>>) -> Self
|
||||
pub fn left_items(mut self, iter: impl IntoIterator<Item = impl Element<V>>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
@@ -37,7 +37,7 @@ impl<V: 'static> Toolbar<V> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn right_item(mut self, child: impl Component<V>) -> Self
|
||||
pub fn right_item(mut self, child: impl Element<V>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
@@ -45,7 +45,7 @@ impl<V: 'static> Toolbar<V> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn right_items(mut self, iter: impl IntoIterator<Item = impl Component<V>>) -> Self
|
||||
pub fn right_items(mut self, iter: impl IntoIterator<Item = impl Element<V>>) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
@@ -54,7 +54,7 @@ impl<V: 'static> Toolbar<V> {
|
||||
self
|
||||
}
|
||||
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.bg(cx.theme().colors().toolbar_background)
|
||||
.p_2()
|
||||
|
||||
@@ -21,7 +21,7 @@ impl TrafficLight {
|
||||
}
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
let system_colors = &cx.theme().styles.system;
|
||||
|
||||
let fill = match (self.window_has_focus, self.color) {
|
||||
@@ -52,7 +52,7 @@ impl TrafficLights {
|
||||
self
|
||||
}
|
||||
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
|
||||
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
|
||||
div()
|
||||
.flex()
|
||||
.items_center()
|
||||
|
||||
Reference in New Issue
Block a user