1use crate::{
2 AnyElement, Bounds, DispatchPhase, Element, Interactive, MouseDownEvent, MouseEventListeners,
3 MouseUpEvent, ParentElement, Pixels, StatefulElement, Styled, ViewContext,
4};
5use refineable::{CascadeSlot, Refineable, RefinementCascade};
6use smallvec::SmallVec;
7use std::sync::{
8 atomic::{AtomicBool, Ordering::SeqCst},
9 Arc,
10};
11
12pub struct Pressable<E: Styled> {
13 cascade_slot: CascadeSlot,
14 pressed_style: <E::Style as Refineable>::Refinement,
15 child: E,
16}
17
18pub struct PressableState<S> {
19 pressed: Arc<AtomicBool>,
20 child_state: S,
21}
22
23impl<E: Styled> Pressable<E> {
24 pub fn new(mut child: E) -> Self {
25 Self {
26 cascade_slot: child.style_cascade().reserve(),
27 pressed_style: Default::default(),
28 child,
29 }
30 }
31}
32
33impl<E> Styled for Pressable<E>
34where
35 E: Styled,
36{
37 type Style = E::Style;
38
39 fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
40 self.child.style_cascade()
41 }
42
43 fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
44 &mut self.pressed_style
45 }
46}
47
48impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Pressable<E> {
49 fn listeners(&mut self) -> &mut MouseEventListeners<S> {
50 self.child.listeners()
51 }
52}
53
54impl<E> Element for Pressable<E>
55where
56 E: Styled + StatefulElement,
57 <E as Styled>::Style: 'static + Refineable + Send + Sync + Default,
58 <<E as Styled>::Style as Refineable>::Refinement: 'static + Refineable + Send + Sync + Default,
59{
60 type ViewState = E::ViewState;
61 type ElementState = PressableState<E::ElementState>;
62
63 fn layout(
64 &mut self,
65 state: &mut Self::ViewState,
66 element_state: Option<Self::ElementState>,
67 cx: &mut ViewContext<Self::ViewState>,
68 ) -> (crate::LayoutId, Self::ElementState) {
69 if let Some(element_state) = element_state {
70 let (id, child_state) = self
71 .child
72 .layout(state, Some(element_state.child_state), cx);
73 let element_state = PressableState {
74 pressed: element_state.pressed,
75 child_state,
76 };
77 (id, element_state)
78 } else {
79 let (id, child_state) = self.child.layout(state, None, cx);
80 let element_state = PressableState {
81 pressed: Default::default(),
82 child_state,
83 };
84 (id, element_state)
85 }
86 }
87
88 fn paint(
89 &mut self,
90 bounds: Bounds<Pixels>,
91 state: &mut Self::ViewState,
92 element_state: &mut Self::ElementState,
93 cx: &mut ViewContext<Self::ViewState>,
94 ) {
95 let slot = self.cascade_slot;
96 let style = element_state
97 .pressed
98 .load(SeqCst)
99 .then_some(self.pressed_style.clone());
100 self.style_cascade().set(slot, style);
101
102 let pressed = element_state.pressed.clone();
103 cx.on_mouse_event(move |_, event: &MouseDownEvent, phase, cx| {
104 if phase == DispatchPhase::Capture {
105 if bounds.contains_point(event.position) != pressed.load(SeqCst) {
106 cx.notify();
107 }
108 }
109 });
110 let hovered = element_state.pressed.clone();
111 cx.on_mouse_event(move |_, event: &MouseUpEvent, phase, cx| {
112 if phase == DispatchPhase::Capture {
113 if bounds.contains_point(event.position) != hovered.load(SeqCst) {
114 cx.notify();
115 }
116 }
117 });
118
119 self.child
120 .paint(bounds, state, &mut element_state.child_state, cx);
121 }
122}
123
124impl<E: ParentElement + Styled> ParentElement for Pressable<E> {
125 type State = E::State;
126
127 fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
128 self.child.children_mut()
129 }
130}
131
132// use crate::{
133// element::{AnyElement, Element, IntoElement, Layout, ParentElement},
134// interactive::{InteractionHandlers, Interactive},
135// style::{Style, StyleHelpers, Styleable},
136// ViewContext,
137// };
138// use anyhow::Result;
139// use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
140// use refineable::{CascadeSlot, Refineable, RefinementCascade};
141// use smallvec::SmallVec;
142// use std::{cell::Cell, rc::Rc};
143
144// pub struct Pressable<E: Styleable> {
145// pressed: Rc<Cell<bool>>,
146// pressed_style: <E::Style as Refineable>::Refinement,
147// cascade_slot: CascadeSlot,
148// child: E,
149// }
150
151// pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
152// Pressable {
153// pressed: Rc::new(Cell::new(false)),
154// pressed_style: Default::default(),
155// cascade_slot: child.style_cascade().reserve(),
156// child,
157// }
158// }
159
160// impl<E: Styleable> Styleable for Pressable<E> {
161// type Style = E::Style;
162
163// fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
164// &mut self.pressed_style
165// }
166
167// fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
168// self.child.style_cascade()
169// }
170// }
171
172// impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
173// type PaintState = E::PaintState;
174
175// fn layout(
176// &mut self,
177// view: &mut V,
178// cx: &mut ViewContext<V>,
179// ) -> Result<(LayoutId, Self::PaintState)>
180// where
181// Self: Sized,
182// {
183// self.child.layout(view, cx)
184// }
185
186// fn paint(
187// &mut self,
188// view: &mut V,
189// parent_origin: Vector2F,
190// layout: &Layout,
191// paint_state: &mut Self::PaintState,
192// cx: &mut ViewContext<V>,
193// ) where
194// Self: Sized,
195// {
196// let slot = self.cascade_slot;
197// let style = self.pressed.get().then_some(self.pressed_style.clone());
198// self.style_cascade().set(slot, style);
199
200// let pressed = self.pressed.clone();
201// let bounds = layout.bounds + parent_origin;
202// cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
203// if event.is_down {
204// if bounds.contains_point(event.position) {
205// pressed.set(true);
206// cx.repaint();
207// }
208// } else if pressed.get() {
209// pressed.set(false);
210// cx.repaint();
211// }
212// });
213
214// self.child
215// .paint(view, parent_origin, layout, paint_state, cx);
216// }
217// }
218
219// impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
220// fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
221// self.child.interaction_handlers()
222// }
223// }
224
225// impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
226// fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
227// self.child.children_mut()
228// }
229// }
230
231// impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
232// type Element = Self;
233
234// fn into_element(self) -> Self::Element {
235// self
236// }
237// }