Checkpoint

Nathan Sobo created

Change summary

Cargo.lock                                    |  25 +
Cargo.toml                                    |   1 
crates/storybook/Cargo.toml                   |   3 
crates/storybook/src/gpui3/app.rs             | 200 ------------
crates/storybook/src/gpui3/color.rs           | 190 ------------
crates/storybook/src/gpui3/element.rs         | 275 -----------------
crates/storybook/src/gpui3/elements.rs        |   8 
crates/storybook/src/gpui3/elements/div.rs    |  38 --
crates/storybook/src/gpui3/elements/editor.rs |  61 ---
crates/storybook/src/gpui3/geometry.rs        | 325 ---------------------
crates/storybook/src/gpui3/mod.rs             | 101 ------
crates/storybook/src/gpui3/platform.rs        |  58 ---
crates/storybook/src/gpui3/platform/test.rs   |   0 
crates/storybook/src/gpui3/renderer.rs        | 164 ----------
crates/storybook/src/gpui3/scene.rs           | 111 -------
crates/storybook/src/gpui3/shader.frag.wgsl   |   1 
crates/storybook/src/gpui3/shader.vert.wgsl   |   0 
crates/storybook/src/gpui3/style.rs           | 245 ---------------
crates/storybook/src/gpui3/taffy.rs           | 238 ---------------
crates/storybook/src/gpui3/window.rs          | 231 --------------
crates/storybook/src/storybook.rs             |   1 
21 files changed, 29 insertions(+), 2,247 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -3340,6 +3340,31 @@ dependencies = [
  "syn 1.0.109",
 ]
 
+[[package]]
+name = "gpui3"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "bytemuck",
+ "derive_more",
+ "font-kit",
+ "itertools 0.11.0",
+ "log",
+ "parking_lot 0.11.2",
+ "plane-split",
+ "raw-window-handle",
+ "refineable",
+ "rust-embed",
+ "schemars",
+ "serde",
+ "simplelog",
+ "slotmap",
+ "smallvec",
+ "taffy",
+ "util",
+ "wgpu",
+]
+
 [[package]]
 name = "gpui_macros"
 version = "0.1.0"

Cargo.toml 🔗

@@ -35,6 +35,7 @@ members = [
     "crates/gpui_macros",
     "crates/gpui2",
     "crates/gpui2_macros",
+    "crates/gpui3",
     "crates/install_cli",
     "crates/journal",
     "crates/language",

crates/storybook/Cargo.toml 🔗

@@ -8,6 +8,9 @@ publish = false
 name = "storybook"
 path = "src/storybook.rs"
 
+[features]
+test-support = []
+
 [dependencies]
 anyhow.workspace = true
 bytemuck = "1.14.0"

crates/storybook/src/gpui3/app.rs 🔗

@@ -1,200 +0,0 @@
-use anyhow::{anyhow, Result};
-use slotmap::SlotMap;
-use std::{any::Any, marker::PhantomData, rc::Rc};
-
-use super::{
-    platform::Platform,
-    window::{Window, WindowHandle, WindowId},
-    Context, LayoutId, Reference, View, WindowContext,
-};
-
-pub struct AppContext {
-    platform: Rc<dyn Platform>,
-    pub(crate) entities: SlotMap<EntityId, Option<Box<dyn Any>>>,
-    pub(crate) windows: SlotMap<WindowId, Option<Window>>,
-    // We recycle this memory across layout requests.
-    pub(crate) layout_id_buffer: Vec<LayoutId>,
-}
-
-impl AppContext {
-    pub fn new(platform: Rc<dyn Platform>) -> Self {
-        AppContext {
-            platform,
-            entities: SlotMap::with_key(),
-            windows: SlotMap::with_key(),
-            layout_id_buffer: Default::default(),
-        }
-    }
-
-    pub fn test() -> Self {
-        Self::new(TestPlatform::new())
-    }
-
-    pub fn open_window<S: 'static>(
-        &mut self,
-        build_root_view: impl FnOnce(&mut WindowContext) -> View<S>,
-    ) -> WindowHandle<S> {
-        let id = self.windows.insert(None);
-
-        let mut window = Window::new(id);
-        let root_view = build_root_view(&mut WindowContext::mutable(self, &mut window));
-        window.root_view.replace(Box::new(root_view));
-
-        self.windows.get_mut(id).unwrap().replace(window);
-        WindowHandle::new(id)
-    }
-
-    pub(crate) fn update_window<R>(
-        &mut self,
-        window_id: WindowId,
-        update: impl FnOnce(&mut WindowContext) -> R,
-    ) -> Result<R> {
-        let mut window = self
-            .windows
-            .get_mut(window_id)
-            .ok_or_else(|| anyhow!("window not found"))?
-            .take()
-            .unwrap();
-
-        let result = update(&mut WindowContext::mutable(self, &mut window));
-
-        self.windows
-            .get_mut(window_id)
-            .ok_or_else(|| anyhow!("window not found"))?
-            .replace(window);
-
-        Ok(result)
-    }
-}
-
-impl Context for AppContext {
-    type EntityContext<'a, 'w, T: 'static> = ModelContext<'a, T>;
-
-    fn entity<T: 'static>(
-        &mut self,
-        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
-    ) -> Handle<T> {
-        let id = self.entities.insert(None);
-        let entity = Box::new(build_entity(&mut ModelContext::mutable(self, id)));
-        self.entities.get_mut(id).unwrap().replace(entity);
-
-        Handle::new(id)
-    }
-
-    fn update_entity<T: 'static, R>(
-        &mut self,
-        handle: &Handle<T>,
-        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
-    ) -> R {
-        let mut entity = self
-            .entities
-            .get_mut(handle.id)
-            .unwrap()
-            .take()
-            .unwrap()
-            .downcast::<T>()
-            .unwrap();
-
-        let result = update(&mut *entity, &mut ModelContext::mutable(self, handle.id));
-        self.entities.get_mut(handle.id).unwrap().replace(entity);
-        result
-    }
-}
-
-pub struct ModelContext<'a, T> {
-    app: Reference<'a, AppContext>,
-    entity_type: PhantomData<T>,
-    entity_id: EntityId,
-}
-
-impl<'a, T: 'static> ModelContext<'a, T> {
-    pub(crate) fn mutable(app: &'a mut AppContext, entity_id: EntityId) -> Self {
-        Self {
-            app: Reference::Mutable(app),
-            entity_type: PhantomData,
-            entity_id,
-        }
-    }
-
-    fn immutable(app: &'a AppContext, entity_id: EntityId) -> Self {
-        Self {
-            app: Reference::Immutable(app),
-            entity_type: PhantomData,
-            entity_id,
-        }
-    }
-
-    fn update<R>(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R {
-        let mut entity = self
-            .app
-            .entities
-            .get_mut(self.entity_id)
-            .unwrap()
-            .take()
-            .unwrap();
-        let result = update(entity.downcast_mut::<T>().unwrap(), self);
-        self.app
-            .entities
-            .get_mut(self.entity_id)
-            .unwrap()
-            .replace(entity);
-        result
-    }
-}
-
-impl<'a, T: 'static> Context for ModelContext<'a, T> {
-    type EntityContext<'b, 'c, U: 'static> = ModelContext<'b, U>;
-
-    fn entity<U: 'static>(
-        &mut self,
-        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, U>) -> U,
-    ) -> Handle<U> {
-        self.app.entity(build_entity)
-    }
-
-    fn update_entity<U: 'static, R>(
-        &mut self,
-        handle: &Handle<U>,
-        update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
-    ) -> R {
-        self.app.update_entity(handle, update)
-    }
-}
-
-pub struct Handle<T> {
-    pub(crate) id: EntityId,
-    pub(crate) entity_type: PhantomData<T>,
-}
-
-slotmap::new_key_type! { pub struct EntityId; }
-
-impl<T: 'static> Handle<T> {
-    fn new(id: EntityId) -> Self {
-        Self {
-            id,
-            entity_type: PhantomData,
-        }
-    }
-
-    /// Update the entity referenced by this handle with the given function.
-    ///
-    /// The update function receives a context appropriate for its environment.
-    /// When updating in an `AppContext`, it receives a `ModelContext`.
-    /// When updating an a `WindowContext`, it receives a `ViewContext`.
-    pub fn update<C: Context, R>(
-        &self,
-        cx: &mut C,
-        update: impl FnOnce(&mut T, &mut C::EntityContext<'_, '_, T>) -> R,
-    ) -> R {
-        cx.update_entity(self, update)
-    }
-}
-
-impl<T> Clone for Handle<T> {
-    fn clone(&self) -> Self {
-        Self {
-            id: self.id,
-            entity_type: PhantomData,
-        }
-    }
-}

