1use crate::{
2 div::div,
3 element::{Element, ParentElement},
4 style::StyleHelpers,
5 text::ArcCow,
6 themes::rose_pine,
7};
8use gpui::ViewContext;
9use playground_macros::Element;
10use std::{marker::PhantomData, rc::Rc};
11
12struct ButtonHandlers<V, D> {
13 click: Option<Rc<dyn Fn(&mut V, &D, &mut ViewContext<V>)>>,
14}
15
16impl<V, D> Default for ButtonHandlers<V, D> {
17 fn default() -> Self {
18 Self { click: None }
19 }
20}
21
22use crate as playground;
23#[derive(Element)]
24pub struct Button<V: 'static, D: 'static> {
25 handlers: ButtonHandlers<V, D>,
26 label: Option<ArcCow<'static, str>>,
27 icon: Option<ArcCow<'static, str>>,
28 data: Rc<D>,
29 view_type: PhantomData<V>,
30}
31
32// Impl block for buttons without data.
33// See below for an impl block for any button.
34impl<V: 'static> Button<V, ()> {
35 fn new() -> Self {
36 Self {
37 handlers: ButtonHandlers::default(),
38 label: None,
39 icon: None,
40 data: Rc::new(()),
41 view_type: PhantomData,
42 }
43 }
44
45 pub fn data<D: 'static>(self, data: D) -> Button<V, D> {
46 Button {
47 handlers: ButtonHandlers::default(),
48 label: self.label,
49 icon: self.icon,
50 data: Rc::new(data),
51 view_type: PhantomData,
52 }
53 }
54}
55
56// Impl block for *any* button.
57impl<V: 'static, D: 'static> Button<V, D> {
58 pub fn label(mut self, label: impl Into<ArcCow<'static, str>>) -> Self {
59 self.label = Some(label.into());
60 self
61 }
62
63 pub fn icon(mut self, icon: impl Into<ArcCow<'static, str>>) -> Self {
64 self.icon = Some(icon.into());
65 self
66 }
67
68 // pub fn click(self, handler: impl Fn(&mut V, &D, &mut ViewContext<V>) + 'static) -> Self {
69 // let data = self.data.clone();
70 // Self::click(self, MouseButton::Left, move |view, _, cx| {
71 // handler(view, data.as_ref(), cx);
72 // })
73 // }
74}
75
76pub fn button<V>() -> Button<V, ()> {
77 Button::new()
78}
79
80impl<V: 'static, D: 'static> Button<V, D> {
81 fn render(&mut self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
82 // TODO: Drive theme from the context
83 let button = div()
84 .fill(rose_pine::dawn().error(0.5))
85 .h_4()
86 .children(self.label.clone());
87
88 button
89
90 // TODO: Event handling
91 // if let Some(handler) = self.handlers.click.clone() {
92 // let data = self.data.clone();
93 // // button.mouse_down(MouseButton::Left, move |view, event, cx| {
94 // // handler(view, data.as_ref(), cx)
95 // // })
96 // } else {
97 // button
98 // }
99 }
100}