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 style = element_state
96 .pressed
97 .load(SeqCst)
98 .then_some(self.pressed_style.clone());
99 let slot = self.cascade_slot;
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) {
106 dbg!("pressed");
107 pressed.store(true, SeqCst);
108 cx.notify();
109 }
110 }
111 });
112 let pressed = element_state.pressed.clone();
113 cx.on_mouse_event(move |_, _: &MouseUpEvent, phase, cx| {
114 if phase == DispatchPhase::Capture {
115 if pressed.load(SeqCst) {
116 dbg!("released");
117 pressed.store(false, SeqCst);
118 cx.notify();
119 }
120 }
121 });
122
123 self.child
124 .paint(bounds, state, &mut element_state.child_state, cx);
125 }
126}
127
128impl<E: ParentElement + Styled> ParentElement for Pressable<E> {
129 type State = E::State;
130
131 fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
132 self.child.children_mut()
133 }
134}
135
136// use crate::{
137// element::{AnyElement, Element, IntoElement, Layout, ParentElement},
138// interactive::{InteractionHandlers, Interactive},
139// style::{Style, StyleHelpers, Styleable},
140// ViewContext,
141// };
142// use anyhow::Result;
143// use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
144// use refineable::{CascadeSlot, Refineable, RefinementCascade};
145// use smallvec::SmallVec;
146// use std::{cell::Cell, rc::Rc};
147
148// pub struct Pressable<E: Styleable> {
149// pressed: Rc<Cell<bool>>,
150// pressed_style: <E::Style as Refineable>::Refinement,
151// cascade_slot: CascadeSlot,
152// child: E,
153// }
154
155// pub fn pressable<E: Styleable>(mut child: E) -> Pressable<E> {
156// Pressable {
157// pressed: Rc::new(Cell::new(false)),
158// pressed_style: Default::default(),
159// cascade_slot: child.style_cascade().reserve(),
160// child,
161// }
162// }
163
164// impl<E: Styleable> Styleable for Pressable<E> {
165// type Style = E::Style;
166
167// fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
168// &mut self.pressed_style
169// }
170
171// fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
172// self.child.style_cascade()
173// }
174// }
175
176// impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
177// type PaintState = E::PaintState;
178
179// fn layout(
180// &mut self,
181// view: &mut V,
182// cx: &mut ViewContext<V>,
183// ) -> Result<(LayoutId, Self::PaintState)>
184// where
185// Self: Sized,
186// {
187// self.child.layout(view, cx)
188// }
189
190// fn paint(
191// &mut self,
192// view: &mut V,
193// parent_origin: Vector2F,
194// layout: &Layout,
195// paint_state: &mut Self::PaintState,
196// cx: &mut ViewContext<V>,
197// ) where
198// Self: Sized,
199// {
200// let slot = self.cascade_slot;
201// let style = self.pressed.get().then_some(self.pressed_style.clone());
202// self.style_cascade().set(slot, style);
203
204// let pressed = self.pressed.clone();
205// let bounds = layout.bounds + parent_origin;
206// cx.on_event(layout.order, move |_view, event: &MouseButtonEvent, cx| {
207// if event.is_down {
208// if bounds.contains_point(event.position) {
209// pressed.set(true);
210// cx.repaint();
211// }
212// } else if pressed.get() {
213// pressed.set(false);
214// cx.repaint();
215// }
216// });
217
218// self.child
219// .paint(view, parent_origin, layout, paint_state, cx);
220// }
221// }
222
223// impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Pressable<E> {
224// fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
225// self.child.interaction_handlers()
226// }
227// }
228
229// impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Pressable<E> {
230// fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
231// self.child.children_mut()
232// }
233// }
234
235// impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Pressable<E> {
236// type Element = Self;
237
238// fn into_element(self) -> Self::Element {
239// self
240// }
241// }