crates/storybook/src/gpui3/color.rs 🔗

@@ -1,190 +0,0 @@
-#![allow(dead_code)]
-
-use bytemuck::{Pod, Zeroable};
-use serde::de::{self, Deserialize, Deserializer, Visitor};
-use std::fmt;
-use std::num::ParseIntError;
-
-pub fn rgb<C: From<Rgba>>(hex: u32) -> C {
-    let r = ((hex >> 16) & 0xFF) as f32 / 255.0;
-    let g = ((hex >> 8) & 0xFF) as f32 / 255.0;
-    let b = (hex & 0xFF) as f32 / 255.0;
-    Rgba { r, g, b, a: 1.0 }.into()
-}
-
-#[derive(Clone, Copy, Default, Debug)]
-pub struct Rgba {
-    pub r: f32,
-    pub g: f32,
-    pub b: f32,
-    pub a: f32,
-}
-
-struct RgbaVisitor;
-
-impl<'de> Visitor<'de> for RgbaVisitor {
-    type Value = Rgba;
-
-    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-        formatter.write_str("a string in the format #rrggbb or #rrggbbaa")
-    }
-
-    fn visit_str<E: de::Error>(self, value: &str) -> Result<Rgba, E> {
-        if value.len() == 7 || value.len() == 9 {
-            let r = u8::from_str_radix(&value[1..3], 16).unwrap() as f32 / 255.0;
-            let g = u8::from_str_radix(&value[3..5], 16).unwrap() as f32 / 255.0;
-            let b = u8::from_str_radix(&value[5..7], 16).unwrap() as f32 / 255.0;
-            let a = if value.len() == 9 {
-                u8::from_str_radix(&value[7..9], 16).unwrap() as f32 / 255.0
-            } else {
-                1.0
-            };
-            Ok(Rgba { r, g, b, a })
-        } else {
-            Err(E::custom(
-                "Bad format for RGBA. Expected #rrggbb or #rrggbbaa.",
-            ))
-        }
-    }
-}
-
-impl<'de> Deserialize<'de> for Rgba {
-    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
-        deserializer.deserialize_str(RgbaVisitor)
-    }
-}
-
-impl From<Hsla> for Rgba {
-    fn from(color: Hsla) -> Self {
-        let h = color.h;
-        let s = color.s;
-        let l = color.l;
-
-        let c = (1.0 - (2.0 * l - 1.0).abs()) * s;
-        let x = c * (1.0 - ((h * 6.0) % 2.0 - 1.0).abs());
-        let m = l - c / 2.0;
-        let cm = c + m;
-        let xm = x + m;
-
-        let (r, g, b) = match (h * 6.0).floor() as i32 {
-            0 | 6 => (cm, xm, m),
-            1 => (xm, cm, m),
-            2 => (m, cm, xm),
-            3 => (m, xm, cm),
-            4 => (xm, m, cm),
-            _ => (cm, m, xm),
-        };
-
-        Rgba {
-            r,
-            g,
-            b,
-            a: color.a,
-        }
-    }
-}
-
-impl TryFrom<&'_ str> for Rgba {
-    type Error = ParseIntError;
-
-    fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
-        let r = u8::from_str_radix(&value[1..3], 16)? as f32 / 255.0;
-        let g = u8::from_str_radix(&value[3..5], 16)? as f32 / 255.0;
-        let b = u8::from_str_radix(&value[5..7], 16)? as f32 / 255.0;
-        let a = if value.len() > 7 {
-            u8::from_str_radix(&value[7..9], 16)? as f32 / 255.0
-        } else {
-            1.0
-        };
-
-        Ok(Rgba { r, g, b, a })
-    }
-}
-
-#[derive(Default, Copy, Clone, Debug, PartialEq)]
-#[repr(C)]
-pub struct Hsla {
-    pub h: f32,
-    pub s: f32,
-    pub l: f32,
-    pub a: f32,
-}
-
-unsafe impl Zeroable for Hsla {}
-unsafe impl Pod for Hsla {}
-
-pub fn hsla(h: f32, s: f32, l: f32, a: f32) -> Hsla {
-    Hsla {
-        h: h.clamp(0., 1.),
-        s: s.clamp(0., 1.),
-        l: l.clamp(0., 1.),
-        a: a.clamp(0., 1.),
-    }
-}
-
-pub fn black() -> Hsla {
-    Hsla {
-        h: 0.,
-        s: 0.,
-        l: 0.,
-        a: 1.,
-    }
-}
-
-impl Hsla {
-    /// Returns true if the HSLA color is fully transparent, false otherwise.
-    pub fn is_transparent(&self) -> bool {
-        self.a == 0.0
-    }
-}
-
-impl From<Rgba> for Hsla {
-    fn from(color: Rgba) -> Self {
-        let r = color.r;
-        let g = color.g;
-        let b = color.b;
-
-        let max = r.max(g.max(b));
-        let min = r.min(g.min(b));
-        let delta = max - min;
-
-        let l = (max + min) / 2.0;
-        let s = if l == 0.0 || l == 1.0 {
-            0.0
-        } else if l < 0.5 {
-            delta / (2.0 * l)
-        } else {
-            delta / (2.0 - 2.0 * l)
-        };
-
-        let h = if delta == 0.0 {
-            0.0
-        } else if max == r {
-            ((g - b) / delta).rem_euclid(6.0) / 6.0
-        } else if max == g {
-            ((b - r) / delta + 2.0) / 6.0
-        } else {
-            ((r - g) / delta + 4.0) / 6.0
-        };
-
-        Hsla {
-            h,
-            s,
-            l,
-            a: color.a,
-        }
-    }
-}
-
-impl<'de> Deserialize<'de> for Hsla {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        // First, deserialize it into Rgba
-        let rgba = Rgba::deserialize(deserializer)?;
-
-        // Then, use the From<Rgba> for Hsla implementation to convert it
-        Ok(Hsla::from(rgba))
-    }
-}

crates/storybook/src/gpui3/element.rs 🔗

