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<()>;
}
pub trait ParentElement<S> {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<S>; 2]>;
pub trait ParentElement {
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
Self: Sized,
{
@ -33,7 +35,7 @@ pub trait ParentElement<S> {
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
Self: Sized,
{

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
use crate::{
BorrowWindow, Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, StyleHelpers,
Styled, ViewContext,
BorrowWindow, Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, Styled,
ViewContext,
};
use futures::FutureExt;
use refineable::RefinementCascade;
@ -98,5 +98,3 @@ impl<S> Styled for Img<S> {
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> {
fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
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 std::marker::PhantomData;
@ -68,5 +68,3 @@ impl<S> Styled for Svg<S> {
self.style.base()
}
}
impl<S> StyleHelpers for Svg<S> {}

View file

@ -516,3 +516,5 @@ pub trait StyleHelpers: Styled<Style = Style> {
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 {
type Style: Refineable + Default;
@ -14,7 +14,7 @@ pub trait Styled {
where
Self: Sized,
{
hoverable(self)
Hoverable::new(self)
}
// fn active(self) -> Pressable<Self>

View file

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

View file

@ -1,7 +1,8 @@
use crate::theme::{theme, Theme};
use gpui3::{
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 {
@ -129,6 +130,8 @@ impl CollabPanel {
.flex()
.justify_between()
.items_center()
.hover()
.fill(theme.lowest.base.active.background)
.child(div().flex().gap_1().text_sm().child(label))
.child(
div().flex().h_full().gap_1().items_center().child(