components.rs

  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}