@@ -1,275 +0,0 @@
-use super::{Handle, Layout, LayoutId, Pixels, Point, Result, ViewContext, WindowContext};
-use std::{any::Any, cell::RefCell, marker::PhantomData, rc::Rc};
-
-pub trait Element: 'static {
-    type State;
-    type FrameState;
-
-    fn layout(
-        &mut self,
-        state: &mut Self::State,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<(LayoutId, Self::FrameState)>;
-
-    fn paint(
-        &mut self,
-        layout: Layout,
-        state: &mut Self::State,
-        frame_state: &mut Self::FrameState,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<()>;
-}
-
-pub trait ParentElement<S> {
-    fn child(self, child: impl IntoAnyElement<S>) -> Self;
-}
-
-trait ElementObject<S> {
-    fn layout(&mut self, state: &mut S, cx: &mut ViewContext<S>) -> Result<LayoutId>;
-    fn paint(
-        &mut self,
-        parent_origin: super::Point<Pixels>,
-        state: &mut S,
-        cx: &mut ViewContext<S>,
-    ) -> Result<()>;
-}
-
-struct RenderedElement<E: Element> {
-    element: E,
-    phase: ElementRenderPhase<E::FrameState>,
-}
-
-#[derive(Default)]
-enum ElementRenderPhase<S> {
-    #[default]
-    Rendered,
-    LayoutRequested {
-        layout_id: LayoutId,
-        frame_state: S,
-    },
-    Painted {
-        layout: Layout,
-        frame_state: S,
-    },
-}
-
-/// Internal struct that wraps an element to store Layout and FrameState after the element is rendered.
-/// It's allocated as a trait object to erase the element type and wrapped in AnyElement<E::State> for
-/// improved usability.
-impl<E: Element> RenderedElement<E> {
-    fn new(element: E) -> Self {
-        RenderedElement {
-            element,
-            phase: ElementRenderPhase::Rendered,
-        }
-    }
-}
-
-impl<E: Element> ElementObject<E::State> for RenderedElement<E> {
-    fn layout(&mut self, state: &mut E::State, cx: &mut ViewContext<E::State>) -> Result<LayoutId> {
-        let (layout_id, frame_state) = self.element.layout(state, cx)?;
-        self.phase = ElementRenderPhase::LayoutRequested {
-            layout_id,
-            frame_state,
-        };
-        Ok(layout_id)
-    }
-
-    fn paint(
-        &mut self,
-        parent_origin: Point<Pixels>,
-        state: &mut E::State,
-        cx: &mut ViewContext<E::State>,
-    ) -> Result<()> {
-        self.phase = match std::mem::take(&mut self.phase) {
-            ElementRenderPhase::Rendered => panic!("must call layout before paint"),
-
-            ElementRenderPhase::LayoutRequested {
-                layout_id,
-                mut frame_state,
-            } => {
-                let mut layout = cx.layout(layout_id)?;
-                layout.bounds.origin += parent_origin;
-                self.element
-                    .paint(layout.clone(), state, &mut frame_state, cx)?;
-                ElementRenderPhase::Painted {
-                    layout,
-                    frame_state,
-                }
-            }
-
-            ElementRenderPhase::Painted {
-                layout,
-                mut frame_state,
-            } => {
-                self.element
-                    .paint(layout.clone(), state, &mut frame_state, cx)?;
-                ElementRenderPhase::Painted {
-                    layout,
-                    frame_state,
-                }
-            }
-        };
-
-        Ok(())
-    }
-}
-
-pub struct AnyElement<S>(Box<dyn ElementObject<S>>);
-
-impl<S> AnyElement<S> {
-    pub fn layout(&mut self, state: &mut S, cx: &mut ViewContext<S>) -> Result<LayoutId> {
-        self.0.layout(state, cx)
-    }
-
-    pub fn paint(
-        &mut self,
-        parent_origin: Point<Pixels>,
-        state: &mut S,
-        cx: &mut ViewContext<S>,
-    ) -> Result<()> {
-        self.0.paint(parent_origin, state, cx)
-    }
-}
-
-pub trait IntoAnyElement<S> {
-    fn into_any(self) -> AnyElement<S>;
-}
-
-impl<E: Element> IntoAnyElement<E::State> for E {
-    fn into_any(self) -> AnyElement<E::State> {
-        AnyElement(Box::new(RenderedElement::new(self)))
-    }
-}
-
-impl<S> IntoAnyElement<S> for AnyElement<S> {
-    fn into_any(self) -> AnyElement<S> {
-        self
-    }
-}
-
-#[derive(Clone)]
-pub struct View<S> {
-    state: Handle<S>,
-    render: Rc<dyn Fn(&mut S, &mut ViewContext<S>) -> AnyElement<S>>,
-}
-
-pub fn view<S: 'static, E: Element<State = S>>(
-    state: Handle<S>,
-    render: impl 'static + Fn(&mut S, &mut ViewContext<S>) -> E,
-) -> View<S> {
-    View {
-        state,
-        render: Rc::new(move |state, cx| render(state, cx).into_any()),
-    }
-}
-
-impl<S: 'static> View<S> {
-    pub fn into_any<ParentState>(self) -> AnyView<ParentState> {
-        AnyView {
-            view: Rc::new(RefCell::new(self)),
-            parent_state_type: PhantomData,
-        }
-    }
-}
-
-impl<S: 'static> Element for View<S> {
-    type State = ();
-    type FrameState = AnyElement<S>;
-
-    fn layout(
-        &mut self,
-        _: &mut Self::State,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<(LayoutId, Self::FrameState)> {
-        self.state.update(cx, |state, cx| {
-            let mut element = (self.render)(state, cx);
-            let layout_id = element.layout(state, cx)?;
-            Ok((layout_id, element))
-        })
-    }
-
-    fn paint(
-        &mut self,
-        layout: Layout,
-        _: &mut Self::State,
-        element: &mut Self::FrameState,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<()> {
-        self.state.update(cx, |state, cx| {
-            element.paint(layout.bounds.origin, state, cx)
-        })
-    }
-}
-
-trait ViewObject {
-    fn layout(&mut self, cx: &mut WindowContext) -> Result<(LayoutId, Box<dyn Any>)>;
-    fn paint(
-        &mut self,
-        layout: Layout,
-        element: &mut dyn Any,
-        cx: &mut WindowContext,
-    ) -> Result<()>;
-}
-
-impl<S: 'static> ViewObject for View<S> {
-    fn layout(&mut self, cx: &mut WindowContext) -> Result<(LayoutId, Box<dyn Any>)> {
-        self.state.update(cx, |state, cx| {
-            let mut element = (self.render)(state, cx);
-            let layout_id = element.layout(state, cx)?;
-            let element = Box::new(element) as Box<dyn Any>;
-            Ok((layout_id, element))
-        })
-    }
-
-    fn paint(
-        &mut self,
-        layout: Layout,
-        element: &mut dyn Any,
-        cx: &mut WindowContext,
-    ) -> Result<()> {
-        self.state.update(cx, |state, cx| {
-            element
-                .downcast_mut::<AnyElement<S>>()
-                .unwrap()
-                .paint(layout.bounds.origin, state, cx)
-        })
-    }
-}
-
-pub struct AnyView<S> {
-    view: Rc<RefCell<dyn ViewObject>>,
-    parent_state_type: PhantomData<S>,
-}
-
-impl<S: 'static> Element for AnyView<S> {
-    type State = S;
-    type FrameState = Box<dyn Any>;
-
-    fn layout(
-        &mut self,
-        _: &mut Self::State,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<(LayoutId, Self::FrameState)> {
-        self.view.borrow_mut().layout(cx)
-    }
-
-    fn paint(
-        &mut self,
-        layout: Layout,
-        _: &mut Self::State,
-        element: &mut Self::FrameState,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<()> {
-        self.view.borrow_mut().paint(layout, element, cx)
-    }
-}
-
-impl<S> Clone for AnyView<S> {
-    fn clone(&self) -> Self {
-        Self {
-            view: self.view.clone(),
-            parent_state_type: PhantomData,
-        }
-    }
-}

crates/storybook/src/gpui3/elements/div.rs 🔗

@@ -1,38 +0,0 @@
-use super::{
-    Element, IntoAnyElement, Layout, LayoutId, ParentElement, PhantomData, Result, ViewContext,
-};
-
-pub struct Div<S>(PhantomData<S>);
-
-impl<S: 'static> Element for Div<S> {
-    type State = S;
-    type FrameState = ();
-
-    fn layout(
-        &mut self,
-        state: &mut Self::State,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<(LayoutId, Self::FrameState)> {
-        todo!()
-    }
-
-    fn paint(
-        &mut self,
-        layout: Layout,
-        state: &mut Self::State,
-        frame_state: &mut Self::FrameState,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<()> {
-        todo!()
-    }
-}
-
-impl<S> ParentElement<S> for Div<S> {
-    fn child(self, child: impl IntoAnyElement<S>) -> Self {
-        todo!()
-    }
-}
-
-pub fn div<S>() -> Div<S> {
-    todo!()
-}

crates/storybook/src/gpui3/elements/editor.rs 🔗

@@ -1,61 +0,0 @@
-use super::{Element, Handle, Layout, LayoutId, Result, SharedString, ViewContext};
-use std::marker::PhantomData;
-
-pub fn field<S>(editor: Handle<Editor>) -> EditorElement<S> {
-    EditorElement {
-        editor,
-        field: true,
-        placeholder_text: None,
-        parent_state: PhantomData,
-    }
-}
-
-pub struct EditorElement<S> {
-    editor: Handle<Editor>,
-    field: bool,
-    placeholder_text: Option<SharedString>,
-    parent_state: PhantomData<S>,
-}
-
-impl<S> EditorElement<S> {
-    pub fn field(mut self) -> Self {
-        self.field = true;
-        self
-    }
-
-    pub fn placeholder_text(mut self, text: impl Into<SharedString>) -> Self {
-        self.placeholder_text = Some(text.into());
-        self
-    }
-}
-
-impl<S: 'static> Element for EditorElement<S> {
-    type State = S;
-    type FrameState = ();
-
-    fn layout(
-        &mut self,
-        _: &mut Self::State,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<(LayoutId, Self::FrameState)> {
-        self.editor.update(cx, |editor, cx| todo!())
-    }
-
-    fn paint(
-        &mut self,
-        layout: Layout,
-        state: &mut Self::State,
-        frame_state: &mut Self::FrameState,
-        cx: &mut ViewContext<Self::State>,
-    ) -> Result<()> {
-        self.editor.update(cx, |editor, cx| todo!())
-    }
-}
-
-pub struct Editor {}
-
-impl Editor {
-    pub fn new(_: &mut ViewContext<Self>) -> Self {
-        Editor {}
-    }
-}

crates/storybook/src/gpui3/geometry.rs 🔗

@@ -1,325 +0,0 @@
-use bytemuck::{Pod, Zeroable};
-use core::fmt::Debug;
-use derive_more::{Add, AddAssign, Div, Mul, Sub};
-use refineable::Refineable;
-use std::ops::Mul;
-
-#[derive(Refineable, Default, Add, AddAssign, Sub, Mul, Div, Copy, Debug, PartialEq, Eq, Hash)]
-#[refineable(debug)]
-#[repr(C)]
-pub struct Point<T: Clone + Debug> {
-    pub x: T,
-    pub y: T,
-}
-
-impl<T: Clone + Debug> Point<T> {
-    pub fn new(x: T, y: T) -> Self {
-        Self { x, y }
-    }
-}
-
-impl<T: Clone + Debug> Clone for Point<T> {
-    fn clone(&self) -> Self {
-        Self {
-            x: self.x.clone(),
-            y: self.y.clone(),
-        }
-    }
-}
-
-unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Point<T> {}
-
-unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Point<T> {}
-
-#[derive(Refineable, Default, Clone, Copy, Debug, PartialEq)]
-#[refineable(debug)]
-pub struct Size<T: Clone + Debug> {
-    pub width: T,
-    pub height: T,
-}
-
-impl Size<Length> {
-    pub fn full() -> Self {
-        Self {
-            width: relative(1.),
-            height: relative(1.),
-        }
-    }
-}
-
-impl Size<DefiniteLength> {
-    pub fn zero() -> Self {
-        Self {
-            width: px(0.),
-            height: px(0.),
-        }
-    }
-}
-
-impl Size<Length> {
-    pub fn auto() -> Self {
-        Self {
-            width: Length::Auto,
-            height: Length::Auto,
-        }
-    }
-}
-
-#[derive(Refineable, Clone, Default, Debug, PartialEq)]
-#[refineable(debug)]
-pub struct Bounds<T: Clone + Debug> {
-    pub origin: Point<T>,
-    pub size: Size<T>,
-}
-
-impl<T: Clone + Debug + Copy> Copy for Bounds<T> {}
-
-#[derive(Refineable, Clone, Default, Debug)]
-#[refineable(debug)]
-pub struct Edges<T: Clone + Debug> {
-    pub top: T,
-    pub right: T,
-    pub bottom: T,
-    pub left: T,
-}
-
-impl Edges<Length> {
-    pub fn auto() -> Self {
-        Self {
-            top: Length::Auto,
-            right: Length::Auto,
-            bottom: Length::Auto,
-            left: Length::Auto,
-        }
-    }
-
-    pub fn zero() -> Self {
-        Self {
-            top: px(0.),
-            right: px(0.),
-            bottom: px(0.),
-            left: px(0.),
-        }
-    }
-}
-
-impl Edges<DefiniteLength> {
-    pub fn zero() -> Self {
-        Self {
-            top: px(0.),
-            right: px(0.),
-            bottom: px(0.),
-            left: px(0.),
-        }
-    }
-}
-
-impl Edges<AbsoluteLength> {
-    pub fn zero() -> Self {
-        Self {
-            top: px(0.),
-            right: px(0.),
-            bottom: px(0.),
-            left: px(0.),
-        }
-    }
-
-    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
-        Edges {
-            top: self.top.to_pixels(rem_size),
-            right: self.right.to_pixels(rem_size),
-            bottom: self.bottom.to_pixels(rem_size),
-            left: self.left.to_pixels(rem_size),
-        }
-    }
-}
-
-impl Edges<Pixels> {
-    pub fn is_empty(&self) -> bool {
-        self.top == px(0.) && self.right == px(0.) && self.bottom == px(0.) && self.left == px(0.)
-    }
-}
-
-#[derive(Clone, Copy, Default, Add, AddAssign, Sub, Mul, Div, PartialEq)]
-#[repr(transparent)]
-pub struct Pixels(pub(crate) f32);
-
-unsafe impl bytemuck::Pod for Pixels {}
-unsafe impl bytemuck::Zeroable for Pixels {}
-
-impl Debug for Pixels {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{} px", self.0)
-    }
-}
-
-impl From<Pixels> for f32 {
-    fn from(pixels: Pixels) -> Self {
-        pixels.0
-    }
-}
-
-impl From<&Pixels> for f32 {
-    fn from(pixels: &Pixels) -> Self {
-        pixels.0
-    }
-}
-
-#[derive(Clone, Copy, Default, Add, Sub, Mul, Div)]
-pub struct Rems(f32);
-
-impl Mul<Pixels> for Rems {
-    type Output = Pixels;
-
-    fn mul(self, other: Pixels) -> Pixels {
-        Pixels(self.0 * other.0)
-    }
-}
-
-impl Debug for Rems {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{} rem", self.0)
-    }
-}
-
-#[derive(Clone, Copy, Debug)]
-pub enum AbsoluteLength {
-    Pixels(Pixels),
-    Rems(Rems),
-}
-
-impl From<Pixels> for AbsoluteLength {
-    fn from(pixels: Pixels) -> Self {
-        AbsoluteLength::Pixels(pixels)
-    }
-}
-
-impl From<Rems> for AbsoluteLength {
-    fn from(rems: Rems) -> Self {
-        AbsoluteLength::Rems(rems)
-    }
-}
-
-impl AbsoluteLength {
-    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
-        match self {
-            AbsoluteLength::Pixels(pixels) => *pixels,
-            AbsoluteLength::Rems(rems) => *rems * rem_size,
-        }
-    }
-}
-
-impl Default for AbsoluteLength {
-    fn default() -> Self {
-        px(0.)
-    }
-}
-
-/// A non-auto length that can be defined in pixels, rems, or percent of parent.
-#[derive(Clone, Copy)]
-pub enum DefiniteLength {
-    Absolute(AbsoluteLength),
-    /// A fraction of the parent's size between 0 and 1.
-    Fraction(f32),
-}
-
-impl Debug for DefiniteLength {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        match self {
-            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
-            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
-        }
-    }
-}
-
-impl From<Pixels> for DefiniteLength {
-    fn from(pixels: Pixels) -> Self {
-        Self::Absolute(pixels.into())
-    }
-}
-
-impl From<Rems> for DefiniteLength {
-    fn from(rems: Rems) -> Self {
-        Self::Absolute(rems.into())
-    }
-}
-
-impl From<AbsoluteLength> for DefiniteLength {
-    fn from(length: AbsoluteLength) -> Self {
-        Self::Absolute(length)
-    }
-}
-
-impl Default for DefiniteLength {
-    fn default() -> Self {
-        Self::Absolute(AbsoluteLength::default())
-    }
-}
-
-/// A length that can be defined in pixels, rems, percent of parent, or auto.
-#[derive(Clone, Copy)]
-pub enum Length {
-    Definite(DefiniteLength),
-    Auto,
-}
-
-impl Debug for Length {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        match self {
-            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
-            Length::Auto => write!(f, "auto"),
-        }
-    }
-}
-
-pub fn relative<T: From<DefiniteLength>>(fraction: f32) -> T {
-    DefiniteLength::Fraction(fraction).into()
-}
-
-pub fn rems<T: From<Rems>>(rems: f32) -> T {
-    Rems(rems).into()
-}
-
-pub fn px<T: From<Pixels>>(pixels: f32) -> T {
-    Pixels(pixels).into()
-}
-
-pub fn auto() -> Length {
-    Length::Auto
-}
-
-impl From<Pixels> for Length {
-    fn from(pixels: Pixels) -> Self {
-        Self::Definite(pixels.into())
-    }
-}
-
-impl From<Rems> for Length {
-    fn from(rems: Rems) -> Self {
-        Self::Definite(rems.into())
-    }
-}
-
-impl From<DefiniteLength> for Length {
-    fn from(length: DefiniteLength) -> Self {
-        Self::Definite(length)
-    }
-}
-
-impl From<AbsoluteLength> for Length {
-    fn from(length: AbsoluteLength) -> Self {
-        Self::Definite(length.into())
-    }
-}
-
-impl Default for Length {
-    fn default() -> Self {
-        Self::Definite(DefiniteLength::default())
-    }
-}
-
-impl From<()> for Length {
-    fn from(_: ()) -> Self {
-        Self::Definite(DefiniteLength::default())
-    }
-}

