Compare commits

...
Sign in to create a new pull request.

4 commits

Author SHA1 Message Date
Mikayla
e3da2e691c
continue trampoline 2023-10-24 06:08:37 -07:00
Marshall Bowers
317acbf1d7 WIP: Trampoline 2023-10-24 14:55:23 +02:00
Nathan Sobo
b52db5c5e6 WIP 2023-10-24 10:51:54 +02:00
Nathan Sobo
30280ab897 WIP 2023-10-23 23:34:33 +02:00
25 changed files with 417 additions and 417 deletions

84
Cargo.lock generated
View file

@ -5953,61 +5953,6 @@ dependencies = [
"util",
]
[[package]]
name = "project2"
version = "0.1.0"
dependencies = [
"aho-corasick",
"anyhow",
"async-trait",
"backtrace",
"client2",
"clock",
"collections",
"copilot2",
"ctor",
"db2",
"env_logger 0.9.3",
"fs",
"fsevent",
"futures 0.3.28",
"fuzzy2",
"git",
"git2",
"globset",
"gpui2",
"ignore",
"itertools 0.10.5",
"language2",
"lazy_static",
"log",
"lsp2",
"node_runtime",
"parking_lot 0.11.2",
"postage",
"prettier",
"pretty_assertions",
"rand 0.8.5",
"regex",
"rpc",
"schemars",
"serde",
"serde_derive",
"serde_json",
"settings2",
"sha2 0.10.7",
"similar",
"smol",
"sum_tree",
"tempdir",
"terminal",
"text",
"thiserror",
"toml 0.5.11",
"unindent",
"util",
]
[[package]]
name = "project_panel"
version = "0.1.0"
@ -8374,35 +8319,6 @@ dependencies = [
"util",
]
[[package]]
name = "terminal2"
version = "0.1.0"
dependencies = [
"alacritty_terminal",
"anyhow",
"db2",
"dirs 4.0.0",
"futures 0.3.28",
"gpui2",
"itertools 0.10.5",
"lazy_static",
"libc",
"mio-extras",
"ordered-float 2.10.0",
"procinfo",
"rand 0.8.5",
"schemars",
"serde",
"serde_derive",
"settings2",
"shellexpand",
"smallvec",
"smol",
"theme2",
"thiserror",
"util",
]
[[package]]
name = "terminal_view"
version = "0.1.0"

View file

