Checkpoint

This commit is contained in:
Antonio Scandurra 2023-10-10 16:47:09 +02:00
parent 48a12be538
commit 96fbf9fd06
11 changed files with 77 additions and 55 deletions

View file

@ -22,10 +22,12 @@ pub trait Element: 'static {
) -> Result<()>; ) -> Result<()>;
} }
pub trait ParentElement<S> { pub trait ParentElement {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<S>; 2]>; type State;
fn child(mut self, child: impl IntoAnyElement<S>) -> Self fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]>;
fn child(mut self, child: impl IntoAnyElement<Self::State>) -> Self
where where
Self: Sized, Self: Sized,
{ {
@ -33,7 +35,7 @@ pub trait ParentElement<S> {
self self
} }
fn children(mut self, iter: impl IntoIterator<Item = impl IntoAnyElement<S>>) -> Self fn children(mut self, iter: impl IntoIterator<Item = impl IntoAnyElement<Self::State>>) -> Self
where where
Self: Sized, Self: Sized,
{ {

View file

@ -6,6 +6,7 @@ mod svg;
mod text; mod text;
pub use div::*; pub use div::*;
pub use hoverable::*;
pub use img::*; pub use img::*;
pub use stateless::*; pub use stateless::*;
pub use svg::*; pub use svg::*;

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
AnyElement, Bounds, Element, Interactive, LayoutId, MouseEventListeners, Overflow, AnyElement, Bounds, Element, Interactive, LayoutId, MouseEventListeners, Overflow,
ParentElement, Pixels, Point, Refineable, RefinementCascade, Result, Style, StyleHelpers, ParentElement, Pixels, Point, Refineable, RefinementCascade, Result, Style, Styled,
Styled, ViewContext, ViewContext,
}; };
use parking_lot::Mutex; use parking_lot::Mutex;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -249,16 +249,16 @@ impl<V> Styled for Div<V> {
} }
} }
impl<V> StyleHelpers for Div<V> {}
impl<V: Send + Sync + 'static> Interactive<V> for Div<V> { impl<V: Send + Sync + 'static> Interactive<V> for Div<V> {
fn listeners(&mut self) -> &mut MouseEventListeners<V> { fn listeners(&mut self) -> &mut MouseEventListeners<V> {
&mut self.listeners &mut self.listeners
} }
} }
impl<V: 'static> ParentElement<V> for Div<V> { impl<S: 'static> ParentElement for Div<S> {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> { type State = S;
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<S>; 2]> {
&mut self.children &mut self.children
} }
} }

View file

@ -1,26 +1,33 @@
use crate::{ use crate::{
Bounds, Element, Interactive, MouseEventListeners, Pixels, Style, Styled, ViewContext, AnyElement, Bounds, DispatchPhase, Element, Interactive, MouseEventListeners, MouseMoveEvent,
ParentElement, Pixels, Styled, ViewContext,
}; };
use anyhow::Result; use anyhow::Result;
use refineable::{CascadeSlot, RefinementCascade}; use refineable::{CascadeSlot, Refineable, RefinementCascade};
use std::{cell::Cell, rc::Rc}; use smallvec::SmallVec;
use std::sync::{
pub fn hoverable<E: Styled>(mut child: E) -> Hoverable<E> { atomic::{AtomicBool, Ordering::SeqCst},
Hoverable { Arc,
hovered: Rc::new(Cell::new(false)), };
cascade_slot: child.style_cascade().reserve(),
hovered_style: Default::default(),
child,
}
}
pub struct Hoverable<E: Styled> { pub struct Hoverable<E: Styled> {
hovered: Rc<Cell<bool>>, hovered: Arc<AtomicBool>,
cascade_slot: CascadeSlot, cascade_slot: CascadeSlot,
hovered_style: RefinementCascade<E::Style>, hovered_style: <E::Style as Refineable>::Refinement,
child: E, child: E,
} }
impl<E: Styled> Hoverable<E> {
pub fn new(mut child: E) -> Self {
Self {
hovered: Arc::new(AtomicBool::new(false)),
cascade_slot: child.style_cascade().reserve(),
hovered_style: Default::default(),
child,
}
}
}
impl<E> Styled for Hoverable<E> impl<E> Styled for Hoverable<E>
where where
E: Styled, E: Styled,
@ -61,22 +68,30 @@ impl<E: Element + Styled> Element for Hoverable<E> {
frame_state: &mut Self::FrameState, frame_state: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>, cx: &mut ViewContext<Self::State>,
) -> Result<()> { ) -> Result<()> {
todo!() let hovered = bounds.contains_point(cx.mouse_position());
// self.hovered.set(bounds.contains_point(cx.mouse_position())); let slot = self.cascade_slot;
let style = hovered.then_some(self.hovered_style.clone());
self.style_cascade().set(slot, style);
self.hovered.store(hovered, SeqCst);
// let slot = self.cascade_slot; let hovered = self.hovered.clone();
// let style = self.hovered.get().then_some(self.hovered_style.clone()); cx.on_mouse_event(move |event: &MouseMoveEvent, phase, cx| {
// self.style_cascade().set(slot, style); if phase == DispatchPhase::Capture {
if bounds.contains_point(event.position) != hovered.load(SeqCst) {
cx.notify();
}
}
});
// let hovered = self.hovered.clone(); self.child.paint(bounds, state, frame_state, cx)?;
// cx.on_event(layout.order, move |_view, _: &MouseMovedEvent, cx| { Ok(())
// cx.bubble_event(); }
// if bounds.contains_point(cx.mouse_position()) != hovered.get() { }
// cx.repaint();
// } impl<E: ParentElement + Styled> ParentElement for Hoverable<E> {
// }); type State = E::State;
// self.child fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
// .paint(view, parent_origin, layout, paint_state, cx); self.child.children_mut()
} }
} }

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
BorrowWindow, Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, StyleHelpers, BorrowWindow, Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, Styled,
Styled, ViewContext, ViewContext,
}; };
use futures::FutureExt; use futures::FutureExt;
use refineable::RefinementCascade; use refineable::RefinementCascade;
@ -98,5 +98,3 @@ impl<S> Styled for Img<S> {
self.style.base() self.style.base()
} }
} }
impl<S> StyleHelpers for Img<S> {}