crates/storybook/src/gpui3/mod.rs 🔗

@@ -1,101 +0,0 @@
-mod app;
-mod color;
-mod element;
-mod elements;
-mod geometry;
-mod platform;
-mod renderer;
-mod scene;
-mod style;
-mod taffy;
-mod window;
-
-use self::editor::Editor;
-use anyhow::Result;
-pub use app::*;
-pub use color::*;
-pub use element::*;
-pub use elements::*;
-pub use geometry::*;
-pub use gpui2::ArcCow;
-use gpui2::Reference;
-pub use scene::*;
-pub use style::*;
-pub use taffy::LayoutId;
-use taffy::TaffyLayoutEngine;
-pub use window::*;
-
-pub trait Context {
-    type EntityContext<'a, 'w, T: 'static>;
-
-    fn entity<T: 'static>(
-        &mut self,
-        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
-    ) -> Handle<T>;
-
-    fn update_entity<T: 'static, R>(
-        &mut self,
-        handle: &Handle<T>,
-        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
-    ) -> R;
-}
-
-#[derive(Clone, Eq, PartialEq)]
-pub struct SharedString(ArcCow<'static, str>);
-
-impl std::fmt::Debug for SharedString {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
-    fn from(value: T) -> Self {
-        Self(value.into())
-    }
-}
-
-struct Workspace {
-    left_panel: AnyView<Self>,
-}
-
-fn workspace(cx: &mut WindowContext) -> View<Workspace> {
-    let workspace = cx.entity(|cx| Workspace {
-        left_panel: collab_panel(cx).into_any(),
-    });
-    view(workspace, |workspace, cx| {
-        div().child(workspace.left_panel.clone())
-    })
-}
-
-struct CollabPanel {
-    filter_editor: Handle<editor::Editor>,
-}
-
-fn collab_panel(cx: &mut WindowContext) -> View<CollabPanel> {
-    let panel = cx.entity(|cx| CollabPanel::new(cx));
-    view(panel, |panel, cx| {
-        div()
-            .child(div())
-            .child(field(panel.filter_editor.clone()).placeholder_text("Search channels, contacts"))
-    })
-}
-
-impl CollabPanel {
-    fn new(cx: &mut ViewContext<Self>) -> Self {
-        Self {
-            filter_editor: cx.entity(|cx| Editor::new(cx)),
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test() {
-        let mut cx = AppContext::new();
-        cx.open_window(|cx| workspace(cx));
-    }
-}

crates/storybook/src/gpui3/platform.rs 🔗

@@ -1,58 +0,0 @@
-mod test;
-use super::{AnyWindowHandle, Bounds, Point};
-use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
-
-pub trait Platform {
-    fn open_window(
-        &self,
-        handle: AnyWindowHandle,
-        options: WindowOptions,
-    ) -> Box<dyn PlatformWindow>;
-}
-
-pub trait PlatformWindow: HasRawWindowHandle + HasRawDisplayHandle {}
-
-#[derive(Debug)]
-pub struct WindowOptions<'a> {
-    pub bounds: WindowBounds,
-    pub titlebar: Option<TitlebarOptions<'a>>,
-    pub center: bool,
-    pub focus: bool,
-    pub show: bool,
-    pub kind: WindowKind,
-    pub is_movable: bool,
-}
-
-#[derive(Debug, Default)]
-pub struct TitlebarOptions<'a> {
-    pub title: Option<&'a str>,
-    pub appears_transparent: bool,
-    pub traffic_light_position: Option<Point<f32>>,
-}
-
-#[derive(Copy, Clone, Debug)]
-pub enum Appearance {
-    Light,
-    VibrantLight,
-    Dark,
-    VibrantDark,
-}
-
-impl Default for Appearance {
-    fn default() -> Self {
-        Self::Light
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum WindowKind {
-    Normal,
-    PopUp,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum WindowBounds {
-    Fullscreen,
-    Maximized,
-    Fixed(Bounds<f32>),
-}

crates/storybook/src/gpui3/renderer.rs 🔗

@@ -1,164 +0,0 @@
-use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
-
-use super::{Scene, Size};
-
-pub struct Renderer {
-    device: wgpu::Device,
-    queue: wgpu::Queue,
-    surface: wgpu::Surface,
-    surface_config: wgpu::SurfaceConfiguration,
-    pipeline: wgpu::RenderPipeline,
-    vertex_buffer: wgpu::Buffer,
-    vertex_count: u32,
-}
-
-pub trait Window: HasRawWindowHandle + HasRawDisplayHandle {
-    fn inner_size(&self) -> Size<u32>;
-}
-
-impl Renderer {
-    pub async fn new<W>(window: &W) -> Self
-    where
-        W: Window,
-    {
-        let instance = wgpu::Instance::new(Default::default());
-        let surface = unsafe { instance.create_surface(window).unwrap() };
-
-        let adapter = instance
-            .request_adapter(&wgpu::RequestAdapterOptions::default())
-            .await
-            .unwrap();
-
-        let (device, queue) = adapter
-            .request_device(&wgpu::DeviceDescriptor::default(), None)
-            .await
-            .unwrap();
-
-        let surface_config = wgpu::SurfaceConfiguration {
-            usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
-            format: wgpu::TextureFormat::Bgra8UnormSrgb,
-            width: window.inner_size().width,
-            height: window.inner_size().height,
-
-            // "FIFO" mode renders frames in queue synced with the display's refresh rate.
-            // Avoids screen tearing but may not offer the lowest latency. Ideal when image
-            // quality takes priority over input latency.
-            present_mode: wgpu::PresentMode::Fifo,
-
-            // Use the Premultiplied alpha mode. With premultiplication, the color components
-            // are multiplied by the alpha value before storage or blending, meaning calculations
-            // with colors already factor in the influence of alpha. This typically results
-            // in better performance and avoids a separate multiplication operation during blending.
-            alpha_mode: wgpu::CompositeAlphaMode::PreMultiplied,
-
-            // Specify the color formats for the views the surface can have.
-            // In this case, the format is BGRA (blue, green, red, alpha) with unsigned
-            // normalised integers in the 8-bit range and the color space is sRGB (standard RGB).
-            // sRGB is the standard color space for displaying images and video on digital displays,
-            // as it optimises color accuracy and consistency.
-            view_formats: vec![wgpu::TextureFormat::Bgra8UnormSrgb],
-        };
-
-        surface.configure(&device, &surface_config);
-
-        let vs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: Some("Vertex Shader"),
-            source: wgpu::ShaderSource::Wgsl(include_str!("shader.vert.wgsl").into()),
-        });
-
-        let fs_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
-            label: Some("Fragment Shader"),
-            source: wgpu::ShaderSource::Wgsl(include_str!("shader.frag.wgsl").into()),
-        });
-
-        let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
-            label: Some("Render Pipeline Layout"),
-            bind_group_layouts: &[],
-            push_constant_ranges: &[],
-        });
-
-        let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
-            label: Some("Vertex Buffer"),
-            size: 0,
-            usage: wgpu::BufferUsages::VERTEX,
-            mapped_at_creation: false,
-        });
-
-        let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
-            label: Some("Render Pipeline"),
-            layout: Some(&pipeline_layout),
-            vertex: wgpu::VertexState {
-                module: &vs_module,
-                entry_point: "main",
-                buffers: &[],
-            },
-            fragment: Some(wgpu::FragmentState {
-                module: &fs_module,
-                entry_point: "main",
-                targets: &[Some(wgpu::ColorTargetState {
-                    format: surface_config.format,
-                    blend: Some(wgpu::BlendState::REPLACE),
-                    write_mask: wgpu::ColorWrites::ALL,
-                })],
-            }),
-            primitive: wgpu::PrimitiveState {
-                topology: wgpu::PrimitiveTopology::TriangleStrip,
-                ..Default::default()
-            },
-            depth_stencil: None,
-            multisample: wgpu::MultisampleState::default(),
-            multiview: None,
-        });
-
-        Self {
-            device,
-            queue,
-            surface,
-            surface_config,
-            pipeline,
-            vertex_buffer,
-            vertex_count: 0,
-        }
-    }
-
-    pub fn render(&mut self, scene: &Scene) {
-        let frame = self.surface.get_current_texture().unwrap();
-        let view = frame
-            .texture
-            .create_view(&wgpu::TextureViewDescriptor::default());
-
-        self.queue.write_buffer(
-            &self.vertex_buffer,
-            0,
-            bytemuck::cast_slice(&scene.opaque_primitives().quads),
-        );
-        self.vertex_count = scene.opaque_primitives().quads.len() as u32;
-
-        let mut encoder = self
-            .device
-            .create_command_encoder(&wgpu::CommandEncoderDescriptor {
-                label: Some("Render Encoder"),
-            });
-
-        {
-            let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
-                label: Some("Render Pass"),
-                color_attachments: &[Some(wgpu::RenderPassColorAttachment {
-                    view: &view,
-                    resolve_target: None,
-                    ops: wgpu::Operations {
-                        load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
-                        store: true,
-                    },
-                })],
-                depth_stencil_attachment: None,
-            });
-
-            render_pass.set_pipeline(&self.pipeline);
-            render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
-            render_pass.draw(0..self.vertex_count, 0..1);
-        }
-
-        self.queue.submit(std::iter::once(encoder.finish()));
-    }
-}

