Add View::update which provides a ViewContext

This commit is contained in:
Nathan Sobo 2023-10-26 19:41:42 +02:00
parent 8e3314e680
commit a1c3826858
17 changed files with 403 additions and 247 deletions

View file

@ -1,6 +1,6 @@
use crate::themes::rose_pine;
use gpui2::{
div, view, Context, Focusable, KeyBinding, ParentElement, StatelessInteractive, Styled, View,
div, Focusable, KeyBinding, ParentElement, StatelessInteractive, Styled, View, VisualContext,
WindowContext,
};
use serde::Deserialize;
@ -35,80 +35,83 @@ impl FocusStory {
let color_4 = theme.lowest.accent.default.foreground;
let color_5 = theme.lowest.variant.default.foreground;
let color_6 = theme.highest.negative.default.foreground;
let child_1 = cx.focus_handle();
let child_2 = cx.focus_handle();
view(cx.entity(|cx| ()), 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()
.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"),
)
})
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()
.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"),
)
},
)
}
}

View file

@ -1,4 +1,4 @@
use gpui2::{view, Context, View};
use gpui2::{AppContext, Context, View};
use strum::IntoEnumIterator;
use ui::prelude::*;
@ -12,8 +12,12 @@ impl KitchenSinkStory {
Self {}
}
pub fn view(cx: &mut WindowContext) -> View<Self> {
view(cx.entity(|cx| Self::new()), Self::render)
pub fn view(cx: &mut AppContext) -> View<Self> {
{
let state = cx.entity(|cx| Self::new());
let render = Self::render;
View::for_handle(state, render)
}
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Component<Self> {

View file

@ -1,6 +1,6 @@
use crate::themes::rose_pine;
use gpui2::{
div, px, view, Component, Context, ParentElement, SharedString, Styled, View, WindowContext,
div, px, Component, ParentElement, SharedString, Styled, View, VisualContext, WindowContext,
};
pub struct ScrollStory {
@ -11,7 +11,9 @@ impl ScrollStory {
pub fn view(cx: &mut WindowContext) -> View<()> {
let theme = rose_pine();
view(cx.entity(|cx| ()), move |_, cx| checkerboard(1))
{
cx.build_view(|cx| (), move |_, cx| checkerboard(1))
}
}
}

View file

@ -1,4 +1,4 @@
use gpui2::{div, view, white, Context, ParentElement, Styled, View, WindowContext};
use gpui2::{div, white, ParentElement, Styled, View, VisualContext, WindowContext};
pub struct TextStory {
text: View<()>,
@ -6,7 +6,7 @@ pub struct TextStory {
impl TextStory {
pub fn view(cx: &mut WindowContext) -> View<()> {
view(cx.entity(|cx| ()), |_, cx| {
cx.build_view(|cx| (), |_, cx| {
div()
.size_full()
.bg(white())

View file

@ -5,7 +5,7 @@ use crate::stories::*;
use anyhow::anyhow;
use clap::builder::PossibleValue;
use clap::ValueEnum;
use gpui2::{view, AnyView, Context};
use gpui2::{AnyView, VisualContext};
use strum::{EnumIter, EnumString, IntoEnumIterator};
use ui::prelude::*;
@ -27,16 +27,18 @@ pub enum ElementStory {
impl ElementStory {
pub fn story(&self, cx: &mut WindowContext) -> AnyView {
match self {
Self::Avatar => view(cx.entity(|cx| ()), |_, _| ui::AvatarStory.render()).into_any(),
Self::Button => view(cx.entity(|cx| ()), |_, _| ui::ButtonStory.render()).into_any(),
Self::Details => view(cx.entity(|cx| ()), |_, _| ui::DetailsStory.render()).into_any(),
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::Focus => FocusStory::view(cx).into_any(),
Self::Icon => view(cx.entity(|cx| ()), |_, _| ui::IconStory.render()).into_any(),
Self::Input => view(cx.entity(|cx| ()), |_, _| ui::InputStory.render()).into_any(),
Self::Label => view(cx.entity(|cx| ()), |_, _| ui::LabelStory.render()).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::Scroll => ScrollStory::view(cx).into_any(),
Self::Text => TextStory::view(cx).into_any(),
Self::ZIndex => view(cx.entity(|cx| ()), |_, _| ZIndexStory.render()).into_any(),
Self::ZIndex => { cx.build_view(|cx| (), |_, _| ZIndexStory.render()) }.into_any(),
}
}
}
@ -76,65 +78,67 @@ impl ComponentStory {
pub fn story(&self, cx: &mut WindowContext) -> AnyView {
match self {
Self::AssistantPanel => {
view(cx.entity(|cx| ()), |_, _| ui::AssistantPanelStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::AssistantPanelStory.render()) }.into_any()
}
Self::Buffer => view(cx.entity(|cx| ()), |_, _| ui::BufferStory.render()).into_any(),
Self::Buffer => { cx.build_view(|cx| (), |_, _| ui::BufferStory.render()) }.into_any(),
Self::Breadcrumb => {
view(cx.entity(|cx| ()), |_, _| ui::BreadcrumbStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::BreadcrumbStory.render()) }.into_any()
}
Self::ChatPanel => {
view(cx.entity(|cx| ()), |_, _| ui::ChatPanelStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::ChatPanelStory.render()) }.into_any()
}
Self::CollabPanel => {
view(cx.entity(|cx| ()), |_, _| ui::CollabPanelStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::CollabPanelStory.render()) }.into_any()
}
Self::CommandPalette => {
view(cx.entity(|cx| ()), |_, _| ui::CommandPaletteStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::CommandPaletteStory.render()) }.into_any()
}
Self::ContextMenu => {
view(cx.entity(|cx| ()), |_, _| ui::ContextMenuStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::ContextMenuStory.render()) }.into_any()
}
Self::Facepile => {
view(cx.entity(|cx| ()), |_, _| ui::FacepileStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::FacepileStory.render()) }.into_any()
}
Self::Keybinding => {
view(cx.entity(|cx| ()), |_, _| ui::KeybindingStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::KeybindingStory.render()) }.into_any()
}
Self::LanguageSelector => {
{ cx.build_view(|cx| (), |_, _| ui::LanguageSelectorStory.render()) }.into_any()
}
Self::LanguageSelector => view(cx.entity(|cx| ()), |_, _| {
ui::LanguageSelectorStory.render()
})
.into_any(),
Self::MultiBuffer => {
view(cx.entity(|cx| ()), |_, _| ui::MultiBufferStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::MultiBufferStory.render()) }.into_any()
}
Self::NotificationsPanel => view(cx.entity(|cx| ()), |_, _| {
ui::NotificationsPanelStory.render()
})
.into_any(),
Self::Palette => view(cx.entity(|cx| ()), |_, _| ui::PaletteStory.render()).into_any(),
Self::Panel => view(cx.entity(|cx| ()), |_, _| ui::PanelStory.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 => {
view(cx.entity(|cx| ()), |_, _| ui::ProjectPanelStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::ProjectPanelStory.render()) }.into_any()
}
Self::RecentProjects => {
view(cx.entity(|cx| ()), |_, _| ui::RecentProjectsStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::RecentProjectsStory.render()) }.into_any()
}
Self::Tab => view(cx.entity(|cx| ()), |_, _| ui::TabStory.render()).into_any(),
Self::TabBar => view(cx.entity(|cx| ()), |_, _| ui::TabBarStory.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 => {
view(cx.entity(|cx| ()), |_, _| ui::TerminalStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::TerminalStory.render()) }.into_any()
}
Self::ThemeSelector => {
view(cx.entity(|cx| ()), |_, _| ui::ThemeSelectorStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::ThemeSelectorStory.render()) }.into_any()
}
Self::TitleBar => ui::TitleBarStory::view(cx).into_any(),
Self::Toast => view(cx.entity(|cx| ()), |_, _| ui::ToastStory.render()).into_any(),
Self::Toolbar => view(cx.entity(|cx| ()), |_, _| ui::ToolbarStory.render()).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 => {
view(cx.entity(|cx| ()), |_, _| ui::TrafficLightsStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::TrafficLightsStory.render()) }.into_any()
}
Self::Copilot => {
view(cx.entity(|cx| ()), |_, _| ui::CopilotModalStory.render()).into_any()
{ cx.build_view(|cx| (), |_, _| ui::CopilotModalStory.render()) }.into_any()
}
Self::Workspace => ui::WorkspaceStory::view(cx).into_any(),
}

View file

@ -10,7 +10,7 @@ use std::sync::Arc;
use clap::Parser;
use gpui2::{
div, px, size, view, AnyView, AppContext, Bounds, Context, ViewContext, WindowBounds,
div, px, size, AnyView, AppContext, Bounds, ViewContext, VisualContext, WindowBounds,
WindowOptions,
};
use log::LevelFilter;
@ -85,8 +85,8 @@ fn main() {
..Default::default()
},
move |cx| {
view(
cx.entity(|cx| StoryWrapper::new(selector.story(cx), theme)),
cx.build_view(
|cx| StoryWrapper::new(selector.story(cx), theme),
StoryWrapper::render,
)
},