View file

@ -85,8 +85,6 @@ impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
} }
} }
impl<E: Styleable<Style = Style>> StyleHelpers for Pressable<E> {}
impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> { impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> { fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
self.child.interaction_handlers() self.child.interaction_handlers()

View file

@ -1,4 +1,4 @@
use crate::{Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, StyleHelpers, Styled}; use crate::{Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, Styled};
use refineable::RefinementCascade; use refineable::RefinementCascade;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -68,5 +68,3 @@ impl<S> Styled for Svg<S> {
self.style.base() self.style.base()
} }
} }
impl<S> StyleHelpers for Svg<S> {}

View file

@ -516,3 +516,5 @@ pub trait StyleHelpers: Styled<Style = Style> {
self self
} }
} }
impl<E: Styled<Style = Style>> StyleHelpers for E {}

View file

@ -1,4 +1,4 @@
use crate::{Refineable, RefinementCascade}; use crate::{Hoverable, Refineable, RefinementCascade};
pub trait Styled { pub trait Styled {
type Style: Refineable + Default; type Style: Refineable + Default;
@ -14,7 +14,7 @@ pub trait Styled {
where where
Self: Sized, Self: Sized,
{ {
hoverable(self) Hoverable::new(self)
} }
// fn active(self) -> Pressable<Self> // fn active(self) -> Pressable<Self>

View file

@ -2,10 +2,11 @@ use crate::{
image_cache::RenderImageParams, px, size, AnyView, AppContext, AsyncWindowContext, image_cache::RenderImageParams, px, size, AnyView, AppContext, AsyncWindowContext,
AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId, AvailableSpace, BorrowAppContext, Bounds, BoxShadow, Context, Corners, DevicePixels, DisplayId,
Edges, Effect, Element, EntityId, Event, FontId, GlyphId, Handle, Hsla, ImageData, IsZero, Edges, Effect, Element, EntityId, Event, FontId, GlyphId, Handle, Hsla, ImageData, IsZero,
LayoutId, MainThread, MainThreadOnly, MonochromeSprite, Path, Pixels, PlatformAtlas, LayoutId, MainThread, MainThreadOnly, MonochromeSprite, MouseMoveEvent, Path, Pixels,
PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams, RenderSvgParams, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Quad, Reference, RenderGlyphParams,
ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style, TaffyLayoutEngine, Task, RenderSvgParams, ScaledPixels, SceneBuilder, Shadow, SharedString, Size, Style,
Underline, UnderlineStyle, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS, TaffyLayoutEngine, Task, Underline, UnderlineStyle, WeakHandle, WindowOptions,
SUBPIXEL_VARIANTS,
}; };
use anyhow::Result; use anyhow::Result;
use collections::HashMap; use collections::HashMap;
@ -619,6 +620,10 @@ impl<'a, 'w> WindowContext<'a, 'w> {
fn dispatch_event(&mut self, event: Event) -> bool { fn dispatch_event(&mut self, event: Event) -> bool {
if let Some(any_mouse_event) = event.mouse_event() { if let Some(any_mouse_event) = event.mouse_event() {
if let Some(MouseMoveEvent { position, .. }) = any_mouse_event.downcast_ref() {
self.window.mouse_position = *position;
}
if let Some(mut handlers) = self if let Some(mut handlers) = self
.window .window
.mouse_event_handlers .mouse_event_handlers

View file

@ -1,7 +1,8 @@
use crate::theme::{theme, Theme}; use crate::theme::{theme, Theme};
use gpui3::{ use gpui3::{
div, img, svg, view, AppContext, Context, Element, Interactive, IntoAnyElement, MouseButton, div, img, svg, view, AppContext, Context, Element, Interactive, IntoAnyElement, MouseButton,
ParentElement, ScrollState, SharedString, StyleHelpers, View, ViewContext, WindowContext, ParentElement, ScrollState, SharedString, StyleHelpers, Styled, View, ViewContext,
WindowContext,
}; };
pub struct CollabPanel { pub struct CollabPanel {
@ -129,6 +130,8 @@ impl CollabPanel {
.flex() .flex()
.justify_between() .justify_between()
.items_center() .items_center()
.hover()
.fill(theme.lowest.base.active.background)
.child(div().flex().gap_1().text_sm().child(label)) .child(div().flex().gap_1().text_sm().child(label))
.child( .child(
div().flex().h_full().gap_1().items_center().child( div().flex().h_full().gap_1().items_center().child(