crates/storybook/src/gpui3/scene.rs 🔗

@@ -1,111 +0,0 @@
-use super::{Bounds, Hsla, Pixels, Point};
-use bytemuck::{Pod, Zeroable};
-use plane_split::BspSplitter;
-
-pub struct Scene {
-    opaque_primitives: PrimitiveBatch,
-    transparent_primitives: slotmap::SlotMap<slotmap::DefaultKey, Primitive>,
-    splitter: BspSplitter<slotmap::DefaultKey>,
-}
-
-impl Scene {
-    pub fn new() -> Scene {
-        Scene {
-            opaque_primitives: PrimitiveBatch::default(),
-            transparent_primitives: slotmap::SlotMap::new(),
-            splitter: BspSplitter::new(),
-        }
-    }
-
-    pub fn insert(&mut self, primitive: impl Into<Primitive>, is_transparent: bool) {
-        if is_transparent {
-            self.transparent_primitives.insert(primitive.into());
-        } else {
-            match primitive.into() {
-                Primitive::Quad(quad) => self.opaque_primitives.quads.push(quad),
-                Primitive::Glyph(glyph) => self.opaque_primitives.glyphs.push(glyph),
-            }
-        }
-    }
-
-    pub fn opaque_primitives(&self) -> &PrimitiveBatch {
-        &self.opaque_primitives
-    }
-}
-
-#[derive(Clone, Debug)]
-pub enum Primitive {
-    Quad(Quad),
-    Glyph(Glyph),
-}
-
-impl Primitive {
-    pub fn is_transparent(&self) -> bool {
-        match self {
-            Primitive::Quad(quad) => {
-                quad.background.is_transparent() && quad.border_color.is_transparent()
-            }
-            Primitive::Glyph(glyph) => glyph.color.is_transparent(),
-        }
-    }
-}
-
-#[derive(Default)]
-pub struct PrimitiveBatch {
-    pub quads: Vec<Quad>,
-    pub glyphs: Vec<Glyph>,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(C)]
-pub struct Quad {
-    pub order: f32,
-    pub bounds: Bounds<Pixels>,
-    pub background: Hsla,
-    pub border_color: Hsla,
-    pub corner_radius: Pixels,
-    pub border_left: Pixels,
-    pub border_right: Pixels,
-    pub border_top: Pixels,
-    pub border_bottom: Pixels,
-}
-
-impl Quad {
-    pub fn vertices(&self) -> impl Iterator<Item = Point<Pixels>> {
-        let x1 = self.bounds.origin.x;
-        let y1 = self.bounds.origin.y;
-        let x2 = x1 + self.bounds.size.width;
-        let y2 = y1 + self.bounds.size.height;
-        [
-            Point::new(x1, y1),
-            Point::new(x2, y1),
-            Point::new(x2, y2),
-            Point::new(x1, y2),
-        ]
-        .into_iter()
-    }
-}
-
-unsafe impl Zeroable for Quad {}
-
-unsafe impl Pod for Quad {}
-
-#[derive(Debug, Clone)]
-pub struct Glyph {
-    pub order: f32,
-    pub bounds: Bounds<Pixels>,
-    pub color: Hsla,
-    // ...
-}
-
-impl From<Quad> for Primitive {
-    fn from(quad: Quad) -> Self {
-        Primitive::Quad(quad)
-    }
-}
-
-impl From<Glyph> for Primitive {
-    fn from(glyph: Glyph) -> Self {
-        Primitive::Glyph(glyph)
-    }
-}