@ -62,7 +62,7 @@ members = [
"crates/plugin_runtime",
"crates/prettier",
"crates/project",
"crates/project2",
# "crates/project2",
"crates/project_panel",
"crates/project_symbols",
"crates/recent_projects",
@ -78,7 +78,7 @@ members = [
"crates/storybook2",
"crates/sum_tree",
"crates/terminal",
"crates/terminal2",
#"crates/terminal2",
"crates/text",
"crates/theme",
"crates/theme2",

View file

@ -178,7 +178,7 @@ pub struct AppContext {
pub(crate) svg_renderer: SvgRenderer,
pub(crate) image_cache: ImageCache,
pub(crate) text_style_stack: Vec<TextStyleRefinement>,
pub(crate) globals_by_type: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
pub(crate) globals_by_type: HashMap<TypeId, AnyBox>,
pub(crate) unit_entity: Handle<()>,
pub(crate) entities: EntityMap,
pub(crate) windows: SlotMap<WindowId, Option<Window>>,
@ -574,7 +574,7 @@ impl AppContext {
)
}
pub(crate) fn lease_global<G: 'static + Send + Sync>(&mut self) -> Box<G> {
pub(crate) fn lease_global<G: Any>(&mut self) -> Box<G> {
self.globals_by_type
.remove(&TypeId::of::<G>())
.ok_or_else(|| anyhow!("no global registered of type {}", type_name::<G>()))
@ -583,7 +583,7 @@ impl AppContext {
.unwrap()
}
pub(crate) fn restore_global<G: 'static + Send + Sync>(&mut self, global: Box<G>) {
pub(crate) fn restore_global<G: Any>(&mut self, global: Box<G>) {
let global_type = TypeId::of::<G>();
self.push_effect(Effect::NotifyGlobalObservers { global_type });
self.globals_by_type.insert(global_type, global);
@ -639,7 +639,7 @@ impl AppContext {
}
impl Context for AppContext {
type EntityContext<'a, 'w, T: Send + Sync + 'static> = ModelContext<'a, T>;
type EntityContext<'a, 'w, T> = ModelContext<'a, T>;
type Result<T> = T;
fn entity<T: Send + Sync + 'static>(
@ -653,7 +653,7 @@ impl Context for AppContext {
})
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -723,11 +723,11 @@ impl MainThread<AppContext> {
self.platform().open_url(url);
}
pub fn open_window<S: 'static + Send + Sync>(
pub fn open_window<V: 'static + Send + Sync>(
&mut self,
options: crate::WindowOptions,
build_root_view: impl FnOnce(&mut WindowContext) -> View<S> + Send + 'static,
) -> WindowHandle<S> {
build_root_view: impl FnOnce(&mut WindowContext) -> View<V> + Send + 'static,
) -> WindowHandle<V> {
self.update(|cx| {
let id = cx.windows.insert(None);
let handle = WindowHandle::new(id);
@ -739,7 +739,7 @@ impl MainThread<AppContext> {
})
}
pub fn update_global<G: 'static + Send + Sync, R>(
pub fn update_global<G: Any, R>(
&mut self,
update: impl FnOnce(&mut G, &mut MainThread<AppContext>) -> R,
) -> R {
@ -756,7 +756,7 @@ pub(crate) enum Effect {
},
Emit {
emitter: EntityId,
event: Box<dyn Any + Send + Sync + 'static>,
event: AnyBox,
},
FocusChanged {
window_id: WindowId,

View file

@ -14,7 +14,7 @@ pub struct AsyncAppContext {
}
impl Context for AsyncAppContext {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ModelContext<'a, T>;
type EntityContext<'a, 'w, T> = ModelContext<'a, T>;
type Result<T> = Result<T>;
fn entity<T: Send + Sync + 'static>(
@ -29,7 +29,7 @@ impl Context for AsyncAppContext {
Ok(lock.entity(build_entity))
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -213,18 +213,18 @@ impl AsyncWindowContext {
}
impl Context for AsyncWindowContext {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
type Result<T> = Result<T>;
fn entity<R: Send + Sync + 'static>(
fn entity<T: Send + Sync + 'static>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, R>) -> R,
) -> Result<Handle<R>> {
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Result<Handle<T>> {
self.app
.update_window(self.window, |cx| cx.entity(build_entity))
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,

View file

@ -30,7 +30,7 @@ impl Display for EntityId {
}
pub(crate) struct EntityMap {
entities: SecondaryMap<EntityId, Box<dyn Any + Send + Sync>>,
entities: SecondaryMap<EntityId, Box<dyn Any>>,
ref_counts: Arc<RwLock<EntityRefCounts>>,
}
@ -51,24 +51,20 @@ impl EntityMap {
}
/// Reserve a slot for an entity, which you can subsequently use with `insert`.
pub fn reserve<T: 'static + Send + Sync>(&self) -> Slot<T> {
pub fn reserve<T: 'static>(&self) -> Slot<T> {
let id = self.ref_counts.write().counts.insert(1.into());
Slot(Handle::new(id, Arc::downgrade(&self.ref_counts)))
}
/// Insert an entity into a slot obtained by calling `reserve`.
pub fn insert<T: 'static + Any + Send + Sync>(
&mut self,
slot: Slot<T>,
entity: T,
) -> Handle<T> {
pub fn insert<T: Any>(&mut self, slot: Slot<T>, entity: T) -> Handle<T> {
let handle = slot.0;
self.entities.insert(handle.entity_id, Box::new(entity));
handle
}
/// Move an entity to the stack.
pub fn lease<'a, T: 'static + Send + Sync>(&mut self, handle: &'a Handle<T>) -> Lease<'a, T> {
pub fn lease<'a, T>(&mut self, handle: &'a Handle<T>) -> Lease<'a, T> {
let entity = Some(
self.entities
.remove(handle.entity_id)
@ -80,16 +76,16 @@ impl EntityMap {
}
/// Return an entity after moving it to the stack.
pub fn end_lease<T: 'static + Send + Sync>(&mut self, mut lease: Lease<T>) {
pub fn end_lease<T>(&mut self, mut lease: Lease<T>) {
self.entities
.insert(lease.handle.entity_id, lease.entity.take().unwrap());
}
pub fn read<T: 'static + Send + Sync>(&self, handle: &Handle<T>) -> &T {
pub fn read<T>(&self, handle: &Handle<T>) -> &T {
self.entities[handle.entity_id].downcast_ref().unwrap()
}
pub fn weak_handle<T: 'static + Send + Sync>(&self, id: EntityId) -> WeakHandle<T> {
pub fn weak_handle<T>(&self, id: EntityId) -> WeakHandle<T> {
WeakHandle {
any_handle: AnyWeakHandle {
entity_id: id,
@ -100,7 +96,7 @@ impl EntityMap {
}
}
pub fn take_dropped(&mut self) -> Vec<(EntityId, Box<dyn Any + Send + Sync>)> {
pub fn take_dropped(&mut self) -> Vec<(EntityId, Box<dyn Any>)> {
let dropped_entity_ids = mem::take(&mut self.ref_counts.write().dropped_entity_ids);
dropped_entity_ids
.into_iter()
@ -109,15 +105,12 @@ impl EntityMap {
}
}
pub struct Lease<'a, T: Send + Sync> {
pub struct Lease<'a, T> {
entity: Option<Box<T>>,
pub handle: &'a Handle<T>,
}
impl<'a, T> core::ops::Deref for Lease<'a, T>
where
T: Send + Sync,
{
impl<'a, T> core::ops::Deref for Lease<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
@ -125,19 +118,13 @@ where
}
}
impl<'a, T> core::ops::DerefMut for Lease<'a, T>
where
T: Send + Sync,
{
impl<'a, T> core::ops::DerefMut for Lease<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.entity.as_mut().unwrap()
}
}
impl<'a, T> Drop for Lease<'a, T>
where
T: Send + Sync,
{
impl<'a, T> Drop for Lease<'a, T> {
fn drop(&mut self) {
if self.entity.is_some() {
// We don't panic here, because other panics can cause us to drop the lease without ending it cleanly.
@ -147,7 +134,7 @@ where
}
#[derive(Deref, DerefMut)]
pub struct Slot<T: Send + Sync + 'static>(Handle<T>);
pub struct Slot<T>(Handle<T>);
pub struct AnyHandle {
pub(crate) entity_id: EntityId,
@ -178,7 +165,7 @@ impl AnyHandle {
pub fn downcast<T>(&self) -> Option<Handle<T>>
where
T: 'static + Send + Sync,
T: Any,
{
if TypeId::of::<T>() == self.entity_type {
Some(Handle {
@ -231,10 +218,7 @@ impl Drop for AnyHandle {
}
}
impl<T> From<Handle<T>> for AnyHandle
where
T: 'static + Send + Sync,
{
impl<T> From<Handle<T>> for AnyHandle {
fn from(handle: Handle<T>) -> Self {
handle.any_handle
}
@ -255,14 +239,14 @@ impl PartialEq for AnyHandle {
impl Eq for AnyHandle {}
#[derive(Deref, DerefMut)]
pub struct Handle<T: Send + Sync> {
pub struct Handle<T> {
#[deref]
#[deref_mut]
any_handle: AnyHandle,
entity_type: PhantomData<T>,
}
impl<T: 'static + Send + Sync> Handle<T> {
impl<T> Handle<T> {
fn new(id: EntityId, entity_map: Weak<RwLock<EntityRefCounts>>) -> Self {
Self {
any_handle: AnyHandle::new(id, TypeId::of::<T>(), entity_map),
@ -295,7 +279,7 @@ impl<T: 'static + Send + Sync> Handle<T> {
}
}
impl<T: Send + Sync> Clone for Handle<T> {
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Self {
any_handle: self.any_handle.clone(),
@ -304,7 +288,7 @@ impl<T: Send + Sync> Clone for Handle<T> {
}
}
impl<T: 'static + Send + Sync> std::fmt::Debug for Handle<T> {
impl<T> std::fmt::Debug for Handle<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
@ -315,19 +299,19 @@ impl<T: 'static + Send + Sync> std::fmt::Debug for Handle<T> {
}
}
impl<T: Send + Sync + 'static> Hash for Handle<T> {
impl<T> Hash for Handle<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.any_handle.hash(state);
}
}
impl<T: Send + Sync + 'static> PartialEq for Handle<T> {
impl<T> PartialEq for Handle<T> {
fn eq(&self, other: &Self) -> bool {
self.any_handle == other.any_handle
}
}
impl<T: Send + Sync + 'static> Eq for Handle<T> {}
impl<T> Eq for Handle<T> {}
#[derive(Clone)]
pub struct AnyWeakHandle {
@ -436,16 +420,16 @@ impl<T: Send + Sync + 'static> WeakHandle<T> {
}
}
impl<T: Send + Sync + 'static> Hash for WeakHandle<T> {
impl<T> Hash for WeakHandle<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.any_handle.hash(state);
}
}
impl<T: Send + Sync + 'static> PartialEq for WeakHandle<T> {
impl<T> PartialEq for WeakHandle<T> {
fn eq(&self, other: &Self) -> bool {
self.any_handle == other.any_handle
}
}
impl<T: Send + Sync + 'static> Eq for WeakHandle<T> {}
impl<T> Eq for WeakHandle<T> {}

View file

@ -15,7 +15,7 @@ pub struct ModelContext<'a, T> {
entity_id: EntityId,
}
impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
impl<'a, T> ModelContext<'a, T> {
pub(crate) fn mutable(app: &'a mut AppContext, entity_id: EntityId) -> Self {
Self {
app: Reference::Mutable(app),
@ -38,7 +38,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
self.app.entities.weak_handle(self.entity_id)
}
pub fn observe<E: Send + Sync + 'static>(
pub fn observe<E>(
&mut self,
handle: &Handle<E>,
on_notify: impl Fn(&mut T, Handle<E>, &mut ModelContext<'_, T>) + Send + Sync + 'static,
@ -58,7 +58,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
)
}
pub fn subscribe<E: EventEmitter + Send + Sync + 'static>(
pub fn subscribe<E: EventEmitter>(
&mut self,
handle: &Handle<E>,
on_event: impl Fn(&mut T, Handle<E>, &E::Event, &mut ModelContext<'_, T>)
@ -95,7 +95,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
)
}
pub fn observe_release<E: Send + Sync + 'static>(
pub fn observe_release<E>(
&mut self,
handle: &Handle<E>,
on_release: impl Fn(&mut T, &mut E, &mut ModelContext<'_, T>) + Send + Sync + 'static,
@ -176,7 +176,7 @@ impl<'a, T: Send + Sync + 'static> ModelContext<'a, T> {
}
}
impl<'a, T: EventEmitter + Send + Sync + 'static> ModelContext<'a, T> {
impl<'a, T: EventEmitter> ModelContext<'a, T> {
pub fn emit(&mut self, event: T::Event) {
self.app.pending_effects.push_back(Effect::Emit {
emitter: self.entity_id,
@ -186,7 +186,7 @@ impl<'a, T: EventEmitter + Send + Sync + 'static> ModelContext<'a, T> {
}
impl<'a, T: 'static> Context for ModelContext<'a, T> {
type EntityContext<'b, 'c, U: Send + Sync + 'static> = ModelContext<'b, U>;
type EntityContext<'b, 'c, U> = ModelContext<'b, U>;
type Result<U> = U;
fn entity<U: Send + Sync + 'static>(
@ -196,7 +196,7 @@ impl<'a, T: 'static> Context for ModelContext<'a, T> {
self.app.entity(build_entity)
}
fn update_entity<U: Send + Sync + 'static, R>(
fn update_entity<U, R>(
&mut self,
handle: &Handle<U>,
update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,

View file

@ -3,9 +3,9 @@ use derive_more::{Deref, DerefMut};
pub(crate) use smallvec::SmallVec;
use std::mem;
pub trait Element: 'static + Send + Sync + IntoAnyElement<Self::ViewState> {
type ViewState: 'static + Send + Sync;
type ElementState: 'static + Send + Sync;
pub trait Element: IntoAnyElement<Self::ViewState> {
type ViewState;
type ElementState;
fn id(&self) -> Option<ElementId>;
@ -59,7 +59,7 @@ pub trait ParentElement: Element {
}
}
trait ElementObject<V>: 'static + Send + Sync {
trait ElementObject<V> {
fn initialize(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
fn layout(&mut self, view_state: &mut V, cx: &mut ViewContext<V>) -> LayoutId;
fn paint(&mut self, view_state: &mut V, cx: &mut ViewContext<V>);
@ -173,7 +173,7 @@ where
pub struct AnyElement<V>(Box<dyn ElementObject<V>>);
impl<V: 'static + Send + Sync> AnyElement<V> {
impl<V> AnyElement<V> {
pub fn new<E: Element<ViewState = V>>(element: E) -> Self {
AnyElement(Box::new(RenderedElement::new(element)))
}

View file

@ -2,8 +2,10 @@ mod div;
mod img;
mod svg;
mod text;
mod trampoline;
pub use div::*;
pub use img::*;
pub use svg::*;
pub use text::*;
pub use trampoline::*;

View file

@ -9,7 +9,7 @@ use refineable::Refineable;
use smallvec::SmallVec;
pub struct Div<
V: 'static + Send + Sync,
V,
I: ElementInteraction<V> = StatelessInteraction<V>,
F: ElementFocus<V> = FocusDisabled,
> {
@ -21,8 +21,8 @@ pub struct Div<
}
pub fn div<V>() -> Div<V, StatelessInteraction<V>, FocusDisabled>
where
V: 'static + Send + Sync,
// where
// V: 'static + Send + Sync,
{
Div {
interaction: StatelessInteraction::default(),
@ -36,7 +36,6 @@ where
impl<V, F> Div<V, StatelessInteraction<V>, F>
where
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
pub fn id(self, id: impl Into<ElementId>) -> Div<V, StatefulInteraction<V>, F> {
Div {
@ -53,7 +52,6 @@ impl<V, I, F> Div<V, I, F>
where
I: ElementInteraction<V>,
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
pub fn group(mut self, group: impl Into<SharedString>) -> Self {
self.group = Some(group.into());
@ -108,10 +106,7 @@ where
}
}
impl<V> Div<V, StatefulInteraction<V>, FocusDisabled>
where
V: 'static + Send + Sync,
{
impl<V> Div<V, StatefulInteraction<V>, FocusDisabled> {
pub fn focusable(self) -> Div<V, StatefulInteraction<V>, FocusEnabled<V>> {
Div {
interaction: self.interaction,
@ -152,10 +147,7 @@ where
}
}
impl<V> Div<V, StatelessInteraction<V>, FocusDisabled>
where
V: 'static + Send + Sync,
{
impl<V> Div<V, StatelessInteraction<V>, FocusDisabled> {
pub fn track_focus(
self,
handle: &FocusHandle,
@ -173,7 +165,6 @@ where
impl<V, I> Focusable for Div<V, I, FocusEnabled<V>>
where
I: ElementInteraction<V>,
V: 'static + Send + Sync,
{
fn focus_listeners(&mut self) -> &mut FocusListeners<V> {
&mut self.focus.focus_listeners
@ -203,7 +194,6 @@ impl<V, I, F> Element for Div<V, I, F>
where
I: ElementInteraction<V>,
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
type ViewState = V;
type ElementState = DivState;
@ -319,7 +309,6 @@ impl<V, I, F> IntoAnyElement<V> for Div<V, I, F>
where
I: ElementInteraction<V>,
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
fn into_any(self) -> AnyElement<V> {
AnyElement::new(self)
@ -330,7 +319,6 @@ impl<V, I, F> ParentElement for Div<V, I, F>
where
I: ElementInteraction<V>,
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]> {
&mut self.children
@ -341,7 +329,6 @@ impl<V, I, F> Styled for Div<V, I, F>
where
I: ElementInteraction<V>,
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
fn style(&mut self) -> &mut StyleRefinement {
&mut self.base_style
@ -352,7 +339,6 @@ impl<V, I, F> StatelessInteractive for Div<V, I, F>
where
I: ElementInteraction<V>,
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
fn stateless_interaction(&mut self) -> &mut StatelessInteraction<V> {
self.interaction.as_stateless_mut()
@ -362,7 +348,6 @@ where
impl<V, F> StatefulInteractive for Div<V, StatefulInteraction<V>, F>
where
F: ElementFocus<V>,
V: 'static + Send + Sync,
{
fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
&mut self.interaction

View file

@ -8,7 +8,7 @@ use futures::FutureExt;
use util::ResultExt;
pub struct Img<
V: 'static + Send + Sync,
V,
I: ElementInteraction<V> = StatelessInteraction<V>,
F: ElementFocus<V> = FocusDisabled,
> {
@ -17,10 +17,7 @@ pub struct Img<
grayscale: bool,
}
pub fn img<V>() -> Img<V, StatelessInteraction<V>, FocusDisabled>
where
V: 'static + Send + Sync,
{
pub fn img<V>() -> Img<V, StatelessInteraction<V>, FocusDisabled> {
Img {
base: div(),
uri: None,
@ -30,7 +27,6 @@ where
impl<V, I, F> Img<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -47,7 +43,6 @@ where
impl<V, F> Img<V, StatelessInteraction<V>, F>
where
V: 'static + Send + Sync,
F: ElementFocus<V>,
{
pub fn id(self, id: impl Into<ElementId>) -> Img<V, StatefulInteraction<V>, F> {
@ -61,7 +56,6 @@ where
impl<V, I, F> IntoAnyElement<V> for Img<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -72,7 +66,6 @@ where
impl<V, I, F> Element for Img<V, I, F>
where
V: Send + Sync + 'static,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -141,7 +134,6 @@ where
impl<V, I, F> Styled for Img<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -152,7 +144,6 @@ where
impl<V, I, F> StatelessInteractive for Img<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -163,7 +154,6 @@ where
impl<V, F> StatefulInteractive for Img<V, StatefulInteraction<V>, F>
where
V: 'static + Send + Sync,
F: ElementFocus<V>,
{
fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
@ -173,7 +163,6 @@ where
impl<V, I> Focusable for Img<V, I, FocusEnabled<V>>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
{
fn focus_listeners(&mut self) -> &mut FocusListeners<Self::ViewState> {

View file

@ -7,7 +7,7 @@ use crate::{
use util::ResultExt;
pub struct Svg<
V: 'static + Send + Sync,
V,
I: ElementInteraction<V> = StatelessInteraction<V>,
F: ElementFocus<V> = FocusDisabled,
> {
@ -15,10 +15,7 @@ pub struct Svg<
path: Option<SharedString>,
}
pub fn svg<V>() -> Svg<V, StatelessInteraction<V>, FocusDisabled>
where
V: 'static + Send + Sync,
{
pub fn svg<V>() -> Svg<V, StatelessInteraction<V>, FocusDisabled> {
Svg {
base: div(),
path: None,
@ -27,7 +24,6 @@ where
impl<V, I, F> Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -39,7 +35,6 @@ where
impl<V, F> Svg<V, StatelessInteraction<V>, F>
where
V: 'static + Send + Sync,
F: ElementFocus<V>,
{
pub fn id(self, id: impl Into<ElementId>) -> Svg<V, StatefulInteraction<V>, F> {
@ -52,7 +47,6 @@ where
impl<V, I, F> IntoAnyElement<V> for Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -63,7 +57,6 @@ where
impl<V, I, F> Element for Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -115,7 +108,6 @@ where
impl<V, I, F> Styled for Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -126,7 +118,6 @@ where
impl<V, I, F> StatelessInteractive for Svg<V, I, F>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
F: ElementFocus<V>,
{
@ -137,7 +128,6 @@ where
impl<V, F> StatefulInteractive for Svg<V, StatefulInteraction<V>, F>
where
V: 'static + Send + Sync,
F: ElementFocus<V>,
{
fn stateful_interaction(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
@ -147,7 +137,6 @@ where
impl<V, I> Focusable for Svg<V, I, FocusEnabled<V>>
where
V: 'static + Send + Sync,
I: ElementInteraction<V>,
{
fn focus_listeners(&mut self) -> &mut FocusListeners<Self::ViewState> {

View file

@ -7,8 +7,8 @@ use smallvec::SmallVec;
use std::{marker::PhantomData, sync::Arc};
use util::ResultExt;
impl<S: 'static + Send + Sync> IntoAnyElement<S> for SharedString {
fn into_any(self) -> AnyElement<S> {
impl<V> IntoAnyElement<V> for SharedString {
fn into_any(self) -> AnyElement<V> {
Text {
text: self,
state_type: PhantomData,
@ -17,7 +17,7 @@ impl<S: 'static + Send + Sync> IntoAnyElement<S> for SharedString {
}
}
impl<V: 'static + Send + Sync> IntoAnyElement<V> for &'static str {
impl<V> IntoAnyElement<V> for &'static str {
fn into_any(self) -> AnyElement<V> {
Text {
text: self.into(),
@ -29,7 +29,7 @@ impl<V: 'static + Send + Sync> IntoAnyElement<V> for &'static str {
// TODO: Figure out how to pass `String` to `child` without this.
// This impl doesn't exist in the `gpui2` crate.
impl<S: 'static + Send + Sync> IntoAnyElement<S> for String {
impl<S> IntoAnyElement<S> for String {
fn into_any(self) -> AnyElement<S> {
Text {
text: self.into(),
@ -44,13 +44,13 @@ pub struct Text<V> {
state_type: PhantomData<V>,
}
impl<V: 'static + Send + Sync> IntoAnyElement<V> for Text<V> {
impl<V> IntoAnyElement<V> for Text<V> {
fn into_any(self) -> AnyElement<V> {
AnyElement::new(self)
}
}
impl<V: 'static + Send + Sync> Element for Text<V> {
impl<V> Element for Text<V> {
type ViewState = V;
type ElementState = Arc<Mutex<Option<TextElementState>>>;

View file

@ -0,0 +1,65 @@
use crate::{Element, ViewContext, AnyElement, IntoAnyElement};
pub trait TemporaryRenderTraitDontWorryAboutIt<S> {
fn render(self, cx: &mut ViewContext<S>) -> AnyElement<S>;
}
struct IntoAnyElementTrampolineName<S, E: TemporaryRenderTraitDontWorryAboutIt<S>> {
contents: Option<E>,
phantom: std::marker::PhantomData<S>,
}
impl<S, E: TemporaryRenderTraitDontWorryAboutIt<S>> IntoAnyElementTrampolineName<S, E> {
fn new(contents: E) -> Self {
IntoAnyElementTrampolineName {
contents: Some(contents),
phantom: std::marker::PhantomData,
}
}
}
impl<S, E: TemporaryRenderTraitDontWorryAboutIt<S>> Element for IntoAnyElementTrampolineName<S, E> {
type ViewState = S;
type ElementState = AnyElement<S>;
fn id(&self) -> Option<crate::ElementId> {
None
}
fn initialize(
&mut self,
view_state: &mut Self::ViewState,
element_state: Option<Self::ElementState>,
cx: &mut ViewContext<Self::ViewState>,
) -> Self::ElementState {
self.contents.take().unwrap().render(cx)
}
fn layout(
&mut self,
view_state: &mut Self::ViewState,
element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>,
) -> crate::LayoutId {
element_state.layout(view_state, cx)
}
fn paint(
&mut self,
bounds: crate::Bounds<crate::Pixels>,
view_state: &mut Self::ViewState,
element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>,
) {
element_state.paint(view_state, cx);
}
}
impl<S, E: TemporaryRenderTraitDontWorryAboutIt<S>> IntoAnyElement<S> for IntoAnyElementTrampolineName<S, E> {
fn into_any(self) -> AnyElement<S> {
AnyElement::new(self)
}
}

View file

@ -135,7 +135,7 @@ pub trait Focusable: Element {
}
}
pub trait ElementFocus<V: 'static + Send + Sync>: 'static + Send + Sync {
pub trait ElementFocus<V> {
fn as_focusable(&self) -> Option<&FocusEnabled<V>>;
fn as_focusable_mut(&mut self) -> Option<&mut FocusEnabled<V>>;
@ -200,7 +200,7 @@ pub trait ElementFocus<V: 'static + Send + Sync>: 'static + Send + Sync {
}
}
pub struct FocusEnabled<V: 'static + Send + Sync> {
pub struct FocusEnabled<V> {
pub focus_handle: Option<FocusHandle>,
pub focus_listeners: FocusListeners<V>,
pub focus_style: StyleRefinement,
@ -208,10 +208,7 @@ pub struct FocusEnabled<V: 'static + Send + Sync> {
pub in_focus_style: StyleRefinement,
}
impl<V> FocusEnabled<V>
where
V: 'static + Send + Sync,
{
impl<V> FocusEnabled<V> {
pub fn new() -> Self {
Self {
focus_handle: None,
@ -233,10 +230,7 @@ where
}
}
impl<V> ElementFocus<V> for FocusEnabled<V>
where
V: 'static + Send + Sync,
{
impl<V> ElementFocus<V> for FocusEnabled<V> {
fn as_focusable(&self) -> Option<&FocusEnabled<V>> {
Some(self)
}
@ -246,10 +240,7 @@ where
}
}
impl<V> From<FocusHandle> for FocusEnabled<V>
where
V: 'static + Send + Sync,
{
impl<V> From<FocusHandle> for FocusEnabled<V> {
fn from(value: FocusHandle) -> Self {
Self {
focus_handle: Some(value),
@ -263,10 +254,7 @@ where
pub struct FocusDisabled;
impl<V> ElementFocus<V> for FocusDisabled
where
V: 'static + Send + Sync,
{
impl<V> ElementFocus<V> for FocusDisabled {
fn as_focusable(&self) -> Option<&FocusEnabled<V>> {
None
}

View file

@ -66,7 +66,7 @@ use taffy::TaffyLayoutEngine;
type AnyBox = Box<dyn Any + Send + Sync>;
pub trait Context {
type EntityContext<'a, 'w, T: 'static + Send + Sync>;
type EntityContext<'a, 'w, T>;
type Result<T>;
fn entity<T: Send + Sync + 'static>(
@ -74,7 +74,7 @@ pub trait Context {
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Self::Result<Handle<T>>;
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -105,10 +105,10 @@ impl<T> DerefMut for MainThread<T> {
}
impl<C: Context> Context for MainThread<C> {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = MainThread<C::EntityContext<'a, 'w, T>>;
type EntityContext<'a, 'w, T> = MainThread<C::EntityContext<'a, 'w, T>>;
type Result<T> = C::Result<T>;
fn entity<T: Send + Sync + 'static>(
fn entity<T: 'static + Send + Sync>(
&mut self,
build_entity: impl FnOnce(&mut Self::EntityContext<'_, '_, T>) -> T,
) -> Self::Result<Handle<T>> {
@ -123,7 +123,7 @@ impl<C: Context> Context for MainThread<C> {
})
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,

View file

@ -387,7 +387,7 @@ pub trait StatefulInteractive: StatelessInteractive {
}
}
pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
pub trait ElementInteraction<V> {
fn as_stateless(&self) -> &StatelessInteraction<V>;
fn as_stateless_mut(&mut self) -> &mut StatelessInteraction<V>;
fn as_stateful(&self) -> Option<&StatefulInteraction<V>>;
@ -397,7 +397,10 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
&mut self,
cx: &mut ViewContext<V>,
f: impl FnOnce(&mut ViewContext<V>) -> R,
) -> R {
) -> R
where
V: 'static + Send + Sync,
{
if let Some(stateful) = self.as_stateful_mut() {
cx.with_element_id(stateful.id.clone(), |global_id, cx| {
stateful.key_listeners.push((
@ -433,7 +436,9 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
bounds: Bounds<Pixels>,
element_state: &InteractiveElementState,
cx: &mut ViewContext<V>,
) {
) where
V: 'static + Send + Sync,
{
let mouse_position = cx.mouse_position();
let stateless = self.as_stateless();
if let Some(group_hover) = stateless.group_hover_style.as_ref() {
@ -487,7 +492,9 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
overflow: Point<Overflow>,
element_state: &mut InteractiveElementState,
cx: &mut ViewContext<V>,
) {
) where
V: 'static + Send + Sync,
{
let stateless = self.as_stateless();
for listener in stateless.mouse_down_listeners.iter().cloned() {
cx.on_mouse_event(move |state, event: &MouseDownEvent, phase, cx| {
@ -681,7 +688,7 @@ pub trait ElementInteraction<V: 'static + Send + Sync>: 'static + Send + Sync {
}
#[derive(Deref, DerefMut)]
pub struct StatefulInteraction<V: 'static + Send + Sync> {
pub struct StatefulInteraction<V> {
pub id: ElementId,
#[deref]
#[deref_mut]
@ -692,10 +699,7 @@ pub struct StatefulInteraction<V: 'static + Send + Sync> {
drag_listener: Option<DragListener<V>>,
}
impl<V> ElementInteraction<V> for StatefulInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V> ElementInteraction<V> for StatefulInteraction<V> {
fn as_stateful(&self) -> Option<&StatefulInteraction<V>> {
Some(self)
}
@ -713,10 +717,7 @@ where
}
}
impl<V> From<ElementId> for StatefulInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V> From<ElementId> for StatefulInteraction<V> {
fn from(id: ElementId) -> Self {
Self {
id,
@ -745,10 +746,7 @@ pub struct StatelessInteraction<V> {
drop_listeners: SmallVec<[(TypeId, Arc<DropListener<V>>); 2]>,
}
impl<V> StatelessInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V> StatelessInteraction<V> {
pub fn into_stateful(self, id: impl Into<ElementId>) -> StatefulInteraction<V> {
StatefulInteraction {
id: id.into(),
@ -840,10 +838,7 @@ impl<V> Default for StatelessInteraction<V> {
}
}
impl<V> ElementInteraction<V> for StatelessInteraction<V>
where
V: 'static + Send + Sync,
{
impl<V> ElementInteraction<V> for StatelessInteraction<V> {
fn as_stateful(&self) -> Option<&StatefulInteraction<V>> {
None
}
@ -918,9 +913,7 @@ pub struct ClickEvent {
pub struct Drag<S, R, V, E>
where
S: 'static + Send + Sync,
R: Fn(&mut V, &mut ViewContext<V>) -> E,
V: 'static + Send + Sync,
E: Element<ViewState = V>,
{
pub state: S,
@ -930,9 +923,7 @@ where
impl<S, R, V, E> Drag<S, R, V, E>
where
S: 'static + Send + Sync,
R: Fn(&mut V, &mut ViewContext<V>) -> E + Send + Sync,
V: 'static + Send + Sync,
E: Element<ViewState = V>,
{
pub fn new(state: S, render_drag_handle: R) -> Self {

View file

@ -6,12 +6,12 @@ use crate::{
};
use std::{marker::PhantomData, sync::Arc};
pub struct View<V: Send + Sync> {
pub struct View<V> {
state: Handle<V>,
render: Arc<dyn Fn(&mut V, &mut ViewContext<V>) -> AnyElement<V> + Send + Sync + 'static>,
}
impl<V: 'static + Send + Sync> View<V> {
impl<V> View<V> {
pub fn into_any(self) -> AnyView {
AnyView {
view: Arc::new(Mutex::new(self)),
@ -19,7 +19,7 @@ impl<V: 'static + Send + Sync> View<V> {
}
}
impl<V: Send + Sync> Clone for View<V> {
impl<V> Clone for View<V> {
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
@ -42,9 +42,7 @@ where
}
}
impl<V: 'static + Send + Sync, ParentViewState: 'static + Send + Sync>
IntoAnyElement<ParentViewState> for View<V>
{
impl<V, ParentViewState> IntoAnyElement<ParentViewState> for View<V> {
fn into_any(self) -> AnyElement<ParentViewState> {
AnyElement::new(EraseViewState {
view: self,
@ -53,7 +51,7 @@ impl<V: 'static + Send + Sync, ParentViewState: 'static + Send + Sync>
}
}
impl<V: 'static + Send + Sync> Element for View<V> {
impl<V> Element for View<V> {
type ViewState = ();
type ElementState = AnyElement<V>;
@ -94,26 +92,18 @@ impl<V: 'static + Send + Sync> Element for View<V> {
}
}
struct EraseViewState<V: 'static + Send + Sync, ParentV> {
struct EraseViewState<V, ParentV> {
view: View<V>,
parent_view_state_type: PhantomData<ParentV>,
}
impl<V, ParentV> IntoAnyElement<ParentV> for EraseViewState<V, ParentV>
where
V: 'static + Send + Sync,
ParentV: 'static + Send + Sync,
{
impl<V, ParentV> IntoAnyElement<ParentV> for EraseViewState<V, ParentV> {
fn into_any(self) -> AnyElement<ParentV> {
AnyElement::new(self)
}
}
impl<V, ParentV> Element for EraseViewState<V, ParentV>
where
V: 'static + Send + Sync,
ParentV: 'static + Send + Sync,
{
impl<V, ParentV> Element for EraseViewState<V, ParentV> {
type ViewState = ParentV;
type ElementState = AnyBox;
@ -150,14 +140,14 @@ where
}
}
trait ViewObject: 'static + Send + Sync {
trait ViewObject {
fn entity_id(&self) -> EntityId;
fn initialize(&mut self, cx: &mut WindowContext) -> AnyBox;
fn layout(&mut self, element: &mut AnyBox, cx: &mut WindowContext) -> LayoutId;
fn paint(&mut self, bounds: Bounds<Pixels>, element: &mut AnyBox, cx: &mut WindowContext);
}
impl<V: Send + Sync + 'static> ViewObject for View<V> {
impl<V: 'static + Send + Sync> ViewObject for View<V> {
fn entity_id(&self) -> EntityId {
self.state.entity_id
}

View file

@ -1129,7 +1129,7 @@ impl<'a, 'w> MainThread<WindowContext<'a, 'w>> {
}
impl Context for WindowContext<'_, '_> {
type EntityContext<'a, 'w, T: 'static + Send + Sync> = ViewContext<'a, 'w, T>;
type EntityContext<'a, 'w, T> = ViewContext<'a, 'w, T>;
type Result<T> = T;
fn entity<T: Send + Sync + 'static>(
@ -1145,7 +1145,7 @@ impl Context for WindowContext<'_, '_> {
self.entities.insert(slot, entity)
}
fn update_entity<T: Send + Sync + 'static, R>(
fn update_entity<T, R>(
&mut self,
handle: &Handle<T>,
update: impl FnOnce(&mut T, &mut Self::EntityContext<'_, '_, T>) -> R,
@ -1340,7 +1340,7 @@ impl<S> BorrowWindow for ViewContext<'_, '_, S> {
}
}
impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
impl<'a, 'w, V> ViewContext<'a, 'w, V> {
fn mutable(app: &'a mut AppContext, window: &'w mut Window, entity_id: EntityId) -> Self {
Self {
window_cx: WindowContext::mutable(app, window),
@ -1580,8 +1580,9 @@ impl<'a, 'w, V: Send + Sync + 'static> ViewContext<'a, 'w, V> {
f: impl FnOnce(WeakHandle<V>, AsyncWindowContext) -> Fut + Send + 'static,
) -> Task<R>
where
R: Send + 'static,
Fut: Future<Output = R> + Send + 'static,
V: 'static + Send + Sync,
R: 'static + Send,
Fut: 'static + Future<Output = R> + Send,
{
let handle = self.handle();
self.window_cx.spawn(move |_, cx| {
@ -1640,11 +1641,8 @@ impl<'a, 'w, V: EventEmitter + Send + Sync + 'static> ViewContext<'a, 'w, V> {
}
}
impl<'a, 'w, V> Context for ViewContext<'a, 'w, V>
where
V: 'static + Send + Sync,
{
type EntityContext<'b, 'c, U: 'static + Send + Sync> = ViewContext<'b, 'c, U>;
impl<'a, 'w, V> Context for ViewContext<'a, 'w, V> {
type EntityContext<'b, 'c, U> = ViewContext<'b, 'c, U>;
type Result<U> = U;
fn entity<T2: Send + Sync + 'static>(
@ -1654,7 +1652,7 @@ where
self.window_cx.entity(build_entity)
}
fn update_entity<U: 'static + Send + Sync, R>(
fn update_entity<U, R>(
&mut self,
handle: &Handle<U>,
update: impl FnOnce(&mut U, &mut Self::EntityContext<'_, '_, U>) -> R,

View file

@ -0,0 +1,132 @@
// impl<V> IntoAnyElement<V> for Modal
// where
// V: 'static + Send + Sync,
// {
// fn into_any(self) -> AnyElement<V> {
// self.render().into_any()
// }
// }
// name the function pub fn derive_into_any_element
// Defining a derive macro
use proc_macro::TokenStream;
use quote::{quote, format_ident};
use syn::{parse_macro_input, DeriveInput};
pub fn derive_into_any_element(input: TokenStream) -> TokenStream {
// Parse the input tokens into a syntax tree
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let generics = input.generics;
// Check for the presence of a #[view_type = Foo] attribute on the struct
let mut view_type = None;
for attr in &input.attrs {
if attr.path.is_ident("view_type") {
if let Ok(meta) = attr.parse_meta() {
if let syn::Meta::NameValue(nv) = meta {
if let syn::Lit::Str(lit) = nv.lit {
let view_type_token: proc_macro2::TokenStream =
syn::parse_str(&lit.value()).unwrap();
view_type = Some(view_type_token);
break;
}
}
}
}
}
let expanded = if let Some(view_type) = view_type {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
quote! {
impl #impl_generics gpui2::IntoAnyElement<#view_type> for #name #ty_generics
#where_clause
{
fn into_any(self) -> gpui2::AnyElement<#view_type> {
Self::render(self).into_any()
}
}
}
} else {
let mut trait_generics = generics.clone();
trait_generics.params.push(syn::parse_quote! {
ViewState: 'static + Send + Sync
});
let (_, ty_generics, _) = generics.split_for_impl();
let (impl_generics, _, where_clause) = trait_generics.split_for_impl();
let trampoline_name = format_ident!("{}{}", name, "Trampoline");
quote! {
struct #trampoline_name<S, E> {
contents: Option<E>,
phantom: std::marker::PhantomData<S>,
}
impl<S, E> #trampoline_name<S, E> {
fn new(contents: E) -> Self {
IntoAnyElementTrampolineName {
contents: Some(contents),
phantom: std::marker::PhantomData,
}
}
}
impl<S, E> Element for #trampoline_name<S, E> {
type ViewState = S;
type ElementState = AnyElement<S>;
fn id(&self) -> Option<crate::ElementId> {
None
}
fn initialize(
&mut self,
view_state: &mut Self::ViewState,
element_state: Option<Self::ElementState>,
cx: &mut ViewContext<Self::ViewState>,
) -> Self::ElementState {
self.contents.take().unwrap().render(cx)
}
fn layout(
&mut self,
view_state: &mut Self::ViewState,
element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>,
) -> crate::LayoutId {
element_state.layout(view_state, cx)
}
fn paint(
&mut self,
bounds: crate::Bounds<crate::Pixels>,
view_state: &mut Self::ViewState,
element_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>,
) {
element_state.paint(view_state, cx);
}
}
impl<S, E> IntoAnyElement<S> for IntoAnyElementTrampolineName<S, E> {
fn into_any(self) -> AnyElement<S> {
AnyElement::new(self)
}
}
impl #impl_generics gpui2::IntoAnyElement<ViewState> for #name #ty_generics
#where_clause
{
fn into_any(self) -> gpui2::AnyElement<ViewState> {
#trampoline_name::new(self).into_any()
}
}
}
};
TokenStream::from(expanded)
}

View file

@ -1,6 +1,7 @@
use proc_macro::TokenStream;
mod derive_element;
mod derive_into_any_element;
mod style_helpers;
#[proc_macro]
@ -12,3 +13,8 @@ pub fn style_helpers(args: TokenStream) -> TokenStream {
pub fn derive_element(input: TokenStream) -> TokenStream {
derive_element::derive_element(input)
}
#[proc_macro_derive(IntoAnyElement, attributes(view_type))]
pub fn derive_into_any_element(input: TokenStream) -> TokenStream {
derive_into_any_element::derive_into_any_element(input)
}

View file

@ -1,22 +1,17 @@
use std::marker::PhantomData;
use gpui2::{rems, AbsoluteLength};
use crate::prelude::*;
use crate::{Icon, IconButton, Label, Panel, PanelSide};
use gpui2::{div, rems, AbsoluteLength, IntoAnyElement};
#[derive(Element)]
pub struct AssistantPanel<S: 'static + Send + Sync> {
#[derive(IntoAnyElement)]
pub struct AssistantPanel {
id: ElementId,
state_type: PhantomData<S>,
current_side: PanelSide,
}
impl<S: 'static + Send + Sync> AssistantPanel<S> {
impl AssistantPanel {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
id: id.into(),
state_type: PhantomData,
current_side: PanelSide::default(),
}
}
@ -26,54 +21,56 @@ impl<S: 'static + Send + Sync> AssistantPanel<S> {
self
}
fn render(&mut self, view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
let color = ThemeColor::new(cx);
fn render<V>(mut self) -> impl IntoAnyElement<V> {
div()
Panel::new(self.id.clone(), cx)
.children(vec![div()
.flex()
.flex_col()
.h_full()
.px_2()
.gap_2()
// Header
.child(
div()
.flex()
.justify_between()
.gap_2()
.child(
div()
.flex()
.child(IconButton::new(Icon::Menu))
.child(Label::new("New Conversation")),
)
.child(
div()
.flex()
.items_center()
.gap_px()
.child(IconButton::new(Icon::SplitMessage))
.child(IconButton::new(Icon::Quote))
.child(IconButton::new(Icon::MagicWand))
.child(IconButton::new(Icon::Plus))
.child(IconButton::new(Icon::Maximize)),
),
)
// Chat Body
.child(
div()
.id("chat-body")
.w_full()
.flex()
.flex_col()
.gap_3()
.overflow_y_scroll()
.child(Label::new("Is this thing on?")),
)
.into_any()])
.side(self.current_side)
.width(AbsoluteLength::Rems(rems(32.)))
// let color = ThemeColor::new(cx);
// Panel::new(self.id, cx)
// .children(vec![div()
// .flex()
// .flex_col()
// .h_full()
// .px_2()
// .gap_2()
// // Header
// .child(
// div()
// .flex()
// .justify_between()
// .gap_2()
// .child(
// div()
// .flex()
// .child(IconButton::new(Icon::Menu))
// .child(Label::new("New Conversation")),
// )
// .child(
// div()
// .flex()
// .items_center()
// .gap_px()
// .child(IconButton::new(Icon::SplitMessage))
// .child(IconButton::new(Icon::Quote))
// .child(IconButton::new(Icon::MagicWand))
// .child(IconButton::new(Icon::Plus))
// .child(IconButton::new(Icon::Maximize)),
// ),
// )
// // Chat Body
// .child(
// div()
// .id("chat-body")
// .w_full()
// .flex()
// .flex_col()
// .gap_3()
// .overflow_y_scroll()
// .child(Label::new("Is this thing on?")),
// )
// .into_any()])
// .side(self.current_side)
// .width(AbsoluteLength::Rems(rems(32.)))
}
}
@ -82,29 +79,19 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
use gpui2::AppContext;
use crate::Story;
use super::*;
#[derive(Element)]
pub struct AssistantPanelStory<S: 'static + Send + Sync> {
state_type: PhantomData<S>,
}
#[derive(IntoAnyElement)]
pub struct AssistantPanelStory;
impl<S: 'static + Send + Sync> AssistantPanelStory<S> {
pub fn new() -> Self {
Self {
state_type: PhantomData,
}
}
fn render(
&mut self,
_view: &mut S,
cx: &mut ViewContext<S>,
) -> impl Element<ViewState = S> {
Story::container(cx)
.child(Story::title_for::<_, AssistantPanel<S>>(cx))
impl AssistantPanelStory {
fn render<V>(self, cx: &mut ViewContext<V>) -> impl IntoAnyElement<V> {
Story::container(self.0)
.child(Story::title_for::<_, AssistantPanel>(self.0))
.child(Story::label(cx, "Default"))
.child(AssistantPanel::new("assistant-panel"))
}

View file

@ -1,7 +1,7 @@
use std::marker::PhantomData;
use std::path::PathBuf;
use gpui2::Div;
use gpui2::{AppContext, Div};
use crate::prelude::*;
use crate::{h_stack, HighlightedText};
@ -9,33 +9,25 @@ use crate::{h_stack, HighlightedText};
#[derive(Clone)]
pub struct Symbol(pub Vec<HighlightedText>);
#[derive(Element)]
pub struct Breadcrumb<S: 'static + Send + Sync> {
state_type: PhantomData<S>,
#[derive(IntoAnyElement)]
pub struct Breadcrumb<'a> {
path: PathBuf,
symbols: Vec<Symbol>,
cx: &'a AppContext,
}
impl<S: 'static + Send + Sync> Breadcrumb<S> {
pub fn new(path: PathBuf, symbols: Vec<Symbol>) -> Self {
Self {
state_type: PhantomData,
path,
symbols,
}
impl<'a> Breadcrumb<'a> {
pub fn new(path: PathBuf, symbols: Vec<Symbol>, cx: &'a AppContext) -> Self {
Self { path, symbols, cx }
}
fn render_separator(&self, cx: &WindowContext) -> Div<S> {
fn render_separator<V>(&self, cx: &WindowContext) -> impl IntoAnyElement<V> {
let color = ThemeColor::new(cx);
div().child(" ").text_color(color.text_muted)
}
fn render(
&mut self,
view_state: &mut S,
cx: &mut ViewContext<S>,
) -> impl Element<ViewState = S> {
let color = ThemeColor::new(cx);
fn render<V>(mut self) -> impl IntoAnyElement<V> {
let color = ThemeColor::new(self.cx);
let symbols_len = self.symbols.len();

View file

@ -5,13 +5,13 @@ use chrono::NaiveDateTime;
use crate::prelude::*;
use crate::{Icon, IconButton, Input, Label, LabelColor};
#[derive(Element)]
pub struct ChatPanel<S: 'static + Send + Sync> {
#[derive(IntoAnyElement)]
pub struct ChatPanel {
element_id: ElementId,
messages: Vec<ChatMessage<S>>,
messages: Vec<ChatMessage>,
}
impl<S: 'static + Send + Sync> ChatPanel<S> {
impl ChatPanel {
pub fn new(element_id: impl Into<ElementId>) -> Self {
Self {
element_id: element_id.into(),
@ -19,14 +19,14 @@ impl<S: 'static + Send + Sync> ChatPanel<S> {
}
}
pub fn messages(mut self, messages: Vec<ChatMessage<S>>) -> Self {
pub fn messages(mut self, messages: Vec<ChatMessage>) -> Self {
self.messages = messages;
self
}
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
fn render<S: 'static + Send + Sync>(self) -> impl IntoAnyElement<S> {
div()
.id(self.element_id.clone())
.id(self.element_id)
.flex()
.flex_col()
.justify_between()
@ -62,7 +62,7 @@ impl<S: 'static + Send + Sync> ChatPanel<S> {
.flex_col()
.gap_3()
.overflow_y_scroll()
.children(self.messages.drain(..)),
.children(self.messages),
)
// Composer
.child(div().flex().my_2().child(Input::new("Message #design"))),
@ -70,39 +70,30 @@ impl<S: 'static + Send + Sync> ChatPanel<S> {
}
}
#[derive(Element)]
pub struct ChatMessage<S: 'static + Send + Sync> {
state_type: PhantomData<S>,
#[derive(IntoAnyElement)]
pub struct ChatMessage {
author: String,
text: String,
sent_at: NaiveDateTime,
}
impl<S: 'static + Send + Sync> ChatMessage<S> {
impl ChatMessage {
pub fn new(author: String, text: String, sent_at: NaiveDateTime) -> Self {
Self {
state_type: PhantomData,
author,
text,
sent_at,
}
}
fn render(&mut self, _view: &mut S, cx: &mut ViewContext<S>) -> impl Element<ViewState = S> {
fn render<S: 'static + Send + Sync>(mut self) -> impl Element<ViewState = S> {
div()
.flex()
.flex_col()
.child(
div()
.flex()
.gap_2()
.child(Label::new(self.author.clone()))
.child(
Label::new(self.sent_at.format("%m/%d/%Y").to_string())
.color(LabelColor::Muted),
),
)
.child(div().child(Label::new(self.text.clone())))
.child(div().flex().gap_2().child(Label::new(self.author)).child(
Label::new(self.sent_at.format("%m/%d/%Y").to_string()).color(LabelColor::Muted),
))
.child(div().child(Label::new(self.text)))
}
}

View file

@ -18,10 +18,7 @@ impl Story {
.bg(color.background)
}
pub fn title<S: 'static + Send + Sync>(
cx: &mut ViewContext<S>,
title: &str,
) -> impl Element<ViewState = S> {
pub fn title<V>(cx: &mut ViewContext<V>, title: &str) -> impl Element<ViewState = V> {
let color = ThemeColor::new(cx);
div()
@ -30,16 +27,11 @@ impl Story {
.child(title.to_owned())
}
pub fn title_for<S: 'static + Send + Sync, T>(
cx: &mut ViewContext<S>,
) -> impl Element<ViewState = S> {
pub fn title_for<V, T>(cx: &mut ViewContext<V>) -> impl Element<ViewState = V> {
Self::title(cx, std::any::type_name::<T>())
}
pub fn label<S: 'static + Send + Sync>(
cx: &mut ViewContext<S>,
label: &str,
) -> impl Element<ViewState = S> {
pub fn label<V>(cx: &mut ViewContext<V>, label: &str) -> impl Element<ViewState = V> {
let color = ThemeColor::new(cx);
div()

View file

@ -150,7 +150,7 @@ pub struct Themed<E> {
impl<E> IntoAnyElement<E::ViewState> for Themed<E>
where
E: Element,
E: 'static + Element + Send + Sync,
{
fn into_any(self) -> AnyElement<E::ViewState> {
AnyElement::new(self)
@ -160,7 +160,10 @@ where
#[derive(Default)]
struct ThemeStack(Vec<Theme>);
impl<E: Element> Element for Themed<E> {
impl<E> Element for Themed<E>
where
E: 'static + Element + Send + Sync,
{
type ViewState = E::ViewState;
type ElementState = E::ElementState;