#![allow(dead_code, unused_variables)] use frame::{length::auto, *}; use gpui::{AnyElement, Element, LayoutContext, View, ViewContext}; use std::{borrow::Cow, cell::RefCell, marker::PhantomData, rc::Rc}; use themes::{rose_pine, ThemeColors}; use tokens::{margin::m4, text::lg}; mod color; mod frame; mod themes; mod tokens; #[derive(Element, Clone, Default)] pub struct Playground(PhantomData); impl Frame {} impl Playground { pub fn render(&mut self, _: &mut V, _: &mut gpui::ViewContext) -> impl Element { workspace(&rose_pine::dawn()) } } fn workspace(theme: &ThemeColors) -> impl Element { column() .size(auto()) .fill(theme.base(0.1)) .child(title_bar(theme)) .child(stage(theme)) .child(status_bar(theme)) } fn title_bar(theme: &ThemeColors) -> impl Element { row().fill(theme.surface(1.0)) } fn stage(theme: &ThemeColors) -> impl Element { row().fill(theme.surface(0.9)) } fn status_bar(theme: &ThemeColors) -> impl Element { row().fill(theme.surface(0.1)) } pub trait DialogDelegate: 'static {} impl DialogDelegate for () {} #[derive(Element)] pub struct Dialog> { title: Cow<'static, str>, description: Cow<'static, str>, delegate: Option>>, buttons: Vec AnyElement>>, view_type: PhantomData, } pub fn dialog( title: impl Into>, description: impl Into>, ) -> Dialog { Dialog { title: title.into(), description: description.into(), delegate: None, buttons: Vec::new(), view_type: PhantomData, } } impl> Dialog { pub fn delegate(mut self, delegate: D) -> Dialog { let old_delegate = self.delegate.replace(Rc::new(RefCell::new(delegate))); debug_assert!(old_delegate.is_none(), "delegate already set"); self } pub fn button(mut self, label: L, data: Data, handler: H) -> Self where L: 'static + Into>, Data: 'static + Clone, H: ClickHandler, { let label = label.into(); self.buttons.push(Box::new(move || { button(label).data(data).click(handler).into_any() })); self } } #[derive(Element)] struct Button> { label: Cow<'static, str>, click_handler: Option, data: Option, view_type: PhantomData, } pub trait ClickHandler: 'static { fn handle(&self, view: &mut V, data: &D, cx: &mut ViewContext); } impl)> ClickHandler for F { fn handle(&self, view: &mut V, data: &M, cx: &mut ViewContext) { self(view, data, cx) } } impl ClickHandler for () { fn handle(&self, view: &mut V, data: &D, cx: &mut ViewContext) {} } fn button(label: impl Into>) -> Button where V: View, { Button { label: label.into(), click_handler: None, data: None, view_type: PhantomData, } } impl Button where V: View, F: ClickHandler, { fn render(&mut self, _: &mut V, _: &mut LayoutContext) -> AnyElement { // TODO! Handle click etc row().child(text(self.label.clone())).into_any() } } // impl Button // where // V: View, // F: ClickHandler, // { // fn render(&mut self, _: &mut V, _: &mut LayoutContext) -> impl Element { // // TODO! Handle click etc // row() // .fill(theme.colors.primary(5)) // .child(text(self.label.clone()).text_color(theme.colors.on_primary())) // } // } // struct Tab { // active: bool, // } // impl Tab // where // V: View, // { // fn tab(&mut self, _: &mut V, _: &mut LayoutContext) -> impl Element { // let theme = todo!(); // // TODO! Handle click etc // row() // .fill(theme.colors.neutral(6)) // .child(text(self.label.clone()).text_color(theme.colors.on_neutral())) // } // } impl Button { fn data(self, data: D) -> Button where D: 'static, { Button { label: self.label, click_handler: self.click_handler, data: Some(data), view_type: self.view_type, } } } impl Button { fn click(self, handler: H) -> Button where H: 'static + ClickHandler, { Button { label: self.label, click_handler: Some(handler), data: self.data, view_type: self.view_type, } } } impl> Dialog { pub fn render(&mut self, _: &mut V, _: &mut gpui::ViewContext) -> AnyElement { column() .child(text(self.title.clone()).text_size(lg())) .child(text(self.description.clone()).margins((m4(), auto()))) .child(row().children(self.buttons.drain(..).map(|button| (button)()))) .into_any() } }