crates/storybook/src/gpui3/style.rs 🔗

@@ -1,245 +0,0 @@
-use refineable::Refineable;
-
-pub use super::taffy::style::{
-    AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
-    Overflow, Position,
-};
-use super::{
-    rems, AbsoluteLength, Bounds, DefiniteLength, Edges, EdgesRefinement, Hsla, Length, Pixels,
-    Point, PointRefinement, Rems, SharedString, Size, SizeRefinement, ViewContext, WindowContext,
-};
-pub use gpui2::style::{FontStyle, FontWeight};
-
-#[derive(Clone, Debug)]
-pub struct FontSize(f32);
-
-#[derive(Clone, Refineable, Debug)]
-#[refineable(debug)]
-pub struct Style {
-    /// What layout strategy should be used?
-    pub display: Display,
-
-    // Overflow properties
-    /// How children overflowing their container should affect layout
-    #[refineable]
-    pub overflow: Point<Overflow>,
-    /// How much space (in points) should be reserved for the scrollbars of `Overflow::Scroll` and `Overflow::Auto` nodes.
-    pub scrollbar_width: f32,
-
-    // Position properties
-    /// What should the `position` value of this struct use as a base offset?
-    pub position: Position,
-    /// How should the position of this element be tweaked relative to the layout defined?
-    #[refineable]
-    pub inset: Edges<Length>,
-
-    // Size properies
-    /// Sets the initial size of the item
-    #[refineable]
-    pub size: Size<Length>,
-    /// Controls the minimum size of the item
-    #[refineable]
-    pub min_size: Size<Length>,
-    /// Controls the maximum size of the item
-    #[refineable]
-    pub max_size: Size<Length>,
-    /// Sets the preferred aspect ratio for the item. The ratio is calculated as width divided by height.
-    pub aspect_ratio: Option<f32>,
-
-    // Spacing Properties
-    /// How large should the margin be on each side?
-    #[refineable]
-    pub margin: Edges<Length>,
-    /// How large should the padding be on each side?
-    #[refineable]
-    pub padding: Edges<DefiniteLength>,
-    /// How large should the border be on each side?
-    #[refineable]
-    pub border_widths: Edges<AbsoluteLength>,
-
-    // Alignment properties
-    /// How this node's children aligned in the cross/block axis?
-    pub align_items: Option<AlignItems>,
-    /// How this node should be aligned in the cross/block axis. Falls back to the parents [`AlignItems`] if not set
-    pub align_self: Option<AlignSelf>,
-    /// How should content contained within this item be aligned in the cross/block axis
-    pub align_content: Option<AlignContent>,
-    /// How should contained within this item be aligned in the main/inline axis
-    pub justify_content: Option<JustifyContent>,
-    /// How large should the gaps between items in a flex container be?
-    #[refineable]
-    pub gap: Size<DefiniteLength>,
-
-    // Flexbox properies
-    /// Which direction does the main axis flow in?
-    pub flex_direction: FlexDirection,
-    /// Should elements wrap, or stay in a single line?
-    pub flex_wrap: FlexWrap,
-    /// Sets the initial main axis size of the item
-    pub flex_basis: Length,
-    /// The relative rate at which this item grows when it is expanding to fill space, 0.0 is the default value, and this value must be positive.
-    pub flex_grow: f32,
-    /// The relative rate at which this item shrinks when it is contracting to fit into space, 1.0 is the default value, and this value must be positive.
-    pub flex_shrink: f32,
-
-    /// The fill color of this element
-    pub fill: Option<Fill>,
-
-    /// The border color of this element
-    pub border_color: Option<Hsla>,
-
-    /// The radius of the corners of this element
-    #[refineable]
-    pub corner_radii: CornerRadii,
-
-    /// The color of text within this element. Cascades to children unless overridden.
-    pub text_color: Option<Hsla>,
-
-    /// The font size in rems.
-    pub font_size: Option<Rems>,
-
-    pub font_family: Option<SharedString>,
-
-    pub font_weight: Option<FontWeight>,
-
-    pub font_style: Option<FontStyle>,
-}
-
-#[derive(Refineable, Clone, Debug)]
-#[refineable(debug)]
-pub struct TextStyle {
-    pub color: Hsla,
-    pub font_family: SharedString,
-    pub font_size: Rems,
-    pub font_weight: FontWeight,
-    pub font_style: FontStyle,
-    pub underline: Underline,
-}
-
-#[derive(Refineable, Clone, Default, Debug)]
-#[refineable(debug)]
-pub struct Underline {
-    pub origin: Point<Pixels>,
-    pub width: Pixels,
-    pub thickness: Pixels,
-    pub color: Hsla,
-    pub squiggly: bool,
-}
-
-impl Style {
-    pub fn text_style(&self, cx: &WindowContext) -> Option<TextStyleRefinement> {
-        if self.text_color.is_none()
-            && self.font_size.is_none()
-            && self.font_family.is_none()
-            && self.font_weight.is_none()
-            && self.font_style.is_none()
-        {
-            return None;
-        }
-
-        Some(TextStyleRefinement {
-            color: self.text_color,
-            font_family: self.font_family.clone(),
-            font_size: self.font_size,
-            font_weight: self.font_weight,
-            font_style: self.font_style,
-            underline: None,
-        })
-    }
-
-    /// Paints the background of an element styled with this style.
-    pub fn paint_background<V: 'static>(&self, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
-        let rem_size = cx.rem_size();
-        if let Some(color) = self.fill.as_ref().and_then(Fill::color) {
-            todo!();
-        }
-    }
-
-    /// Paints the foreground of an element styled with this style.
-    pub fn paint_foreground<V: 'static>(&self, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
-        let rem_size = cx.rem_size();
-
-        if let Some(color) = self.border_color {
-            let border = self.border_widths.to_pixels(rem_size);
-            if !border.is_empty() {
-                todo!();
-            }
-        }
-    }
-}
-
-impl Default for Style {
-    fn default() -> Self {
-        Style {
-            display: Display::Block,
-            overflow: Point {
-                x: Overflow::Visible,
-                y: Overflow::Visible,
-            },
-            scrollbar_width: 0.0,
-            position: Position::Relative,
-            inset: Edges::auto(),
-            margin: Edges::<Length>::zero(),
-            padding: Edges::<DefiniteLength>::zero(),
-            border_widths: Edges::<AbsoluteLength>::zero(),
-            size: Size::auto(),
-            min_size: Size::auto(),
-            max_size: Size::auto(),
-            aspect_ratio: None,
-            gap: Size::zero(),
-            // Aligment
-            align_items: None,
-            align_self: None,
-            align_content: None,
-            justify_content: None,
-            // Flexbox
-            flex_direction: FlexDirection::Row,
-            flex_wrap: FlexWrap::NoWrap,
-            flex_grow: 0.0,
-            flex_shrink: 1.0,
-            flex_basis: Length::Auto,
-            fill: None,
-            border_color: None,
-            corner_radii: CornerRadii::default(),
-            text_color: None,
-            font_size: Some(rems(1.)),
-            font_family: None,
-            font_weight: None,
-            font_style: None,
-        }
-    }
-}
-
-#[derive(Clone, Debug)]
-pub enum Fill {
-    Color(Hsla),
-}
-
-impl Fill {
-    pub fn color(&self) -> Option<Hsla> {
-        match self {
-            Fill::Color(color) => Some(*color),
-        }
-    }
-}
-
-impl Default for Fill {
-    fn default() -> Self {
-        Self::Color(Hsla::default())
-    }
-}
-
-impl From<Hsla> for Fill {
-    fn from(color: Hsla) -> Self {
-        Self::Color(color)
-    }
-}
-
-#[derive(Clone, Refineable, Default, Debug)]
-#[refineable(debug)]
-pub struct CornerRadii {
-    top_left: AbsoluteLength,
-    top_right: AbsoluteLength,
-    bottom_left: AbsoluteLength,
-    bottom_right: AbsoluteLength,
-}

