1use crate::{
2 Bounds, Element, Interactive, MouseEventListeners, Pixels, Style, Styled, ViewContext,
3};
4use anyhow::Result;
5use refineable::{CascadeSlot, RefinementCascade};
6use std::{cell::Cell, rc::Rc};
7
8pub fn hoverable<E: Styled>(mut child: E) -> Hoverable<E> {
9 Hoverable {
10 hovered: Rc::new(Cell::new(false)),
11 cascade_slot: child.style_cascade().reserve(),
12 hovered_style: Default::default(),
13 child,
14 }
15}
16
17pub struct Hoverable<E: Styled> {
18 hovered: Rc<Cell<bool>>,
19 cascade_slot: CascadeSlot,
20 hovered_style: RefinementCascade<E::Style>,
21 child: E,
22}
23
24impl<E> Styled for Hoverable<E>
25where
26 E: Styled,
27{
28 type Style = E::Style;
29
30 fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
31 self.child.style_cascade()
32 }
33
34 fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
35 &mut self.hovered_style
36 }
37}
38
39impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Hoverable<E> {
40 fn listeners(&mut self) -> &mut MouseEventListeners<S> {
41 self.child.listeners()
42 }
43}
44
45impl<E: Element + Styled> Element for Hoverable<E> {
46 type State = E::State;
47 type FrameState = E::FrameState;
48
49 fn layout(
50 &mut self,
51 state: &mut Self::State,
52 cx: &mut ViewContext<Self::State>,
53 ) -> Result<(crate::LayoutId, Self::FrameState)> {
54 Ok(self.child.layout(state, cx)?)
55 }
56
57 fn paint(
58 &mut self,
59 bounds: Bounds<Pixels>,
60 state: &mut Self::State,
61 frame_state: &mut Self::FrameState,
62 cx: &mut ViewContext<Self::State>,
63 ) -> Result<()> {
64 todo!()
65 // self.hovered.set(bounds.contains_point(cx.mouse_position()));
66
67 // let slot = self.cascade_slot;
68 // let style = self.hovered.get().then_some(self.hovered_style.clone());
69 // self.style_cascade().set(slot, style);
70
71 // let hovered = self.hovered.clone();
72 // cx.on_event(layout.order, move |_view, _: &MouseMovedEvent, cx| {
73 // cx.bubble_event();
74 // if bounds.contains_point(cx.mouse_position()) != hovered.get() {
75 // cx.repaint();
76 // }
77 // });
78
79 // self.child
80 // .paint(view, parent_origin, layout, paint_state, cx);
81 }
82}