Merge branch 'zed2-render' into zed2

This commit is contained in:
Max Brunsfeld 2023-10-30 15:37:00 -07:00
commit 58446c2715
51 changed files with 669 additions and 665 deletions

View file

@ -1,13 +1,13 @@
use gpui2::px;
use crate::story::Story;
use gpui2::{px, Div, Render};
use ui::prelude::*;
use crate::story::Story;
#[derive(Component)]
pub struct ColorsStory;
impl ColorsStory {
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
impl Render for ColorsStory {
type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let color_scales = theme2::default_color_scales();
Story::container(cx)

View file

@ -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);
})
.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)
.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 parent {:?} {:?}", phase, event)
println!("Key down on child 1 {:?} {:?}", phase, event)
})
.on_key_up(|_, event, phase, _| {
println!("Key up on parent {:?} {:?}", phase, event)
println!("Key up on child 1 {:?} {:?}", 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 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"),
)
}
}

View file

@ -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<_>>();

View file

@ -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>>;
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))
},
)
}))
}))
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. 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))
},
)
}))
}))
}
}

View file

@ -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.",
))
}
}

View file

@ -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(

View file

@ -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")]
@ -28,19 +28,17 @@ 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::Colors => { cx.build_view(|cx| (), |_, _| ColorsStory.render()) }.into_any(),
Self::Details => {
{ cx.build_view(|cx| (), |_, _| ui::DetailsStory.render()) }.into_any()
}
Self::Colors => cx.build_view(|_| ColorsStory).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(),
}
}
}
@ -79,69 +77,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(),
}
}

View file

@ -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 }
}
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {
impl Render for StoryWrapper {
type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
div()
.flex()
.flex_col()