crates/gpui3/src/arc_cow.rs 🔗
Nathan Sobo created
crates/gpui3/src/arc_cow.rs | 0
crates/gpui3/src/element.rs | 20 +
crates/gpui3/src/elements/hoverable.rs | 14
crates/gpui3/src/elements/identified.rs | 20
crates/gpui3/src/elements/pressable.rs | 339 +++++++++++++-------------
crates/gpui3/src/gpui3.rs | 9
crates/gpui3/src/identified.rs | 1
7 files changed, 201 insertions(+), 202 deletions(-)
@@ -1,12 +1,16 @@
-use crate::{Bounds, ElementId, ElementWithId};
-
-use super::{LayoutId, Pixels, Point, Result, ViewContext};
+use crate::{Bounds, Identified, LayoutId, Pixels, Point, Result, ViewContext};
+use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec;
+use util::arc_cow::ArcCow;
pub trait Element: 'static {
type State;
type FrameState;
+ fn element_id(&self) -> Option<ElementId> {
+ None
+ }
+
fn layout(
&mut self,
state: &mut Self::State,
@@ -21,14 +25,20 @@ pub trait Element: 'static {
cx: &mut ViewContext<Self::State>,
) -> Result<()>;
- fn id(self, id: ElementId) -> ElementWithId<Self>
+ fn id(self, id: ElementId) -> Identified<Self>
where
Self: Sized,
{
- ElementWithId { element: self, id }
+ Identified { element: self, id }
}
}
+#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+pub struct ElementId(ArcCow<'static, [u8]>);
+
+#[derive(Deref, DerefMut, Default, Clone, Debug)]
+pub(crate) struct GlobalElementId(SmallVec<[ElementId; 8]>);
+
pub trait ParentElement {
type State;
@@ -1,6 +1,6 @@
use crate::{
- AnyElement, Bounds, DispatchPhase, Element, ElementId, Identified, Interactive,
- MouseEventListeners, MouseMoveEvent, ParentElement, Pixels, Styled, ViewContext,
+ AnyElement, Bounds, DispatchPhase, Element, ElementId, Interactive, MouseEventListeners,
+ MouseMoveEvent, ParentElement, Pixels, Stateful, Styled, ViewContext,
};
use anyhow::Result;
use refineable::{CascadeSlot, Refineable, RefinementCascade};
@@ -53,6 +53,10 @@ impl<E: Element + Styled> Element for Hoverable<E> {
type State = E::State;
type FrameState = E::FrameState;
+ fn element_id(&self) -> Option<ElementId> {
+ self.child.element_id()
+ }
+
fn layout(
&mut self,
state: &mut Self::State,
@@ -96,8 +100,4 @@ impl<E: ParentElement + Styled> ParentElement for Hoverable<E> {
}
}
-impl<E: Identified + Styled> Identified for Hoverable<E> {
- fn id(&self) -> ElementId {
- self.child.id()
- }
-}
+impl<E: Stateful + Styled> Stateful for Hoverable<E> {}
@@ -1,19 +1,25 @@
use crate::{BorrowWindow, Bounds, Element, ElementId, LayoutId, ViewContext};
use anyhow::Result;
-pub trait Identified {
- fn id(&self) -> ElementId;
+pub trait Stateful: Element {
+ fn element_id(&self) -> ElementId {
+ Element::element_id(self).unwrap()
+ }
}
-pub struct ElementWithId<E> {
+pub struct Identified<E> {
pub(crate) element: E,
pub(crate) id: ElementId,
}
-impl<E: Element> Element for ElementWithId<E> {
+impl<E: Element> Element for Identified<E> {
type State = E::State;
type FrameState = E::FrameState;
+ fn element_id(&self) -> Option<ElementId> {
+ Some(self.id.clone())
+ }
+
fn layout(
&mut self,
state: &mut Self::State,
@@ -35,8 +41,4 @@ impl<E: Element> Element for ElementWithId<E> {
}
}
-impl<E> Identified for ElementWithId<E> {
- fn id(&self) -> ElementId {
- self.id.clone()
- }
-}
+impl<E: Element> Stateful for Identified<E> {}
@@ -1,214 +1,211 @@
-use crate::{
- AnyElement, Bounds, DispatchPhase, Element, Identified, Interactive, MouseDownEvent,
- MouseEventListeners, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
-};
-use anyhow::Result;
-use refineable::{CascadeSlot, Refineable, RefinementCascade};
-use smallvec::SmallVec;
-use std::sync::{
- atomic::{AtomicBool, Ordering::SeqCst},
- Arc,
-};
-
-pub struct Pressable<E: Styled> {
- pressed: Arc<AtomicBool>,
- cascade_slot: CascadeSlot,
- pressed_style: <E::Style as Refineable>::Refinement,
- child: E,
-}
-
-impl<E: Identified + Styled> Pressable<E> {
- pub fn new(mut child: E) -> Self {
- Self {
- pressed: Arc::new(AtomicBool::new(false)),
- cascade_slot: child.style_cascade().reserve(),
- pressed_style: Default::default(),
- child,
- }
- }
-}
-
-impl<E> Styled for Pressable<E>
-where
- E: Styled,
-{
- type Style = E::Style;
-
- fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
- self.child.style_cascade()
- }
-
- fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
- &mut self.pressed_style
- }
-}
-
-impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Pressable<E> {
- fn listeners(&mut self) -> &mut MouseEventListeners<S> {
- self.child.listeners()
- }
-}
-
-impl<E: Element + Identified + Styled> Element for Pressable<E> {
- type State = E::State;
- type FrameState = E::FrameState;
-
- fn layout(
- &mut self,
- state: &mut Self::State,
- cx: &mut ViewContext<Self::State>,
- ) -> Result<(crate::LayoutId, Self::FrameState)> {
- Ok(self.child.layout(state, cx)?)
- }
-
- fn paint(
- &mut self,
- bounds: Bounds<Pixels>,
- state: &mut Self::State,
- frame_state: &mut Self::FrameState,
- cx: &mut ViewContext<Self::State>,
- ) -> Result<()> {
- let pressed = bounds.contains_point(cx.mouse_position());
- let slot = self.cascade_slot;
- let style = pressed.then_some(self.pressed_style.clone());
- self.style_cascade().set(slot, style);
- self.pressed.store(pressed, SeqCst);
-
- let hovered = self.pressed.clone();
- cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
- if phase == DispatchPhase::Capture {
- if bounds.contains_point(event.position) != hovered.load(SeqCst) {
- cx.notify();
- }
- }
- });
- cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| {
- if phase == DispatchPhase::Capture {
- if bounds.contains_point(event.position) != hovered.load(SeqCst) {
- cx.notify();
- }
- }
- });
-
- cx.frame_state::<Self>(self.id().to_global(cx))
- // cx.frame_state
-
- self.child.paint(bounds, state, frame_state, cx)?;
- Ok(())
- }
-}
-
-impl<E: ParentElement + Styled> ParentElement for Pressable<E> {
- type State = E::State;
-
- fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
- self.child.children_mut()
- }
-}
-
// use crate::{
-// element::{AnyElement, Element, IntoElement, Layout, ParentElement},
-// interactive::{InteractionHandlers, Interactive},
-// style::{Style, StyleHelpers, Styleable},
-// ViewContext,
+// AnyElement, Bounds, DispatchPhase, Element, Identified, Interactive, MouseDownEvent,
+// MouseEventListeners, MouseUpEvent, ParentElement, Pixels, Styled, ViewContext,
// };
// use anyhow::Result;
-// use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
// use refineable::{CascadeSlot, Refineable, RefinementCascade};
// use smallvec::SmallVec;
-// use std::{cell::Cell, rc::Rc};
+// use std::sync::{
+// atomic::{AtomicBool, Ordering::SeqCst},
+// Arc,
+// };
-// pub struct Pressable<E: Styleable> {
-// pressed: Rc<Cell<bool>>,
-// pressed_style: <E::Style as Refineable>::Refinement,
+// pub struct Pressable<E: Styled> {
+// pressed: Arc<AtomicBool>,
// cascade_slot: CascadeSlot,
+// pressed_style: <E::Style as Refineable>::Refinement,
// child: E,
// }
-// pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
-// Pressable {
-// pressed: Rc::new(Cell::new(false)),
-// pressed_style: Default::default(),
-// cascade_slot: child.style_cascade().reserve(),
-// child,
+// impl<E: Identified + Styled> Pressable<E> {
+// pub fn new(mut child: E) -> Self {
+// Self {
+// pressed: Arc::new(AtomicBool::new(false)),
+// cascade_slot: child.style_cascade().reserve(),
+// pressed_style: Default::default(),
+// child,
+// }
// }
// }
-// impl<E: Styleable> Styleable for Pressable<E> {
+// impl<E> Styled for Pressable<E>
+// where
+// E: Styled,
+// {
// type Style = E::Style;
-// fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
+// fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
+// self.child.style_cascade()
+// }
+
+// fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
// &mut self.pressed_style
// }
+// }
-// fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
-// self.child.style_cascade()
+// impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Pressable<E> {
+// fn listeners(&mut self) -> &mut MouseEventListeners<S> {
+// self.child.listeners()
// }
// }
-// impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
-// type PaintState = E::PaintState;
+// impl<E: Element + Identified + Styled> Element for Pressable<E> {
+// type State = E::State;
+// type FrameState = E::FrameState;
// fn layout(
// &mut self,
-// view: &mut V,
-// cx: &mut ViewContext<V>,
-// ) -> Result<(LayoutId, Self::PaintState)>
-// where
-// Self: Sized,
-// {
-// self.child.layout(view, cx)
+// state: &mut Self::State,
+// cx: &mut ViewContext<Self::State>,
+// ) -> Result<(crate::LayoutId, Self::FrameState)> {
+// Ok(self.child.layout(state, cx)?)
// }
// fn paint(
// &mut self,
-// view: &mut V,
-// parent_origin: Vector2F,
-// layout: &Layout,
-// paint_state: &mut Self::PaintState,
-// cx: &mut ViewContext<V>,
-// ) where
-// Self: Sized,
-// {
+// bounds: Bounds<Pixels>,
+// state: &mut Self::State,
+// frame_state: &mut Self::FrameState,
+// cx: &mut ViewContext<Self::State>,
+// ) -> Result<()> {
+// let pressed = bounds.contains_point(cx.mouse_position());
// let slot = self.cascade_slot;
-// let style = self.pressed.get().then_some(self.pressed_style.clone());
+// let style = pressed.then_some(self.pressed_style.clone());
// self.style_cascade().set(slot, style);
+// self.pressed.store(pressed, SeqCst);
-// let pressed = self.pressed.clone();
-// let bounds = layout.bounds + parent_origin;
-// cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
-// if event.is_down {
-// if bounds.contains_point(event.position) {
-// pressed.set(true);
-// cx.repaint();
+// let hovered = self.pressed.clone();
+// cx.on_mouse_event(move |event: &MouseDownEvent, phase, cx| {
+// if phase == DispatchPhase::Capture {
+// if bounds.contains_point(event.position) != hovered.load(SeqCst) {
+// cx.notify();
+// }
+// }
+// });
+// cx.on_mouse_event(move |event: &MouseUpEvent, phase, cx| {
+// if phase == DispatchPhase::Capture {
+// if bounds.contains_point(event.position) != hovered.load(SeqCst) {
+// cx.notify();
// }
-// } else if pressed.get() {
-// pressed.set(false);
-// cx.repaint();
// }
// });
-// self.child
-// .paint(view, parent_origin, layout, paint_state, cx);
+// self.child.paint(bounds, state, frame_state, cx)?;
+// Ok(())
// }
// }
-// impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
-// fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
-// self.child.interaction_handlers()
-// }
-// }
+// impl<E: ParentElement + Styled> ParentElement for Pressable<E> {
+// type State = E::State;
-// impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
-// fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
+// fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
// self.child.children_mut()
// }
// }
-// impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
-// type Element = Self;
-
-// fn into_element(self) -> Self::Element {
-// self
-// }
-// }
+// // use crate::{
+// // element::{AnyElement, Element, IntoElement, Layout, ParentElement},
+// // interactive::{InteractionHandlers, Interactive},
+// // style::{Style, StyleHelpers, Styleable},
+// // ViewContext,
+// // };
+// // use anyhow::Result;
+// // use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
+// // use refineable::{CascadeSlot, Refineable, RefinementCascade};
+// // use smallvec::SmallVec;
+// // use std::{cell::Cell, rc::Rc};
+
+// // pub struct Pressable<E: Styleable> {
+// // pressed: Rc<Cell<bool>>,
+// // pressed_style: <E::Style as Refineable>::Refinement,
+// // cascade_slot: CascadeSlot,
+// // child: E,
+// // }
+
+// // pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
+// // Pressable {
+// // pressed: Rc::new(Cell::new(false)),
+// // pressed_style: Default::default(),
+// // cascade_slot: child.style_cascade().reserve(),
+// // child,
+// // }
+// // }
+
+// // impl<E: Styleable> Styleable for Pressable<E> {
+// // type Style = E::Style;
+
+// // fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
+// // &mut self.pressed_style
+// // }
+
+// // fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
+// // self.child.style_cascade()
+// // }
+// // }
+
+// // impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
+// // type PaintState = E::PaintState;
+
+// // fn layout(
+// // &mut self,
+// // view: &mut V,
+// // cx: &mut ViewContext<V>,
+// // ) -> Result<(LayoutId, Self::PaintState)>
+// // where
+// // Self: Sized,
+// // {
+// // self.child.layout(view, cx)
+// // }
+
+// // fn paint(
+// // &mut self,
+// // view: &mut V,
+// // parent_origin: Vector2F,
+// // layout: &Layout,
+// // paint_state: &mut Self::PaintState,
+// // cx: &mut ViewContext<V>,
+// // ) where
+// // Self: Sized,
+// // {
+// // let slot = self.cascade_slot;
+// // let style = self.pressed.get().then_some(self.pressed_style.clone());
+// // self.style_cascade().set(slot, style);
+
+// // let pressed = self.pressed.clone();
+// // let bounds = layout.bounds + parent_origin;
+// // cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
+// // if event.is_down {
+// // if bounds.contains_point(event.position) {
+// // pressed.set(true);
+// // cx.repaint();
+// // }
+// // } else if pressed.get() {
+// // pressed.set(false);
+// // cx.repaint();
+// // }
+// // });
+
+// // self.child
+// // .paint(view, parent_origin, layout, paint_state, cx);
+// // }
+// // }
+
+// // impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
+// // fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
+// // self.child.interaction_handlers()
+// // }
+// // }
+
+// // impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
+// // fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
+// // self.child.children_mut()
+// // }
+// // }
+
+// // impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
+// // type Element = Self;
+
+// // fn into_element(self) -> Self::Element {
+// // self
+// // }
+// // }
@@ -6,7 +6,6 @@ mod elements;
mod events;
mod executor;
mod geometry;
-mod identified;
mod image_cache;
mod interactive;
mod platform;
@@ -31,7 +30,6 @@ pub use events::*;
pub use executor::*;
pub use geometry::*;
pub use gpui3_macros::*;
-pub use identified::*;
pub use image_cache::*;
pub use interactive::*;
pub use platform::*;
@@ -51,7 +49,6 @@ pub use util::arc_cow::ArcCow;
pub use view::*;
pub use window::*;
-use derive_more::{Deref, DerefMut};
use std::{
mem,
ops::{Deref, DerefMut},
@@ -171,12 +168,6 @@ impl<T> Flatten<T> for Result<T> {
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct SharedString(ArcCow<'static, str>);
-#[derive(Clone, Debug, Eq, PartialEq, Hash)]
-pub struct ElementId(ArcCow<'static, [u8]>);
-
-#[derive(Default, Deref, DerefMut, Clone, Debug)]
-pub(crate) struct GlobalElementId(SmallVec<[ElementId; 8]>);
-
impl Default for SharedString {
fn default() -> Self {
Self(ArcCow::Owned("".into()))
@@ -1 +0,0 @@
-