crates/storybook/src/gpui3/taffy.rs 🔗

@@ -1,238 +0,0 @@
-use super::{
-    AbsoluteLength, Bounds, DefiniteLength, Edges, Layout, Length, Pixels, Point, Result, Size,
-    Style,
-};
-use gpui2::taffy::{self, Taffy};
-use std::fmt::Debug;
-pub use taffy::*;
-
-pub use gpui2::taffy::tree::NodeId as LayoutId;
-pub struct TaffyLayoutEngine(Taffy);
-
-impl TaffyLayoutEngine {
-    pub fn new() -> Self {
-        TaffyLayoutEngine(Taffy::new())
-    }
-
-    pub fn request_layout(
-        &mut self,
-        style: Style,
-        rem_size: Pixels,
-        children: &[LayoutId],
-    ) -> Result<LayoutId> {
-        let style = style.to_taffy(rem_size);
-        if children.is_empty() {
-            Ok(self.0.new_leaf(style)?)
-        } else {
-            Ok(self.0.new_with_children(style, children)?)
-        }
-    }
-
-    pub fn layout(&mut self, id: LayoutId) -> Result<Layout> {
-        Ok(self.0.layout(id).map(Into::into)?)
-    }
-}
-
-trait ToTaffy<Output> {
-    fn to_taffy(&self, rem_size: Pixels) -> Output;
-}
-
-impl ToTaffy<taffy::style::Style> for Style {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::style::Style {
-        taffy::style::Style {
-            display: self.display,
-            overflow: self.overflow.clone().into(),
-            scrollbar_width: self.scrollbar_width,
-            position: self.position,
-            inset: self.inset.to_taffy(rem_size),
-            size: self.size.to_taffy(rem_size),
-            min_size: self.min_size.to_taffy(rem_size),
-            max_size: self.max_size.to_taffy(rem_size),
-            aspect_ratio: self.aspect_ratio,
-            margin: self.margin.to_taffy(rem_size),
-            padding: self.padding.to_taffy(rem_size),
-            border: self.border_widths.to_taffy(rem_size),
-            align_items: self.align_items,
-            align_self: self.align_self,
-            align_content: self.align_content,
-            justify_content: self.justify_content,
-            gap: self.gap.to_taffy(rem_size),
-            flex_direction: self.flex_direction,
-            flex_wrap: self.flex_wrap,
-            flex_basis: self.flex_basis.to_taffy(rem_size),
-            flex_grow: self.flex_grow,
-            flex_shrink: self.flex_shrink,
-            ..Default::default() // Ignore grid properties for now
-        }
-    }
-}
-
-// impl ToTaffy for Bounds<Length> {
-//     type Output = taffy::prelude::Bounds<taffy::prelude::LengthPercentageAuto>;
-
-//     fn to_taffy(
-//         &self,
-//         rem_size: Pixels,
-//     ) -> taffy::prelude::Bounds<taffy::prelude::LengthPercentageAuto> {
-//         taffy::prelude::Bounds {
-//             origin: self.origin.to_taffy(rem_size),
-//             size: self.size.to_taffy(rem_size),
-//         }
-//     }
-// }
-
-impl ToTaffy<taffy::style::LengthPercentageAuto> for Length {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::prelude::LengthPercentageAuto {
-        match self {
-            Length::Definite(length) => length.to_taffy(rem_size),
-            Length::Auto => taffy::prelude::LengthPercentageAuto::Auto,
-        }
-    }
-}
-
-impl ToTaffy<taffy::style::Dimension> for Length {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::prelude::Dimension {
-        match self {
-            Length::Definite(length) => length.to_taffy(rem_size),
-            Length::Auto => taffy::prelude::Dimension::Auto,
-        }
-    }
-}
-
-impl ToTaffy<taffy::style::LengthPercentage> for DefiniteLength {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::style::LengthPercentage {
-        match self {
-            DefiniteLength::Absolute(length) => match length {
-                AbsoluteLength::Pixels(pixels) => {
-                    taffy::style::LengthPercentage::Length(pixels.into())
-                }
-                AbsoluteLength::Rems(rems) => {
-                    taffy::style::LengthPercentage::Length((*rems * rem_size).into())
-                }
-            },
-            DefiniteLength::Fraction(fraction) => {
-                taffy::style::LengthPercentage::Percent(*fraction)
-            }
-        }
-    }
-}
-
-impl ToTaffy<taffy::style::LengthPercentageAuto> for DefiniteLength {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::style::LengthPercentageAuto {
-        match self {
-            DefiniteLength::Absolute(length) => match length {
-                AbsoluteLength::Pixels(pixels) => {
-                    taffy::style::LengthPercentageAuto::Length(pixels.into())
-                }
-                AbsoluteLength::Rems(rems) => {
-                    taffy::style::LengthPercentageAuto::Length((*rems * rem_size).into())
-                }
-            },
-            DefiniteLength::Fraction(fraction) => {
-                taffy::style::LengthPercentageAuto::Percent(*fraction)
-            }
-        }
-    }
-}
-
-impl ToTaffy<taffy::style::Dimension> for DefiniteLength {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::style::Dimension {
-        match self {
-            DefiniteLength::Absolute(length) => match length {
-                AbsoluteLength::Pixels(pixels) => taffy::style::Dimension::Length(pixels.into()),
-                AbsoluteLength::Rems(rems) => {
-                    taffy::style::Dimension::Length((*rems * rem_size).into())
-                }
-            },
-            DefiniteLength::Fraction(fraction) => taffy::style::Dimension::Percent(*fraction),
-        }
-    }
-}
-
-impl ToTaffy<taffy::style::LengthPercentage> for AbsoluteLength {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::style::LengthPercentage {
-        match self {
-            AbsoluteLength::Pixels(pixels) => taffy::style::LengthPercentage::Length(pixels.into()),
-            AbsoluteLength::Rems(rems) => {
-                taffy::style::LengthPercentage::Length((*rems * rem_size).into())
-            }
-        }
-    }
-}
-
-impl<T, T2: Clone + Debug> From<taffy::geometry::Point<T>> for Point<T2>
-where
-    T: Into<T2>,
-{
-    fn from(point: taffy::geometry::Point<T>) -> Point<T2> {
-        Point {
-            x: point.x.into(),
-            y: point.y.into(),
-        }
-    }
-}
-
-impl<T: Clone + Debug, T2> Into<taffy::geometry::Point<T2>> for Point<T>
-where
-    T: Into<T2>,
-{
-    fn into(self) -> taffy::geometry::Point<T2> {
-        taffy::geometry::Point {
-            x: self.x.into(),
-            y: self.y.into(),
-        }
-    }
-}
-
-impl<T: ToTaffy<U> + Clone + Debug, U> ToTaffy<taffy::geometry::Size<U>> for Size<T> {
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::geometry::Size<U> {
-        taffy::geometry::Size {
-            width: self.width.to_taffy(rem_size).into(),
-            height: self.height.to_taffy(rem_size).into(),
-        }
-    }
-}
-
-impl<T, U> ToTaffy<taffy::geometry::Rect<U>> for Edges<T>
-where
-    T: ToTaffy<U> + Clone + Debug,
-{
-    fn to_taffy(&self, rem_size: Pixels) -> taffy::geometry::Rect<U> {
-        taffy::geometry::Rect {
-            top: self.top.to_taffy(rem_size).into(),
-            right: self.right.to_taffy(rem_size).into(),
-            bottom: self.bottom.to_taffy(rem_size).into(),
-            left: self.left.to_taffy(rem_size).into(),
-        }
-    }
-}
-
-impl<S, T: Clone + Default + Debug> From<taffy::geometry::Size<S>> for Size<T>
-where
-    S: Into<T>,
-{
-    fn from(value: taffy::geometry::Size<S>) -> Self {
-        Self {
-            width: value.width.into(),
-            height: value.height.into(),
-        }
-    }
-}
-
-impl From<&taffy::tree::Layout> for Layout {
-    fn from(layout: &taffy::tree::Layout) -> Self {
-        Layout {
-            order: layout.order,
-            bounds: Bounds {
-                origin: layout.location.into(),
-                size: layout.size.into(),
-            },
-        }
-    }
-}
-
-impl From<f32> for Pixels {
-    fn from(pixels: f32) -> Self {
-        Pixels(pixels)
-    }
-}

