Detailed changes
@@ -898,11 +898,8 @@ impl<G: 'static> DerefMut for GlobalLease<G> {
/// Contains state associated with an active drag operation, started by dragging an element
/// within the window or by dragging into the app from the underlying platform.
pub(crate) struct AnyDrag {
- pub render: Box<dyn FnOnce(&mut WindowContext) -> AnyElement<()>>,
- pub drag_handle_view: Option<AnyView>,
+ pub view: AnyView,
pub cursor_offset: Point<Pixels>,
- pub state: AnyBox,
- pub state_type: TypeId,
}
#[cfg(test)]
@@ -147,7 +147,7 @@ pub struct Slot<T>(Model<T>);
pub struct AnyModel {
pub(crate) entity_id: EntityId,
- entity_type: TypeId,
+ pub(crate) entity_type: TypeId,
entity_map: Weak<RwLock<EntityRefCounts>>,
}
@@ -247,8 +247,8 @@ impl Eq for AnyModel {}
pub struct Model<T> {
#[deref]
#[deref_mut]
- any_model: AnyModel,
- entity_type: PhantomData<T>,
+ pub(crate) any_model: AnyModel,
+ pub(crate) entity_type: PhantomData<T>,
}
unsafe impl<T> Send for Model<T> {}
@@ -272,6 +272,11 @@ impl<T: 'static> Model<T> {
}
}
+ /// Convert this into a dynamically typed model.
+ pub fn into_any(self) -> AnyModel {
+ self.any_model
+ }
+
pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
cx.entities.read(self)
}
@@ -90,13 +90,11 @@ pub trait Context {
pub trait VisualContext: Context {
type ViewContext<'a, 'w, V>;
- fn build_view<E, V>(
+ fn build_view<V>(
&mut self,
- build_model: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
- render: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + 'static,
+ build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
) -> Self::Result<View<V>>
where
- E: Component<V>,
V: 'static + Send;
fn update_view<V: 'static, R>(
@@ -171,27 +169,22 @@ impl<C: Context> Context for MainThread<C> {
impl<C: VisualContext> VisualContext for MainThread<C> {
type ViewContext<'a, 'w, V> = MainThread<C::ViewContext<'a, 'w, V>>;
- fn build_view<E, V>(
+ fn build_view<V>(
&mut self,
- build_model: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
- render: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + 'static,
+ build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
) -> Self::Result<View<V>>
where
- E: Component<V>,
V: 'static + Send,
{
- self.0.build_view(
- |cx| {
- let cx = unsafe {
- mem::transmute::<
- &mut C::ViewContext<'_, '_, V>,
- &mut MainThread<C::ViewContext<'_, '_, V>>,
- >(cx)
- };
- build_model(cx)
- },
- render,
- )
+ self.0.build_view(|cx| {
+ let cx = unsafe {
+ mem::transmute::<
+ &mut C::ViewContext<'_, '_, V>,
+ &mut MainThread<C::ViewContext<'_, '_, V>>,
+ >(cx)
+ };
+ build_view_state(cx)
+ })
}
fn update_view<V: 'static, R>(
@@ -1,7 +1,7 @@
use crate::{
- point, px, Action, AnyBox, AnyDrag, AppContext, BorrowWindow, Bounds, Component,
- DispatchContext, DispatchPhase, Element, ElementId, FocusHandle, KeyMatch, Keystroke,
- Modifiers, Overflow, Pixels, Point, SharedString, Size, Style, StyleRefinement, View,
+ div, point, px, Action, AnyDrag, AnyView, AppContext, BorrowWindow, Bounds, Component,
+ DispatchContext, DispatchPhase, Div, Element, ElementId, FocusHandle, KeyMatch, Keystroke,
+ Modifiers, Overflow, Pixels, Point, Render, SharedString, Size, Style, StyleRefinement, View,
ViewContext,
};
use collections::HashMap;
@@ -258,17 +258,17 @@ pub trait StatelessInteractive<V: 'static>: Element<V> {
self
}
- fn on_drop<S: 'static>(
+ fn on_drop<W: 'static + Send>(
mut self,
- listener: impl Fn(&mut V, S, &mut ViewContext<V>) + Send + 'static,
+ listener: impl Fn(&mut V, View<W>, &mut ViewContext<V>) + Send + 'static,
) -> Self
where
Self: Sized,
{
self.stateless_interaction().drop_listeners.push((
- TypeId::of::<S>(),
- Box::new(move |view, drag_state, cx| {
- listener(view, *drag_state.downcast().unwrap(), cx);
+ TypeId::of::<W>(),
+ Box::new(move |view, dragged_view, cx| {
+ listener(view, dragged_view.downcast().unwrap(), cx);
}),
));
self
@@ -314,43 +314,22 @@ pub trait StatefulInteractive<V: 'static>: StatelessInteractive<V> {
self
}
- fn on_drag<S, R, E>(
+ fn on_drag<W>(
mut self,
- listener: impl Fn(&mut V, &mut ViewContext<V>) -> Drag<S, R, V, E> + Send + 'static,
+ listener: impl Fn(&mut V, &mut ViewContext<V>) -> View<W> + Send + 'static,
) -> Self
where
Self: Sized,
- S: Any + Send,
- R: Fn(&mut V, &mut ViewContext<V>) -> E,
- R: 'static + Send,
- E: Component<V>,
+ W: 'static + Send + Render,
{
debug_assert!(
self.stateful_interaction().drag_listener.is_none(),
"calling on_drag more than once on the same element is not supported"
);
self.stateful_interaction().drag_listener =
- Some(Box::new(move |view_state, cursor_offset, cx| {
- let drag = listener(view_state, cx);
- let drag_handle_view = Some(
- cx.build_view(|cx| DragView {
- model: cx.model().upgrade().unwrap(),
- drag,
- })
- .into_any(),
- );
- AnyDrag {
- render: {
- let view = cx.view();
- Box::new(move |cx| {
- view.update(cx, |view, cx| drag.render_drag_handle(view, cx))
- })
- },
- drag_handle_view,
- cursor_offset,
- state: Box::new(drag.state),
- state_type: TypeId::of::<S>(),
- }
+ Some(Box::new(move |view_state, cursor_offset, cx| AnyDrag {
+ view: listener(view_state, cx).into_any(),
+ cursor_offset,
}));
self
}
@@ -419,7 +398,7 @@ pub trait ElementInteraction<V: 'static>: 'static + Send {
if let Some(drag) = cx.active_drag.take() {
for (state_type, group_drag_style) in &self.as_stateless().group_drag_over_styles {
if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) {
- if *state_type == drag.state_type
+ if *state_type == drag.view.entity_type()
&& group_bounds.contains_point(&mouse_position)
{
style.refine(&group_drag_style.style);
@@ -428,7 +407,8 @@ pub trait ElementInteraction<V: 'static>: 'static + Send {
}
for (state_type, drag_over_style) in &self.as_stateless().drag_over_styles {
- if *state_type == drag.state_type && bounds.contains_point(&mouse_position) {
+ if *state_type == drag.view.entity_type() && bounds.contains_point(&mouse_position)
+ {
style.refine(drag_over_style);
}
}
@@ -516,7 +496,7 @@ pub trait ElementInteraction<V: 'static>: 'static + Send {
cx.on_mouse_event(move |view, event: &MouseUpEvent, phase, cx| {
if phase == DispatchPhase::Bubble && bounds.contains_point(&event.position) {
if let Some(drag_state_type) =
- cx.active_drag.as_ref().map(|drag| drag.state_type)
+ cx.active_drag.as_ref().map(|drag| drag.view.entity_type())
{
for (drop_state_type, listener) in &drop_listeners {
if *drop_state_type == drag_state_type {
@@ -524,7 +504,7 @@ pub trait ElementInteraction<V: 'static>: 'static + Send {
.active_drag
.take()
.expect("checked for type drag state type above");
- listener(view, drag.state, cx);
+ listener(view, drag.view.clone(), cx);
cx.notify();
cx.stop_propagation();
}
@@ -692,7 +672,7 @@ impl<V> From<ElementId> for StatefulInteraction<V> {
}
}
-type DropListener<V> = dyn Fn(&mut V, AnyBox, &mut ViewContext<V>) + 'static + Send;
+type DropListener<V> = dyn Fn(&mut V, AnyView, &mut ViewContext<V>) + 'static + Send;
pub struct StatelessInteraction<V> {
pub dispatch_context: DispatchContext,
@@ -873,7 +853,7 @@ pub struct Drag<S, R, V, E>
where
R: Fn(&mut V, &mut ViewContext<V>) -> E,
V: 'static,
- E: Component<V>,
+ E: Component<()>,
{
pub state: S,
pub render_drag_handle: R,
@@ -884,7 +864,7 @@ impl<S, R, V, E> Drag<S, R, V, E>
where
R: Fn(&mut V, &mut ViewContext<V>) -> E,
V: 'static,
- E: Component<V>,
+ E: Component<()>,
{
pub fn new(state: S, render_drag_handle: R) -> Self {
Drag {
@@ -1006,6 +986,14 @@ impl Deref for MouseExitEvent {
#[derive(Debug, Clone, Default)]
pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
+impl Render for ExternalPaths {
+ type Element = Div<Self>;
+
+ fn render(&mut self, _: &mut ViewContext<Self>) -> Self::Element {
+ div() // Intentionally left empty because the platform will render icons for the dragged files
+ }
+}
+
#[derive(Debug, Clone)]
pub enum FileDropEvent {
Entered {
@@ -1,9 +1,10 @@
use crate::{
- AnyBox, AnyElement, AvailableSpace, BorrowWindow, Bounds, Component, Element, ElementId,
- EntityId, LayoutId, Model, Pixels, Size, ViewContext, VisualContext, WeakModel, WindowContext,
+ AnyBox, AnyElement, AnyModel, AppContext, AvailableSpace, BorrowWindow, Bounds, Component,
+ Element, ElementId, EntityId, LayoutId, Model, Pixels, Size, ViewContext, VisualContext,
+ WeakModel, WindowContext,
};
use anyhow::{Context, Result};
-use std::{marker::PhantomData, sync::Arc};
+use std::{any::TypeId, marker::PhantomData, sync::Arc};
pub trait Render: 'static + Sized {
type Element: Element<Self> + 'static + Send;
@@ -38,6 +39,10 @@ impl<V: 'static> View<V> {
{
cx.update_view(self, f)
}
+
+ pub fn read<'a>(&self, cx: &'a AppContext) -> &'a V {
+ self.model.read(cx)
+ }
}
impl<V> Clone for View<V> {
@@ -178,7 +183,9 @@ impl<V: Render, ParentV: 'static> Element<ParentV> for EraseViewState<V, ParentV
}
trait ViewObject: Send + Sync {
+ fn entity_type(&self) -> TypeId;
fn entity_id(&self) -> EntityId;
+ fn model(&self) -> AnyModel;
fn initialize(&self, cx: &mut WindowContext) -> AnyBox;
fn layout(&self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId;
fn paint(&self, bounds: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext);
@@ -188,10 +195,18 @@ impl<V> ViewObject for View<V>
where
V: Render,
{
+ fn entity_type(&self) -> TypeId {
+ TypeId::of::<V>()
+ }
+
fn entity_id(&self) -> EntityId {
self.model.entity_id
}
+ fn model(&self) -> AnyModel {
+ self.model.clone().into_any()
+ }
+
fn initialize(&self, cx: &mut WindowContext) -> AnyBox {
cx.with_element_id(self.entity_id(), |_global_id, cx| {
self.update(cx, |state, cx| {
@@ -225,6 +240,14 @@ where
pub struct AnyView(Arc<dyn ViewObject>);
impl AnyView {
+ pub fn downcast<V: 'static + Send>(self) -> Option<View<V>> {
+ self.0.model().downcast().map(|model| View { model })
+ }
+
+ pub(crate) fn entity_type(&self) -> TypeId {
+ self.0.entity_type()
+ }
+
pub(crate) fn draw(&self, available_space: Size<AvailableSpace>, cx: &mut WindowContext) {
let mut rendered_element = self.0.initialize(cx);
let layout_id = self.0.layout(&mut rendered_element, cx);
@@ -294,6 +317,18 @@ impl<ParentV: 'static> Component<ParentV> for EraseAnyViewState<ParentV> {
}
}
+impl<T, E> Render for T
+where
+ T: 'static + FnMut(&mut WindowContext) -> E,
+ E: 'static + Send + Element<T>,
+{
+ type Element = E;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+ (self)(cx)
+ }
+}
+
impl<ParentV: 'static> Element<ParentV> for EraseAnyViewState<ParentV> {
type ElementState = AnyBox;
@@ -1,11 +1,11 @@
use crate::{
px, size, Action, AnyBox, AnyDrag, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
Bounds, BoxShadow, Context, Corners, DevicePixels, DispatchContext, DisplayId, Edges, Effect,
- EntityId, EventEmitter, ExternalPaths, FileDropEvent, FocusEvent, FontId, GlobalElementId,
- GlyphId, Hsla, ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke,
- LayoutId, MainThread, MainThreadOnly, Model, ModelContext, Modifiers, MonochromeSprite,
- MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas,
- PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
+ EntityId, EventEmitter, FileDropEvent, FocusEvent, FontId, GlobalElementId, GlyphId, Hsla,
+ ImageData, InputEvent, IsZero, KeyListener, KeyMatch, KeyMatcher, Keystroke, LayoutId,
+ MainThread, MainThreadOnly, Model, ModelContext, Modifiers, MonochromeSprite, MouseButton,
+ MouseDownEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas, PlatformWindow,
+ Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderImageParams,
RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, Subscription,
TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext, WeakModel, WeakView,
WindowOptions, SUBPIXEL_VARIANTS,
@@ -891,18 +891,13 @@ impl<'a, 'w> WindowContext<'a, 'w> {
root_view.draw(available_space, cx);
});
- if let Some(mut active_drag) = self.app.active_drag.take() {
+ if let Some(active_drag) = self.app.active_drag.take() {
self.stack(1, |cx| {
let offset = cx.mouse_position() - active_drag.cursor_offset;
cx.with_element_offset(Some(offset), |cx| {
let available_space =
size(AvailableSpace::MinContent, AvailableSpace::MinContent);
- if let Some(drag_handle_view) = &mut active_drag.drag_handle_view {
- drag_handle_view.draw(available_space, cx);
- }
- if let Some(render) = &mut active_drag.render {
- (render)()
- }
+ active_drag.view.draw(available_space, cx);
cx.active_drag = Some(active_drag);
});
});
@@ -970,12 +965,12 @@ impl<'a, 'w> WindowContext<'a, 'w> {
InputEvent::FileDrop(file_drop) => match file_drop {
FileDropEvent::Entered { position, files } => {
self.window.mouse_position = position;
- self.active_drag.get_or_insert_with(|| AnyDrag {
- drag_handle_view: None,
- cursor_offset: position,
- state: Box::new(files),
- state_type: TypeId::of::<ExternalPaths>(),
- });
+ if self.active_drag.is_none() {
+ self.active_drag = Some(AnyDrag {
+ view: self.build_view(|_| files).into_any(),
+ cursor_offset: position,
+ });
+ }
InputEvent::MouseDown(MouseDownEvent {
position,
button: MouseButton::Left,
@@ -1276,21 +1271,17 @@ impl Context for WindowContext<'_, '_> {
impl VisualContext for WindowContext<'_, '_> {
type ViewContext<'a, 'w, V> = ViewContext<'a, 'w, V>;
- /// Builds a new view in the current window. The first argument is a function that builds
- /// an entity representing the view's state. It is invoked with a `ViewContext` that provides
- /// entity-specific access to the window and application state during construction. The second
- /// argument is a render function that returns a component based on the view's state.
- fn build_view<E, V>(
+ fn build_view<V>(
&mut self,
build_view_state: impl FnOnce(&mut Self::ViewContext<'_, '_, V>) -> V,
- render: impl Fn(&mut V, &mut ViewContext<'_, '_, V>) -> E + Send + 'static,
) -> Self::Result<View<V>>
where
- E: crate::Component<V>,
V: 'static + Send,
{
let slot = self.app.entities.reserve();
- let view = View::for_handle(slot.clone(), render);
+ let view = View {
+ model: slot.clone(),
+ };
let mut cx = ViewContext::mutable(&mut *self.app, &mut *self.window, view.downgrade());
let entity = build_view_state(&mut cx);
self.entities.insert(slot, entity);
@@ -1885,16 +1876,11 @@ impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
impl<V: 'static> VisualContext for ViewContext<'_, '_, V> {
type ViewContext<'a, 'w, V2> = ViewContext<'a, 'w, V2>;
- fn build_view<E, V2>(
+ fn build_view<W: 'static + Send>(
&mut self,
- build_view: impl FnOnce(&mut Self::ViewContext<'_, '_, V2>) -> V2,
- render: impl Fn(&mut V2, &mut ViewContext<'_, '_, V2>) -> E + Send + 'static,
- ) -> Self::Result<View<V2>>
- where
- E: crate::Component<V2>,
- V2: 'static + Send,
- {
- self.window_cx.build_view(build_view, render)
+ build_view: impl FnOnce(&mut Self::ViewContext<'_, '_, W>) -> W,
+ ) -> Self::Result<View<W>> {
+ self.window_cx.build_view(build_view)
}
fn update_view<V2: 'static, R>(
@@ -1,6 +1,6 @@
use gpui2::{
- div, Focusable, KeyBinding, ParentElement, StatelessInteractive, Styled, View, VisualContext,
- WindowContext,
+ div, Div, FocusEnabled, Focusable, KeyBinding, ParentElement, Render, StatefulInteraction,
+ StatelessInteractive, Styled, View, VisualContext, WindowContext,
};
use serde::Deserialize;
use theme2::theme;
@@ -14,12 +14,10 @@ struct ActionB;
#[derive(Clone, Default, PartialEq, Deserialize)]
struct ActionC;
-pub struct FocusStory {
- text: View<()>,
-}
+pub struct FocusStory {}
impl FocusStory {
- pub fn view(cx: &mut WindowContext) -> View<()> {
+ pub fn view(cx: &mut WindowContext) -> View<Self> {
cx.bind_keys([
KeyBinding::new("cmd-a", ActionA, Some("parent")),
KeyBinding::new("cmd-a", ActionB, Some("child-1")),
@@ -27,8 +25,16 @@ impl FocusStory {
]);
cx.register_action_type::<ActionA>();
cx.register_action_type::<ActionB>();
- let theme = theme(cx);
+ cx.build_view(move |cx| Self {})
+ }
+}
+
+impl Render for FocusStory {
+ type Element = Div<Self, StatefulInteraction<Self>, FocusEnabled<Self>>;
+
+ fn render(&mut self, cx: &mut gpui2::ViewContext<Self>) -> Self::Element {
+ let theme = theme(cx);
let color_1 = theme.git_created;
let color_2 = theme.git_modified;
let color_3 = theme.git_deleted;
@@ -38,80 +44,73 @@ impl FocusStory {
let child_1 = cx.focus_handle();
let child_2 = cx.focus_handle();
- cx.build_view(
- |_| (),
- move |_, cx| {
+ div()
+ .id("parent")
+ .focusable()
+ .context("parent")
+ .on_action(|_, action: &ActionA, phase, cx| {
+ println!("Action A dispatched on parent during {:?}", phase);
+ })
+ .on_action(|_, action: &ActionB, phase, cx| {
+ println!("Action B dispatched on parent during {:?}", phase);
+ })
+ .on_focus(|_, _, _| println!("Parent focused"))
+ .on_blur(|_, _, _| println!("Parent blurred"))
+ .on_focus_in(|_, _, _| println!("Parent focus_in"))
+ .on_focus_out(|_, _, _| println!("Parent focus_out"))
+ .on_key_down(|_, event, phase, _| {
+ println!("Key down on parent {:?} {:?}", phase, event)
+ })
+ .on_key_up(|_, event, phase, _| println!("Key up on parent {:?} {:?}", phase, event))
+ .size_full()
+ .bg(color_1)
+ .focus(|style| style.bg(color_2))
+ .focus_in(|style| style.bg(color_3))
+ .child(
div()
- .id("parent")
- .focusable()
- .context("parent")
- .on_action(|_, action: &ActionA, phase, cx| {
- println!("Action A dispatched on parent during {:?}", phase);
- })
+ .track_focus(&child_1)
+ .context("child-1")
.on_action(|_, action: &ActionB, phase, cx| {
- println!("Action B dispatched on parent during {:?}", phase);
+ println!("Action B dispatched on child 1 during {:?}", phase);
+ })
+ .w_full()
+ .h_6()
+ .bg(color_4)
+ .focus(|style| style.bg(color_5))
+ .in_focus(|style| style.bg(color_6))
+ .on_focus(|_, _, _| println!("Child 1 focused"))
+ .on_blur(|_, _, _| println!("Child 1 blurred"))
+ .on_focus_in(|_, _, _| println!("Child 1 focus_in"))
+ .on_focus_out(|_, _, _| println!("Child 1 focus_out"))
+ .on_key_down(|_, event, phase, _| {
+ println!("Key down on child 1 {:?} {:?}", phase, event)
+ })
+ .on_key_up(|_, event, phase, _| {
+ println!("Key up on child 1 {:?} {:?}", phase, event)
+ })
+ .child("Child 1"),
+ )
+ .child(
+ div()
+ .track_focus(&child_2)
+ .context("child-2")
+ .on_action(|_, action: &ActionC, phase, cx| {
+ println!("Action C dispatched on child 2 during {:?}", phase);
})
- .on_focus(|_, _, _| println!("Parent focused"))
- .on_blur(|_, _, _| println!("Parent blurred"))
- .on_focus_in(|_, _, _| println!("Parent focus_in"))
- .on_focus_out(|_, _, _| println!("Parent focus_out"))
+ .w_full()
+ .h_6()
+ .bg(color_4)
+ .on_focus(|_, _, _| println!("Child 2 focused"))
+ .on_blur(|_, _, _| println!("Child 2 blurred"))
+ .on_focus_in(|_, _, _| println!("Child 2 focus_in"))
+ .on_focus_out(|_, _, _| println!("Child 2 focus_out"))
.on_key_down(|_, event, phase, _| {
- println!("Key down on parent {:?} {:?}", phase, event)
+ println!("Key down on child 2 {:?} {:?}", phase, event)
})
.on_key_up(|_, event, phase, _| {
- println!("Key up on parent {:?} {:?}", phase, event)
+ println!("Key up on child 2 {:?} {:?}", phase, event)
})
- .size_full()
- .bg(color_1)
- .focus(|style| style.bg(color_2))
- .focus_in(|style| style.bg(color_3))
- .child(
- div()
- .track_focus(&child_1)
- .context("child-1")
- .on_action(|_, action: &ActionB, phase, cx| {
- println!("Action B dispatched on child 1 during {:?}", phase);
- })
- .w_full()
- .h_6()
- .bg(color_4)
- .focus(|style| style.bg(color_5))
- .in_focus(|style| style.bg(color_6))
- .on_focus(|_, _, _| println!("Child 1 focused"))
- .on_blur(|_, _, _| println!("Child 1 blurred"))
- .on_focus_in(|_, _, _| println!("Child 1 focus_in"))
- .on_focus_out(|_, _, _| println!("Child 1 focus_out"))
- .on_key_down(|_, event, phase, _| {
- println!("Key down on child 1 {:?} {:?}", phase, event)
- })
- .on_key_up(|_, event, phase, _| {
- println!("Key up on child 1 {:?} {:?}", phase, event)
- })
- .child("Child 1"),
- )
- .child(
- div()
- .track_focus(&child_2)
- .context("child-2")
- .on_action(|_, action: &ActionC, phase, cx| {
- println!("Action C dispatched on child 2 during {:?}", phase);
- })
- .w_full()
- .h_6()
- .bg(color_4)
- .on_focus(|_, _, _| println!("Child 2 focused"))
- .on_blur(|_, _, _| println!("Child 2 blurred"))
- .on_focus_in(|_, _, _| println!("Child 2 focus_in"))
- .on_focus_out(|_, _, _| println!("Child 2 focus_out"))
- .on_key_down(|_, event, phase, _| {
- println!("Key down on child 2 {:?} {:?}", phase, event)
- })
- .on_key_up(|_, event, phase, _| {
- println!("Key up on child 2 {:?} {:?}", phase, event)
- })
- .child("Child 2"),
- )
- },
- )
+ .child("Child 2"),
+ )
}
}
@@ -1,26 +1,23 @@
-use gpui2::{AppContext, Context, View};
+use crate::{
+ story::Story,
+ story_selector::{ComponentStory, ElementStory},
+};
+use gpui2::{Div, Render, StatefulInteraction, View, VisualContext};
use strum::IntoEnumIterator;
use ui::prelude::*;
-use crate::story::Story;
-use crate::story_selector::{ComponentStory, ElementStory};
-
-pub struct KitchenSinkStory {}
+pub struct KitchenSinkStory;
impl KitchenSinkStory {
- pub fn new() -> Self {
- Self {}
+ pub fn view(cx: &mut WindowContext) -> View<Self> {
+ cx.build_view(|cx| Self)
}
+}
- pub fn view(cx: &mut AppContext) -> View<Self> {
- {
- let state = cx.build_model(|cx| Self::new());
- let render = Self::render;
- View::for_handle(state, render)
- }
- }
+impl Render for KitchenSinkStory {
+ type Element = Div<Self, StatefulInteraction<Self>>;
- fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let element_stories = ElementStory::iter()
.map(|selector| selector.story(cx))
.collect::<Vec<_>>();
@@ -1,54 +1,54 @@
use gpui2::{
- div, px, Component, ParentElement, SharedString, Styled, View, VisualContext, WindowContext,
+ div, px, Component, Div, ParentElement, Render, SharedString, StatefulInteraction, Styled,
+ View, VisualContext, WindowContext,
};
use theme2::theme;
-pub struct ScrollStory {
- text: View<()>,
-}
+pub struct ScrollStory;
impl ScrollStory {
- pub fn view(cx: &mut WindowContext) -> View<()> {
- cx.build_view(|cx| (), move |_, cx| checkerboard(cx, 1))
+ pub fn view(cx: &mut WindowContext) -> View<ScrollStory> {
+ cx.build_view(|cx| ScrollStory)
}
}
-fn checkerboard<S>(cx: &mut WindowContext, depth: usize) -> impl Component<S>
-where
- S: 'static + Send + Sync,
-{
- let theme = theme(cx);
- let color_1 = theme.git_created;
- let color_2 = theme.git_modified;
+impl Render for ScrollStory {
+ type Element = Div<Self, StatefulInteraction<Self>>;
+
+ fn render(&mut self, cx: &mut gpui2::ViewContext<Self>) -> Self::Element {
+ let theme = theme(cx);
+ let color_1 = theme.git_created;
+ let color_2 = theme.git_modified;
- div()
- .id("parent")
- .bg(theme.background)
- .size_full()
- .overflow_scroll()
- .children((0..10).map(|row| {
- div()
- .w(px(1000.))
- .h(px(100.))
- .flex()
- .flex_row()
- .children((0..10).map(|column| {
- let id = SharedString::from(format!("{}, {}", row, column));
- let bg = if row % 2 == column % 2 {
- color_1
- } else {
- color_2
- };
- div().id(id).bg(bg).size(px(100. / depth as f32)).when(
- row >= 5 && column >= 5,
- |d| {
- d.overflow_scroll()
- .child(div().size(px(50.)).bg(color_1))
- .child(div().size(px(50.)).bg(color_2))
- .child(div().size(px(50.)).bg(color_1))
- .child(div().size(px(50.)).bg(color_2))
- },
- )
- }))
- }))
+ div()
+ .id("parent")
+ .bg(theme.background)
+ .size_full()
+ .overflow_scroll()
+ .children((0..10).map(|row| {
+ div()
+ .w(px(1000.))
+ .h(px(100.))
+ .flex()
+ .flex_row()
+ .children((0..10).map(|column| {
+ let id = SharedString::from(format!("{}, {}", row, column));
+ let bg = if row % 2 == column % 2 {
+ color_1
+ } else {
+ color_2
+ };
+ div().id(id).bg(bg).size(px(100. as f32)).when(
+ row >= 5 && column >= 5,
+ |d| {
+ d.overflow_scroll()
+ .child(div().size(px(50.)).bg(color_1))
+ .child(div().size(px(50.)).bg(color_2))
+ .child(div().size(px(50.)).bg(color_1))
+ .child(div().size(px(50.)).bg(color_2))
+ },
+ )
+ }))
+ }))
+ }
}
@@ -1,20 +1,21 @@
-use gpui2::{div, white, ParentElement, Styled, View, VisualContext, WindowContext};
+use gpui2::{div, white, Div, ParentElement, Render, Styled, View, VisualContext, WindowContext};
-pub struct TextStory {
- text: View<()>,
-}
+pub struct TextStory;
impl TextStory {
- pub fn view(cx: &mut WindowContext) -> View<()> {
- cx.build_view(|cx| (), |_, cx| {
- div()
- .size_full()
- .bg(white())
- .child(concat!(
- "The quick brown fox jumps over the lazy dog. ",
- "Meanwhile, the lazy dog decided it was time for a change. ",
- "He started daily workout routines, ate healthier and became the fastest dog in town.",
- ))
- })
+ pub fn view(cx: &mut WindowContext) -> View<Self> {
+ cx.build_view(|cx| Self)
+ }
+}
+
+impl Render for TextStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut gpui2::ViewContext<Self>) -> Self::Element {
+ div().size_full().bg(white()).child(concat!(
+ "The quick brown fox jumps over the lazy dog. ",
+ "Meanwhile, the lazy dog decided it was time for a change. ",
+ "He started daily workout routines, ate healthier and became the fastest dog in town.",
+ ))
}
}
@@ -1,15 +1,16 @@
-use gpui2::{px, rgb, Div, Hsla};
+use gpui2::{px, rgb, Div, Hsla, Render};
use ui::prelude::*;
use crate::story::Story;
/// A reimplementation of the MDN `z-index` example, found here:
/// [https://developer.mozilla.org/en-US/docs/Web/CSS/z-index](https://developer.mozilla.org/en-US/docs/Web/CSS/z-index).
-#[derive(Component)]
pub struct ZIndexStory;
-impl ZIndexStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+impl Render for ZIndexStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title(cx, "z-index"))
.child(
@@ -7,7 +7,7 @@ use clap::builder::PossibleValue;
use clap::ValueEnum;
use gpui2::{AnyView, VisualContext};
use strum::{EnumIter, EnumString, IntoEnumIterator};
-use ui::prelude::*;
+use ui::{prelude::*, AvatarStory, ButtonStory, DetailsStory, IconStory, InputStory, LabelStory};
#[derive(Debug, PartialEq, Eq, Clone, Copy, strum::Display, EnumString, EnumIter)]
#[strum(serialize_all = "snake_case")]
@@ -27,18 +27,16 @@ pub enum ElementStory {
impl ElementStory {
pub fn story(&self, cx: &mut WindowContext) -> AnyView {
match self {
- Self::Avatar => { cx.build_view(|cx| (), |_, _| ui::AvatarStory.render()) }.into_any(),
- Self::Button => { cx.build_view(|cx| (), |_, _| ui::ButtonStory.render()) }.into_any(),
- Self::Details => {
- { cx.build_view(|cx| (), |_, _| ui::DetailsStory.render()) }.into_any()
- }
+ Self::Avatar => cx.build_view(|_| AvatarStory).into_any(),
+ Self::Button => cx.build_view(|_| ButtonStory).into_any(),
+ Self::Details => cx.build_view(|_| DetailsStory).into_any(),
Self::Focus => FocusStory::view(cx).into_any(),
- Self::Icon => { cx.build_view(|cx| (), |_, _| ui::IconStory.render()) }.into_any(),
- Self::Input => { cx.build_view(|cx| (), |_, _| ui::InputStory.render()) }.into_any(),
- Self::Label => { cx.build_view(|cx| (), |_, _| ui::LabelStory.render()) }.into_any(),
+ Self::Icon => cx.build_view(|_| IconStory).into_any(),
+ Self::Input => cx.build_view(|_| InputStory).into_any(),
+ Self::Label => cx.build_view(|_| LabelStory).into_any(),
Self::Scroll => ScrollStory::view(cx).into_any(),
Self::Text => TextStory::view(cx).into_any(),
- Self::ZIndex => { cx.build_view(|cx| (), |_, _| ZIndexStory.render()) }.into_any(),
+ Self::ZIndex => cx.build_view(|_| ZIndexStory).into_any(),
}
}
}
@@ -77,69 +75,31 @@ pub enum ComponentStory {
impl ComponentStory {
pub fn story(&self, cx: &mut WindowContext) -> AnyView {
match self {
- Self::AssistantPanel => {
- { cx.build_view(|cx| (), |_, _| ui::AssistantPanelStory.render()) }.into_any()
- }
- Self::Buffer => { cx.build_view(|cx| (), |_, _| ui::BufferStory.render()) }.into_any(),
- Self::Breadcrumb => {
- { cx.build_view(|cx| (), |_, _| ui::BreadcrumbStory.render()) }.into_any()
- }
- Self::ChatPanel => {
- { cx.build_view(|cx| (), |_, _| ui::ChatPanelStory.render()) }.into_any()
- }
- Self::CollabPanel => {
- { cx.build_view(|cx| (), |_, _| ui::CollabPanelStory.render()) }.into_any()
- }
- Self::CommandPalette => {
- { cx.build_view(|cx| (), |_, _| ui::CommandPaletteStory.render()) }.into_any()
- }
- Self::ContextMenu => {
- { cx.build_view(|cx| (), |_, _| ui::ContextMenuStory.render()) }.into_any()
- }
- Self::Facepile => {
- { cx.build_view(|cx| (), |_, _| ui::FacepileStory.render()) }.into_any()
- }
- Self::Keybinding => {
- { cx.build_view(|cx| (), |_, _| ui::KeybindingStory.render()) }.into_any()
- }
- Self::LanguageSelector => {
- { cx.build_view(|cx| (), |_, _| ui::LanguageSelectorStory.render()) }.into_any()
- }
- Self::MultiBuffer => {
- { cx.build_view(|cx| (), |_, _| ui::MultiBufferStory.render()) }.into_any()
- }
- Self::NotificationsPanel => {
- { cx.build_view(|cx| (), |_, _| ui::NotificationsPanelStory.render()) }.into_any()
- }
- Self::Palette => {
- { cx.build_view(|cx| (), |_, _| ui::PaletteStory.render()) }.into_any()
- }
- Self::Panel => { cx.build_view(|cx| (), |_, _| ui::PanelStory.render()) }.into_any(),
- Self::ProjectPanel => {
- { cx.build_view(|cx| (), |_, _| ui::ProjectPanelStory.render()) }.into_any()
- }
- Self::RecentProjects => {
- { cx.build_view(|cx| (), |_, _| ui::RecentProjectsStory.render()) }.into_any()
- }
- Self::Tab => { cx.build_view(|cx| (), |_, _| ui::TabStory.render()) }.into_any(),
- Self::TabBar => { cx.build_view(|cx| (), |_, _| ui::TabBarStory.render()) }.into_any(),
- Self::Terminal => {
- { cx.build_view(|cx| (), |_, _| ui::TerminalStory.render()) }.into_any()
- }
- Self::ThemeSelector => {
- { cx.build_view(|cx| (), |_, _| ui::ThemeSelectorStory.render()) }.into_any()
- }
+ Self::AssistantPanel => cx.build_view(|_| ui::AssistantPanelStory).into_any(),
+ Self::Buffer => cx.build_view(|_| ui::BufferStory).into_any(),
+ Self::Breadcrumb => cx.build_view(|_| ui::BreadcrumbStory).into_any(),
+ Self::ChatPanel => cx.build_view(|_| ui::ChatPanelStory).into_any(),
+ Self::CollabPanel => cx.build_view(|_| ui::CollabPanelStory).into_any(),
+ Self::CommandPalette => cx.build_view(|_| ui::CommandPaletteStory).into_any(),
+ Self::ContextMenu => cx.build_view(|_| ui::ContextMenuStory).into_any(),
+ Self::Facepile => cx.build_view(|_| ui::FacepileStory).into_any(),
+ Self::Keybinding => cx.build_view(|_| ui::KeybindingStory).into_any(),
+ Self::LanguageSelector => cx.build_view(|_| ui::LanguageSelectorStory).into_any(),
+ Self::MultiBuffer => cx.build_view(|_| ui::MultiBufferStory).into_any(),
+ Self::NotificationsPanel => cx.build_view(|cx| ui::NotificationsPanelStory).into_any(),
+ Self::Palette => cx.build_view(|cx| ui::PaletteStory).into_any(),
+ Self::Panel => cx.build_view(|cx| ui::PanelStory).into_any(),
+ Self::ProjectPanel => cx.build_view(|_| ui::ProjectPanelStory).into_any(),
+ Self::RecentProjects => cx.build_view(|_| ui::RecentProjectsStory).into_any(),
+ Self::Tab => cx.build_view(|_| ui::TabStory).into_any(),
+ Self::TabBar => cx.build_view(|_| ui::TabBarStory).into_any(),
+ Self::Terminal => cx.build_view(|_| ui::TerminalStory).into_any(),
+ Self::ThemeSelector => cx.build_view(|_| ui::ThemeSelectorStory).into_any(),
+ Self::Toast => cx.build_view(|_| ui::ToastStory).into_any(),
+ Self::Toolbar => cx.build_view(|_| ui::ToolbarStory).into_any(),
+ Self::TrafficLights => cx.build_view(|_| ui::TrafficLightsStory).into_any(),
+ Self::Copilot => cx.build_view(|_| ui::CopilotModalStory).into_any(),
Self::TitleBar => ui::TitleBarStory::view(cx).into_any(),
- Self::Toast => { cx.build_view(|cx| (), |_, _| ui::ToastStory.render()) }.into_any(),
- Self::Toolbar => {
- { cx.build_view(|cx| (), |_, _| ui::ToolbarStory.render()) }.into_any()
- }
- Self::TrafficLights => {
- { cx.build_view(|cx| (), |_, _| ui::TrafficLightsStory.render()) }.into_any()
- }
- Self::Copilot => {
- { cx.build_view(|cx| (), |_, _| ui::CopilotModalStory.render()) }.into_any()
- }
Self::Workspace => ui::WorkspaceStory::view(cx).into_any(),
}
}
@@ -9,8 +9,8 @@ use std::sync::Arc;
use clap::Parser;
use gpui2::{
- div, px, size, AnyView, AppContext, Bounds, ViewContext, VisualContext, WindowBounds,
- WindowOptions,
+ div, px, size, AnyView, AppContext, Bounds, Div, Render, ViewContext, VisualContext,
+ WindowBounds, WindowOptions,
};
use log::LevelFilter;
use settings2::{default_settings, Settings, SettingsStore};
@@ -82,12 +82,7 @@ fn main() {
}),
..Default::default()
},
- move |cx| {
- cx.build_view(
- |cx| StoryWrapper::new(selector.story(cx)),
- StoryWrapper::render,
- )
- },
+ move |cx| cx.build_view(|cx| StoryWrapper::new(selector.story(cx))),
);
cx.activate(true);
@@ -103,8 +98,12 @@ impl StoryWrapper {
pub(crate) fn new(story: AnyView) -> Self {
Self { story }
}
+}
+
+impl Render for StoryWrapper {
+ type Element = Div<Self>;
- fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div()
.flex()
.flex_col()
@@ -1,7 +1,6 @@
-use gpui2::{rems, AbsoluteLength};
-
use crate::prelude::*;
use crate::{Icon, IconButton, Label, Panel, PanelSide};
+use gpui2::{rems, AbsoluteLength};
#[derive(Component)]
pub struct AssistantPanel {
@@ -76,15 +75,15 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
-
- #[derive(Component)]
+ use crate::Story;
+ use gpui2::{Div, Render};
pub struct AssistantPanelStory;
- impl AssistantPanelStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for AssistantPanelStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, AssistantPanel>(cx))
.child(Story::label(cx, "Default"))
@@ -73,21 +73,17 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use std::str::FromStr;
-
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::Render;
+ use std::str::FromStr;
- #[derive(Component)]
pub struct BreadcrumbStory;
- impl BreadcrumbStory {
- fn render<V: 'static>(
- self,
- view_state: &mut V,
- cx: &mut ViewContext<V>,
- ) -> impl Component<V> {
+ impl Render for BreadcrumbStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let theme = theme(cx);
Story::container(cx)
@@ -233,20 +233,19 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use gpui2::rems;
-
+ use super::*;
use crate::{
empty_buffer_example, hello_world_rust_buffer_example,
hello_world_rust_buffer_with_status_example, Story,
};
+ use gpui2::{rems, Div, Render};
- use super::*;
-
- #[derive(Component)]
pub struct BufferStory;
- impl BufferStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for BufferStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let theme = theme(cx);
Story::container(cx)
@@ -1,4 +1,4 @@
-use gpui2::{AppContext, Context, View};
+use gpui2::{Div, Render, View, VisualContext};
use crate::prelude::*;
use crate::{h_stack, Icon, IconButton, IconColor, Input};
@@ -21,15 +21,15 @@ impl BufferSearch {
cx.notify();
}
- pub fn view(cx: &mut AppContext) -> View<Self> {
- {
- let state = cx.build_model(|cx| Self::new());
- let render = Self::render;
- View::for_handle(state, render)
- }
+ pub fn view(cx: &mut WindowContext) -> View<Self> {
+ cx.build_view(|cx| Self::new())
}
+}
+
+impl Render for BufferSearch {
+ type Element = Div<Self>;
- fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Div<Self> {
let theme = theme(cx);
h_stack().bg(theme.toolbar).p_2().child(
@@ -108,16 +108,18 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
use chrono::DateTime;
+ use gpui2::{Div, Render};
use crate::{Panel, Story};
use super::*;
- #[derive(Component)]
pub struct ChatPanelStory;
- impl ChatPanelStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for ChatPanelStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, ChatPanel>(cx))
.child(Story::label(cx, "Default"))
@@ -89,15 +89,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct CollabPanelStory;
- impl CollabPanelStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for CollabPanelStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, CollabPanel>(cx))
.child(Story::label(cx, "Default"))
@@ -27,15 +27,18 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
+ use gpui2::{Div, Render};
+
use crate::Story;
use super::*;
- #[derive(Component)]
pub struct CommandPaletteStory;
- impl CommandPaletteStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for CommandPaletteStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, CommandPalette>(cx))
.child(Story::label(cx, "Default"))
@@ -68,15 +68,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::story::Story;
-
use super::*;
+ use crate::story::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct ContextMenuStory;
- impl ContextMenuStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for ContextMenuStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, ContextMenu>(cx))
.child(Story::label(cx, "Default"))
@@ -25,15 +25,18 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
+ use gpui2::{Div, Render};
+
use crate::Story;
use super::*;
- #[derive(Component)]
pub struct CopilotModalStory;
- impl CopilotModalStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for CopilotModalStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, CopilotModal>(cx))
.child(Story::label(cx, "Default"))
@@ -1,6 +1,6 @@
use std::path::PathBuf;
-use gpui2::{AppContext, Context, View};
+use gpui2::{Div, Render, View, VisualContext};
use crate::prelude::*;
use crate::{
@@ -20,7 +20,7 @@ pub struct EditorPane {
impl EditorPane {
pub fn new(
- cx: &mut AppContext,
+ cx: &mut ViewContext<Self>,
tabs: Vec<Tab>,
path: PathBuf,
symbols: Vec<Symbol>,
@@ -42,15 +42,15 @@ impl EditorPane {
cx.notify();
}
- pub fn view(cx: &mut AppContext) -> View<Self> {
- {
- let state = cx.build_model(|cx| hello_world_rust_editor_with_status_example(cx));
- let render = Self::render;
- View::for_handle(state, render)
- }
+ pub fn view(cx: &mut WindowContext) -> View<Self> {
+ cx.build_view(|cx| hello_world_rust_editor_with_status_example(cx))
}
+}
+
+impl Render for EditorPane {
+ type Element = Div<Self>;
- fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Div<Self> {
v_stack()
.w_full()
.h_full()
@@ -31,15 +31,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::{static_players, Story};
-
use super::*;
+ use crate::{static_players, Story};
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct FacepileStory;
- impl FacepileStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for FacepileStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let players = static_players();
Story::container(cx)
@@ -158,17 +158,17 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use itertools::Itertools;
-
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
+ use itertools::Itertools;
- #[derive(Component)]
pub struct KeybindingStory;
- impl KeybindingStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for KeybindingStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let all_modifier_permutations = ModifierKey::iter().permutations(2);
Story::container(cx)
@@ -38,15 +38,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct LanguageSelectorStory;
- impl LanguageSelectorStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for LanguageSelectorStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, LanguageSelector>(cx))
.child(Story::label(cx, "Default"))
@@ -40,15 +40,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::{hello_world_rust_buffer_example, Story};
-
use super::*;
+ use crate::{hello_world_rust_buffer_example, Story};
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct MultiBufferStory;
- impl MultiBufferStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for MultiBufferStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let theme = theme(cx);
Story::container(cx)
@@ -48,15 +48,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::{Panel, Story};
-
use super::*;
+ use crate::{Panel, Story};
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct NotificationsPanelStory;
- impl NotificationsPanelStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for NotificationsPanelStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, NotificationsPanel>(cx))
.child(Story::label(cx, "Default"))
@@ -152,58 +152,71 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
+ use gpui2::{Div, Render};
+
use crate::{ModifierKeys, Story};
use super::*;
- #[derive(Component)]
pub struct PaletteStory;
- impl PaletteStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
- Story::container(cx)
- .child(Story::title_for::<_, Palette>(cx))
- .child(Story::label(cx, "Default"))
- .child(Palette::new("palette-1"))
- .child(Story::label(cx, "With Items"))
- .child(
- Palette::new("palette-2")
- .placeholder("Execute a command...")
- .items(vec![
- PaletteItem::new("theme selector: toggle").keybinding(
- Keybinding::new_chord(
- ("k".to_string(), ModifierKeys::new().command(true)),
- ("t".to_string(), ModifierKeys::new().command(true)),
+ impl Render for PaletteStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+ {
+ Story::container(cx)
+ .child(Story::title_for::<_, Palette>(cx))
+ .child(Story::label(cx, "Default"))
+ .child(Palette::new("palette-1"))
+ .child(Story::label(cx, "With Items"))
+ .child(
+ Palette::new("palette-2")
+ .placeholder("Execute a command...")
+ .items(vec![
+ PaletteItem::new("theme selector: toggle").keybinding(
+ Keybinding::new_chord(
+ ("k".to_string(), ModifierKeys::new().command(true)),
+ ("t".to_string(), ModifierKeys::new().command(true)),
+ ),
+ ),
+ PaletteItem::new("assistant: inline assist").keybinding(
+ Keybinding::new(
+ "enter".to_string(),
+ ModifierKeys::new().command(true),
+ ),
+ ),
+ PaletteItem::new("assistant: quote selection").keybinding(
+ Keybinding::new(
+ ">".to_string(),
+ ModifierKeys::new().command(true),
+ ),
+ ),
+ PaletteItem::new("assistant: toggle focus").keybinding(
+ Keybinding::new(
+ "?".to_string(),
+ ModifierKeys::new().command(true),
+ ),
),
- ),
- PaletteItem::new("assistant: inline assist").keybinding(
- Keybinding::new(
- "enter".to_string(),
- ModifierKeys::new().command(true),
+ PaletteItem::new("auto update: check"),
+ PaletteItem::new("auto update: view release notes"),
+ PaletteItem::new("branches: open recent").keybinding(
+ Keybinding::new(
+ "b".to_string(),
+ ModifierKeys::new().command(true).alt(true),
+ ),
),
- ),
- PaletteItem::new("assistant: quote selection").keybinding(
- Keybinding::new(">".to_string(), ModifierKeys::new().command(true)),
- ),
- PaletteItem::new("assistant: toggle focus").keybinding(
- Keybinding::new("?".to_string(), ModifierKeys::new().command(true)),
- ),
- PaletteItem::new("auto update: check"),
- PaletteItem::new("auto update: view release notes"),
- PaletteItem::new("branches: open recent").keybinding(Keybinding::new(
- "b".to_string(),
- ModifierKeys::new().command(true).alt(true),
- )),
- PaletteItem::new("chat panel: toggle focus"),
- PaletteItem::new("cli: install"),
- PaletteItem::new("client: sign in"),
- PaletteItem::new("client: sign out"),
- PaletteItem::new("editor: cancel").keybinding(Keybinding::new(
- "escape".to_string(),
- ModifierKeys::new(),
- )),
- ]),
- )
+ PaletteItem::new("chat panel: toggle focus"),
+ PaletteItem::new("cli: install"),
+ PaletteItem::new("client: sign in"),
+ PaletteItem::new("client: sign out"),
+ PaletteItem::new("editor: cancel").keybinding(Keybinding::new(
+ "escape".to_string(),
+ ModifierKeys::new(),
+ )),
+ ]),
+ )
+ }
}
}
}
@@ -128,17 +128,18 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::{Label, Story};
-
use super::*;
+ use crate::{Label, Story};
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct PanelStory;
- impl PanelStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for PanelStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
- .child(Story::title_for::<_, Panel<V>>(cx))
+ .child(Story::title_for::<_, Panel<Self>>(cx))
.child(Story::label(cx, "Default"))
.child(
Panel::new("panel", cx).child(
@@ -1,4 +1,4 @@
-use gpui2::{hsla, red, AnyElement, ElementId, ExternalPaths, Hsla, Length, Size};
+use gpui2::{hsla, red, AnyElement, ElementId, ExternalPaths, Hsla, Length, Size, View};
use smallvec::SmallVec;
use crate::prelude::*;
@@ -18,13 +18,6 @@ pub struct Pane<V: 'static> {
children: SmallVec<[AnyElement<V>; 2]>,
}
-// impl<V: 'static> IntoAnyElement<V> for Pane<V> {
-// fn into_any(self) -> AnyElement<V> {
-// (move |view_state: &mut V, cx: &mut ViewContext<'_, '_, V>| self.render(view_state, cx))
-// .into_any()
-// }
-// }
-
impl<V: 'static> Pane<V> {
pub fn new(id: impl Into<ElementId>, size: Size<Length>) -> Self {
// Fill is only here for debugging purposes, remove before release
@@ -57,8 +50,8 @@ impl<V: 'static> Pane<V> {
.z_index(1)
.id("drag-target")
.drag_over::<ExternalPaths>(|d| d.bg(red()))
- .on_drop(|_, files: ExternalPaths, _| {
- dbg!("dropped files!", files);
+ .on_drop(|_, files: View<ExternalPaths>, cx| {
+ dbg!("dropped files!", files.read(cx));
})
.absolute()
.inset_0(),
@@ -57,15 +57,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::{Panel, Story};
-
use super::*;
+ use crate::{Panel, Story};
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct ProjectPanelStory;
- impl ProjectPanelStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for ProjectPanelStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, ProjectPanel>(cx))
.child(Story::label(cx, "Default"))
@@ -34,15 +34,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct RecentProjectsStory;
- impl RecentProjectsStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for RecentProjectsStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, RecentProjects>(cx))
.child(Story::label(cx, "Default"))
@@ -1,5 +1,6 @@
use crate::prelude::*;
use crate::{Icon, IconColor, IconElement, Label, LabelColor};
+use gpui2::{black, red, Div, ElementId, Render, View, VisualContext};
#[derive(Component, Clone)]
pub struct Tab {
@@ -19,6 +20,14 @@ struct TabDragState {
title: String,
}
+impl Render for TabDragState {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+ div().w_8().h_4().bg(red())
+ }
+}
+
impl Tab {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
@@ -118,12 +127,10 @@ impl Tab {
div()
.id(self.id.clone())
- .on_drag(move |_view, _cx| {
- Drag::new(drag_state.clone(), |view, cx| div().w_8().h_4().bg(red()))
- })
+ .on_drag(move |_view, cx| cx.build_view(|cx| drag_state.clone()))
.drag_over::<TabDragState>(|d| d.bg(black()))
- .on_drop(|_view, state: TabDragState, cx| {
- dbg!(state);
+ .on_drop(|_view, state: View<TabDragState>, cx| {
+ dbg!(state.read(cx));
})
.px_2()
.py_0p5()
@@ -160,23 +167,21 @@ impl Tab {
}
}
-use gpui2::{black, red, Drag, ElementId};
#[cfg(feature = "stories")]
pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use strum::IntoEnumIterator;
-
- use crate::{h_stack, v_stack, Icon, Story};
-
use super::*;
+ use crate::{h_stack, v_stack, Icon, Story};
+ use strum::IntoEnumIterator;
- #[derive(Component)]
pub struct TabStory;
- impl TabStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for TabStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let git_statuses = GitStatus::iter();
let fs_statuses = FileSystemStatus::iter();
@@ -92,15 +92,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct TabBarStory;
- impl TabBarStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for TabBarStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, TabBar>(cx))
.child(Story::label(cx, "Default"))
@@ -83,15 +83,15 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
-
- #[derive(Component)]
+ use crate::Story;
+ use gpui2::{Div, Render};
pub struct TerminalStory;
- impl TerminalStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for TerminalStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, Terminal>(cx))
.child(Story::label(cx, "Default"))
@@ -39,15 +39,18 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
+ use gpui2::{Div, Render};
+
use crate::Story;
use super::*;
- #[derive(Component)]
pub struct ThemeSelectorStory;
- impl ThemeSelectorStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for ThemeSelectorStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, ThemeSelector>(cx))
.child(Story::label(cx, "Default"))
@@ -1,7 +1,7 @@
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
-use gpui2::{AppContext, Context, ModelContext, View};
+use gpui2::{Div, Render, View, VisualContext};
use crate::prelude::*;
use crate::settings::user_settings;
@@ -28,7 +28,7 @@ pub struct TitleBar {
}
impl TitleBar {
- pub fn new(cx: &mut ModelContext<Self>) -> Self {
+ pub fn new(cx: &mut ViewContext<Self>) -> Self {
let is_active = Arc::new(AtomicBool::new(true));
let active = is_active.clone();
@@ -80,15 +80,15 @@ impl TitleBar {
cx.notify();
}
- pub fn view(cx: &mut AppContext, livestream: Option<Livestream>) -> View<Self> {
- {
- let state = cx.build_model(|cx| Self::new(cx).set_livestream(livestream));
- let render = Self::render;
- View::for_handle(state, render)
- }
+ pub fn view(cx: &mut WindowContext, livestream: Option<Livestream>) -> View<Self> {
+ cx.build_view(|cx| Self::new(cx).set_livestream(livestream))
}
+}
- fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
+impl Render for TitleBar {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Div<Self> {
let theme = theme(cx);
let settings = user_settings(cx);
@@ -187,26 +187,25 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
pub struct TitleBarStory {
title_bar: View<TitleBar>,
}
impl TitleBarStory {
- pub fn view(cx: &mut AppContext) -> View<Self> {
- {
- let state = cx.build_model(|cx| Self {
- title_bar: TitleBar::view(cx, None),
- });
- let render = Self::render;
- View::for_handle(state, render)
- }
+ pub fn view(cx: &mut WindowContext) -> View<Self> {
+ cx.build_view(|cx| Self {
+ title_bar: TitleBar::view(cx, None),
+ })
}
+ }
+
+ impl Render for TitleBarStory {
+ type Element = Div<Self>;
- fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Div<Self> {
Story::container(cx)
.child(Story::title_for::<_, TitleBar>(cx))
.child(Story::label(cx, "Default"))
@@ -72,17 +72,20 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
+ use gpui2::{Div, Render};
+
use crate::{Label, Story};
use super::*;
- #[derive(Component)]
pub struct ToastStory;
- impl ToastStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for ToastStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
- .child(Story::title_for::<_, Toast<V>>(cx))
+ .child(Story::title_for::<_, Toast<Self>>(cx))
.child(Story::label(cx, "Default"))
.child(Toast::new(ToastOrigin::Bottom).child(Label::new("label")))
}
@@ -75,19 +75,22 @@ mod stories {
use std::path::PathBuf;
use std::str::FromStr;
+ use gpui2::{Div, Render};
+
use crate::{Breadcrumb, HighlightedText, Icon, IconButton, Story, Symbol};
use super::*;
- #[derive(Component)]
pub struct ToolbarStory;
- impl ToolbarStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for ToolbarStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let theme = theme(cx);
Story::container(cx)
- .child(Story::title_for::<_, Toolbar<V>>(cx))
+ .child(Story::title_for::<_, Toolbar<Self>>(cx))
.child(Story::label(cx, "Default"))
.child(
Toolbar::new()
@@ -77,15 +77,18 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
+ use gpui2::{Div, Render};
+
use crate::Story;
use super::*;
- #[derive(Component)]
pub struct TrafficLightsStory;
- impl TrafficLightsStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for TrafficLightsStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, TrafficLights>(cx))
.child(Story::label(cx, "Default"))
@@ -1,7 +1,7 @@
use std::sync::Arc;
use chrono::DateTime;
-use gpui2::{px, relative, rems, AppContext, Context, Size, View};
+use gpui2::{px, relative, rems, Div, Render, Size, View, VisualContext};
use crate::{prelude::*, NotificationsPanel};
use crate::{
@@ -44,7 +44,7 @@ pub struct Workspace {
}
impl Workspace {
- pub fn new(cx: &mut AppContext) -> Self {
+ pub fn new(cx: &mut ViewContext<Self>) -> Self {
Self {
title_bar: TitleBar::view(cx, None),
editor_1: EditorPane::view(cx),
@@ -170,15 +170,15 @@ impl Workspace {
cx.notify();
}
- pub fn view(cx: &mut AppContext) -> View<Self> {
- {
- let state = cx.build_model(|cx| Self::new(cx));
- let render = Self::render;
- View::for_handle(state, render)
- }
+ pub fn view(cx: &mut WindowContext) -> View<Self> {
+ cx.build_view(|cx| Self::new(cx))
}
+}
+
+impl Render for Workspace {
+ type Element = Div<Self>;
- pub fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Div<Self> {
let theme = theme(cx);
// HACK: This should happen inside of `debug_toggle_user_settings`, but
@@ -355,9 +355,8 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use gpui2::VisualContext;
-
use super::*;
+ use gpui2::VisualContext;
pub struct WorkspaceStory {
workspace: View<Workspace>,
@@ -365,12 +364,17 @@ mod stories {
impl WorkspaceStory {
pub fn view(cx: &mut WindowContext) -> View<Self> {
- cx.build_view(
- |cx| Self {
- workspace: Workspace::view(cx),
- },
- |view, cx| view.workspace.clone(),
- )
+ cx.build_view(|cx| Self {
+ workspace: Workspace::view(cx),
+ })
+ }
+ }
+
+ impl Render for WorkspaceStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+ div().child(self.workspace.clone())
}
}
}
@@ -43,15 +43,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct AvatarStory;
- impl AvatarStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for AvatarStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, Avatar>(cx))
.child(Story::label(cx, "Default"))
@@ -219,22 +219,21 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use gpui2::rems;
- use strum::IntoEnumIterator;
-
- use crate::{h_stack, v_stack, LabelColor, Story};
-
use super::*;
+ use crate::{h_stack, v_stack, LabelColor, Story};
+ use gpui2::{rems, Div, Render};
+ use strum::IntoEnumIterator;
- #[derive(Component)]
pub struct ButtonStory;
- impl ButtonStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for ButtonStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let states = InteractionState::iter();
Story::container(cx)
- .child(Story::title_for::<_, Button<V>>(cx))
+ .child(Story::title_for::<_, Button<Self>>(cx))
.child(
div()
.flex()
@@ -46,17 +46,18 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::{Button, Story};
-
use super::*;
+ use crate::{Button, Story};
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct DetailsStory;
- impl DetailsStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for DetailsStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
- .child(Story::title_for::<_, Details<V>>(cx))
+ .child(Story::title_for::<_, Details<Self>>(cx))
.child(Story::label(cx, "Default"))
.child(Details::new("The quick brown fox jumps over the lazy dog"))
.child(Story::label(cx, "With meta"))
@@ -36,7 +36,7 @@ impl IconColor {
IconColor::Error => gpui2::red(),
IconColor::Warning => gpui2::red(),
IconColor::Success => gpui2::red(),
- IconColor::Info => gpui2::red()
+ IconColor::Info => gpui2::red(),
}
}
}
@@ -191,17 +191,19 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
+ use gpui2::{Div, Render};
use strum::IntoEnumIterator;
use crate::Story;
use super::*;
- #[derive(Component)]
pub struct IconStory;
- impl IconStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for IconStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let icons = Icon::iter();
Story::container(cx)
@@ -112,15 +112,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct InputStory;
- impl InputStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for InputStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, Input>(cx))
.child(Story::label(cx, "Default"))
@@ -197,15 +197,16 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
- use crate::Story;
-
use super::*;
+ use crate::Story;
+ use gpui2::{Div, Render};
- #[derive(Component)]
pub struct LabelStory;
- impl LabelStory {
- fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
+ impl Render for LabelStory {
+ type Element = Div<Self>;
+
+ fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
Story::container(cx)
.child(Story::title_for::<_, Label>(cx))
.child(Story::label(cx, "Default"))
@@ -1,7 +1,7 @@
use std::path::PathBuf;
use std::str::FromStr;
-use gpui2::{AppContext, WindowContext};
+use gpui2::ViewContext;
use rand::Rng;
use theme2::Theme;
@@ -628,7 +628,7 @@ pub fn example_editor_actions() -> Vec<PaletteItem> {
]
}
-pub fn empty_editor_example(cx: &mut WindowContext) -> EditorPane {
+pub fn empty_editor_example(cx: &mut ViewContext<EditorPane>) -> EditorPane {
EditorPane::new(
cx,
static_tabs_example(),
@@ -642,7 +642,7 @@ pub fn empty_buffer_example() -> Buffer {
Buffer::new("empty-buffer").set_rows(Some(BufferRows::default()))
}
-pub fn hello_world_rust_editor_example(cx: &mut WindowContext) -> EditorPane {
+pub fn hello_world_rust_editor_example(cx: &mut ViewContext<EditorPane>) -> EditorPane {
let theme = theme(cx);
EditorPane::new(
@@ -781,7 +781,7 @@ pub fn hello_world_rust_buffer_rows(theme: &Theme) -> Vec<BufferRow> {
]
}
-pub fn hello_world_rust_editor_with_status_example(cx: &mut AppContext) -> EditorPane {
+pub fn hello_world_rust_editor_with_status_example(cx: &mut ViewContext<EditorPane>) -> EditorPane {
let theme = theme(cx);
EditorPane::new(