use std::marker::PhantomData; use crate::prelude::*; use crate::{theme, token, SystemColor}; #[derive(Clone, Copy)] enum TrafficLightColor { Red, Yellow, Green, } #[derive(Element)] struct TrafficLight { state_type: PhantomData, color: TrafficLightColor, window_has_focus: bool, } impl TrafficLight { fn new(color: TrafficLightColor, window_has_focus: bool) -> Self { Self { state_type: PhantomData, color, window_has_focus, } } fn render(&mut self, cx: &mut ViewContext) -> impl Element { let theme = theme(cx); let system_color = SystemColor::new(); let fill = match (self.window_has_focus, self.color) { (true, TrafficLightColor::Red) => system_color.mac_os_traffic_light_red, (true, TrafficLightColor::Yellow) => system_color.mac_os_traffic_light_yellow, (true, TrafficLightColor::Green) => system_color.mac_os_traffic_light_green, (false, _) => theme.lowest.base.active.background, }; div().w_3().h_3().rounded_full().fill(fill) } } #[derive(Element)] pub struct TrafficLights { state_type: PhantomData, window_has_focus: bool, } impl TrafficLights { pub fn new() -> Self { Self { state_type: PhantomData, window_has_focus: true, } } pub fn window_has_focus(mut self, window_has_focus: bool) -> Self { self.window_has_focus = window_has_focus; self } fn render(&mut self, cx: &mut ViewContext) -> impl Element { let theme = theme(cx); let token = token(); div() .flex() .items_center() .gap_2() .child(TrafficLight::new( TrafficLightColor::Red, self.window_has_focus, )) .child(TrafficLight::new( TrafficLightColor::Yellow, self.window_has_focus, )) .child(TrafficLight::new( TrafficLightColor::Green, self.window_has_focus, )) } } #[cfg(feature = "stories")] pub use stories::*; #[cfg(feature = "stories")] mod stories { use crate::Story; use super::*; #[derive(Element)] pub struct TrafficLightsStory { state_type: PhantomData, } impl TrafficLightsStory { pub fn new() -> Self { Self { state_type: PhantomData, } } fn render(&mut self, cx: &mut ViewContext) -> impl Element { Story::container(cx) .child(Story::title_for::<_, TrafficLights>(cx)) .child(Story::label(cx, "Default")) .child(TrafficLights::new()) .child(Story::label(cx, "Unfocused")) .child(TrafficLights::new().window_has_focus(false)) } } }