crates/storybook/src/gpui3/window.rs 🔗

@@ -1,231 +0,0 @@
-use super::{
-    px, taffy::LayoutId, AppContext, Bounds, Context, EntityId, Handle, Pixels, Style,
-    TaffyLayoutEngine,
-};
-use anyhow::Result;
-use derive_more::{Deref, DerefMut};
-use gpui2::Reference;
-use std::{
-    any::{Any, TypeId},
-    marker::PhantomData,
-};
-
-pub struct AnyWindow {}
-
-pub struct Window {
-    id: WindowId,
-    rem_size: Pixels,
-    layout_engine: TaffyLayoutEngine,
-    pub(crate) root_view: Option<Box<dyn Any>>,
-}
-
-impl Window {
-    pub fn new(id: WindowId) -> Window {
-        Window {
-            id,
-            layout_engine: TaffyLayoutEngine::new(),
-            rem_size: px(16.),
-            root_view: None,
-        }
-    }
-}
-
-#[derive(Deref, DerefMut)]
-pub struct WindowContext<'a, 'b> {
-    #[deref]
-    #[deref_mut]
-    app: Reference<'a, AppContext>,
-    window: Reference<'b, Window>,
-}
-
-impl<'a, 'w> WindowContext<'a, 'w> {
-    pub(crate) fn mutable(app: &'a mut AppContext, window: &'w mut Window) -> Self {
-        Self {
-            app: Reference::Mutable(app),
-            window: Reference::Mutable(window),
-        }
-    }
-
-    pub(crate) fn immutable(app: &'a AppContext, window: &'w Window) -> Self {
-        Self {
-            app: Reference::Immutable(app),
-            window: Reference::Immutable(window),
-        }
-    }
-
-    pub fn request_layout(
-        &mut self,
-        style: Style,
-        children: impl IntoIterator<Item = LayoutId>,
-    ) -> Result<LayoutId> {
-        self.app.layout_id_buffer.clear();
-        self.app.layout_id_buffer.extend(children.into_iter());
-        let rem_size = self.rem_size();
-
-        self.window
-            .layout_engine
-            .request_layout(style, rem_size, &self.app.layout_id_buffer)
-    }
-
-    pub fn layout(&mut self, layout_id: LayoutId) -> Result<Layout> {
-        Ok(self
-            .window
-            .layout_engine
-            .layout(layout_id)
-            .map(Into::into)?)
-    }
-
-    pub fn rem_size(&self) -> Pixels {
-        self.window.rem_size
-    }
-
-    fn update_window<R>(
-        &mut self,
-        window_id: WindowId,
-        update: impl FnOnce(&mut WindowContext) -> R,
-    ) -> Result<R> {
-        if window_id == self.window.id {
-            Ok(update(self))
-        } else {
-            self.app.update_window(window_id, update)
-        }
-    }
-}
-
-impl Context for WindowContext<'_, '_> {
-    type EntityContext<'a, 'w, T: 'static> = ViewContext<'a, 'w, T>;
-
-    fn entity<T: 'static>(
-        &mut self,
-        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
-    ) -> Handle<T> {
-        let id = self.entities.insert(None);
-        let entity = Box::new(build_entity(&mut ViewContext::mutable(
-            &mut *self.app,
-            &mut self.window,
-            id,
-        )));
-        self.entities.get_mut(id).unwrap().replace(entity);
-
-        Handle {
-            id,
-            entity_type: PhantomData,
-        }
-    }
-
-    fn update_entity<T: 'static, R>(
-        &mut self,
-        handle: &Handle<T>,
-        update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
-    ) -> R {
-        let mut entity = self
-            .app
-            .entities
-            .get_mut(handle.id)
-            .unwrap()
-            .take()
-            .unwrap()
-            .downcast::<T>()
-            .unwrap();
-
-        let result = update(
-            &mut *entity,
-            &mut ViewContext::mutable(&mut *self.app, &mut *self.window, handle.id),
-        );
-
-        self.app
-            .entities
-            .get_mut(handle.id)
-            .unwrap()
-            .replace(entity);
-
-        result
-    }
-}
-
-#[derive(Deref, DerefMut)]
-pub struct ViewContext<'a, 'w, T> {
-    #[deref]
-    #[deref_mut]
-    window_cx: WindowContext<'a, 'w>,
-    entity_type: PhantomData<T>,
-    entity_id: EntityId,
-}
-
-impl<'a, 'w, T: 'static> ViewContext<'a, 'w, T> {
-    // fn update<R>(&mut self, update: impl FnOnce(&mut T, &mut Self) -> R) -> R {
-
-    //     self.window_cx.update_entity(handle, update)
-
-    //     let mut entity = self.window_cx.app.entities.remove(&self.entity_id).unwrap();
-    //     let result = update(entity.downcast_mut::<T>().unwrap(), self);
-    //     self.window_cx
-    //         .app
-    //         .entities
-    //         .insert(self.entity_id, Box::new(entity));
-    //     result
-    // }
-
-    fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
-        Self {
-            window_cx: WindowContext::mutable(app, window),
-            entity_id,
-            entity_type: PhantomData,
-        }
-    }
-
-    fn immutable(app: &'a AppContext, window: &'w Window, entity_id: EntityId) -> Self {
-        Self {
-            window_cx: WindowContext::immutable(app, window),
-            entity_id,
-            entity_type: PhantomData,
-        }
-    }
-}
-
-impl<'a, 'w, T: 'static> Context for ViewContext<'a, 'w, T> {
-    type EntityContext<'b, 'c, U: 'static> = ViewContext<'b, 'c, U>;
-
-    fn entity<T2: 'static>(
-        &mut self,
-        build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T2>) -> T2,
-    ) -> Handle<T2> {
-        self.window_cx.entity(build_entity)
-    }
-
-    fn update_entity<U: 'static, R>(
-        &mut self,
-        handle: &Handle<U>,
-        update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,
-    ) -> R {
-        self.window_cx.update_entity(handle, update)
-    }
-}
-
-// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
-slotmap::new_key_type! { pub struct WindowId; }
-
-pub struct WindowHandle<S> {
-    id: WindowId,
-    state_type: PhantomData<S>,
-}
-
-impl<S> WindowHandle<S> {
-    pub fn new(id: WindowId) -> Self {
-        WindowHandle {
-            id,
-            state_type: PhantomData,
-        }
-    }
-}
-
-pub struct AnyWindowHandle {
-    id: WindowId,
-    state_type: TypeId,
-}
-
-#[derive(Clone)]
-pub struct Layout {
-    pub order: u32,
-    pub bounds: Bounds<Pixels>,
-}